CbmRoot
Loading...
Searching...
No Matches
CbmTrdUnpackAlgoLegacy2020R.cxx
Go to the documentation of this file.
1/* Copyright (C) 2021 Goethe-University Frankfurt, Frankfurt
2 SPDX-License-Identifier: GPL-3.0-only
3 Authors: Pascal Raisig [committer] */
4
6
7#include "CbmTrdDigi.h"
8#include "CbmTrdParManager.h"
9#include "CbmTrdParSetAsic.h"
11
12#include <FairTask.h>
13#include <Logger.h>
14
15#include <RtypesCore.h>
16
17#include <cstdint>
18#include <memory>
19#include <string>
20#include <typeinfo>
21#include <utility>
22
24 : CbmTrdUnpackAlgoBaseR("CbmTrdUnpackAlgoLegacy2020R")
25{
26}
27
29
30// ---- GetParContainerRequest ----
31std::vector<std::pair<std::string, std::shared_ptr<FairParGenericSet>>>*
32CbmTrdUnpackAlgoLegacy2020R::GetParContainerRequest(std::string geoTag, uint32_t runId)
33{
34 // Basepath for default Trd parameter sets (those connected to a geoTag)
35 std::string basepath = Form("%s/trd_%s", fParFilesBasePath.data(), geoTag.data());
36 std::string temppath = "";
37
38 // Digest the runId information in case of runId = 0 we use the default fall back
39 std::string runpath = "";
40 if (runId != 0) {
41 runpath = ".run" + std::to_string(runId);
42 }
43
44 // Get .asic parameter container
45 temppath = basepath + runpath + ".asic" + ".par";
46 fParContVec.emplace_back(std::make_pair(temppath, std::make_shared<CbmTrdParSetAsic>()));
47
48 // Currently we need the ParSetDigi only for the monitor
49 if (fMonitor) {
50 temppath = basepath + runpath + ".digi" + ".par";
51 auto pair = std::make_pair(temppath, std::make_shared<CbmTrdParSetDigi>());
52 fParContVec.emplace_back(pair);
53 }
54
55
56 // We do not want to require the timeshift pars, since the unpacker has to be run without them to extract them. But if it is available we want to use it.
57 // Get timeshift correction parameters, currently only available for run 831
58 if (runId == 831 && geoTag == "mcbm_beam_2020_03") {
59 temppath = Form("%s/mcbm2020_special/CbmMcbm2020TrdTshiftPar_run%d.par", fParFilesBasePath.data(), runId);
60 fParContVec.emplace_back(std::make_pair(temppath, std::make_shared<CbmMcbm2020TrdTshiftPar>()));
61 }
62
63
64 return &fParContVec;
65}
66
67// ---- extractSample ----
69 uint32_t isample, bool multihit)
70{
71
72 switch (msgType) {
74 if (isample > 2) {
75 LOG(error) << fName << "::ExtractSample] SOM MSG - Idx " << isample << " Wrong sample index!";
76 return -256;
77 }
78 break;
79 }
81 if (isample < 3 || isample > 31) {
82 LOG(error) << fName << "::ExtractSample] RDA MSG - Idx " << isample << " Wrong sample index!";
83 return -256;
84 }
85 break;
86 }
87 default:
88 LOG(error) << fName << "::ExtractSample] Wrong Message Type!";
89 return -256;
90 break;
91 }
92
93 size_t mask = 0x1FF;
94 auto index = fExtractSampleIndicesVec.at(isample);
95
96 mask = mask << (9 * (6 - index));
97 size_t temp = word & mask;
98 temp = temp >> (6 - index) * 9;
99 if (fSpadic->GetUseBaselineAvg() && (isample == 0) && !(multihit)) {
107 temp = temp >> 2;
108 temp ^= (-0 ^ temp) & (1 << 7);
109 temp ^= (-1 ^ temp) & (1 << 8);
110 }
111 struct {
112 signed int x : 9;
113 } s;
114 int16_t result = s.x = temp;
115 return result;
116}
117
118// ---- extractEpoch ----
120{
121 size_t mask = 0x3FFFFFFF;
122 mask = mask << 32;
123 return ((word & mask) >> 32);
124}
125
126// ---- finishDerived ----
128{
129 LOG(info) << fName << fNrWildRda << " unexpected RDA words and\n " << fNrUnknownWords << " unknown words.";
130}
131
132
133// ---- getInfoType ----
135{
136 size_t mask = 0x000FFFFF;
137
138 if (((msg & mask) >> 18) == 3) // BOM
139 {
141 }
142 if (((msg & mask) >> 17) == 2) // MSB
143 {
145 }
146 if (((msg & mask) >> 17) == 3) // BUF
147 {
149 }
150 if (((msg & mask) >> 17) == 4) // UNU
151 {
153 }
154 if (((msg & mask) >> 17) == 5) // MIS
155 {
157 }
158 else {
159 LOG(error) << fName << "::GetInfoType] unknown type!";
161 }
162}
163
164
165// ---- getMessageType ----
167{
168 if ((msg >> 61) == 1) // SOM 001. ....
169 {
171 }
172 else if ((msg >> 63) == 1) // RDA 1... ....
173 {
175 }
176 else if ((msg >> 62) == 1) // Epoch 01.. ....
177 {
179 }
180 else if ((msg >> 60) == 1) // Spadic Info Message 0001 ....
181 {
183 }
184 else if (msg == 0) // Last Word in a Microslice is 0
185 {
187 }
188 else // not a spadic message
189 {
191 }
192}
193
194// ---- getNrOfRdaWords ----
196{
197 auto nwords = (nsamples + 3) / 7;
198 return nwords > 5 ? 5 : nwords;
199}
200
201// ---- makeRaw ----
202CbmTrdRawMessageSpadic CbmTrdUnpackAlgoLegacy2020R::makeRaw(const size_t word, fles::MicrosliceDescriptor msDesc)
203{
204
206 uint8_t elinkId = 0, chId = 0, crobId = 0;
207 uint16_t criId = msDesc.eq_id;
208 // char crobId = msDesc.crob_id; // TODO this needs to be implemented into microslice! - PR 03.2020
209 uint8_t hitType = 0, nSamples = 0;
210 bool multihit = false;
211 uint16_t timestamp = 0;
212 size_t mask = 0x3F;
213 mask = mask << 55;
214 elinkId = (char) ((word & mask) >> 55);
215 //extract chID
216 mask = 0xF;
217 mask = mask << 51;
218 chId = (char) ((word & mask) >> 51);
219 //extract timestamp
220 mask = 0xFFFF;
221 mask = mask << 35;
222 timestamp = (uint16_t)((word & mask) >> 35);
223 //extract hitType
224 mask = 0x3;
225 mask = mask << 33;
226 hitType = (uint8_t)((word & mask) >> 33);
227 //extract MultiHit
228 mask = 0x1;
229 mask = mask << 32;
230 multihit = (bool) ((word & mask) >> 32);
231 //extract nrSamples
232 mask = 0x1F;
233 mask = mask << 27;
234 nSamples = (uint8_t)((word & mask) >> 27);
235 nSamples += 1; //spadic counts from 0 to 31
236
237 // get the correct fulltime
238 size_t fulltime = timestamp + (fEpoch * fMsLengthCC); // this is in units of clock cycles
239
240
241 // put the first 3 samples, contained in som, into the message.
242 std::vector<int16_t> samples = {};
243 for (uint32_t isample = 0; isample < nSamples && isample < 3; isample++) {
244 auto adcvalue = extractSample(word, Spadic::MsMessageType::kSOM, isample, multihit);
245 samples.emplace_back(adcvalue);
246 }
247
248 // Create message
249 CbmTrdRawMessageSpadic retval(chId, elinkId, crobId, criId, hitType, nSamples, multihit, fulltime, samples);
250 return retval;
251}
252
254{
255
256 // Extract the trigger type and translate it to the digi enum
257 auto rawTriggerType = static_cast<Spadic::eTriggerType>(raw.GetHitType());
258 auto triggerType = CbmTrdRawToDigiBaseR::GetDigiTriggerType(rawTriggerType);
259
260 // Get the digi error class (dummy for the time being)
261 Int_t errClass = 0;
262
263 // Get the address of the originating spadic
264 size_t spadicHwAddress(0);
265 spadicHwAddress = (raw.GetElinkId()) + (CbmTrdParAsic::kCriIdPosition * raw.GetCriId())
267 Int_t asicAddress(0);
268 auto mapIt = fSpadicAddressMap.find(spadicHwAddress); // check if asic exists
269 if (mapIt == fSpadicAddressMap.end()) {
270 LOG(debug4) << fName
271 << "::makeDigi - No asic address "
272 "found for Spadic hardware address %lu"
273 << spadicHwAddress;
274 return;
275 }
276 asicAddress = mapIt->second;
277
278 // Get the unique module id from the asic address
279 Int_t uniqueModuleId = asicAddress / 1000;
280
281 // GetChannelId per eLink add NSPADICCH / 2 to the second(first) eLink in the case we start with odd(even) eLinks, since, our mapping is based on odd eLinks
282 auto asicChannelId = (raw.GetElinkId() % 2) == fIsFirstChannelsElinkEven
283 ? raw.GetChannelId()
285
286
287 auto padChNr = (fAsicChannelMap.find(asicAddress))->second.at(asicChannelId);
288
289 // Store the full time information to last full-time member for error message handling
290 fLastFulltime = raw.GetFullTime();
291
292 // Get the time information and apply the necessary correction
293 ULong64_t time = raw.GetTime();
294 if (fTimeshiftsParVec) {
295 time = time - fTimeshiftsParVec->at(padChNr);
296 raw.SetTime(time);
297 }
298 time -= fSystemTimeOffset;
299
300 // Set the time relative to the TS start
301 time -= fTsStartTime;
302
303 auto digi = fRTDMethod->MakeDigi(raw.GetSamples(), padChNr, uniqueModuleId, time, triggerType, errClass);
304
305 // Digest the output, i.e. write to return vector and optional pass to the monitor
306 digestOutput(std::move(digi), raw);
307}
308
309// ---- setDerivedTsParameters ----
311{
312 auto timeshiftpair = fTimeshiftsMap.find(itimeslice);
313 if (timeshiftpair != fTimeshiftsMap.end()) {
314 fTimeshiftsParVec = &timeshiftpair->second;
315 }
316 else
317 return false;
318 return true;
319}
320
321// ---- unpack ----
322bool CbmTrdUnpackAlgoLegacy2020R::unpack(const fles::Timeslice* ts, uint16_t icomp, UInt_t imslice)
323{
324
325
326 bool unpackOk = true;
327
328 auto msdesc = ts->descriptor(icomp, imslice);
329
330 // Get the micro-slice size in bytes to calculate the number of completed words
331 auto mssize = msdesc.size;
332
333 // Get the number of complete words in the input MS buffer.
334 uint32_t msNrWords = mssize / fBytesPerWord;
335
336 const auto mspointer = ts->content(icomp, imslice);
337 const auto mscontent = reinterpret_cast<const size_t*>(mspointer);
338
339 // Loop over all 64bit-Spadic-Words in the current micro-slice
340 for (uint32_t iword = 0; iword < msNrWords; iword++) {
341 // Access the actual word from the pointer
342 auto word = static_cast<size_t>(mscontent[iword]);
343
344 // Get the type of the word
345 auto kWordtype = getMessageType(word);
346
347 switch (kWordtype) {
349 CbmTrdRawMessageSpadic raw = makeRaw(word, msdesc);
350 auto nsamples = raw.GetNrSamples();
352 if (nsamples > 3) {
353 uint32_t isample = 3; // first 3 samples are already handled in som
355 for (uint8_t irda = 0; irda < getNrOfRdaWords(nsamples); irda++) {
356 ++iword;
357 word = static_cast<size_t>(mscontent[iword]);
358 auto kAddWordtype = getMessageType(word);
359 if (kAddWordtype != Spadic::MsMessageType::kRDA) {
360 LOG(error) << fName
361 << "::unpack() Incomplete Spadic "
362 "Message! RDA Word missing, Microslice corrupted.";
363 return kFALSE;
364 }
366 for (uint32_t iwordsample = 0; isample < nsamples && iwordsample < 7; isample++, iwordsample++) {
367 auto adcvalue = extractSample(word, kAddWordtype, isample);
368 raw.SetSample(adcvalue, isample);
369 }
370 }
371 }
372 ++fNrCreatedRawMsgs;
373
374 // Message is completed here. Now lets Generate the digi and save raw message if needed.
375 makeDigi(raw);
376
377 break;
378 }
380 // All rda words should be handled inside the kSOM case. Hence, this case should not appear and we have to count it as an error appearance.
381 LOG(error) << fName
382 << "::unpack() Unexpected RDA "
383 "Word. Microslice corrupted.";
384 fNrWildRda++;
385 return false;
386 break;
387 }
390 if (fOptOutBVec) {
391 fOptOutBVec->emplace_back(std::make_pair(fLastFulltime, word));
392 }
393 fNrCreatedInfoMsgs++;
394 // TODO here we also want to call the monitoring class
395 // Spadic::MsInfoType infoType = getInfoType(word);
396 // "Spadic_Info_Types";
397 // if (fIsActiveHistoVec[kSpadic_Info_Types]) {
398 // ((TH2I*) fHistoArray.At(kSpadic_Info_Types))->Fill(fLastFulltime, (Int_t) infoType);
399 // }
400 break;
401 }
403 if (iword != (msNrWords - 1)) // last word in Microslice is 0.
404 {
405 LOG(error) << fName
406 << "::unpack() Null Word but "
407 "not at end of Microslice.";
408 }
409 break;
410 }
412 LOG(error) << fName
413 << "::unpack() Unknown Word. "
414 "Microslice corrupted.";
416 return false;
417 break;
418 }
420 fEpoch = extractEpoch(word);
421 fNrEpochMsgs++;
422 break;
423 }
424 default:
425 // We have varying msg types for different versions of the message format. Hence, to not produce compiler warnings we have a "default break;" here.
426 break;
427 }
428 }
429 return unpackOk;
430}
431
ClassImp(CbmConverterManager)
Assign pad layout to TRD Modules.
Unpacker algorithms for the TrdR 2020 data.
int Int_t
Base class for storing raw information which comes from the Spadic v2.2 trough flib or from a tsa fil...
void SetSample(int16_t value, uint8_t pos)
void SetTime(double setvalue)
const std::vector< int16_t > * GetSamples() const
static CbmTrdDigi::eTriggerType GetDigiTriggerType(Spadic::eTriggerType tt)
Get the Digi Trigger Type from the raw message triggertype.
static UInt_t GetNrChannels()
std::shared_ptr< CbmTrdRawToDigiBaseR > fRTDMethod
raw to digi extraction method, set in the task
std::map< Int_t, std::vector< Int_t > > fAsicChannelMap
Map to retrieve module channelId from asicAddress and asicChannel.
void digestOutput(std::unique_ptr< CbmTrdDigi > digi, CbmTrdRawMessageSpadic raw)
Handle the output created by the explicit algorithms. E.g. write to output vectors.
std::shared_ptr< CbmTrdUnpackMonitor > fMonitor
Potential (online) monitor for the unpacking process.
std::shared_ptr< CbmTrdSpadic > fSpadic
Spadic software reprensentation object.
size_t fNrWildRda
Number of rda frames outside of a SOM frame range.
size_t fNrUnknownWords
Number of unknown words.
CbmTrdUnpackAlgoBaseR(std::string name)
Create the Cbm Trd Unpack AlgoBase object.
Bool_t fIsFirstChannelsElinkEven
Define if the first 16 channels (00..15) are found on the even (set true) or odd (false) eLinkId....
std::map< size_t, Int_t > fSpadicAddressMap
Map to retrieve asic address from CriId/CrobId/ElinkId (see CbmTrdHardwareSetupR)
std::map< size_t, std::vector< Int_t > > fTimeshiftsMap
Map containing the timeshift parameters for the correction of the micro-Slice timeshifts....
int16_t extractSample(const size_t word, const Spadic::MsMessageType msgType, uint32_t isample, bool multihit=false)
Extract the given sample from the given rda word.
size_t fMsLengthCC
Microslice length [CC]. To be overwritten in the version specific unpackers.
Spadic::MsInfoType getInfoType(const size_t msg)
Identify the InfoType of a 64bit InfoMessage word inside a Microslice.
std::vector< int32_t > * fTimeshiftsParVec
Vector containing the timeshift parameters for the correction of the micro-Slice timeshifts for a giv...
void makeDigi(CbmTrdRawMessageSpadic raw)
Create an actual digi from the raw message.
CbmTrdUnpackAlgoLegacy2020R()
Create the Cbm Trd Unpack AlgoBase object.
Spadic::MsMessageType getMessageType(const size_t msg)
Identify the message type of a 64bit word inside a Microslice.
size_t extractEpoch(const size_t word)
Extract the epoch time reference information from the epoch word.
const std::vector< uint8_t > fExtractSampleIndicesVec
static const uint8_t fBytesPerWord
Bytes per word stored in the microslices.
size_t fEpoch
Time of the current epoch marker.
virtual bool unpack(const fles::Timeslice *ts, uint16_t icomp, UInt_t imslice)
Unpack a given microslice.
virtual std::vector< std::pair< std::string, std::shared_ptr< FairParGenericSet > > > * GetParContainerRequest(std::string geoTag, uint32_t runId)
Get the requested parameter containers. Return the required parameter containers together with the pa...
uint8_t getNrOfRdaWords(uint8_t nsamples)
Get the Nr Of Rda Words required for the amount of ADC samples.
virtual CbmTrdRawMessageSpadic makeRaw(const size_t word, fles::MicrosliceDescriptor msDesc)
Create a CbmTrdRawMessageSpadic from the hit message input.
virtual bool setDerivedTsParameters(size_t itimeslice)
Set the Derived Ts Parameters.
virtual ~CbmTrdUnpackAlgoLegacy2020R()
Destroy the Cbm Trd Unpack Task object.
void finishDerived()
Additional explicit finish function of this algo implementation.
@ kUNU
Unused request. 100. .... .... .... cccc.
@ kBOM
Buffer overflow count. 11nn nnnn nnnn nnnn cccc.
@ kMIS
Missing request. 101. .... .... .... ....
@ kBUF
Buffer full. 011b b... .... .... cccc.
@ kMSB
Message build error. 010. .... .... .... cccc.
@ kEPO
Epoch Marker or TS_MSB depending on the hitmessage version.