Skip to content
Snippets Groups Projects
Commit 43904807 authored by Alexandru Bercuci's avatar Alexandru Bercuci
Browse files

update online parameter structure / definitions for TRD2D

parent 04973491
No related branches found
No related tags found
1 merge request!19952D online unpacker. Updated versions for the algo and the FASP message.
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
#include "ReadoutConfig.h" #include "ReadoutConfig.h"
//#include "CbmTrdAddress.h" //#include "CbmTrdAddress.h"
#include "AlgoFairloggerCompat.h"
#include <cassert> #include <cassert>
#include <iomanip> #include <iomanip>
...@@ -51,6 +52,16 @@ namespace cbm::algo::trd2d ...@@ -51,6 +52,16 @@ namespace cbm::algo::trd2d
} }
// ------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------
// --- List of ASICs registered to the ROB ---------------------
std::vector<uint8_t> ReadoutConfig::GetAsicList(uint16_t equipmentId)
{
std::vector<uint8_t> result;
for (auto& entry : fChannelMap[equipmentId])
result.push_back(entry.first);
return result;
}
// ------------------------------------------------------------------------------------
// --- Number of Channels for a component / equipment, asic pair --------------------- // --- Number of Channels for a component / equipment, asic pair ---------------------
size_t ReadoutConfig::GetNumChans(uint16_t equipmentId, uint16_t asicId) size_t ReadoutConfig::GetNumChans(uint16_t equipmentId, uint16_t asicId)
...@@ -58,8 +69,10 @@ namespace cbm::algo::trd2d ...@@ -58,8 +69,10 @@ namespace cbm::algo::trd2d
size_t result = 0; size_t result = 0;
auto it = fChannelMap.find(equipmentId); auto it = fChannelMap.find(equipmentId);
if (it != fChannelMap.end()) { if (it != fChannelMap.end()) {
if (asicId < fChannelMap[equipmentId].size()) { auto fiberMap = fChannelMap[equipmentId];
result = fChannelMap[equipmentId][asicId].size(); auto jt = fiberMap.find(asicId);
if (jt != fiberMap.end()) {
result = fiberMap[asicId].size();
} }
} }
return result; return result;
...@@ -67,16 +80,17 @@ namespace cbm::algo::trd2d ...@@ -67,16 +80,17 @@ namespace cbm::algo::trd2d
// ------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------
// --- Initialise the component mapping structure ---------------------------------- // --- Initialise the component mapping structure ----------------------------------
void ReadoutConfig::InitComponentMap(const std::map<uint32_t, uint16_t[NCROBMOD]>& map) void ReadoutConfig::InitComponentMap(const std::map<uint32_t, std::vector<uint16_t>>& map)
{ {
// Receive map (moduleId, crobId) -> (equipId) // Receive map (moduleId, crobId) -> (equipId)
// Invert to obtain component map (equipId) -> (module iq, crob id) // Invert to obtain component map (equipId) -> (module iq, crob id)
for (auto& entry : map) { for (auto& entry : map) {
uint16_t mod_id = entry.first; uint16_t mod_id = entry.first;
for (uint8_t rob_id = 0; rob_id < NCROBMOD; rob_id++) { //for (uint8_t eq_id = 0; eq_id < NROBMOD * NELINKROB; eq_id++) {
uint16_t eq_id = entry.second[rob_id]; uint8_t eq_id = 0;
if (!eq_id) continue; for (const auto& eq_add : entry.second) {
fReadoutMap[eq_id] = {mod_id, rob_id}; //uint16_t eq_id = entry.second[elink_id];
fReadoutMap[eq_add] = {mod_id, eq_id++};
} }
} }
} }
...@@ -90,12 +104,10 @@ namespace cbm::algo::trd2d ...@@ -90,12 +104,10 @@ namespace cbm::algo::trd2d
for (auto compMap : channelMap) { for (auto compMap : channelMap) {
uint16_t equipmentId = compMap.first; uint16_t equipmentId = compMap.first;
uint16_t numAsics = compMap.second.size(); uint16_t numAsics = compMap.second.size();
fChannelMap[equipmentId].resize(numAsics);
for (auto asicMap : compMap.second) { for (auto asicMap : compMap.second) {
uint16_t asicId = asicMap.first; uint16_t asicId = asicMap.first;
uint16_t numChans = asicMap.second.size(); uint16_t numChans = asicMap.second.size();
fChannelMap[equipmentId][asicId].resize(numChans); fChannelMap[equipmentId][asicId].resize(16);
for (auto chanMap : asicMap.second) { for (auto chanMap : asicMap.second) {
uint16_t chanId = chanMap.first; uint16_t chanId = chanMap.first;
std::tuple<int32_t, bool, uint64_t> chanPars = chanMap.second; std::tuple<int32_t, bool, uint64_t> chanPars = chanMap.second;
...@@ -109,14 +121,17 @@ namespace cbm::algo::trd2d ...@@ -109,14 +121,17 @@ namespace cbm::algo::trd2d
// --- Mapping (equimentId, asicId, channel) -> (pad address, mask flag, daq offset) ----- // --- Mapping (equimentId, asicId, channel) -> (pad address, mask flag, daq offset) -----
ReadoutConfig::ChanMapping ReadoutConfig::ChanMap(uint16_t equipId, uint16_t asic, uint16_t chan) ReadoutConfig::ChanMapping ReadoutConfig::ChanMap(uint16_t equipId, uint16_t asicId, uint16_t chanId)
{ {
ChanMapping result = {-1, false, 0}; ChanMapping result = {-1, false, 0};
auto it = fChannelMap.find(equipId); auto it = fChannelMap.find(equipId);
if (it != fChannelMap.end()) { if (it != fChannelMap.end()) {
if (asic < fChannelMap[equipId].size()) { auto fiberMap = fChannelMap[equipId];
if (chan < fChannelMap[equipId][asic].size()) { auto jt = fiberMap.find(asicId);
result = fChannelMap[equipId][asic][chan]; if (jt != fiberMap.end()) {
auto asic = fiberMap[asicId];
if (chanId < asic.size()) {
result = asic[chanId];
} }
} }
} }
...@@ -146,27 +161,33 @@ namespace cbm::algo::trd2d ...@@ -146,27 +161,33 @@ namespace cbm::algo::trd2d
uint16_t equipmentId = comp.first; uint16_t equipmentId = comp.first;
auto value = comp.second; auto value = comp.second;
uint16_t moduleId = value.moduleId; uint16_t moduleId = value.moduleId;
uint16_t robId = value.robId; uint16_t fiberId = value.fiberId;
ss << "Equipment " << equipmentId << " Module " << moduleId << " Rob " << robId << "\n"; ss << "Equipment 0x" << std::hex << (int) equipmentId << " Module " << moduleId << " fiberId " << fiberId << "\n";
} }
ss << "\n"; ss << "\n";
for (auto asicMap : fChannelMap) { for (auto asicMap : fChannelMap) {
uint16_t equipmentId = asicMap.first; uint16_t equipmentId = asicMap.first;
uint16_t numAsics = asicMap.second.size(); uint16_t numAsics = asicMap.second.size();
ss << "\n Equipment " << equipmentId << " nAsics " << numAsics; ss << "\n Equipment 0x" << std::hex << (int) equipmentId << " nAsics " << numAsics;
for (size_t asicId = 0; asicId < numAsics; asicId++) {
int asicCnt(0);
uint16_t numChans = asicMap.second.at(asicId).size(); auto asics = asicMap.second;
ss << "\n Equipment " << equipmentId << " AsicId " << asicId << " nChans " << numChans; for (auto asic : asics) {
int asicId = asic.first;
auto asicChs = asic.second;
uint16_t numChans = asicChs.size();
ss << "\n " << asicCnt << " AsicId " << asicId << " nChans " << numChans;
for (size_t chanId = 0; chanId < numChans; chanId++) { for (size_t chanId = 0; chanId < numChans; chanId++) {
auto entry = asicMap.second.at(asicId).at(chanId); auto entry = asicChs.at(chanId);
int32_t address = entry.padAddress; int32_t address = entry.padAddress;
bool isMasked = entry.rPairingFlag; bool isMasked = entry.maskFlag;
uint64_t daqOffset = entry.daqOffset; uint8_t tOffset = entry.tOffset;
ss << "\n Equipment " << equipmentId << " AsicId " << asicId << " chanID " << chanId << " pad address " uint16_t thres = entry.lThreshold;
<< address << " mask " << isMasked << " daq offset " << daqOffset; ss << "\n chanID " << chanId << " {pad " << address << " mask " << isMasked << " time offset[clk] "
<< (int) tOffset << " threshold[" << (thres > 0 ? "on" : "off") << "]}";
} }
asicCnt++;
} }
} }
ss << "\n"; ss << "\n";
......
...@@ -34,22 +34,25 @@ namespace cbm::algo::trd2d ...@@ -34,22 +34,25 @@ namespace cbm::algo::trd2d
public: public:
struct CompMapping { struct CompMapping {
uint16_t moduleId; uint16_t moduleId;
uint8_t robId; uint8_t fiberId;
CBM_YAML_FORMAT(YAML::Flow); CBM_YAML_FORMAT(YAML::Flow);
CBM_YAML_PROPERTIES(yaml::Property(&CompMapping::moduleId, "moduleId", "Module ID"), CBM_YAML_PROPERTIES(yaml::Property(&CompMapping::moduleId, "moduleId", "Module ID"),
yaml::Property(&CompMapping::robId, "crobId", "CROB ID")); yaml::Property(&CompMapping::fiberId, "fiberId", "Optical Fibre ID"));
}; };
struct ChanMapping { struct ChanMapping {
int32_t padAddress; int32_t padAddress; /// map pad and pairing to FASP channel
bool rPairingFlag; bool maskFlag; /// HW mask flag for channel
uint64_t daqOffset; uint8_t tOffset; /// time correction in clk
uint16_t lThreshold; /// SW threshold for ringing channels
CBM_YAML_FORMAT(YAML::Flow); CBM_YAML_FORMAT(YAML::Flow);
CBM_YAML_PROPERTIES(yaml::Property(&ChanMapping::padAddress, "padAddress", "Pad address"), CBM_YAML_PROPERTIES(
yaml::Property(&ChanMapping::rPairingFlag, "rPairingFlag", "R pairing flag"), yaml::Property(&ChanMapping::padAddress, "address", "Pad address"),
yaml::Property(&ChanMapping::daqOffset, "daqOffset", "DAQ offset")); yaml::Property(&ChanMapping::maskFlag, "mask", "Channel masking flag"),
yaml::Property(&ChanMapping::tOffset, "toff", "Channel wise time offset"),
yaml::Property(&ChanMapping::lThreshold, "thres", "SW masking by threshold"));
}; };
/** @brief Constructor **/ /** @brief Constructor **/
...@@ -73,6 +76,13 @@ namespace cbm::algo::trd2d ...@@ -73,6 +76,13 @@ namespace cbm::algo::trd2d
size_t GetNumAsics(uint16_t equipmentId); size_t GetNumAsics(uint16_t equipmentId);
/** @brief Number of ASICS of a component
** @param Equipment ID
** @return List of ASICS linked to the curent ROB
**/
std::vector<uint8_t> GetAsicList(uint16_t equipmentId);
/** @brief Number of channels of a component - ASIC pair /** @brief Number of channels of a component - ASIC pair
** @param Equipment ID ** @param Equipment ID
** @param ASIC ID ** @param ASIC ID
...@@ -102,7 +112,7 @@ namespace cbm::algo::trd2d ...@@ -102,7 +112,7 @@ namespace cbm::algo::trd2d
std::string PrintReadoutMap(); std::string PrintReadoutMap();
/** @brief Initialisation of readout map **/ /** @brief Initialisation of readout map **/
void InitComponentMap(const std::map<uint32_t, uint16_t[NCROBMOD]>& crob_map); void InitComponentMap(const std::map<uint32_t, std::vector<uint16_t>>& map);
/** @brief Initialisation of channel map **/ /** @brief Initialisation of channel map **/
void InitChannelMap( void InitChannelMap(
...@@ -124,14 +134,14 @@ namespace cbm::algo::trd2d ...@@ -124,14 +134,14 @@ namespace cbm::algo::trd2d
// --- TRD2D channel map // --- TRD2D channel map
// --- Map index: (equipment, asic, chan), map value: (pad address, mask flag, daq offset) // --- Map index: (equipment, asic, chan), map value: (pad address, mask flag, daq offset)
std::map<uint16_t, std::vector<std::vector<ChanMapping>>> fChannelMap = {}; //! std::map<uint16_t, std::map<uint8_t, std::vector<ChanMapping>>> fChannelMap = {}; //!
CBM_YAML_PROPERTIES(yaml::Property(&ReadoutConfig::fSystemTimeOffset, "timeOffset", "System time offset for TRD2D"), CBM_YAML_PROPERTIES(
yaml::Property(&ReadoutConfig::fReadoutMap, "readoutMap", "Maps equipment to module and CROB ID", yaml::Property(&ReadoutConfig::fSystemTimeOffset, "timeOffset", "System time offset for TRD2D"),
YAML::Hex), yaml::Property(&ReadoutConfig::fReadoutMap, "readoutMap", "Maps equipment to module and Optical fibre Id", YAML::Hex),
yaml::Property(&ReadoutConfig::fChannelMap, "channelMap", yaml::Property(&ReadoutConfig::fChannelMap, "channelMap",
"Maps equipment, ASIC and channel to pad address, R pairing flag and DAQ offset", "Maps equipment, ASIC and channel to pad address, mask flag and DAQ offset",
{}, YAML::Hex)); YAML::Hex));
}; };
} // namespace cbm::algo::trd2d } // namespace cbm::algo::trd2d
......
...@@ -17,8 +17,7 @@ Unpack::Unpack(const ReadoutConfig& readout) : fReadout(readout) ...@@ -17,8 +17,7 @@ Unpack::Unpack(const ReadoutConfig& readout) : fReadout(readout)
* eMessageVersion::kMessLegacy - refers to the version WITH digi buffering * eMessageVersion::kMessLegacy - refers to the version WITH digi buffering
* eMessageVersion::kMess24 - refers to the version WITHOUT digi buffering * eMessageVersion::kMess24 - refers to the version WITHOUT digi buffering
*/ */
constexpr std::array<u8, int(eMessageVersion::kMessNoDef)> AlgoVersion = {(u8) eMessageVersion::kMessLegacy, constexpr std::array<u8, 2> AlgoVersion = {(u8) eMessageVersion::kMessLegacy, (u8) eMessageVersion::kMess24};
(u8) eMessageVersion::kMess24};
// Create one algorithm per component for TRD and configure it with parameters // Create one algorithm per component for TRD and configure it with parameters
auto equipIdsTrd2d = fReadout.GetEquipmentIds(); auto equipIdsTrd2d = fReadout.GetEquipmentIds();
...@@ -27,42 +26,53 @@ Unpack::Unpack(const ReadoutConfig& readout) : fReadout(readout) ...@@ -27,42 +26,53 @@ Unpack::Unpack(const ReadoutConfig& readout) : fReadout(readout)
trd2d::UnpackPar par{}; trd2d::UnpackPar par{};
const size_t numAsics = fReadout.GetNumAsics(equip); const size_t numAsics = fReadout.GetNumAsics(equip);
for (size_t asic = 0; asic < numAsics; asic++) { auto asics = fReadout.GetAsicList(equip);
for (auto asic : asics) {
trd2d::UnpackAsicPar asicPar; trd2d::UnpackAsicPar asicPar;
const size_t numChans = fReadout.GetNumChans(equip, asic); const size_t numChans = fReadout.GetNumChans(equip, asic);
for (size_t chan = 0; chan < numChans; chan++) { for (size_t chan = 0; chan < numChans; chan++) {
trd2d::UnpackChannelPar chanPar; trd2d::UnpackChannelPar chanPar;
auto pars = fReadout.ChanMap(equip, asic, chan); auto pars = fReadout.ChanMap(equip, asic, chan);
chanPar.fPadAddress = pars.padAddress; // Pad address for channel chanPar.fPadAddress = pars.padAddress; // Pad address for channel
chanPar.fMask = pars.rPairingFlag; // Flag channel mask chanPar.fMask = pars.maskFlag; // Flag channel mask
chanPar.fDaqOffset = pars.daqOffset; // Time calibration parameter chanPar.fDaqOffset = pars.tOffset; // Time calibration parameter
chanPar.fSignalThres = pars.lThreshold; // Threshold cut
asicPar.fChanParams.push_back(chanPar); asicPar.fChanParams.push_back(chanPar);
} }
L_(debug) << "--- Configured asic " << (int) asic << " with " << numChans << " channels";
auto comppars = fReadout.CompMap(equip); auto comppars = fReadout.CompMap(equip);
par.fSystemTimeOffset = fReadout.GetSystemTimeOffset(); par.fSystemTimeOffset = fReadout.GetSystemTimeOffset();
par.fModId = comppars.moduleId; par.fModId = comppars.moduleId;
par.fRobId = comppars.robId; par.fEqAdd = equip;
par.fAsicParams.push_back(asicPar); par.fEqId = comppars.fiberId;
par.fAsicParams[asic] = asicPar;
} }
L_(debug) << "--- Configured equipment 0x" << std::hex << (int) equip << " with " << std::dec << numAsics
<< " asics";
// build all algorithms defined for data unpacking ! Why ?? (AB 25.01.15) // build all algorithms defined for data unpacking ! Why ?? (AB 25.01.15)
std::unique_ptr<UnpackMSBase<CbmTrdDigi, UnpackMonitorData, UnpackAuxData>> algo; std::unique_ptr<UnpackMSBase<CbmTrdDigi, UnpackMonitorData, UnpackAuxData>> algo;
for (auto ver : AlgoVersion) { for (auto ver : AlgoVersion) {
switch (ver) { switch (ver) {
case (int) eMessageVersion::kMessLegacy: case (int) eMessageVersion::kMessLegacy:
algo = std::make_unique<UnpackMS<(u8) eMessageVersion::kMessLegacy>>(par); algo = std::make_unique<UnpackMS<(u8) eMessageVersion::kMessLegacy>>(std::move(par));
break; break;
case (int) eMessageVersion::kMess24: case (int) eMessageVersion::kMess24:
algo = std::make_unique<UnpackMS<(u8) eMessageVersion::kMess24>>(par); algo = std::make_unique<UnpackMS<(u8) eMessageVersion::kMess24>>(std::move(par));
break; break;
} }
// register algorithm // register algorithm
L_(debug) << "Register algo for ver=" << (int) ver << " eqId=0x" << std::hex << (int) equip;
fAlgos[{equip, ver}] = std::move(algo); fAlgos[{equip, ver}] = std::move(algo);
} }
L_(debug) << "--- Configured equipment " << equip << " with " << numAsics << " asics";
} }
L_(info) << "--- Configured " << fAlgos.size() << " unpacker algorithms for TRD2D."; L_(info) << "--- Configured " << fAlgos.size() << " unpacker algorithms for TRD2D.";
// for (const auto& [key, algo] : fAlgos) {
// L_(info) << "eq=0x" << std::hex << key.eqId << " ver=" << int(key.sysVer);
// if (key.sysVer ==2 ) continue;
// (dynamic_cast<const UnpackMS<3>&>(*algo)).DumpParameters();
// }
} }
Unpack::Result_t Unpack::operator()(const fles::Timeslice& ts) const { return DoUnpack(Subsystem::TRD2D, ts); } Unpack::Result_t Unpack::operator()(const fles::Timeslice& ts) const { return DoUnpack(Subsystem::TRD2D, ts); }
...@@ -8,6 +8,8 @@ ...@@ -8,6 +8,8 @@
#include <algorithm> #include <algorithm>
#include <cassert> #include <cassert>
#include <iomanip>
#include <iostream>
#include <sstream> #include <sstream>
#include <vector> #include <vector>
...@@ -16,13 +18,11 @@ using std::unique_ptr; ...@@ -16,13 +18,11 @@ using std::unique_ptr;
namespace cbm::algo::trd2d namespace cbm::algo::trd2d
{ {
// ---- Fasp message constructor ---------------------------------------- // ---- Fasp message constructor ----------------------------------------
FaspMessage::FaspMessage(uint8_t c, uint8_t typ, uint8_t t, uint16_t d, uint8_t r, uint8_t asic, uint8_t e) FaspMessage::FaspMessage(uint8_t c, uint8_t typ, uint8_t t, uint16_t d, uint8_t asic)
: ch(c) : ch(c)
, type(eMessageType::kNone) , type(eMessageType::kNone)
, tlab(t) , tlab(t)
, data(d) , data(d)
, rob(r)
, elink(e)
, fasp(asic) , fasp(asic)
{ {
if (typ == uint8_t(eMessageType::kData)) if (typ == uint8_t(eMessageType::kData))
...@@ -36,12 +36,10 @@ namespace cbm::algo::trd2d ...@@ -36,12 +36,10 @@ namespace cbm::algo::trd2d
std::stringstream ss; std::stringstream ss;
switch (type) { switch (type) {
case eMessageType::kData: case eMessageType::kData:
ss << " DATA : rob=" << rob << (elink ? 'u' : 'd') << " fasp_id=" << fasp << " [" << getFaspIdMod() ss << " DATA : fasp=" << std::setw(2) << (int) fasp << " ch=" << std::setw(2) << (int) ch
<< "] ch_id=" << ch << " tclk=" << tlab << " data=" << data << std::endl; << " t=" << std::setw(3) << (int) tlab << " data=" << std::setw(4) << (int) data << std::endl;
break;
case eMessageType::kEpoch:
ss << " EPOCH: eq_id=" << rob << (elink ? 'u' : 'd') << " ch_id=" << ch << " epoch=" << epoch << std::endl;
break; break;
case eMessageType::kEpoch: ss << " EPOCH: ch=" << (int) ch << " epoch=" << (int) epoch << std::endl; break;
default: ss << " MTYPE: unknown" << std::endl; break; default: ss << " MTYPE: unknown" << std::endl; break;
} }
...@@ -135,6 +133,40 @@ namespace cbm::algo::trd2d ...@@ -135,6 +133,40 @@ namespace cbm::algo::trd2d
return; return;
} }
void UnpackPar::dump() const
{
L_(debug) << "UnpackPar::dump()";
L_(debug) << "mod=" << fModId << " elink[" << (int) fEqId << "]=0x" << std::hex << (int) fEqAdd
<< " nAsics=" << std::dec << fAsicParams.size();
for (const auto& [fasp, par] : fAsicParams) {
L_(debug) << " fasp=" << int(fasp) << " par=" << std::hex << &par;
}
L_(debug) << "UnpackPar::dump(-----------------------)";
}
template<>
uint8_t UnpackPar::mapFaspId2Mod<uint8_t(eMessageVersion::kMessLegacy)>(uint8_t fasp_id) const
{
/** Use the mapping 36 fasp -> 1 optical fiber (equipment id)
* Applies to FASPRO/FW v1 (e.g. mCBM22)
*/
L_(debug) << "<vLegacy> Eq[" << (int) fEqId << "] = 0x" << std::hex << fEqAdd;
return fEqId * NFASPROB + fasp_id;
}
template<>
uint8_t UnpackPar::mapFaspId2Mod<uint8_t(eMessageVersion::kMess24)>(uint8_t fasp_id) const
{
/** Use the mapping 36 fasp -> 2 optical fiber (equipment id)
* Applies to FASPRO/FW v2 (e.g. mCBM25)
*/
int rob = fEqId / 2; // ROB on the current chamber
//L_(debug) << "<v24> ROB=" << rob << " Eq[" << (int)fEqId << "] = 0x" << std::hex << fEqAdd;
return rob * NFASPROB + fasp_id;
}
// ---- Algorithm execution --------------------------------------------- // ---- Algorithm execution ---------------------------------------------
template<> template<>
typename UnpackMS<uint8_t(eMessageVersion::kMessLegacy)>::Result_t typename UnpackMS<uint8_t(eMessageVersion::kMessLegacy)>::Result_t
...@@ -157,7 +189,7 @@ namespace cbm::algo::trd2d ...@@ -157,7 +189,7 @@ namespace cbm::algo::trd2d
uint64_t time = uint64_t((msDescr.idx - tTimeslice - fParams.fSystemTimeOffset) / 12.5); uint64_t time = uint64_t((msDescr.idx - tTimeslice - fParams.fSystemTimeOffset) / 12.5);
// Get parameters for current eq id. // Get parameters for current eq id.
const uint8_t crob_id = fParams.fRobId; //const uint8_t crob_id = fParams.fEqId;
// Get the number of complete words in the input MS buffer. // Get the number of complete words in the input MS buffer.
const uint32_t nwords = msDescr.size / 4; const uint32_t nwords = msDescr.size / 4;
...@@ -203,7 +235,7 @@ namespace cbm::algo::trd2d ...@@ -203,7 +235,7 @@ namespace cbm::algo::trd2d
ctx.fMonitor.fNumSelfTriggeredData++; ctx.fMonitor.fNumSelfTriggeredData++;
data &= 0x1fff; data &= 0x1fff;
} }
vMess.emplace_back(ch_id, (uint8_t) eMessageType::kData, slice, data >> 1, crob_id, lFaspOld); vMess.emplace_back(ch_id, (uint8_t) eMessageType::kData, slice, data >> 1, lFaspOld);
} }
std::get<0>(result) = FinalizeComponent(ctx); //TO DO: Original (non-algo) version calls this after MS loop!! std::get<0>(result) = FinalizeComponent(ctx); //TO DO: Original (non-algo) version calls this after MS loop!!
std::get<1>(result) = ctx.fMonitor; std::get<1>(result) = ctx.fMonitor;
...@@ -214,8 +246,11 @@ namespace cbm::algo::trd2d ...@@ -214,8 +246,11 @@ namespace cbm::algo::trd2d
template<uint8_t sys_ver> template<uint8_t sys_ver>
bool UnpackMS<sys_ver>::pushDigis(std::vector<FaspMessage> messes, const uint64_t time, MsContext& ctx) const bool UnpackMS<sys_ver>::pushDigis(std::vector<FaspMessage> messes, const uint64_t time, MsContext& ctx) const
{ {
constexpr uint8_t mLegacy =
uint8_t(eMessageVersion::kMessLegacy); // message versions compatible with the current algo specialization
const uint16_t mod_id = fParams.fModId; const uint16_t mod_id = fParams.fModId;
const UnpackAsicPar& asicPar = fParams.fAsicParams[messes[0].fasp]; const uint8_t fasp_mod_id = fParams.mapFaspId2Mod<mLegacy>(messes[0].fasp);
const UnpackAsicPar& asicPar = fParams.fAsicParams.at(fasp_mod_id);
const uint64_t tdaqOffset = asicPar.fChanParams[messes[0].ch].fDaqOffset; const uint64_t tdaqOffset = asicPar.fChanParams[messes[0].ch].fDaqOffset;
for (auto imess : messes) { for (auto imess : messes) {
...@@ -334,6 +369,8 @@ namespace cbm::algo::trd2d ...@@ -334,6 +369,8 @@ namespace cbm::algo::trd2d
// Get the number of complete words in the input MS buffer. // Get the number of complete words in the input MS buffer.
const uint32_t nwords = msDescr.size / 4; const uint32_t nwords = msDescr.size / 4;
L_(debug) << "UnpackMS<kMess24>::op() param.elink[" << (int) fParams.fEqId << "]=0x" << std::hex
<< (int) fParams.fEqAdd << " data.rob=0x" << int(msDescr.eq_id) << " words=" << std::dec << nwords;
// We have 32 bit FASP frames in this readout version // We have 32 bit FASP frames in this readout version
const uint32_t* wd = reinterpret_cast<const uint32_t*>(msContent); const uint32_t* wd = reinterpret_cast<const uint32_t*>(msContent);
...@@ -349,7 +386,6 @@ namespace cbm::algo::trd2d ...@@ -349,7 +386,6 @@ namespace cbm::algo::trd2d
case eMessageType::kEpoch: ctx.fMess.readEW<m24>(w); break; case eMessageType::kEpoch: ctx.fMess.readEW<m24>(w); break;
default: break; // no way to reach this line default: break; // no way to reach this line
} }
ctx.fMess.rob = fParams.fRobId;
// PROCESS EPOCH MESSAGES // PROCESS EPOCH MESSAGES
if (ctx.fMess.type == eMessageType::kEpoch) { if (ctx.fMess.type == eMessageType::kEpoch) {
...@@ -377,10 +413,6 @@ namespace cbm::algo::trd2d ...@@ -377,10 +413,6 @@ namespace cbm::algo::trd2d
vMess.clear(); vMess.clear();
lFaspOld = ctx.fMess.fasp; lFaspOld = ctx.fMess.fasp;
} }
if (ctx.fMess.data & 0x1) { // kept for backward compatibility TODO
ctx.fMonitor.fNumErrEndBitSet++;
continue;
}
if (ctx.fMess.data & 0x2000) { // kept for backward compatibility TODO if (ctx.fMess.data & 0x2000) { // kept for backward compatibility TODO
ctx.fMonitor.fNumSelfTriggeredData++; ctx.fMonitor.fNumSelfTriggeredData++;
ctx.fMess.data &= 0x1fff; ctx.fMess.data &= 0x1fff;
...@@ -390,10 +422,12 @@ namespace cbm::algo::trd2d ...@@ -390,10 +422,12 @@ namespace cbm::algo::trd2d
// combine all digis from this ROB // combine all digis from this ROB
std::vector<CbmTrdDigi> outputDigis; std::vector<CbmTrdDigi> outputDigis;
for (uint16_t ipad(0); ipad < NFASPMOD * NFASPCH; ipad++) { for (uint16_t ipad(0); ipad < NFASPMOD * NFASPPAD; ipad++) {
if (!ctx.fRobDigi[ipad].size()) continue; if (!ctx.fRobDigi[ipad].size()) continue;
for (auto id : ctx.fRobDigi[ipad]) for (auto id : ctx.fRobDigi[ipad]) {
L_(debug) << id.ToString();
outputDigis.emplace_back(std::move(id)); outputDigis.emplace_back(std::move(id));
}
} }
std::get<0>(result) = outputDigis; std::get<0>(result) = outputDigis;
std::get<1>(result) = ctx.fMonitor; std::get<1>(result) = ctx.fMonitor;
...@@ -403,14 +437,18 @@ namespace cbm::algo::trd2d ...@@ -403,14 +437,18 @@ namespace cbm::algo::trd2d
bool UnpackMS<uint8_t(eMessageVersion::kMess24)>::pushDigis(std::vector<FaspMessage> messes, const uint64_t time, bool UnpackMS<uint8_t(eMessageVersion::kMess24)>::pushDigis(std::vector<FaspMessage> messes, const uint64_t time,
MsContext& ctx) const MsContext& ctx) const
{ {
const uint16_t mod_id = fParams.fModId; constexpr uint8_t m24 =
const UnpackAsicPar& asicPar = fParams.fAsicParams[messes[0].fasp]; uint8_t(eMessageVersion::kMess24); // message versions compatible with the current algo specialization
const uint64_t tdaqOffset = asicPar.fChanParams[messes[0].ch].fDaqOffset; const uint8_t fasp_mod_id = fParams.mapFaspId2Mod<m24>(messes[0].fasp);
const UnpackAsicPar& asicPar = fParams.fAsicParams.at(fasp_mod_id);
for (auto imess : messes) { for (auto imess : messes) {
const int32_t pad = std::abs(asicPar.fChanParams[imess.ch].fPadAddress); const UnpackChannelPar& chPar = asicPar.fChanParams[imess.ch];
const bool hasPairingR = bool(asicPar.fChanParams[imess.ch].fPadAddress > 0); // skip message if threshold set and signal under
const uint64_t lTime = time + tdaqOffset + imess.tlab; if (chPar.fSignalThres && imess.data <= chPar.fSignalThres) continue;
const int32_t pad = std::abs(chPar.fPadAddress) / 2;
const bool hasPairingR = bool(chPar.fPadAddress > 0);
const uint64_t lTime = time + chPar.fDaqOffset + imess.tlab;
const uint16_t lchR = hasPairingR ? imess.data : 0; const uint16_t lchR = hasPairingR ? imess.data : 0;
const uint16_t lchT = hasPairingR ? 0 : imess.data; const uint16_t lchT = hasPairingR ? 0 : imess.data;
std::vector<CbmTrdDigi>& digiBuffer = ctx.fRobDigi[pad]; std::vector<CbmTrdDigi>& digiBuffer = ctx.fRobDigi[pad];
...@@ -418,14 +456,14 @@ namespace cbm::algo::trd2d ...@@ -418,14 +456,14 @@ namespace cbm::algo::trd2d
// init pad position in array and build digi for message // init pad position in array and build digi for message
if (digiBuffer.size() == 0) { if (digiBuffer.size() == 0) {
digiBuffer.emplace_back(pad, lchT, lchR, lTime); digiBuffer.emplace_back(pad, lchT, lchR, lTime);
digiBuffer.back().SetAddressModule(mod_id); digiBuffer.back().SetAddressModule(fParams.fModId);
continue; continue;
} }
// check if last digi has both R/T message components. // check if last digi has both R/T message components.
// Update if not and is within time window // Update if not and is within time window
auto id = digiBuffer.back(); // Should always be valid here. auto& id = digiBuffer.back(); // Should always be valid here.
// No need to extra check // No need to extra check
double r, t; double r, t;
int32_t dt; int32_t dt;
const int32_t dtime = id.GetTimeDAQ() - lTime; const int32_t dtime = id.GetTimeDAQ() - lTime;
...@@ -446,7 +484,7 @@ namespace cbm::algo::trd2d ...@@ -446,7 +484,7 @@ namespace cbm::algo::trd2d
// build digi for message when update failed // build digi for message when update failed
if (!use) { if (!use) {
digiBuffer.emplace_back(pad, lchT, lchR, lTime); digiBuffer.emplace_back(pad, lchT, lchR, lTime);
digiBuffer.back().SetAddressModule(mod_id); digiBuffer.back().SetAddressModule(fParams.fModId);
} }
} }
messes.clear(); messes.clear();
......
...@@ -12,11 +12,12 @@ ...@@ -12,11 +12,12 @@
#include <sstream> #include <sstream>
#define NFASPMOD 180 #define NFASPMOD 180
#define NCROBMOD 5 #define NROBMOD 5
#define NFASPCROB NFASPMOD / NCROBMOD #define NFASPROB NFASPMOD / NROBMOD
#define NFASPCH 16 #define NFASPCH 16
#define NFASPPAD 8
#define FASP_EPOCH_LENGTH 128 #define FASP_EPOCH_LENGTH 128 // the length in clks of FASP epoch [1600ns @ 40MHz]
namespace cbm::algo::trd2d namespace cbm::algo::trd2d
{ {
...@@ -34,7 +35,6 @@ namespace cbm::algo::trd2d ...@@ -34,7 +35,6 @@ namespace cbm::algo::trd2d
{ {
kMessLegacy = 2, /// unpacker version for 2-board FASPRO+GETS HW kMessLegacy = 2, /// unpacker version for 2-board FASPRO+GETS HW
kMess24 = 3, /// unpacker version for 1-board FASPRO HW first used 18.06.24 (mCBM) kMess24 = 3, /// unpacker version for 1-board FASPRO HW first used 18.06.24 (mCBM)
kMessNoDef /// default unpacker version
}; };
enum class eMessageType : int enum class eMessageType : int
...@@ -78,8 +78,7 @@ namespace cbm::algo::trd2d ...@@ -78,8 +78,7 @@ namespace cbm::algo::trd2d
struct FaspMessage { struct FaspMessage {
FaspMessage() = default; FaspMessage() = default;
FaspMessage(const FaspMessage&) = default; FaspMessage(const FaspMessage&) = default;
FaspMessage(uint8_t c, uint8_t typ, uint8_t t, uint16_t d, uint8_t rob, uint8_t asic, uint8_t e = 0); FaspMessage(uint8_t c, uint8_t typ, uint8_t t, uint16_t d, uint8_t asic);
int getFaspIdMod() const { return fasp + rob * NFASPCROB; }
/** \brief Implementation of message type descriptor according to message version /** \brief Implementation of message type descriptor according to message version
* \param w the message word * \param w the message word
...@@ -106,9 +105,6 @@ namespace cbm::algo::trd2d ...@@ -106,9 +105,6 @@ namespace cbm::algo::trd2d
uint8_t tlab = 0; ///< time of the digi inside the epoch uint8_t tlab = 0; ///< time of the digi inside the epoch
uint16_t data = 0; ///< ADC value uint16_t data = 0; ///< ADC value
uint32_t epoch = 0; ///< epoch id (not used for the moment) uint32_t epoch = 0; ///< epoch id (not used for the moment)
uint32_t mod = 0; ///< full module address according to CbmTrdAddress
uint8_t rob = 0; ///< ROB id in the module
uint8_t elink = 0; ///< optical link for read-out unit (up or down, starting with kMess24)
uint8_t fasp = 0; ///< FASP id in the module uint8_t fasp = 0; ///< FASP id in the module
}; };
...@@ -120,7 +116,8 @@ namespace cbm::algo::trd2d ...@@ -120,7 +116,8 @@ namespace cbm::algo::trd2d
struct UnpackChannelPar { struct UnpackChannelPar {
int32_t fPadAddress; ///< Pad address for channel int32_t fPadAddress; ///< Pad address for channel
bool fMask; ///< Flag for channel masking bool fMask; ///< Flag for channel masking
uint64_t fDaqOffset = 0; ///< Time calibration parameter uint8_t fDaqOffset = 0; ///< Time calibration parameter
uint16_t fSignalThres = 0; ///< Signal threshold to remove ringing channels
}; };
/** @struct UnpackAsicPar /** @struct UnpackAsicPar
...@@ -138,10 +135,22 @@ namespace cbm::algo::trd2d ...@@ -138,10 +135,22 @@ namespace cbm::algo::trd2d
** @brief Parameters required for the TRD2D unpacking (specific to one component) ** @brief Parameters required for the TRD2D unpacking (specific to one component)
**/ **/
struct UnpackPar { struct UnpackPar {
int32_t fSystemTimeOffset = 0; ///< Time calibration parameter int32_t fSystemTimeOffset = 0; ///< Time calibration parameter
uint16_t fModId = 0; ///< Module ID of component uint16_t fModId = 0; ///< Module ID of component
uint8_t fRobId = 0; ///< ROB ID of component uint16_t fEqAdd = 0; ///< Equipment (optical fiber) address [HEX]
std::vector<UnpackAsicPar> fAsicParams = {}; ///< Parameters for each ASIC uint8_t fEqId = 0xff; ///< Equipment (optical fiber) ID of component
std::map<uint8_t, UnpackAsicPar> fAsicParams = {}; ///< Parameters for each ASIC
/** \brief Write to the debug stream the content of the current param object*/
void dump() const;
/** \brief Calculate the module wise FASP id from the FASP id provided at the level
* of equipment Id (optical fibre in TRD2D case).
* \param fasp_id index of fasp as written on the message
* \return fasp id on the module as it is used in the parameter file
*/
template<uint8_t ver>
uint8_t mapFaspId2Mod(uint8_t fasp_id) const;
}; };
...@@ -183,12 +192,12 @@ namespace cbm::algo::trd2d ...@@ -183,12 +192,12 @@ namespace cbm::algo::trd2d
** @since 31 January 2023 ** @since 31 January 2023
** @brief Unpack algorithm for TRD2D ** @brief Unpack algorithm for TRD2D
**/ **/
template<std::uint8_t sys_ve> template<std::uint8_t sys_ver>
class UnpackMS : public UnpackMSBase<CbmTrdDigi, UnpackMonitorData, UnpackAuxData> { class UnpackMS : public UnpackMSBase<CbmTrdDigi, UnpackMonitorData, UnpackAuxData> {
public: public:
/** @brief Construct from parameters **/ /** @brief Construct from parameters **/
UnpackMS(const UnpackPar& /*pars*/) {} UnpackMS(const UnpackPar& pars) : fParams(pars) {}
/** @brief Destructor **/ /** @brief Destructor **/
~UnpackMS() override = default; ~UnpackMS() override = default;
...@@ -239,7 +248,7 @@ namespace cbm::algo::trd2d ...@@ -239,7 +248,7 @@ namespace cbm::algo::trd2d
public: public:
/** @brief Construct from parameters **/ /** @brief Construct from parameters **/
UnpackMS(const UnpackPar& /*pars*/) {} UnpackMS(const UnpackPar& pars) : fParams(pars) {}
/** @brief Destructor **/ /** @brief Destructor **/
~UnpackMS() override = default; ~UnpackMS() override = default;
...@@ -262,7 +271,7 @@ namespace cbm::algo::trd2d ...@@ -262,7 +271,7 @@ namespace cbm::algo::trd2d
private: // Types private: // Types
struct MsContext { struct MsContext {
UnpackMonitorData fMonitor; ///< Container for monitoring data UnpackMonitorData fMonitor; ///< Container for monitoring data
std::array<std::vector<CbmTrdDigi>, NFASPMOD* NFASPCH> fRobDigi = { std::array<std::vector<CbmTrdDigi>, NFASPMOD* NFASPPAD> fRobDigi = {
{}}; ///> Buffered digi for each pad in one Epoch-ROB component {}}; ///> Buffered digi for each pad in one Epoch-ROB component
FaspMessage fMess; ///< encapsulation of the FASP message. FaspMessage fMess; ///< encapsulation of the FASP message.
}; };
......
...@@ -37,7 +37,7 @@ InitStatus CbmTaskTrdUnpackParWrite::Init() ...@@ -37,7 +37,7 @@ InitStatus CbmTaskTrdUnpackParWrite::Init()
cbm::algo::trd2d::ReadoutConfig trd2dConfig; cbm::algo::trd2d::ReadoutConfig trd2dConfig;
// Map (moduleId) -> (array of crobId) // Map (moduleId) -> (array of crobId)
std::map<uint32_t, uint16_t[NCROBMOD]> crobMap; std::map<uint32_t, std::vector<uint16_t>> crobMap;
// Map (equipId, asicId, chanId) -> (pad address, mask flag, daq offset [FASP clk]) // Map (equipId, asicId, chanId) -> (pad address, mask flag, daq offset [FASP clk])
std::map<size_t, std::map<size_t, std::map<size_t, std::tuple<int32_t, bool, uint64_t>>>> channelMap; std::map<size_t, std::map<size_t, std::map<size_t, std::tuple<int32_t, bool, uint64_t>>>> channelMap;
...@@ -53,9 +53,12 @@ InitStatus CbmTaskTrdUnpackParWrite::Init() ...@@ -53,9 +53,12 @@ InitStatus CbmTaskTrdUnpackParWrite::Init()
auto digipar = entry.second; auto digipar = entry.second;
const int* crobs = setDet->GetCrobAddresses(); const int* crobs = setDet->GetCrobAddresses();
for (int icrob(0); icrob < NCROBMOD; icrob++) for (int icrob(0); icrob < NCROBMOD; icrob++) {
crobMap[moduleId][icrob] = crobs[icrob]; crobMap[moduleId].emplace_back(crobs[icrob] & 0xffff);
// check if there is an extra fiber defined on this ROB (version 2025 -)
uint16_t eq_id = (crobs[icrob] >> 16) & 0xffff;
if (eq_id) crobMap[moduleId].emplace_back(eq_id);
}
// Loop through ASICs for this module // Loop through ASICs for this module
std::vector<int32_t> addresses; std::vector<int32_t> addresses;
setDet->GetAsicAddresses(&addresses); setDet->GetAsicAddresses(&addresses);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment