CbmRoot
Loading...
Searching...
No Matches
tof/UnpackMS.cxx
Go to the documentation of this file.
1/* Copyright (C) 2022 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt
2 SPDX-License-Identifier: GPL-3.0-only
3 Authors: Dominik Smith [committer] */
4
5#include "UnpackMS.h"
6
7#include <cassert>
8#include <cmath>
9#include <utility>
10#include <vector>
11
12using std::unique_ptr;
13using std::vector;
14
15namespace cbm::algo::tof
16{
17
18 UnpackMS::UnpackMS(const UnpackPar& pars) : fParams(pars) {}
19 UnpackMS::~UnpackMS() = default;
20
21 // ---- Algorithm execution ---------------------------------------------
22 UnpackMS::Result_t UnpackMS::operator()(const uint8_t* msContent, const fles::MicrosliceDescriptor& msDescr,
23 const uint64_t tTimeslice) const
24 {
25
26 // --- Output data
27 Result_t result = {};
28 TimeSpec time = {};
29
30 // --- Current Timeslice start time in epoch units. Note that it is always a multiple of epochs
31 // --- and the epoch is a multiple of ns.
32 time.currentTsTime = static_cast<uint64_t>(tTimeslice / critof001::kuEpochInNs) % critof001::kulEpochCycleEp;
33
34 // --- Number of messages in microslice
35 auto msSize = msDescr.size;
36 if (msSize % sizeof(critof001::Message) != 0) {
37 std::get<1>(result).fNumErrInvalidMsSize++;
38 return result;
39 }
40 const uint32_t numMessages = msSize / sizeof(critof001::Message);
41 if (numMessages < 2) {
42 std::get<1>(result).fNumErrInvalidMsSize++;
43 return result;
44 }
45
46 // --- Interpret MS content as sequence of Critof messages
47 auto message = reinterpret_cast<const critof001::Message*>(msContent);
48
49 const uint32_t maxDigis = numMessages - 2; // -2 for the TS_MSB and EPOCH messages
50 std::get<0>(result).reserve(maxDigis);
51
52 // --- The first message in the MS is expected to be of type EPOCH.
53 if (message[0].getMessageType() != critof001::MSG_EPOCH) {
54 std::get<1>(result).fNumErrInvalidFirstMessage++;
55 return result;
56 }
57
58 { // --- Check that first epoch matches with the microslice index
59 const uint64_t msStartEpoch =
60 static_cast<uint64_t>(msDescr.idx / critof001::kuEpochInNs) % critof001::kulEpochCycleEp;
61 if (message[0].getGdpbEpEpochNb() != msStartEpoch) {
62 std::get<1>(result).fNumErrInvalidStartEpoch++;
63 return result;
64 }
65 }
66
67 // --- The last message in the MS is expected to be EndOfMs.
68 if (!message[numMessages - 1].isEndOfMs()) {
69 std::get<1>(result).fNumErrInvalidLastMessage++;
70 return result;
71 }
72 // Check if last message is "EndOfMs"!! Maybe loop to messageNr < numMessages - 1
73
74 // --- Message loop
75 for (uint32_t messageNr = 0; messageNr < numMessages; messageNr++) {
76
77 // --- Action depending on message type
78 switch (message[messageNr].getMessageType()) {
79
80 case critof001::MSG_HIT: {
81 ProcessHitMessage(message[messageNr], std::get<0>(result), std::get<1>(result), time);
82 break;
83 }
85 if (critof001::kuChipIdMergedEpoch == message[messageNr].getGet4Idx()) {
86 ProcessEpochMessage(message[messageNr], time);
87 } // if this epoch message is a merged one valid for all chips
88 else {
90 std::get<1>(result).fNumErrInvalidAsicEpochs++;
91 continue;
92 } // if single chip epoch message
93 break;
94 }
96 std::get<1>(result).fNumNonHitOrTsbMessage++;
97 break;
98 }
100 std::get<1>(result).fNumNonHitOrTsbMessage++;
101 break;
102 }
103 default: {
104 std::get<1>(result).fNumNonHitOrTsbMessage++;
105 break;
106 }
107 } //? Message type
108 } //# Messages
109
110 return result;
111 }
112 // --------------------------------------------------------------------------
113
114
115 // ----- Process hit message --------------------------------------------
116 inline void UnpackMS::ProcessHitMessage(const critof001::Message& message, vector<CbmTofDigi>& digiVec,
117 UnpackMonitorData& monitor, TimeSpec& time) const
118 {
119 // --- Check eLink and get parameters
120 const uint32_t elink = message.getGet4Idx();
121 if (elink >= fParams.fElinkParams.size()) {
122 monitor.fNumErrElinkOutOfRange++;
123 return;
124 }
125 const UnpackElinkPar& elinkPar = fParams.fElinkParams.at(elink);
126
127 const uint32_t channel = message.getGdpbHitChanId();
128 const uint32_t channelUId = (elinkPar.fChannelUId)[channel];
129
130 double messageTime = message.getMsgFullTimeD(time.currentEpochInTs) - elinkPar.fTimeOffset;
131 const double charge = (double) message.getGdpbHit32Tot(); //cast from uint32_t
132
133 // --- Create output digi
134 digiVec.emplace_back(channelUId, messageTime, charge);
135 }
136 // --------------------------------------------------------------------------
137
138
139 // ----- Process an epoch message ---------------------------------------
140 inline void UnpackMS::ProcessEpochMessage(const critof001::Message& message, TimeSpec& time) const
141 {
142 const uint64_t epoch = message.getGdpbEpEpochNb();
143
144 // --- Calculate epoch relative to timeslice start time; correct for epoch cycles
145 if (time.currentTsTime <= epoch) {
146 time.currentEpochInTs = epoch - time.currentTsTime;
147 }
148 else {
150 }
151 //Problem if MS spans multiple epoch cycles?
152 }
153 // --------------------------------------------------------------------------
154
155
156} // namespace cbm::algo::tof
std::tuple< std::vector< Digi_t >, Monitor_t, Aux_t > Result_t
Result_t operator()(const uint8_t *msContent, const fles::MicrosliceDescriptor &msDescr, const uint64_t tTimeslice) const override
Algorithm execution.
void ProcessEpochMessage(const critof001::Message &message, TimeSpec &time) const
Process an epoch message.
UnpackPar fParams
Parameter container.
~UnpackMS() override
Destructor.
UnpackMS(const UnpackPar &pars)
Default constructor.
void ProcessHitMessage(const critof001::Message &message, std::vector< CbmTofDigi > &digiVec, UnpackMonitorData &monitor, TimeSpec &time) const
Process a hit message.
uint16_t getGdpbHit32Tot() const
uint16_t getGet4Idx() const
uint16_t getGdpbHitChanId() const
uint32_t getGdpbEpEpochNb() const
double getMsgFullTimeD(uint64_t epoch) const
Returns expanded and adjusted time of message in double (in ns)
const uint64_t kulEpochCycleEp
const uint32_t kuChipIdMergedEpoch
const double kuEpochInNs
TOF Unpacking parameters for one eLink / ASIC.
int32_t fTimeOffset
Time calibration parameter.
std::vector< uint32_t > fChannelUId
CbmTofAddress for different channels.
u64 currentTsTime
Unix time of timeslice in units of epoch length.
u32 currentEpochInTs
Current epoch number relative to timeslice start epoch.
uint32_t fNumErrElinkOutOfRange
Elink not contained in parameters.
Parameters required for the STS unpacking (specific to one component)
std::vector< UnpackElinkPar > fElinkParams
Parameters for each eLink.