BmnRoot 26.10.0-18-g4e3414f9
Software framework of the BM@N experiment
Loading...
Searching...
No Matches
BmnConverterThread.cxx
Go to the documentation of this file.
2
3// ROOT
4#include "TFile.h"
5// BmnRoot
6#include "BmnADCDigit.h"
7#include "BmnAbstractTDCDigit.h"
8#include "BmnConverterTools.h"
9#include "BmnHRBDigit.h"
10#include "BmnHgndRaw.h"
11#include "BmnMSCDigit.h"
12#include "BmnMSCZSDigit.h"
13#include "BmnMath.h"
14#include "BmnT0Raw.h"
15#include "BmnTDCDigit.h"
16#include "BmnTQDCADCDigit.h"
17#include "BmnVspRawDigit.h"
18// CBM
19#include "StorableTimeslice.h"
20#include "StsXyterMessage.h"
21
22using namespace std::chrono;
23
25{ // std::function<void(TString, TObject**) > branch_reg_fun) {
26 fRawTree->Branch("BmnEventHeader.", &eventHeaderDAQ);
27 // FairRootManager* frm = FairRootManager::Instance();
28 // frm->Register("BmnEventHeader.", "BmnEventHeader._dir", eventHeaderDAQ, fSaveOutput);
29 fRawTree->Branch("SYNC", &sync);
30 fRawTree->Branch("ADC32", &adc32);
31 fRawTree->Branch("ADC64", &adc64);
32 fRawTree->Branch("ADC128", &adc128);
33 fRawTree->Branch("ADC", &adc);
34 fRawTree->Branch("VSP_RAW", &vsp);
35 fRawTree->Branch("TDC", &tdc);
36 fRawTree->Branch("TQDC_ADC", &tqdc_adc);
37 fRawTree->Branch("TQDC_TDC", &tqdc_tdc);
38 fRawTree->Branch("TDC_HGND", &tdc_hgnd);
39 fRawTree->Branch("HRB", &hrb);
40}
41
43{
44 fRawTreeSpills->Branch("MSC", &msc);
45 fRawTreeSpills->Branch("T0Raw", &t0raw);
46}
47
49{
50 if (merger) {
51 mergerFile = merger->GetFile();
52 mergerFile->cd();
53 }
54 TString ext = (threadId == -1) ? "" : to_string(threadId);
55 // TString ext = "";//(threadId == -1) ? "" : to_string(threadId);
56 fRawTree = new TTree((TString) "BMN_RAW" + ext, (TString) "BMN_RAW" + ext);
57 fRawTree->SetAutoSave(0); // Very important
58 fRawTreeSpills = new TTree((TString) "BMN_RAW_SPILLS" + ext, (TString) "BMN_RAW_SPILLS" + ext);
59 fRawTreeSpills->SetAutoSave(0); // Very important
74}
75
77{
78 fRawTree = tree;
79 fRawTree->SetBranchAddress("BmnEventHeader.", &eventHeaderDAQ);
80 fRawTree->SetBranchAddress("SYNC", &sync);
81 fRawTree->SetBranchAddress("ADC32", &adc32);
82 fRawTree->SetBranchAddress("ADC64", &adc64);
83 fRawTree->SetBranchAddress("ADC128", &adc128);
84 fRawTree->SetBranchAddress("ADC", &adc);
85 fRawTree->SetBranchAddress("VSP_RAW", &vsp);
86 fRawTree->SetBranchAddress("TDC", &tdc);
87 fRawTree->SetBranchAddress("TQDC_ADC", &tqdc_adc);
88 fRawTree->SetBranchAddress("TQDC_TDC", &tqdc_tdc);
89 fRawTree->SetBranchAddress("TDC_HGND", &tdc_hgnd);
90 fRawTree->SetBranchAddress("HRB", &hrb);
91 fRawTreeSpills = treeSpills;
92 fRawTreeSpills->SetBranchAddress("MSC", &msc);
93 fRawTreeSpills->SetBranchAddress("T0Raw", &t0raw);
94}
95
97{
98 auto f = merger->GetFile();
99 TTree* tree = new TTree("BMN_RAW", "BMN_RAW");
100 TTree* treeSpills = new TTree("BMN_RAW_SPILLS", "BMN_RAW_SPILLS");
101 tree->Branch("BmnEventHeader.", &eventHeaderDAQ);
102 tree->Branch("SYNC", &sync);
103 tree->Branch("ADC32", &adc32);
104 tree->Branch("ADC64", &adc64);
105 tree->Branch("ADC128", &adc128);
106 tree->Branch("ADC", &adc);
107 tree->Branch("VSP_RAW", &vsp);
108 tree->Branch("TDC", &tdc);
109 tree->Branch("TQDC_ADC", &tqdc_adc);
110 tree->Branch("TQDC_TDC", &tqdc_tdc);
111 tree->Branch("TDC_HGND", &tdc_hgnd);
112 tree->Branch("HRB", &hrb);
113 treeSpills->Branch("MSC", &msc);
114 treeSpills->Branch("T0Raw", &t0raw);
115 for (size_t j = 0; j < vecTree->size(); j++) {
116 if ((*vecTree)[j].first == spillId) {
117 if ((*vecTree)[j].second.first == threadId) {
118 fRawTree->GetEntry((*vecTree)[j].second.second);
119 tree->Fill();
120 }
121 }
122 }
123 for (size_t j = 0; j < vecTreeSpills->size(); j++) {
124 if ((*vecTreeSpills)[j].first == spillId) {
125 if ((*vecTreeSpills)[j].second.first == threadId) {
126 fRawTreeSpills->GetEntry((*vecTreeSpills)[j].second.second);
127 treeSpills->Fill();
128 }
129 }
130 }
131 f->Write();
132}
133
135{
136 LOGF(debug2, "Calculate task %d in id %d", taskId, threadId);
137 if (taskId == 1) {
139 // if(!isTaskMode){
140 fRawTree->Fill();
141 //}
142 } else if (taskId == 2) {
144 SpillEnd();
145 } else if (taskId == 3) {
147 }
148 LOGF(debug2, "Calculate task %d in id %d done", taskId, threadId);
149}
150
152{
153 fRawTree->Write();
154}
155
160
162{
163 // fRawTree->Write();
164 // fRawTreeSpills->Write();
165 if (mergerFile) {
166 mergerFile->Write();
167 mergerFile->Close();
168 mergerFile.reset();
169 LOGF(info, "thread file closed");
170 }
171}
172
174 Int_t len,
175 const uint32_t* data,
176 BmnEventType fCurEvType,
177 uint32_t fRunId,
178 uint32_t fEventId)
179{
180 dataLen = len;
181 if (data)
182 std::memcpy(rawData, data, sizeof(uint32_t) * len);
183 fCurEvent.fEvType = fCurEvType;
184 fCurEvent.fRunId = fRunId;
185 // fCurEvent.fPeriodId = fPeriodId;
186 fCurEvent.fEventId = fEventId;
187 this->taskId = id;
188}
189
190// not actually spill end since 8th period
191
193{
194 if (fRawTreeSpills) {
195 fRawTreeSpills->Fill();
197 }
198}
199
200BmnStatus BmnConverterThread::ConvertStatEvent(const uint32_t* d, uint32_t& len)
201{
202 eventHeaderDAQ->SetEventType(fCurEvent.fEvType);
203 ProcessEvent(d, len);
204 // if (fRootFileOut) fRawTree->Fill();
205 /*if ((fCurEvType == kBMNEOS) && (fPrevEvType != kBMNEOS)) {
206 LOGF(debug1, "\tspill! nSpillEvents %d", nSpillEvents);
207 isSpillStart = kTRUE;
208 nSpillEvents = 0;
209 fSpillCntr++;
210 // if (msc->GetEntriesFast() > 0)
211
212 }*/
213 return kBMNSUCCESS;
214}
215
216BmnStatus BmnConverterThread::ProcessEvent(const uint32_t* d, uint32_t len)
217{
218 // timer.Start();
220 if ((fCurEvent.fEventId % 5000 <= 1) && (fCurEvent.fEvType != kBMNSTAT) && (fCurEvent.fEventId > 0))
221 LOG(info) << "Converted event #" << fCurEvent.fEventId;
222 // } else if (fVerbose == 0)
223 // DrawBar(fCurentPositionRawFile, fLengthRawFile);
224
225 uint32_t idx = 1;
226 // BmnEventType evType = kBMNPAYLOAD;
227 BmnTrigInfo trigInfo;
228 while (idx < len) {
229 Bool_t recognized = kTRUE;
230 const DeviceHeader* dh = reinterpret_cast<const DeviceHeader*>(d + idx);
231 // printf("[%u]\n", idx);
232 // if (fCurEvType == kBMNSTAT)
233 // dh->Print();
234 uint32_t serial = dh->Serial;
235 uint8_t id = dh->DeviceId;
236 // if (serial == 0) id = kGENERIC_DEVICE;
237 uint32_t payload = dh->GetNWords();
238 idx += sizeof(DeviceHeader) / kNBYTESINWORD;
239 if (payload > 2000000) {
240 LOGF(warn, "Event %d:\n serial = 0x%06X\n id = Ox%02X\n payload = %d", fCurEvent.fEventId, serial, id,
241 payload);
242 break;
243 }
244 if (fCurEvent.fEvType == kBMNSTAT)
245 LOGF(debug4, "STAT iev %7d idx %6u/%6u idev %02X serial 0x%08X payload %4u", fCurEvent.fEventId, idx,
246 len, id, serial, payload);
247 switch (id) {
248 case kTQDC16VS_E:
249 FillTQDC_E(&d[idx], serial, payload);
250 break;
251 case kTDC72VXS: // Trig & ToF400 VXS TDC
252 case kTDC64VHLE_E: // ToF700 VHL TDC
253 FillTDC72VXS(&d[idx], serial, payload, id);
254 break;
255 case kTTVXS:
256 FillTTVXS(&d[idx], serial, payload);
257 break;
258 case kGENERIC_DEVICE:
259 ProcessGenericDevice(&d[idx], dh);
260 break;
261 case kMSC16VE_E:
262 // printf("MSC16VE-E serial 0x%08X words %u\n", serial, payload);
263 if (msc)
264 FillMSC16VE_E(&d[idx], dh);
265 break;
266 case kADC64VE_XGE:
267 case kADC64VE: {
268 BmnConverterTools::Process_ADC64<int16_t>(&d[idx], payload, serial,
269 [&](Int_t n_samples) -> TClonesArray* {
270 switch (n_samples) {
271 case 32:
272 return adc32;
273 break;
274 case 64:
275 return adc64;
276 break;
277 case 128:
278 return adc128;
279 break;
280 default:
281 return nullptr;
282 break;
283 }
284 });
285 break;
286 }
287 case kADC64WR: {
289 &d[idx], payload, serial, [&](Int_t n_samples) -> TClonesArray* { return adc; });
290 if (ret == kBMNERROR)
291 LOGF(warning, "Malformed data from ADC64WR %08X in the event %u", serial, fCurEvent.fEventId);
292 break;
293 }
294 case kFVME:
295 Process_FVME(&d[idx], payload, serial, trigInfo);
296 break;
297 case kHRB:
298 Process_HRB(&d[idx], payload, serial);
299 break;
300 case kUT24VE_TRC:
301 FillUT24VE_TRC(&d[idx], serial, payload);
302 break;
303 case kVIRTUAL_DEVICE:
304 FillVirtualDevice(&d[idx], dh);
305 break;
306 default:
307 // printf("Device id %02X not recognized\n", id);
308 recognized = kFALSE;
309 break;
310 }
311 if (payload + idx > len) {
312 printf(
313 "Error in the event #%d: 0x%08X : %2X device payload length mismatch! pauload %5u idx/len: %5u/%5u \n",
314 fCurEvent.fEventId, serial, id, payload, idx, len);
315 return kBMNERROR;
316 } else {
317 if (recognized)
318 idx += payload;
319 else
320 idx--;
321 }
322 }
323 if (time_slice_map.size())
324 FillVSP(nullptr);
325 eventHeaderDAQ->SetRunId(fCurEvent.fRunId);
326 eventHeaderDAQ->SetPeriodId(fPeriodId);
327 eventHeaderDAQ->SetEventId(fCurEvent.fEventId);
328 eventHeaderDAQ->SetEventTimeTS(TTimeStamp(time_t(fCurEvent.fTime_s), fCurEvent.fTime_ns));
329 eventHeaderDAQ->SetEventTime(TTimeStamp(time_t(fCurEvent.fTime_s), fCurEvent.fTime_ns).AsDouble());
330 eventHeaderDAQ->SetEventType(fCurEvent.fEvType);
331 eventHeaderDAQ->SetTripWord(kFALSE);
332 eventHeaderDAQ->SetTrigInfo(trigInfo);
333 // eventHeaderDAQ->SetTimeShift(fTimeShifts);
334 // eventHeaderDAQ->SetStartSignalInfo(fT0Time, fT0Width);
335 // eventHeaderDAQ->SetSpillStart(isSpillStart);
336 // if ((fCurEvent.fCurEvType == kBMNSTAT) || (fCurEvent.fCurEvType == kBMNEOS))
337 // eventHeaderDAQ->SetEventId(0);
338 return kBMNSUCCESS;
339}
340
341BmnStatus BmnConverterThread::Process_FVME(const uint32_t* d, uint32_t len, uint32_t serial, BmnTrigInfo& spillInfo)
342{
343 // printf("FVME serial %08X len %u\n",serial, len);
344 if (fCurEvent.fEvType == kBMNSTAT) {
345 fCurEvent.fEvType = kBMNEOS;
346 // printf("stat FVME serial %08X len %u\n", serial, len);
347 }
348 uint32_t modId = 0;
349 uint32_t slot = 0;
350 uint32_t type = 0;
351 for (uint32_t i = 0; i < len; i++) {
352 type = d[i] >> 28;
353 // if (fCurEvType == kBMNSTAT)
354 // printf(" type %02X i %u\n", type, i);
355 switch (type) {
356 case kEVHEADER:
357 // if (fCurEvType == kBMNSTAT)
358 // printf("Ev header \n");
359 break;
360 case kEVTRAILER:
361 // if (fCurEvType == kBMNSTAT)
362 // printf("Ev trailer\n");
363 return kBMNSUCCESS;
364 break;
365 case kSTATUS:
366 case kPADDING:
367 break;
368 case kMODHEADER:
369 modId = (d[i] >> 16) & 0x7F;
370 slot = (d[i] >> 23) & 0x1F;
371 // if (fCurEvType == kBMNSTAT)
372 // printf("\tmodid 0x%02X slot %d serial 0x%08X\n", modId, slot, serial);
373 break;
374 case kMODTRAILER:
375 // if (fCurEvType == kBMNSTAT)
376 // printf("\tmodule trailer\n");
377 if (!((d[i] >> 16) & 0x1))
378 printf(ANSI_COLOR_RED "Readout overflow error\n" ANSI_COLOR_RESET);
379 if (!((d[i] >> 17) & 0x1))
380 printf(ANSI_COLOR_RED "Readout error\n" ANSI_COLOR_RESET);
381 if (!((d[i] >> 18) & 0x1))
382 printf(ANSI_COLOR_RED "TTC error\n" ANSI_COLOR_RESET);
383 if (!((d[i] >> 19) & 0x1))
384 printf(ANSI_COLOR_RED "Access error\n" ANSI_COLOR_RESET);
385 modId = 0x00;
386 slot = 0x00;
387 break;
388 default: // data
389 {
390 // BmnStatus parsing_status(kBMNSUCCESS);
391 switch (modId) {
392 case kTDC64V:
393 case kTDC64VHLE:
394 case kTDC72VHL:
395 case kTDC32VL:
396 FillTDC(d, serial, slot, modId, i);
397 break;
398 case kTQDC16:
399 case kTQDC16VS:
400 FillTQDC(d, serial, slot, modId, i);
401 break;
402 case kMSC16V:
403 FillMSC(d, serial, slot, i);
404 break;
405 case kTRIG:
406 /*parsing_status = */ FillFVME2TMWR(d, serial, i, len);
407 break;
408 case kU40VE_RC:
409 FillU40VE(d, slot, i, spillInfo);
410 break;
411 }
412 }
413 }
414 }
415 return kBMNSUCCESS;
416}
417
418BmnStatus BmnConverterThread::Process_HRB(const uint32_t* d, uint32_t len, uint32_t serial)
419{
420 // uint32_t evId = d[0];
421 uint32_t tH = d[1];
422 uint32_t tL = d[2];
423 uint32_t nWords = 4; // 4 words per plane (per 96 channels, why 4 words - 3 is enough???)
424 uint32_t nSmpl = (len - 3) / nWords; // 3 words are read now. Why divide by 4 (To ask Vadim)
425
426 for (uint32_t iSmpl = 0; iSmpl < nSmpl; ++iSmpl) {
427 for (uint32_t iWord = 0; iWord < nWords; ++iWord) {
428 uint32_t word32 = d[3 + iWord + iSmpl * nWords];
429 for (Int_t iCh = 0; iCh < 32; ++iCh) {
430 if (word32 & BIT(iCh)) {
431 TClonesArray& ar_hrb = *hrb;
432 new (ar_hrb[hrb->GetEntriesFast()]) BmnHRBDigit(serial, iCh + 32 * iWord, iSmpl, tH, tL);
433 }
434 }
435 }
436 }
437
438 return kBMNSUCCESS;
439}
440
441BmnStatus BmnConverterThread::FillU40VE(const uint32_t* d, uint32_t slot, uint32_t& idx, BmnTrigInfo& trigInfo)
442{
443 uint32_t type = d[idx] >> 28;
444 // printf("\t\tU40VE start type %u slot %u idx %u\n", type, slot, idx);
445 Bool_t countersDone = kFALSE;
446 while (type == kWORDTAI || type == kWORDTRIG || type == kWORDAUX) {
447 if (fPeriodId > 4 && type == kWORDTRIG && slot == kEVENTTYPESLOT) {
448 fCurEvent.fEvType = ((d[idx] & BIT(3)) >> 3) ? kBMNPEDESTAL : kBMNPAYLOAD;
449 // uint32_t trigSrc = ((d[idx] >> 16) & (BIT(8) - 1));
450 // printf("EvId %6u trig source %u evType %d\n", fEventId, trigSrc, evType);
451 // if (!( ((d[idx]>>10) & 0x1) ^ (fPeriodId >= 7 && fBmnSetup == kBMNSETUP)))
452 // printf("Ev not Good!\n");
453 // printf("evGood %d\n", (d[idx] & BIT(10)));
454 }
455 if (type == kWORDAUX && !countersDone) {
456 trigInfo.SetTrigCand(d[idx + 0] & 0xFFFFFFF);
457 trigInfo.SetTrigAccepted(d[idx + 1] & 0xFFFFFFF);
458 trigInfo.SetTrigBefo(d[idx + 2] & 0xFFFFFFF);
459 trigInfo.SetTrigAfter(d[idx + 3] & 0xFFFFFFF);
460 trigInfo.SetTrigRjct(d[idx + 4] & 0xFFFFFFF);
461 trigInfo.SetTrigAll(d[idx + 5] & 0xFFFFFFF);
462 trigInfo.SetTrigAvail(d[idx + 6] & 0xFFFFFFF);
463 idx += 4;
464 countersDone = kTRUE;
465 }
466 idx++; // go to the next DATA-word
467 type = d[idx] >> 28;
468 // printf("\t type %u slot %u idx %u\n", type, slot, idx);
469 }
470
471 return kBMNSUCCESS;
472}
473
474BmnStatus BmnConverterThread::FillTDC(const uint32_t* d, uint32_t serial, uint32_t slot, uint32_t modId, uint32_t& idx)
475{
476 uint32_t type = d[idx] >> 28;
477 while (type != kMODTRAILER) { // data will be finished when module trailer appears
478 if (type == TDC_ERROR) {
479 LOGF(warning, "TDC (modID 0x%02X serial 0x%08X slot %d tdcID %d) error flags: 0x%04X", modId, serial, slot,
480 ((d[idx] >> 24) & 0xF), (d[idx] & ((1 << 15) - 1)));
481 if ((d[idx] & BIT(12)) || (d[idx] & BIT(13))) {
482 LOGF(warning, "TDC data loss in 0x%08X ", serial);
483 return kBMNERROR;
484 }
485 }
486 if (type == TDC_LEADING || type == TDC_TRAILING) {
487 uint32_t tdcId = (d[idx] >> 24) & 0xF;
488 uint32_t time =
489 (modId == kTDC64V) ? (d[idx] & 0x7FFFF) : ((d[idx] & 0x7FFFF) << 2) | ((d[idx] & 0x180000) >> 19);
490 uint32_t channel = (modId == kTDC64V) ? (d[idx] >> 19) & 0x1F : (d[idx] >> 21) & 0x7;
491 // if (modId == kTDC64V && tdcId == 2) channel += 32;
492 TClonesArray& ar_tdc = *tdc;
493 new (ar_tdc[tdc->GetEntriesFast()])
494 BmnTDCDigit(serial, modId, slot, (type == TDC_LEADING), channel, tdcId, time);
495 if (fCurEvent.fEvType == kBMNSTAT)
496 LOGF(debug4, "tdc %08X : %d channel %d", serial, slot, channel);
497 }
498 idx++; // go to the next DATA-word
499 type = d[idx] >> 28;
500 }
501 return kBMNSUCCESS;
502}
503
504BmnStatus BmnConverterThread::FillTQDC(const uint32_t* d, uint32_t serial, uint32_t slot, uint32_t modId, uint32_t& idx)
505{
506 uint32_t type = d[idx] >> 28;
507 UShort_t trigTimestamp = 0;
508 UShort_t adcTimestamp = 0;
509 UShort_t tdcTimestamp = 0;
510 // uint32_t iSampl = 0;
511 uint32_t channel = 0;
512 // Short_t valI[ADC_SAMPLING_LIMIT];
513 vector<int16_t> valI;
514 Bool_t inADC = kFALSE;
515 while (type != kMODTRAILER) {
516 if (type == TDC_ERROR) {
517 LOGF(warning, "TDC (serial 0x%08X slot %d tdcID %d) error flags: 0x%04X", serial, slot,
518 ((d[idx] >> 24) & ((1 << 4) - 1)), (d[idx] & ((1 << 15) - 1)));
519 if ((d[idx] & BIT(12)) || (d[idx] & BIT(13))) {
520 LOGF(warning, "TQDC data loss in 0x%08X ", serial);
521 return kBMNERROR;
522 }
523 }
524 uint32_t mode = (d[idx] >> 26) & 0x3;
525 if (!inADC) { // printf("type %d mode %d word %0X\n", type, mode, d[idx]);
526 if ((mode == 0) && (type == TDC_LEADING || type == TDC_TRAILING)) { // TDC time
527 channel = (d[idx] >> 19) & 0x1F;
528 uint32_t time = ((d[idx] & 0x7FFFF) << 2) | ((d[idx] >> 24) & 0x3); // in 25 ps
529 // printf("TDC time %d channel %d\n", time, channel);
530 new ((*tqdc_tdc)[tqdc_tdc->GetEntriesFast()])
531 BmnTDCDigit(serial, modId, slot, (type == TDC_LEADING), channel, 0, time, tdcTimestamp);
532 // printf("tqdc tdc %08X : %d channel %d\n", serial, slot, channel);
533 } else if ((type == 4) && (mode != 0)) { // Trig | ADC Timestamp
534 channel = (d[idx] >> 19) & 0x1F;
535 if (d[idx] & BIT(16)) { // ADC TS
536 adcTimestamp = d[idx] & 0xFFFF;
537 inADC = kTRUE;
538 } else { // Trig TS
539 trigTimestamp = d[idx] & 0xFFFF;
540 }
541 } else if (type == TDC_EV_HEADER) {
542 tdcTimestamp = d[idx] & 0xFFF;
543 // uint32_t iEv = (d[idx] >> 12) & 0xFFF;
544 // printf("TDC ev header: %d\n", iEv);
545 } else if (type == TDC_EV_TRAILER) {
546 // uint32_t iEv = (d[idx] >> 12) & 0xFFF;
547 // printf("TDC ev trailer: %d\n", iEv);
548 }
549 } else {
550 if ((type == 5) && (mode == 2) /* && (iSampl < ADC_SAMPLING_LIMIT)*/) {
551 Short_t val = (d[idx] & ((1 << 14) - 1)) - (1 << (14 - 1));
552 // valI[iSampl++] = val;
553 valI.push_back(val);
554 } else {
555 new ((*tqdc_adc)[tqdc_adc->GetEntriesFast()])
556 BmnTQDCADCDigit(serial, channel, slot, std::move(valI), trigTimestamp, adcTimestamp);
557 inADC = kFALSE;
558 --idx;
559 // printf("tqdc adc %08X : %d channel %d\n", serial, slot, channel);
560 }
561 }
562 type = d[++idx] >> 28;
563 }
564 return kBMNSUCCESS;
565}
566
568 uint32_t serial,
569 uint8_t channel,
570 uint16_t& len,
571 TClonesArray* ar)
572{
573 vector<int16_t> valI;
574 const uint8_t NBytesInSample = 2;
575 uint16_t iWord = 0;
576 while (iWord < len) {
577 uint16_t adcTS = d[iWord] & (BIT(16) - 1);
578 uint16_t SigLen = d[iWord] >> 16;
579 uint16_t NSamples = SigLen / NBytesInSample;
580 uint16_t NSampleWords = SigLen / kNBYTESINWORD + ((SigLen % kNBYTESINWORD) ? 1 : 0);
581 // printf("SigLen %3u adc len %2u ts %3u NSampleWords %u\n", SigLen, NSamples, adcTS, NSampleWords);
582 if (iWord + NSampleWords + 1 > len) {
583 LOGF(error, "TQDC ADC wrong payload length! iWord %u SigLen %u len %u", iWord, SigLen, len);
584 return kBMNERROR;
585 }
586 uint16_t iSampleWord = 0;
587 while (iSampleWord++ < NSampleWords) {
588 int16_t adcLo = static_cast<int16_t>(d[iWord + iSampleWord] & (BIT(16) - 1));
589 int16_t adcHi = static_cast<int16_t>(d[iWord + iSampleWord] >> 16);
590 valI.push_back(adcLo);
591 if (valI.size() < NSamples)
592 valI.push_back(adcHi);
593 }
594 if (NSamples) // no slot id for ethernet
595 new ((*ar)[ar->GetEntriesFast()]) BmnTQDCADCDigit(serial, channel, 0, move(valI), 0, adcTS);
596 iWord += iSampleWord;
597 }
598 return kBMNSUCCESS;
599}
600
602 uint32_t serial,
603 uint16_t& len,
604 TClonesArray* ar,
605 uint32_t modid = 0)
606{
607 // uint16_t tdcTS = 0;
608 // uint8_t tdcId = 0;
609 uint16_t tdcLine = 0;
610 while (tdcLine < len) {
611 uint32_t word = d[tdcLine];
612 uint32_t bt = word >> 28;
613 switch (bt) {
614 case TDC_EV_HEADER: {
615 // uint16_t evId = (word >> 12) & (BIT(12) - 1);
616 // tdcId = (word >> 24) & (BIT(4) - 1);
617 // tdcTS = word & (BIT(12) - 1);
618 // printf("\tTDC header ev %u TS %u\n", evId, tdcTS);
619 break;
620 }
621 case TDC_EV_TRAILER: {
622 // uint16_t evId = (word >> 12) & (BIT(12) - 1);
623 // uint16_t tdcWC = word & (BIT(12) - 1);
624 // printf("\tTDC trailer ev %u WC %u\n", evId, tdcWC);
625 break;
626 }
627 case TDC_LEADING:
628 case TDC_TRAILING: {
629 uint8_t channel = (word >> 21) & (BIT(7) - 1);
630 // uint16_t time = (word>>2) & (BIT(19) - 1);
631 uint32_t time = word & (BIT(21) - 1);
632 // printf("\tTDC %s ch %u id %d time %u\n", (bt == TDC_LEADING) ? "leading" : "trailing",
633 // channel, tdcId, time);
634 new ((*ar)[ar->GetEntriesFast()])
635 BmnTDCDigit(serial, modid, 0, (bt == TDC_LEADING), channel, 0, time, 0); // ignore tdcId in TQDC
636 break;
637 }
638 case TDC_ERROR:
639 LOGF(warning, "TDC (serial 0x%08X tdcID %d) error flags: 0x%04X %s", serial,
640 ((word >> 24) & ((1 << 4) - 1)), (word & ((1 << 15) - 1)),
641 ((word & BIT(12)) || (word & BIT(13))) ? "data lost" : "");
642 break;
643 }
644 tdcLine++;
645 }
646 return kBMNSUCCESS;
647}
648
649BmnStatus BmnConverterThread::FillTQDC_E(const uint32_t* d, uint32_t serial, uint32_t& len)
650{
651 uint32_t index = 0;
652 // MStreamHeader* ms = reinterpret_cast<MStreamHeader*> (d);
653 index += sizeof(MStreamHeader) / kNBYTESINWORD;
654 // ms->Print();
655 const MStreamTAI* ms0 = reinterpret_cast<const MStreamTAI*>(d + index);
656 if (ms0->valid())
657 FillWR(serial, fCurEvent.fEventId, ms0->Sec, ms0->NSec);
658 index += sizeof(MStreamTAI) / kNBYTESINWORD;
659 // printf("len %u msHeader len %u\n", len, ms.Len / kNBYTESINWORD);
660 // printf("taiFlags %u TAI %s\n",
661 // ms0->Flags, TTimeStamp(time_t(ms0->Sec), ms0->NSec).AsString());
662 while (index < len) {
663 const TqdcDataHeader* th = reinterpret_cast<const TqdcDataHeader*>(d + index);
664 index += sizeof(TqdcDataHeader) / kNBYTESINWORD;
665 // printf("TQDC DataType %u channel %2u adcBits %u len %4u %8X\n", th->DataType, th->Chan,
666 // th->AdcBits, th->Len,*th);
667 uint16_t blockLen = th->Len / kNBYTESINWORD;
668 switch (th->DataType) {
670 FillBlockTDC(d + index, serial, blockLen, tqdc_tdc);
671 break;
673 FillBlockADC(d + index, serial, th->Chan, blockLen, tqdc_adc);
674 break;
675 default:
676 printf("Wrong TQDC data type %u !\n", th->DataType);
677 break;
678 }
679 index += blockLen;
680 }
681 return kBMNSUCCESS;
682}
683
684BmnStatus BmnConverterThread::FillTDC72VXS(const uint32_t* d, uint32_t serial, uint32_t& len, uint32_t modid = 0)
685{
686 uint32_t index = 0;
687 // MStreamHeader* ms = reinterpret_cast<MStreamHeader*> (d);
688 index += sizeof(MStreamHeader) / kNBYTESINWORD;
689 // ms->Print();
690 const MStreamTAI* ms0 = reinterpret_cast<const MStreamTAI*>(d + index);
691 if (ms0->valid())
692 FillWR(serial, fCurEvent.fEventId, ms0->Sec, ms0->NSec);
693 // printf("taiFlags %u TAI %s\n",
694 // ms0->Flags, TTimeStamp(time_t(ms0->Sec), ms0->NSec).AsString());
695 index += sizeof(MStreamTAI) / kNBYTESINWORD;
696 while (index < len) {
697 uint8_t dtype = d[index] >> 28;
698 bool overflow = d[index] & BIT(16);
699 uint16_t blockLen = (d[index++] & (BIT(16) - 1)) / kNBYTESINWORD;
700 if (!overflow)
701 switch (dtype) {
703 // printf("TDC at index %4u len %4u\n", index, blockLen);
704 FillBlockTDC(d + index, serial, blockLen, tdc, modid);
705 break;
707 break;
708 default:
709 printf("Wrong VXS data type %u !\n", dtype);
710 break;
711 }
712 index += blockLen;
713 }
714 return kBMNSUCCESS;
715}
716
717BmnStatus BmnConverterThread::FillTTVXS(const uint32_t* d, uint32_t serial, uint32_t& len)
718{
719 uint32_t index = 0;
720 // MStreamHeader* ms = reinterpret_cast<MStreamHeader*> (d);
721 index += sizeof(MStreamHeader) / kNBYTESINWORD;
722 // ms->Print();
723 const MStreamTAI* ms0 = reinterpret_cast<const MStreamTAI*>(d + index);
724 index += sizeof(MStreamTAI) / kNBYTESINWORD;
725 if (ms0->valid())
726 FillWR(serial, fCurEvent.fEventId, ms0->Sec, ms0->NSec);
727 // LOGF(debug, "ts :\t %s TTVXS 0x%08X valid %d",
728 // TTimeStamp(time_t(ms0->Sec), ms0->NSec).AsString(), serial, ms0->valid());
729 // LOGF(debug, "ts :\t %10u %9u TTVXS 0x%08X", ms0->Sec, ms0->NSec, serial);
730 while (index < len) {
731 uint8_t dtype = d[index] >> 28;
732 bool overflow = d[index] & BIT(16);
733 uint16_t blockLen = (d[index++] & (BIT(16) - 1)) / kNBYTESINWORD;
734 // printf("type 0x%02X len %4u\n", dtype, blockLen);
735 if (!overflow)
736 switch (dtype) {
737 case kMSTREAM_TYPE_TRIG: {
738 // printf("Trig at index %4u len %4u\n", index, blockLen);
739 // uint8_t trigType = (d[index] << 8) & (BIT(8) - 1);
740 // uint8_t trigSrc = d[index] & (BIT(8) - 1);
741 // printf("Trig type %4u src %4u\n", trigType, trigSrc);
742 } break;
744 break;
745 default:
746 printf("Wrong TTVXS data type %u !\n", dtype);
747 break;
748 }
749 index += blockLen;
750 }
751 return kBMNSUCCESS;
752}
753
754BmnStatus BmnConverterThread::ProcessGenericDevice(const uint32_t* d, const DeviceHeader* dev_hdr)
755{
756 // dev_hdr->Print();
757 if ((dev_hdr->Serial & 0x00FFFFFF) == kVSP_SERIALS)
758 return MapVSP(d, dev_hdr);
759 else if (dev_hdr->Serial == kHGND_SERIALS)
760 return FillTDC250HGND(d, dev_hdr->Serial, dev_hdr->Len);
761 else
762 LOGF(error, "BmnRawSource::ProcessGenericDevice: Unknown device serial 0x%08X", dev_hdr->Serial);
763
764 return kBMNSUCCESS;
765}
766
767BmnStatus BmnConverterThread::FillTDC250HGND(const uint32_t* d, uint32_t serial, uint32_t len)
768{
769 if (!d || len == 0)
770 return kBMNSUCCESS;
771
772 const uint16_t* words = reinterpret_cast<const uint16_t*>(d);
773 size_t total_words = len / sizeof(uint16_t);
774
775 if (FairLogger::GetLogger()->IsLogNeeded(fair::Severity::debug4)) {
776 for (size_t i = 0; i < total_words; ++i)
777 LOGF(debug4, "0x%04x", words[i]);
778 }
779
780 size_t index = 0;
781 std::vector<uint16_t> event_words;
782 std::unique_ptr<BmnHgndRaw::FIFO_block> event;
783
784 while (index < total_words) {
785 auto* word = words + index;
787 LOGF(error, "BmnRawSource::FillTDC250HGND: Wrong header 0x%04X", *word);
788 return kBMNERROR;
789 }
790
791 auto event_type = BmnHgndRaw::Block::get_event_packet_version(*word);
792 uint32_t event_length = BmnHgndRaw::Block::get_block_size(event_type); // in 16-bit words
793
794 LOGF(debug4, "Event type %d, 16bit words %d (index=%zu, total=%zu)", (uint32_t)event_type, event_length, index,
795 total_words);
796
797 if (index + event_length > total_words) {
798 LOGF(error, "BmnRawSource::FillTDC250HGND: Event block overruns buffer");
799 return kBMNERROR;
800 }
801
802 event_words.assign(word, word + event_length);
803 if (FairLogger::GetLogger()->IsLogNeeded(fair::Severity::debug4)) {
804 for (size_t i = 0; i < event_words.size(); ++i) {
805 LOGF(debug4, "0x%04x", event_words[i]);
806 }
807 }
808
809 if (event_type == BmnHgndRaw::Block::EventPacketVersion::V1) {
810 event = std::make_unique<BmnHgndRaw::Event_type_1>(event_words);
811 } else if (event_type == BmnHgndRaw::Block::EventPacketVersion::V2) {
812 event = std::make_unique<BmnHgndRaw::Event_type_2>(event_words);
813 if (!event->validate()) {
814 LOGF(error, "BmnRawSource::FillTDC250HGND: Event block validation failed");
815 return kBMNERROR;
816 }
817
818 auto* ev2 = dynamic_cast<BmnHgndRaw::Event_type_2*>(event.get());
819 if (!ev2) {
820 LOGF(error, "BmnRawSource::FillTDC250HGND: Event cast to Event_type_2 failed");
821 return kBMNERROR;
822 }
823
824 uint8_t trise_100ps = ev2->TDC_rise_time; // raw time rise
825 uint8_t tfall_100ps = ev2->TDC_falling_time; // raw time fall
826 int64_t time_sec = ev2->timestamp >> 31; // WR timestamp, seconds part
827 time_sec -= tai_utc_dif;
828 uint64_t time_nsec = ((ev2->timestamp & 0x7ffffff0) >> 4) * 32; // WR timestamp, ns part. 32ns step
829 uint16_t time_100ps =
830 (ev2->timestamp & 0xf) * 32 + trise_100ps; // 3.2ns step + 100ps step subns part. trise
831 uint16_t plen_100ps =
832 (ev2->pulse_length + 1) * 32 + tfall_100ps - trise_100ps; // pulse len x100ps +fall -rise
833
834 LOGF(debug4, "ch_num = 0x%02X", ev2->channel_number);
835 LOGF(debug4, "timestamp = 0x%016lX", ev2->timestamp);
836 LOGF(debug4, "time_sec = 0x%08X", time_sec);
837 LOGF(debug4, "time_nsec = 0x%08X", time_nsec);
838 LOGF(debug4, "trise_100ps = 0x%02X", trise_100ps);
839 LOGF(debug4, "tfall_100ps = 0x%02X", tfall_100ps);
840 LOGF(debug4, "time_100ps = 0x%04X", time_100ps);
841 LOGF(debug4, "plen_100ps = 0x%04X", plen_100ps);
842 LOGF(debug4, "global_ch = 0x%04X", ev2->channel_number_global);
843
844 new ((*tdc_hgnd)[tdc_hgnd->GetEntriesFast()])
845 BmnAbstractTDCDigit(serial, ev2->channel_number_global, time_sec, time_nsec, time_100ps, plen_100ps);
846 } else {
847 LOGF(error, "BmnRawSource::FillTDC250HGND: Wrong event type");
848 return kBMNERROR;
849 }
850
851 index += event_length;
852 }
853
854 return kBMNSUCCESS;
855}
856
857BmnStatus BmnConverterThread::MapVSP(const uint32_t* d, const DeviceHeader* dev_hdr)
858{
859 LOGF(debug, "MapVSP");
860 if (dev_hdr->GetNWords() < 3) {
861 LOGF(warning, "Empty VSP block");
862 return kBMNERROR;
863 }
864 uint8_t iComp = (dev_hdr->Serial & 0xFF000000) >> 24;
865 time_slice_map[iComp] = d;
866 return kBMNSUCCESS;
867}
868
870{
871 LOGF(debug, "FillVSP");
872 const uint8_t kuMaxComps = 10; // maximum AFCKs (comps)
873 uint16_t fvuCurrentTsMsbCycle[kuMaxComps] = {}; // FLES Timestamp cycling
874 uint64_t fvulCurrentTsMsb[kuMaxComps] = {}; // FLES Ts_Msb buffer values
875 unique_ptr<fles::StorableTimeslice> stti(new fles::StorableTimeslice(1));
876 uint8_t nComp = time_slice_map.size();
877 // if (nComp != 2)
878 // LOGF(warning, "\t ncomps = %lu", nComp);
879 // append components with a single timeslice
880 for (uint8_t iw01 = 0; iw01 < nComp; iw01++)
881 (*stti).append_component(1);
882 // append microslice #0 to each component
883 for (auto& el : time_slice_map) {
884 uint8_t iw01 = el.first;
885 auto* mslice_descr = el.second;
886 (*stti).append_microslice(iw01, 0, *((fles::MicrosliceDescriptor*)mslice_descr),
887 (uint8_t*)mslice_descr + sizeof(fles::MicrosliceDescriptor));
888 }
889 for (uint8_t uw02 = 0; uw02 < nComp; uw02++) {
890 // microslice descriptor #0 (must be only one microslice) of component (FEB) #uw02
891 const fles::MicrosliceDescriptor& msd = (*stti).descriptor(uw02, 0);
892 // get the current DPB idx
893 uint16_t fuCurrentEquipmentId = static_cast<uint16_t>(msd.eq_id);
894 uint16_t fusCurrentDpbIdx = static_cast<uint32_t>(fuCurrentEquipmentId & 0xFFFF);
895
896 // get the trigger number from microslice
897 uint64_t tgn = msd.idx;
898 if (tgn != fCurEvent.fEventId)
899 LOGF(warning, "!!! Misplaced VSP event! tgn = %lu while EventId = %u !!!\n", tgn, fCurEvent.fEventId);
900 uint32_t tgNev = static_cast<uint32_t>(tgn); // Ex24
901 // printf("fles tgN = %lu\t",tgn); printf("fles CurrDpbId = %u\n", fusCurrentDpbIdx);
902 // if ( tgn% kuUpdateTgN==0 ) {
903 // printf("ev. tgN = %u\t",tgNev);
904 // printf("fles tgN = %lu\t",tgn);
905 // printf("fles CurrDpbId = %u\n", fusCurrentDpbIdx);}
906 // do what is needed with the microslice
907
908 uint32_t size = 0; // the buffer size of the Microslice
909 uint32_t uNbMessages = 0; // the number of complete messages
910 // double dTriggerTime = 0; // TrigTime in ns
911 uint64_t uiTrgTimeFLES = 0; // TrigTime in clocks
912 uint64_t uiHitTimeFLES = 0; // Hits Time in clocks
913
914 size = msd.size;
915 static const uint32_t kuBytesPerMessage = 4;
916 // Compute the number of complete messages in the input microslice buffer
917 uNbMessages = (size - (size % kuBytesPerMessage)) / kuBytesPerMessage;
918 // Prepare variables for the loop on contents
919 // const uint32_t* pInBuff = reinterpret_cast<const uint32_t*>( (*stti).content(0,0) );
920 const uint32_t* pInBuff = reinterpret_cast<const uint32_t*>((*stti).content(uw02, 0));
921
922 // uiTrgTimeFLES = 0;
923 uint64_t uiTrgTime_TsMsb = 0;
924 uint64_t uiHitTime_TsMsb = 0;
925 uint64_t uiTrgTime_Epoch = 0;
926
927 uint16_t uiTsMsbMessageNumber = 0; // to take only the 1st TsMsb message
928 uint16_t uiEpochMessageNumber = 0; // to take only the 1st TsMsb message
929
930 uint16_t usHitMissedEvts = 0; // local counter of Hits with the Missed Events Flag
931 if (uNbMessages == 0)
932 continue;
933 BmnVspRawDigit* dig = new ((*vsp)[vsp->GetEntriesFast()]) BmnVspRawDigit(tgn, fusCurrentDpbIdx);
934
935 for (uint32_t uIdx = 0; uIdx < uNbMessages; ++uIdx) {
936 // Fill message
937 uint32_t ulData = static_cast<uint32_t>(pInBuff[uIdx]);
938
939 stsxyter::Message mess(static_cast<uint32_t>(ulData & 0xFFFFFFFF));
940 stsxyter::MessType typeMess = mess.GetMessType();
941 // if (fbTxtFileOutEna) *foutHitInfoUNI << "typeMess " << static_cast< uint16_t >( typeMess) << std::endl;
942 switch (typeMess) {
944 // The first message in the TS is a special ones: EPOCH
945 uiEpochMessageNumber++;
946 // dTriggerTime = mess.GetEpochVal() * stsxyter::kdClockCycleNs;
947 if (uiEpochMessageNumber == 1)
948 uiTrgTime_Epoch = mess.GetEpochVal(); // all 29 bits, may24
949 else
950 printf("fles WARNING: more than one EPOCH message in event tgN = %lu, exactly: %u\n", tgn,
951 uiEpochMessageNumber);
952 break;
953 }
955 uiTsMsbMessageNumber++;
956 uint64_t uVal = mess.GetTsMsbValBinning();
957 if (uVal < fvulCurrentTsMsb[uw02]) {
958 printf("TsMsbCycle: event trigger# %u", tgNev);
959 printf("\tDPB: %u, Old TsMsb= %lu, new TsMsb=%lu, Old MsbCy=%u\n", uw02, fvulCurrentTsMsb[uw02],
960 uVal, fvuCurrentTsMsbCycle[uw02]);
961
962 if ((fvulCurrentTsMsb[uw02] - uVal) > 10000000)
963 fvuCurrentTsMsbCycle[uw02]++;
964
965 } // if( uVal < fvulCurrentTsMsb[uw02] )
966 fvulCurrentTsMsb[uw02] = uVal;
967 uiHitTime_TsMsb = uVal << 10; // shift to 10 bits;
968 uiHitTime_TsMsb += static_cast<uint64_t>(stsxyter::kulTsCycleNbBinsBinning)
969 * fvuCurrentTsMsbCycle[uw02]; // TsMsbCycle added
970 if (uiTsMsbMessageNumber == 1) {
971 uiTrgTime_TsMsb =
972 uiHitTime_TsMsb & 0xFFE0000000; // remove the lower 29 bits, the faster procedure
973 }
974 break;
975 } // case stsxyter::MessType::TsMsb :
977 uint16_t usRawTs = static_cast<uint16_t>(mess.GetHitTimeBinning());
978 uiHitTimeFLES = uiHitTime_TsMsb + static_cast<uint64_t>(usRawTs);
979 uint16_t usElinkIdx = mess.GetLinkIndexHitBinning();
980 uint16_t usChan = mess.GetHitChannel();
981 uint16_t usRawAdc = mess.GetHitAdc();
982
983 if (mess.IsHitMissedEvts())
984 usHitMissedEvts++;
985 dig->AppendHit(uiHitTimeFLES, usElinkIdx, usChan, usRawAdc);
986 break;
987 }
988 default:
989 break;
990 } // switch( typeMess )
991
992 } // for( uint32_t uIdx = 0; uIdx < uNbMessages; ++uIdx )
993 dig->SetTHitMissedEvts(usHitMissedEvts);
994 uiTrgTimeFLES = uiTrgTime_TsMsb + uiTrgTime_Epoch;
995 dig->SetTTrigTime(uiTrgTimeFLES);
996 }
997 time_slice_map.clear();
998 return kBMNSUCCESS;
999}
1000
1001BmnStatus BmnConverterThread::FillMSC16VE_E(const uint32_t* d, const DeviceHeader* dev_hdr)
1002{
1003 // msc->Delete();
1004 uint32_t index = 0;
1005 const uint32_t len = dev_hdr->GetNWords();
1006 const MSC16VE_EHeader* ms = reinterpret_cast<const MSC16VE_EHeader*>(d);
1007 index += sizeof(MSC16VE_EHeader) / kNBYTESINWORD;
1008 // ms->Hdr.Print();
1009 if (ms->Hdr.Len > (len - 1)) {
1010 LOGF(error, "MSC header payload length mismatch!");
1011 return kBMNERROR;
1012 }
1013 // LOGF(info, "MSC TAI\t%s taiFlags %u ",
1014 // TTimeStamp(time_t(ms->Tai.Sec), ms->Tai.NSec).AsString(), ms->Tai.Flags);
1015 // LOGF(info, "MSC ver %u CntrBitsNum %u SliceInt %3u ns ChanNum %2u ExtCondNum %u",
1016 // ms->GetVersion(), ms->NCntrBits, ms->SliceInt, ms->ChanNumber, ms->ExtCondCnt);
1017 Bool_t hasValues = kFALSE;
1018 std::array<uint8_t, MSC_N_COUNTERS> cntrs = {};
1019 switch (ms->GetVersion()) {
1020 case 1: {
1021 const uint8_t NumsInWord = 4;
1022 while (index < len) {
1023 uint8_t type = d[index] >> 28;
1024 // printf(" index %4u len %4u type %u\n", index, len, type);
1025 if (type == MSC_TIME_SLICE_INFO) {
1026 if (hasValues) {
1027 uint32_t ext_cond = (d[index] >> 24) & (BIT(4) - 1);
1028 uint32_t sliceNum = (d[index]) & (BIT(24) - 1);
1029 auto sc_time_shift = ms->SliceInt * sliceNum * 1ns;
1030 SysPoint p{(ms->Tai.Sec - tai_utc_dif) * 1s + ms->Tai.NSec * 1ns + sc_time_shift};
1031 LOGF(debug, "MSC ext_cond %2u sliceNum %7u time %s", ext_cond, sliceNum,
1033 new ((*msc)[msc->GetEntriesFast()])
1034 BmnMSCDigit<uint8_t>(dev_hdr->Serial, 0, cntrs, fCurEvent.fEventId, p, ext_cond);
1035 hasValues = kFALSE;
1036 memset(cntrs.data(), 0, sizeof(UChar_t) * MSC_N_COUNTERS);
1037 }
1038 } else {
1039 for (uint8_t i = 0; i < NumsInWord; i++) {
1040 uint32_t cnt = (d[index] >> (i * ms->NCntrBits)) & (BIT(ms->NCntrBits) - 1);
1041 cntrs[type * NumsInWord + i] = cnt;
1042 // LOGF(info,"\tcnt[%2u] = %2u", (type * NumsInWord + i), cnt);
1043 hasValues = kTRUE;
1044 }
1045 }
1046 index++;
1047 }
1048 } break;
1049 case 2: {
1050 if (ms->Hdr.Len <= 1 + (sizeof(MSC16VE_EHeader) - sizeof(MStreamHeader)) / kNBYTESINWORD)
1051 break; // empty record
1052 uint32_t n_slices = ms->Hdr.Len - 1 - (sizeof(MSC16VE_EHeader) - sizeof(MStreamHeader)) / kNBYTESINWORD;
1053 uint32_t missing_hits = d[index++];
1054 if (missing_hits)
1055 LOGF(info, "missing_hits %3u !!!", missing_hits);
1056 SysPoint point{(ms->Tai.Sec - tai_utc_dif) * 1s + ms->Tai.NSec * 1ns};
1057 BmnMSCZSDigit<uint8_t>* dig = new ((*msc)[msc->GetEntriesFast()])
1058 BmnMSCZSDigit<uint8_t>(dev_hdr->Serial, ms->ChanNumber, point, n_slices, missing_hits);
1059 vector<uint8_t>& vals = dig->GetValues();
1060 auto& times = dig->GetTimes();
1061 vector<uint8_t>& conds = dig->GetExtCond();
1062 int32_t istart = index;
1063 while (index < len) {
1064 uint8_t cnt = d[index] & (BIT(ms->NCntrBits) - 1);
1065 uint8_t ext_cond = (d[index] >> ms->NCntrBits) & (BIT(ms->ExtCondCnt) - 1);
1066 uint32_t sliceNum = d[index] >> (ms->NCntrBits + ms->ExtCondCnt);
1067 auto sc_time_shift = ms->SliceInt * sliceNum * 1ns;
1068 SysPoint point_slice{point + sc_time_shift};
1069 int32_t iVal = index - istart;
1070 // LOGF(info, "iVal %4u", iVal);
1071 vals[iVal] = cnt;
1072 // times[iVal] = point_slice;
1073 times[iVal] = BmnFunctionSet::TimePoint2TS(point_slice);
1074 conds[iVal] = ext_cond;
1075 LOGF(debug, "MSC ext_cond %2u cnt %2u sliceNum %7u time %s", ext_cond, cnt, sliceNum,
1076 BmnFunctionSet::TimePoint2String(point_slice).c_str());
1077 index++;
1078 }
1079 } break;
1080 default:
1081 LOGF(warning, "MSC16 ver $u not implemented", ms->GetVersion());
1082 return kBMNERROR;
1083 break;
1084 }
1085 return kBMNSUCCESS;
1086}
1087
1088BmnStatus BmnConverterThread::FillVirtualDevice(const uint32_t* d, const DeviceHeader* dh)
1089{
1090 LOGF(info, "Found virtual device 0x%08X block", dh->Serial);
1091 if (dh->Serial != SERIAL_TO_CFG) {
1092 LOGF(info, "Not T0 device");
1093 return kBMNSUCCESS;
1094 }
1096 std::ofstream outfile(Form("virt_device_run_%u_%08X_%02X_t_%ld_%ld.txt", fCurEvent.fRunId, dh->Serial,
1097 dh->DeviceId, // fSubName.Data(),
1098 fCurEvent.fTime_s, fCurEvent.fTime_ns),
1099 ios::out | ios::binary);
1100 for (uint32_t i = 0; i < kT0_BIN_BLOCK_WORDS; i++)
1101 outfile << std::hex << d[i];
1102 outfile.write(reinterpret_cast<const char*>(d) + kT0_BIN_BLOCK_BYTES, dh->Len - kT0_BIN_BLOCK_BYTES);
1103 }
1104 BmnT0Raw* lastT0 = BmnConverterTools::Process_T0Raw(d, dh->Len, t0raw);
1105 auto tsle =
1106 lastT0->GetTime() - BmnFunctionSet::TimeStamp2TP(TTimeStamp(time_t(fCurEvent.fTime_s), fCurEvent.fTime_ns));
1107 // Get time since last event
1108 // (surely it will be incorrect for several ns, but at average precise enough to assign it to the spill)
1109 lastT0->SetTimeSinceLastEvNs(duration_cast<nanoseconds>(tsle).count());
1110 return kBMNSUCCESS;
1111}
1112
1113BmnStatus BmnConverterThread::FillUT24VE_TRC(const uint32_t* d, uint32_t& serial, uint32_t& len)
1114{
1115 uint32_t index = 0;
1116 const MStreamHeader* ms = reinterpret_cast<const MStreamHeader*>(d);
1117 index += sizeof(MStreamHeader) / kNBYTESINWORD;
1118 // ms->Print();
1119 // start bit input time in the MStreamTAI, and should be the 4th word timeslice
1120 auto* ms0 = reinterpret_cast<const MStreamTAI*>(d + index);
1121 if (ms0->valid()) {
1122 BmnSyncDigit* sd = FillWR(serial, fCurEvent.fEventId, ms0->Sec, ms0->NSec);
1123 fCurEvent.fTime_ns = sd->GetTime_ns();
1124 fCurEvent.fTime_s = sd->GetTime_sec();
1125 }
1126 index += sizeof(MStreamTAI) / kNBYTESINWORD;
1127 if (ms->Len / kNBYTESINWORD > len)
1128 LOGF(error, "UT24VE-TRC Error! MSHeader payload length larger than from device header!");
1129 fCurEvent.fEvType = (d[index] & BIT(16)) ? kBMNPEDESTAL : kBMNPAYLOAD;
1130 // bool randomTrigger = d[index] & BIT(17);
1131 // bool periodicTrigger = d[index] & BIT(18);
1132 // bool externalTTL = d[index] & BIT(19);
1133 LOGF(debug, "FillUT24VE_TRC etype %u WR %08X ts: %s", (uint32_t)fCurEvent.fEvType, serial,
1134 TTimeStamp(time_t(fCurEvent.fTime_s), fCurEvent.fTime_ns).AsString());
1135 eventHeaderDAQ->SetInputSignalsAR(d[index++]);
1136 eventHeaderDAQ->SetInputSignalsBR(d[index]);
1137 vector<uint32_t>& vec = eventHeaderDAQ->GetInputSignalsVector();
1138 while (++index < len) {
1139 uint32_t sig_states = d[index];
1140 vec.push_back(sig_states);
1141 bitset<32> sig_states_bs(sig_states);
1142 LOGF(debug2, "TRC states d[%3u] %s", index, sig_states_bs.to_string());
1143 }
1144 return kBMNSUCCESS;
1145}
1146
1147BmnSyncDigit* BmnConverterThread::FillWR(uint32_t serial, uint64_t iEvent, int64_t t_sec, int64_t t_ns)
1148{
1149 // LOGF(debug4, "Fill WR %08X", serial);
1150 // LOGF(info, "Fill WR %08X RS ts %s", serial, TTimeStamp(time_t(t_sec), t_ns).AsString());
1151 if (tai_utc_dif == 0) {
1152 tai_utc_dif = GetUTCShift(TTimeStamp(time_t(t_sec), t_ns));
1153 if (tai_utc_dif == 0)
1154 LOGF(warn, "Possibly wrong state of %08X", serial);
1155 }
1156 return new ((*sync)[sync->GetEntriesFast()]) BmnSyncDigit(serial, iEvent, t_sec - tai_utc_dif, t_ns);
1157}
1158
1159BmnStatus BmnConverterThread::FillFVME2TMWR(const uint32_t* d, uint32_t serial, uint32_t& idx, uint32_t& len)
1160{
1161 while (idx < len) {
1162 uint32_t word = d[idx];
1163 uint32_t id = word >> 28;
1164 switch (id) {
1165 case TMWR_TAI: {
1166 uint32_t d0 = d[idx + 0];
1167 uint32_t d1 = d[idx + 1];
1168 uint32_t d2 = d[idx + 2];
1169 uint32_t d3 = d[idx + 3];
1170 if ((d0 >> 28) != 2 || (d1 >> 28) != 2 || (d2 >> 28) != 2 || (d3 >> 28) != 2)
1171 return kBMNERROR; // check TAI code
1172 int64_t ts_t0_s = -1;
1173 int64_t ts_t0_ns = -1;
1174 int64_t GlobalEvent = -1;
1175 ts_t0_ns = (d0 & 0x0FFFFFFF) | ((d1 & 0x3) << 28);
1176 ts_t0_s = ((d1 >> 4) & 0xFFFFFF) | ((d2 & 0xFFFF) << 24);
1177 GlobalEvent = ((d3 & 0x0FFFFFFF) << 12) | ((d2 >> 16) & 0xFFF);
1178 BmnSyncDigit* sd = FillWR(serial, GlobalEvent, ts_t0_s, ts_t0_ns);
1179 if (fPeriodId < 8) {
1180 fCurEvent.fTime_ns = sd->GetTime_ns();
1181 fCurEvent.fTime_s = sd->GetTime_sec();
1182 }
1183 idx += 4;
1184 LOGF(debug2, "ts :\t %10lli %9lli TMWR 0x%08X", ts_t0_s, ts_t0_ns, serial);
1185 } break;
1186 case TMWR_REL_TS: {
1187 uint32_t d0 = d[idx + 0];
1188 uint32_t d1 = d[idx + 1];
1189 if (((d0 >> 28) != 4) || ((d1 >> 28) != 5))
1190 return kBMNERROR;
1191 // Int_t rts(((d0 & (BIT(24) - 1)) << 8) | ((d1 >> 20) & (BIT(8) - 1)));
1192 // uint32_t ext_word((d1 >> 16) & (BIT(4) - 1));
1193 // uint32_t trg_word(d1 & (BIT(16) - 1));
1194 idx += 2;
1195 // printf("rts %7d ext_tr word %u tr word %u\n" , rts, ext_word, trg_word);
1196 } break;
1198 case TMWR_EOS_CNT: {
1199 // uint32_t d0 = d[idx + 0];
1200 // uint32_t logic_cnt(d0 & (BIT(28) - 1));
1201 // printf("logic_cnt %7u %s\n" , logic_cnt, id == TMWR_EOS_CNT_MATCHED ? "matched" :
1202 // "");
1203 idx++;
1204 } break;
1205 case TMWR_PULSE:
1206 case TMWR_REL_TS_TB:
1207 idx++; // just skip
1208 break;
1209 case kMODTRAILER:
1210 case kSTATUS:
1211 case kPADDING:
1212 idx--;
1213 return kBMNSUCCESS;
1214 default:
1215 printf("unrecognized TMWR id %u\n", id);
1216 idx++;
1217 break;
1218 }
1219 }
1220 return kBMNSUCCESS;
1221}
1222
1223BmnStatus BmnConverterThread::FillMSC(const uint32_t* d, uint32_t serial, uint32_t slot, uint32_t& idx)
1224{
1225 uint32_t type = d[idx] >> 28;
1226 uint32_t iCnt = 0;
1228 new ((*msc)[msc->GetEntriesFast()]) BmnMSCDigit<uint32_t>(serial, slot, fCurEvent.fEventId);
1229 std::array<uint32_t, MSC_N_COUNTERS>& cntrArrCur = dig->GetValue();
1230 // printf("MSC type %u serial %08X last eventID = %6u\n", type, serial, fEventId);
1231 while (type < 6) {
1232 if (type < 5) {
1233 // uint32_t cnt3 = (d[idx] >> 21) & (BIT(8) - 1);
1234 // uint32_t cnt2 = (d[idx] >> 14) & (BIT(8) - 1);
1235 // uint32_t cnt1 = (d[idx] >> 7) & (BIT(8) - 1);
1236 // uint32_t cnt0 = d[idx] & (BIT(8) - 1);
1237 // printf("type = %u %06u %06u %06u %06u \n", type, cnt3, cnt2, cnt1, cnt0);
1238 } else if (type == 5) {
1239 uint32_t cnt = d[idx] & (BIT(28) - 1);
1240 if (iCnt >= MSC_N_COUNTERS)
1241 continue;
1242 cntrArrCur[iCnt++] = cnt;
1243 // printf("\ttype = %u arr[%2u] = %8u\n", type, iCnt - 1, cntrArrCur[iCnt - 1]);
1244 }
1245 type = (d[++idx] >> 28) & (BIT(5) - 1);
1246 }
1247
1248 return kBMNSUCCESS;
1249};
1250
1252{
1253 leaps.insert(pair<TTimeStamp, Int_t>(TTimeStamp(1972, 1, 1, 0, 0, 9), 10));
1254 leaps.insert(pair<TTimeStamp, Int_t>(TTimeStamp(1972, 7, 1, 0, 0, 10), 11));
1255 leaps.insert(pair<TTimeStamp, Int_t>(TTimeStamp(1973, 1, 1, 0, 0, 11), 12));
1256 leaps.insert(pair<TTimeStamp, Int_t>(TTimeStamp(1974, 1, 1, 0, 0, 12), 13));
1257 leaps.insert(pair<TTimeStamp, Int_t>(TTimeStamp(1975, 1, 1, 0, 0, 13), 14));
1258 leaps.insert(pair<TTimeStamp, Int_t>(TTimeStamp(1976, 1, 1, 0, 0, 14), 15));
1259 leaps.insert(pair<TTimeStamp, Int_t>(TTimeStamp(1977, 1, 1, 0, 0, 15), 16));
1260 leaps.insert(pair<TTimeStamp, Int_t>(TTimeStamp(1978, 1, 1, 0, 0, 16), 17));
1261 leaps.insert(pair<TTimeStamp, Int_t>(TTimeStamp(1979, 1, 1, 0, 0, 17), 18));
1262 leaps.insert(pair<TTimeStamp, Int_t>(TTimeStamp(1980, 1, 1, 0, 0, 18), 19));
1263 leaps.insert(pair<TTimeStamp, Int_t>(TTimeStamp(1981, 7, 1, 0, 0, 19), 20));
1264 leaps.insert(pair<TTimeStamp, Int_t>(TTimeStamp(1982, 7, 1, 0, 0, 20), 21));
1265 leaps.insert(pair<TTimeStamp, Int_t>(TTimeStamp(1983, 7, 1, 0, 0, 21), 22));
1266 leaps.insert(pair<TTimeStamp, Int_t>(TTimeStamp(1985, 7, 1, 0, 0, 22), 23));
1267 leaps.insert(pair<TTimeStamp, Int_t>(TTimeStamp(1988, 1, 1, 0, 0, 23), 24));
1268 leaps.insert(pair<TTimeStamp, Int_t>(TTimeStamp(1990, 1, 1, 0, 0, 24), 25));
1269 leaps.insert(pair<TTimeStamp, Int_t>(TTimeStamp(1991, 1, 1, 0, 0, 25), 26));
1270 leaps.insert(pair<TTimeStamp, Int_t>(TTimeStamp(1992, 7, 1, 0, 0, 26), 27));
1271 leaps.insert(pair<TTimeStamp, Int_t>(TTimeStamp(1993, 7, 1, 0, 0, 27), 28));
1272 leaps.insert(pair<TTimeStamp, Int_t>(TTimeStamp(1994, 7, 1, 0, 0, 28), 29));
1273 leaps.insert(pair<TTimeStamp, Int_t>(TTimeStamp(1996, 1, 1, 0, 0, 29), 30));
1274 leaps.insert(pair<TTimeStamp, Int_t>(TTimeStamp(1997, 7, 1, 0, 0, 30), 31));
1275 leaps.insert(pair<TTimeStamp, Int_t>(TTimeStamp(1999, 1, 1, 0, 0, 31), 32));
1276 leaps.insert(pair<TTimeStamp, Int_t>(TTimeStamp(2006, 1, 1, 0, 0, 32), 33));
1277 leaps.insert(pair<TTimeStamp, Int_t>(TTimeStamp(2009, 1, 1, 0, 0, 33), 34));
1278 leaps.insert(pair<TTimeStamp, Int_t>(TTimeStamp(2012, 7, 1, 0, 0, 34), 35));
1279 leaps.insert(pair<TTimeStamp, Int_t>(TTimeStamp(2015, 7, 1, 0, 0, 35), 36));
1280 leaps.insert(pair<TTimeStamp, Int_t>(TTimeStamp(2017, 1, 1, 0, 0, 36), 37));
1281 utc_valid = TTimeStamp(2026, 12, 30, 0, 0, 1);
1282 return kBMNSUCCESS;
1283}
1284
1286{
1287 if (t < leaps.begin()->first) {
1288 LOGF(warning, "Wrong time! %s", t.AsString());
1289 return 0;
1290 }
1291 if (t > utc_valid)
1292 LOGF(warning, "Warning! Leap seconds table expired!");
1293 Int_t shift = 0;
1294 auto it = leaps.lower_bound(t);
1295 if ((it == leaps.end()))
1296 it--;
1297 else if (it->first > t)
1298 it--;
1299 shift = it->second;
1300 return shift;
1301}
1302
1304{
1305 sync->Delete();
1306 tdc->Delete();
1307 tqdc_adc->Delete();
1308 tqdc_tdc->Delete();
1309 tdc_hgnd->Delete();
1310 hrb->Delete();
1311 adc32->Delete();
1312 adc64->Delete();
1313 adc128->Delete();
1314 adc->Delete();
1315 vsp->Delete();
1316}
1317
1319{
1320 msc->Delete();
1321 t0raw->Delete();
1322}
void memset(T *dest, T i, size_t num)
Copy to memory block [@dest, @dest+@num] num number of times the value of i of type @T with size @typ...
Definition L1Grid.h:27
int i
Definition P4_F32vec4.h:22
bool Bool_t
unsigned short UShort_t
int Int_t
unsigned char UChar_t
short Short_t
constexpr Bool_t kFALSE
constexpr Bool_t kTRUE
#define BIT(n)
char * Form(const char *fmt,...)
BmnStatus
Define status code.
Definition BmnEnums.h:93
@ kBMNERROR
Error.
Definition BmnEnums.h:95
@ kBMNSUCCESS
Success.
Definition BmnEnums.h:94
@ kBMNSTAT
Statistics.
Definition BmnEnums.h:147
@ kBMNEOS
End of spill.
Definition BmnEnums.h:146
@ kBMNPAYLOAD
spill event.
Definition BmnEnums.h:145
@ kBMNPEDESTAL
pedestal event.
Definition BmnEnums.h:144
std::chrono::time_point< SysClock > SysPoint
#define ANSI_COLOR_RED
Definition BmnMath.h:16
#define ANSI_COLOR_RESET
Definition BmnMath.h:18
const uint32_t kTRIG
Definition RawTypes.h:54
const uint32_t kMSTREAM_TYPE_TRIG
Definition RawTypes.h:41
const uint32_t kADC64VE_XGE
Definition RawTypes.h:62
const uint32_t kTDC72VXS
Definition RawTypes.h:65
const uint32_t kFVME
Definition RawTypes.h:66
const uint32_t kTTVXS
Definition RawTypes.h:55
const uint32_t TDC_ERROR
Definition RawTypes.h:86
const uint32_t kU40VE_RC
Definition RawTypes.h:72
const uint32_t kEVENTTYPESLOT
Definition RawTypes.h:75
const uint32_t kVSP_SERIALS
Definition RawTypes.h:68
const uint32_t kMODTRAILER
Definition RawTypes.h:24
const uint32_t kTDC72VHL
Definition RawTypes.h:48
const uint32_t kTQDC16
Definition RawTypes.h:50
const uint32_t TDC_TRAILING
Definition RawTypes.h:85
const uint32_t kSTATUS
Definition RawTypes.h:29
const uint32_t kMSTREAM_TYPE_TDC
Definition RawTypes.h:39
const uint32_t TMWR_REL_TS
Definition RawTypes.h:32
const uint32_t kVIRTUAL_DEVICE
Definition RawTypes.h:52
const uint32_t kTQDC16VS_E
Definition RawTypes.h:53
const uint32_t kADC64WR
Definition RawTypes.h:63
const uint32_t kEVTRAILER
Definition RawTypes.h:26
const uint32_t TMWR_REL_TS_TB
Definition RawTypes.h:33
const uint32_t TMWR_EOS_CNT
Definition RawTypes.h:35
const uint32_t kUT24VE_TRC
Definition RawTypes.h:58
const uint32_t kMSTREAM_TYPE_STAT
Definition RawTypes.h:42
const uint32_t kTDC64VHLE
Definition RawTypes.h:46
const uint32_t TMWR_TAI
Definition RawTypes.h:31
const uint32_t TDC_EV_HEADER
Definition RawTypes.h:82
const uint32_t TDC_EV_TRAILER
Definition RawTypes.h:83
const uint32_t TDC_LEADING
Definition RawTypes.h:84
const uint32_t MSC_N_COUNTERS
Definition RawTypes.h:88
const uint32_t kMSTREAM_TYPE_ADC
Definition RawTypes.h:40
const uint32_t kNBYTESINWORD
Definition RawTypes.h:19
const uint32_t kGENERIC_DEVICE
Definition RawTypes.h:67
const uint32_t kHGND_SERIALS
Definition RawTypes.h:69
const uint32_t kTDC32VL
Definition RawTypes.h:49
const uint32_t kT0_BIN_BLOCK_BYTES
Definition RawTypes.h:94
const uint32_t kWORDTAI
Definition RawTypes.h:76
const uint32_t kADC64VE
Definition RawTypes.h:61
const uint32_t SERIAL_TO_CFG
Definition RawTypes.h:71
const uint32_t kWORDTRIG
Definition RawTypes.h:77
const uint32_t kEVHEADER
Definition RawTypes.h:25
const uint32_t kHRB
Definition RawTypes.h:64
const uint32_t TMWR_PULSE
Definition RawTypes.h:34
const uint32_t kTDC64VHLE_E
Definition RawTypes.h:47
const uint32_t kMSC16V
Definition RawTypes.h:56
const uint32_t kT0_BIN_BLOCK_WORDS
Definition RawTypes.h:93
const uint32_t kTQDC16VS
Definition RawTypes.h:51
const uint8_t MSC_TIME_SLICE_INFO
Definition RawTypes.h:91
const uint32_t kMSC16VE_E
Definition RawTypes.h:57
const uint32_t kWORDAUX
Definition RawTypes.h:78
const uint32_t kTDC64V
Definition RawTypes.h:45
const uint32_t kPADDING
Definition RawTypes.h:30
const uint32_t kMODHEADER
Definition RawTypes.h:23
const uint32_t TMWR_EOS_CNT_MATCHED
Definition RawTypes.h:36
BmnStatus FillTTVXS(const uint32_t *d, uint32_t serial, uint32_t &len)
https://afi.jinr.ru/TTVXS_DataFormat
Int_t GetUTCShift(TTimeStamp t)
uint32_t rawData[10000000]
vector< pair< int, pair< int, int > > > * vecTree
BmnStatus ConvertStatEvent(const uint32_t *d, uint32_t &len)
void WriteSpill(Int_t spillId)
BmnSyncDigit * FillWR(uint32_t iSerial, uint64_t iEvent, int64_t t_sec, int64_t t_ns)
BmnStatus FillTQDC_E(const uint32_t *d, uint32_t serial, uint32_t &len)
Parse TQDC16VS-E MStream data block https://afi.jinr.ru/DataFormatTQDC16VSE.
BmnStatus MapVSP(const uint32_t *d, const DeviceHeader *dev_hdr)
Parse VSP data block.
TClonesArray * tqdc_tdc
BmnStatus FillVSP(TClonesArray *ar)
void SetTrees(TTree *tree, TTree *treeSpills)
BmnStatus FillTDC72VXS(const uint32_t *d, uint32_t serial, uint32_t &len, uint32_t modid)
https://afi.jinr.ru/TDC72VXS_DataFormat
BmnStatus Process_HRB(const uint32_t *data, uint32_t len, uint32_t serial)
BmnStatus FillBlockTDC(const uint32_t *d, uint32_t serial, uint16_t &len, TClonesArray *ar, uint32_t modid)
BmnStatus FillTQDC(const uint32_t *d, uint32_t serial, uint32_t slot, uint32_t modId, uint32_t &idx)
BmnStatus FillFVME2TMWR(const uint32_t *d, uint32_t serial, uint32_t &idx, uint32_t &len)
std::shared_ptr< TBufferMergerFile > mergerFile
BmnStatus FillMSC16VE_E(const uint32_t *d, const DeviceHeader *dev_hdr)
Parse MSC16VE-E MStream data block https://afi.jinr.ru/DataFormatMSC_ETH.
TBufferMerger * merger
BmnStatus FillTDC250HGND(const uint32_t *d, uint32_t serial, uint32_t len)
Parse custom HGND TDC data block.
map< TTimeStamp, Int_t > leaps
BmnStatus ProcessEvent(const uint32_t *data, uint32_t len)
TClonesArray * tqdc_adc
void SetData(Int_t taskId, Int_t len=0, const uint32_t *data=nullptr, BmnEventType fCurEvType=kBMNEMPTY, uint32_t fRunId=7444, uint32_t fEventId=-1)
BmnStatus FillUT24VE_TRC(const uint32_t *d, uint32_t &serial, uint32_t &len)
Parse UT24VE-TRC MStream data block https://afi.jinr.ru/DataFormatUT24VE-TRC.
BmnEventHeader * eventHeaderDAQ
BmnStatus FillMSC(const uint32_t *d, uint32_t serial, uint32_t slot, uint32_t &idx)
BmnStatus Process_FVME(const uint32_t *data, uint32_t len, uint32_t serial, BmnTrigInfo &spillInfo)
BmnStatus FillU40VE(const uint32_t *d, uint32_t slot, uint32_t &idx, BmnTrigInfo &spillInfo)
BmnStatus ProcessGenericDevice(const uint32_t *d, const DeviceHeader *dev_hdr)
BmnStatus FillTDC(const uint32_t *d, uint32_t serial, uint32_t slot, uint32_t modId, uint32_t &idx)
TClonesArray * tdc_hgnd
BmnStatus FillVirtualDevice(const uint32_t *d, const DeviceHeader *dh)
BmnStatus FillBlockADC(const uint32_t *d, uint32_t serial, uint8_t channel, uint16_t &len, TClonesArray *ar)
vector< pair< int, pair< int, int > > > * vecTreeSpills
std::map< uint8_t, const uint32_t * > time_slice_map
static BmnStatus Process_ADC64(const uint32_t *d, UInt_t len, UInt_t serial, LamType arr_selector)
Parse ADC64 format Mstream Waveform V2 from https://afi.jinr.ru/MStreamWaveformDigitizer.
static BmnT0Raw * Process_T0Raw(const uint32_t *d, uint32_t len, TClonesArray *t0raw=nullptr)
static std::string TimePoint2String(SysPoint p)
static SysPoint TimeStamp2TP(TTimeStamp p)
static TTimeStamp TimePoint2TS(SysPoint p)
std::array< IntType, MSC_N_COUNTERS > & GetValue()
Definition BmnMSCDigit.h:65
Raw MSC block with zero suppression and for one specific channel.
std::vector< IntType > & GetValues()
std::vector< TTimeStamp > & GetTimes()
std::vector< uint8_t > & GetExtCond()
Long64_t GetTime_sec() const
Long64_t GetTime_ns() const
T0 module spill settings and counts.
Definition BmnT0Raw.h:70
SysPoint GetTime()
Definition BmnT0Raw.h:92
void SetTimeSinceLastEvNs(Double_t dur)
Write time since the last written event.
Definition BmnT0Raw.h:105
Class BmnTrigInfo Trigger counters of the current spill from U40VE card.
Definition BmnTrigInfo.h:15
void SetTrigBefo(UInt_t _v)
Definition BmnTrigInfo.h:32
void SetTrigAccepted(UInt_t _v)
Definition BmnTrigInfo.h:28
void SetTrigAfter(UInt_t _v)
Definition BmnTrigInfo.h:36
void SetTrigAll(UInt_t _v)
Definition BmnTrigInfo.h:44
void SetTrigRjct(UInt_t _v)
Definition BmnTrigInfo.h:40
void SetTrigCand(UInt_t _v)
Definition BmnTrigInfo.h:24
void SetTrigAvail(UInt_t _v)
Definition BmnTrigInfo.h:48
void AppendHit(uint64_t HitTime, uint16_t ElinkIdx, uint16_t Chan, uint16_t Adc)
void SetTHitMissedEvts(uint16_t val)
void SetTTrigTime(uint64_t val)
Int_t GetEntriesFast() const
static TClass * Class()
Double_t AsDouble() const
const char * AsString(const Option_t *option="") const
virtual Int_t Fill()
virtual Int_t Branch(const char *folder, Int_t bufsize=32000, Int_t splitlevel=99)
The StorableTimeslice class contains the data of a single timeslice.
uint32_t GetTsMsbValBinning() const
For TS MSB data: Returns the TS MSB 29 bit field).
uint16_t GetHitAdc() const
For Hit data: Returns ADC value (5 bit field).
uint16_t GetLinkIndexHitBinning() const
For Hit data: Returns (global) index of the eLink on which the message was received (6 bit field) => ...
uint16_t GetHitTimeBinning() const
For Hit data: Returns timestamp (9 bit field + 1b extra on b30) => Quick and dirty hack for binning F...
uint32_t GetEpochVal() const
For Epoch data: Returns the Epoch (29 bit field).
uint16_t GetHitChannel() const
For Hit data: Returns StsXYTER channel number (7 bit field).
MessType GetMessType() const
Returns the message type, see enum MessType.
bool IsHitMissedEvts() const
For Hit data: Returns Missed event flag (1 bit field).
bool is_word_event_header(uint16_t word)
Definition BmnHgndRaw.h:18
uint16_t get_block_size(EventPacketVersion packet_version=ERR)
Definition BmnHgndRaw.h:45
EventPacketVersion get_event_packet_version(uint16_t word)
Definition BmnHgndRaw.h:31
static constexpr uint64_t kulTsCycleNbBinsBinning
MessType
Message types.
Microslice descriptor struct.
uint64_t idx
Microslice index / start time.
uint32_t size
Content size (bytes).
uint16_t eq_id
Equipment identifier.