BmnRoot 26.10.0-18-g4e3414f9
Software framework of the BM@N experiment
Loading...
Searching...
No Matches
BmnRawSource.cxx
Go to the documentation of this file.
1#include "BmnRawSource.h"
2// System
3#include <arpa/inet.h> /* For ntohl for Big Endian LAND. */
4// C++
5#include <chrono>
6#include <filesystem>
7#include <iostream>
8// ROOT
9#include <TStopwatch.h>
10#include <TSystem.h>
11// FairRoot
12#include "FairLogger.h"
13// BmnRoot
14#include "BmnADCDigit.h"
15#include "BmnAbstractTDCDigit.h"
16#include "BmnCompressionGlobalFunctions.h"
17#include "BmnConverterTools.h"
18#include "BmnFileProp.h"
19#include "BmnGemStripDigit.h"
20#include "BmnHRBDigit.h"
21#include "BmnHgndRaw.h"
22#include "BmnIFileReader.h"
23#include "BmnMSCDigit.h"
24#include "BmnMSCZSDigit.h"
25#include "BmnSyncDigit.h"
26#include "BmnTDCDigit.h"
27#include "BmnTQDCADCDigit.h"
28#include "BmnVspRawDigit.h"
29#include "TangoData.h"
30#include "UniDetectorParameter.h"
31#include "UniRawFile.h"
32#include "UniRun.h"
33// CBM
34#include "StorableTimeslice.h"
35#include "StsXyterMessage.h"
36
37// Double_t realtime = 0.0;
38// Double_t converterTime = 0.0;
39namespace fs = std::filesystem;
40using namespace std::chrono;
41
42BmnRawSource::BmnRawSource(TString file, TString outfile, uint32_t nEvents, uint32_t period, bool save)
43 : isSpillStart(false)
44 , isTaskMode(false)
45 , isForwardMode(false)
46 , fSpillCntr(0)
47 , isRawRootInputFile(false)
48 , fPeriodId(period)
49 , fEventId(0)
50 , fNTotalEvents(0)
52 , fStartEventId(0)
53 , fTime_s(0)
54 , fTime_ns(0)
57 , fRawTree(nullptr)
58 , fRawTreeSpills(nullptr)
59 , fRootFileName(outfile)
60 , fRawFileName(file)
61 , fRawRunHdrName("RawRunHeader")
62 , fMetadataName("RawRunMetadata")
63 , fRootFileOut(nullptr)
64 , fFileReader(nullptr)
65 , sync(nullptr)
66 , adc32(nullptr)
67 , adc64(nullptr)
68 , adc128(nullptr)
69 , adc(nullptr)
70 , vsp(nullptr)
71 , hrb(nullptr)
72 , tdc(nullptr)
73 , tqdc_tdc(nullptr)
74 , tqdc_adc(nullptr)
75 , tdc_hgnd(nullptr)
76 , msc(nullptr)
77 , eventHeaderDAQ(nullptr)
78 , spillHeader(nullptr)
79 , runHeader(make_unique<DigiRunHeader>(fPeriodId))
80 , metadata(make_unique<BmnMetadataRaw>())
81 , fMaxEvent(nEvents)
82 , fDat(0)
83 , syncCounter(0)
84 , nSpillEvents(0)
85 , fExportJsonBlocks(false)
87 , tai_utc_dif(0)
88 , fVerbose(0)
89 , fSaveOutput(save)
90{
91 LOGF(debug1, "BmnRawSource: input %s, output %s", fRawFileName.Data(), fRootFileName.Data());
92
93 if (fRawFileName != "") {
94 BmnFileProp prop;
96 LOG(debug) << "RunId " << prop.GetRunId() << " got from props";
97 fRunId = (prop.GetRunId() > 0) ? prop.GetRunId() : GetRunIdFromFile(fRawFileName);
99 LOG(debug) << "subname " << subName;
100 LOG(info) << "RunId " << fRunId << " got from " << (isRawRootInputFile ? "RawRoot" : "RawData") << " file";
101 if (fRootFileName.Length()) {
102
103 } else {
104 fRootFileName = Form("bmn_run%d%s_raw.root", fRunId, subName.Data());
105 }
106 fSubName = subName;
107 }
108 InitUTCShift();
109}
110
112{
113 // @todo very possible memory leak here - there were many pointers in declarations
114 // Check it later. Other classes might actually own the memory... possibly add shared_ptr
115}
116
118{
119 printf(ANSI_COLOR_RED "\n================ CONVERTING ================\n" ANSI_COLOR_RESET);
120 isTaskMode = true;
121 LoadConfig();
122 // @todo remove fRawFileName later - I don't think we need it here
123 // @todo Checking or calling close first?
125 if (!fFileReader)
126 return kBMNERROR;
127 fFileReader->Open();
128 if (!fFileReader->IsOpen()) {
129 printf("\n!!!!!\ncannot open file %s\nConvertRawToRoot stopped\n!!!!!\n\n", fRawFileName.Data());
130 return false;
131 }
132 fs::path raw_file_path(fRawFileName.Data());
133 fLengthRawFile = fs::file_size(raw_file_path);
134 printf("\nRAW FILE: ");
135 printf(ANSI_COLOR_BLUE "%s" ANSI_COLOR_RESET, fRawFileName.Data());
136 printf("\nRAW FILE LENGTH: ");
137 printf(ANSI_COLOR_BLUE "%.3f MB\n" ANSI_COLOR_RESET, fLengthRawFile / 1024. / 1024.);
138 std::string fileType{};
139 fileType += fFileReader->GetFileType();
140 printf("\nRAW FILE TYPE: " ANSI_COLOR_BLUE "%s" ANSI_COLOR_RESET, fileType.data());
142 // FairRootManager* frm = FairRootManager::Instance();
143 /*auto reg_fun = [&] (TString name, TObject ** ar) -> void
144 {
145 TClass *cl = TClass::GetClass((*ar)->ClassName());
146 if (cl == TClonesArray::Class())
147 frm->Register(name, name + "_dir", static_cast<TClonesArray*> ((*ar)), fSaveOutput);
148 else
149 frm->Register(name, name + "_dir", static_cast<TNamed*> ((*ar)), fSaveOutput);
150 LOG(debug1) << "Register by class " << cl->GetName() << " : " << name;
151 return;
152 };*/
153 RegisterBranches(); // reg_fun);
154 bool convertMSC = conf.get<bool>("Decoder.ProcessMSC", false);
155 if (convertMSC) {
156 fRawTreeSpills = new TTree("BMN_RAW_SPILLS", "BMN_RAW_SPILLS");
157 // fRawTreeSpillsT0 = new TTree("BMN_RAW_SPILLS_T0", "BMN_RAW_SPILLS_T0");
158 // auto spill_reg_fun = [&](TTree* tree, TString name, TObject* ar) -> void {
159 // TBranch* b = tree->Branch(name, &ar);
160 // LOGF(info, "Register branch %p : %s", (void*)b, name.Data());
161 // return;
162 // };
164 }
165 return true;
166}
167
169{
170 printf(ANSI_COLOR_RED "\n================ CONVERTING ================\n" ANSI_COLOR_RESET);
171 // @todo It's very strange to keep this and `Init` separate. Instead, allow this with move semantics and call `Init`
172 fRawFileName = std::move(FileName);
174 if (!fFileReader)
175 return kBMNERROR;
176 fFileReader->Open();
177 if (!fFileReader->IsOpen()) {
178 LOGF(error, "\n!!!!!\ncannot open file %s\nConvertRawToRoot are stopped\n!!!!!\n", fRawFileName.Data());
179 return kBMNERROR;
180 }
181 fs::path raw_file_path(fRawFileName.Data());
182 fLengthRawFile = fs::file_size(raw_file_path);
183 printf("\nRAW FILE: ");
184 printf(ANSI_COLOR_BLUE "%s" ANSI_COLOR_RESET, fRawFileName.Data());
185 printf("\nRAW FILE LENGTH: ");
186 printf(ANSI_COLOR_BLUE "%.3f MB\n" ANSI_COLOR_RESET, fLengthRawFile / 1024. / 1024.);
187 std::string fileType{};
188 fileType += fFileReader->GetFileType();
189 printf("RAW FILE TYPE: " ANSI_COLOR_BLUE "%s" ANSI_COLOR_RESET "\n", fileType.data());
190 // if (!isTaskMode) {
191 // fRootFileOut = TFile::Open(fRootFileName, "recreate");
192 fRootFileOut = new TFile(fRootFileName, "recreate");
193 isSpillStart = true;
194 if (!fRootFileOut->IsOpen()) {
195 delete fRootFileOut;
196 return kBMNERROR;
197 }
198 return InitConverter();
199}
200
202{
203 LOGF(info, "InitConverter without file");
204 fRawTree = new TTree("BMN_RAW", "BMN_RAW");
205 LOGF(info, "ROOT FILE: " ANSI_COLOR_BLUE "%s" ANSI_COLOR_RESET, fRootFileName.Data());
206 LOGF(debug, "fRawTree %p init", (void*)fRawTree);
207 LOGF(debug, "fRawTree path %s", fRawTree->GetDirectory()->GetPath());
209#ifdef MULTITHREAD
210 int threadNumber = 0;
211 if (threadNumber == 0) {
212 if (std::thread::hardware_concurrency() <= 1)
213 threadNumber = 1; // either 1 core or no info
214 else
215 threadNumber = std::thread::hardware_concurrency() - 1;
216 }
218 for (int i = 0; i < threadNumber; i++)
219 ((BmnConverterThread*)(fThreads->Add()))->SetInitData(&leaps, utc_valid, tai_utc_dif, fVerbose);
220#endif
221 bool convertMSC = conf.get<bool>("Decoder.ProcessMSC", false);
222 if (convertMSC) {
223 fRawTreeSpills = new TTree("BMN_RAW_SPILLS", "BMN_RAW_SPILLS");
224 // fRawTreeSpillsT0 = new TTree("BMN_RAW_SPILLS_T0", "BMN_RAW_SPILLS_T0");
225 // auto spill_reg_fun = [&](TTree* tree, TString name, TObject* ar) -> void {
226 // TBranch* b = tree->Branch(name, &ar);
227 // LOGF(debug1, "Register branch %p : %s", (void*)b, name.Data());
228 // return;
229 // };
231 }
232 return kBMNSUCCESS;
233}
234
236{
237 LOGF(debug1, "%s ", __func__);
238 if (fRawTreeSpills)
239 fRawTreeSpills->Write();
240 // if (fRawTreeSpillsT0)
241 // fRawTreeSpillsT0->Write();
242 fFileReader->Close();
243 delete fFileReader;
244 fFileReader = nullptr;
245 delete eventHeaderDAQ;
246 eventHeaderDAQ = nullptr;
247 delete sync;
248 sync = nullptr;
249 delete adc32;
250 adc32 = nullptr;
251 delete adc64;
252 adc64 = nullptr;
253 delete adc128;
254 adc128 = nullptr;
255 delete adc;
256 adc = nullptr;
257 delete vsp;
258 vsp = nullptr;
259 delete hrb;
260 hrb = nullptr;
261 delete tdc;
262 tdc = nullptr;
263 delete tqdc_tdc;
264 tqdc_tdc = nullptr;
265 delete tqdc_adc;
266 tqdc_adc = nullptr;
267 delete tdc_hgnd;
268 tdc_hgnd = nullptr;
269 delete msc;
270 msc = nullptr;
271}
272
274
276{
278 // printf("convert_status %d\n", convert_status);
279 if (convert_status == kBMNSUCCESS) {
280 return ((fCurEvType == kBMNPAYLOAD) || (fCurEvType == kBMNPEDESTAL)) ? 0 : 2;
281 } else
282 return 1;
283}
284
286{ // std::function<void(TString, TObject**) > branch_reg_fun) {
288 BranchRegFun("BmnEventHeader.", &eventHeaderDAQ, fRawTree);
289 // FairRootManager* frm = FairRootManager::Instance();
290 // frm->Register("BmnEventHeader.", "BmnEventHeader._dir", eventHeaderDAQ, fSaveOutput);
292 BranchRegFun("SYNC", &sync, fRawTree);
294 BranchRegFun("ADC32", &adc32, fRawTree);
296 BranchRegFun("ADC64", &adc64, fRawTree);
298 BranchRegFun("ADC128", &adc128, fRawTree);
300 BranchRegFun("ADC", &adc, fRawTree);
302 BranchRegFun("VSP_RAW", &vsp, fRawTree);
304 BranchRegFun("TDC", &tdc, fRawTree);
306 BranchRegFun("TQDC_ADC", &tqdc_adc, fRawTree);
308 BranchRegFun("TQDC_TDC", &tqdc_tdc, fRawTree);
310 BranchRegFun("HRB", &hrb, fRawTree);
312 BranchRegFun("TDC_HGND", &tdc_hgnd, fRawTree);
313}
314
315void BmnRawSource::RegisterSpillBranches() // std::function<void(TTree* tree, TString, TObject*)> branch_reg_fun)
316{
323 // spillHeader = new BmnSpillHeader();
324 // GenRegFun("BmnSpillHeader.", spillHeader);
325}
326
327BmnStatus BmnRawSource::ParseJsonTLV(const uint32_t* d, uint32_t& len)
328{
329 try {
330 uint32_t idx = 0;
331 idx++; // skip evId (it is 0)
332 const DeviceHeader* dh = reinterpret_cast<const DeviceHeader*>(d + idx);
333 idx += sizeof(DeviceHeader) / kNBYTESINWORD;
334 // dh->Print();
335 uint32_t str_len = len - idx * kNBYTESINWORD;
336 string str(reinterpret_cast<const char*>(d + idx), str_len);
337 json j = json::parse(str);
338 // cout << "json type : " << j.type_name() << endl;
339 // Int_t key_cnt(0);
340 for (json::iterator it = j.begin(); it != j.end(); ++it) {
341 // std::cout << "["<< key_cnt <<"] : "<< it.key() << '\n';
342 string jkey(it.key());
343 // printf("j[%d] : %s\n", key_cnt, jkey.c_str());
344 if (!jkey.compare("status")) {
345 auto& j_runtime = it.value()["runTime"];
346 auto j_spill = j_runtime["spill"];
347 Int_t phase = static_cast<Int_t>(j_spill["phase"]);
348 // uint32_t curSpillTimeMs = j_spill["curSpillTimeMs"];
349 auto wr = j_runtime["time"]["WR"];
350 Int_t ns = static_cast<Int_t>(wr["ns"]);
351 Int_t sec = static_cast<Int_t>(wr["sec"]);
352 if (tai_utc_dif == 0)
353 tai_utc_dif = GetUTCShift(TTimeStamp(time_t(sec), ns)); // crutch
354 sec -= tai_utc_dif;
356 // skip invalid timestamps
357 if (!ss.times_valid)
358 continue;
359 // if (ts_spill_start > eventHeaderDAQ->GetSpillStartTS()) {
360 // eventHeaderDAQ->SetSpillStartTS(ts_spill_start); // @TODO: rewrite with basing on
361 // spill map eventHeaderDAQ->GetSpillId()++; LOGF(debug, "spill_id %d",
362 // eventHeaderDAQ->GetSpillId());
363 // }
364 LOGF(info, "JSON status phase %d", phase);
365 LOGF(info, "ts :\t%s start", BmnFunctionSet::TimePoint2String(ss.start_ts));
366 if (phase == 0)
367 LOGF(info, "ts :\t%s stop", BmnFunctionSet::TimePoint2String(ss.stop_ts));
368 auto spill_it = fSpillMap.find(ss.start_ts);
369 if (spill_it == fSpillMap.end()) {
370 bool inserted;
371 std::tie(spill_it, inserted) = fSpillMap.insert(
372 make_pair(ss.start_ts,
373 BmnSpillInfo{// .jsons = vector<json>(1, it.value()),
374 .start_ts = ss.start_ts,
375 .stop_ts = ss.start_ts}));
376 LOGF(debug, "spill record inserted %d", inserted);
377 }
378 BmnSpillInfo& info = spill_it->second;
379 // info.jsons.push_back(it.value());
380 if (info.stop_ts < ss.stop_ts)
381 info.stop_ts = ss.stop_ts;
382 if (fExportJsonBlocks) {
383 std::ofstream outfile(Form("j_%s_%d_%9d_%09d_%02X_%08X_phase_%d_%s.json", jkey.c_str(), fRunId, sec,
384 ns, dh->DeviceId, dh->Serial, phase, fSubName.Data()),
385 std::ofstream::binary);
386 outfile << std::setw(4) << j << std::endl;
387 outfile.close();
388 }
389 metadata->SpillStatusVec().push_back(move(ss));
390 } else {
391 LOGF(info, "JSON config");
392 if (!jkey.compare("config")) {
393 string start_DT = it.value()["meta"]["startDateTime"];
394 if (fExportJsonBlocks) {
395 std::ofstream outfile(Form("j_%s_%d_%s_%02X_%08X.json", jkey.c_str(), fRunId, start_DT.data(),
396 dh->DeviceId, dh->Serial),
397 std::ofstream::binary);
398 outfile << std::setw(4) << j << std::endl;
399 outfile.close();
400 }
401 BmnStatus jconfigStatus =
402 BmnConverterTools::ParseJsonConfig(it.value(), runHeader->GetTrigConfig());
403 if (jconfigStatus == kBMNERROR)
404 LOGF(error, "Parsing JSON config failed!");
405 } else
406 LOGF(info, "Unknown json key %s", jkey.data());
407 }
408 }
409 } catch (std::exception& ex) {
410 LOGF(error, "Exception for JSON block: %s", ex.what());
411 }
412 return kBMNSUCCESS;
413}
414
415BmnStatus BmnRawSource::ConvertStatEvent(const uint32_t* d, uint32_t& len)
416{
417 eventHeaderDAQ->SetEventType(fCurEvType);
418 eventHeaderDAQ->SetRunId(fRunId);
419 // Int_t ml = msc->GetEntriesFast();
420 ProcessEvent(d, len);
421 // if (msc->GetEntriesFast() == ml) {
422 // LOGF(info, "MSC not Filled!");
423 // }
424 // if (fRootFileOut) fRawTree->Fill();
425 if (fPeriodId > 7) {
426 if (!isForwardMode)
427 FinalizeStat();
428 } else if ((fCurEvType == kBMNEOS) && (fPrevEvType != kBMNEOS)) {
429 LOGF(debug1, "\tspill! nSpillEvents %d", nSpillEvents);
431 nSpillEvents = 0;
432 fSpillCntr++;
433 // if (msc->GetEntriesFast() > 0)
434 if (fRawTreeSpills)
435 FinalizeStat();
436 }
437 return kBMNSUCCESS;
438}
439
441{
442 if (isRawRootInputFile) {
443 LOGF(info, "Input is raw root file. Nothing to do!");
444 return kBMNSUCCESS;
445 }
447 LOGF(error, "Init converter failed!");
448 return kBMNERROR;
449 }
451 if ((fStartEventId == 0) && (fEventId))
453 }
454
455 for (auto& it : fSpillMap) {
456 BmnSpillInfo& si = it.second;
457 LOGF(info, "\tstart %s\n\tstop %s", BmnFunctionSet::TimePoint2String(si.start_ts),
459 }
460
463 if ((shift != tai_utc_dif)) {
464 LOGF(info, "START (event %u):\t%s", fStartEventId, fRunStartTime.AsString());
465 LOGF(info, "FINISH (event %u):\t%s", fEventId, fRunEndTime.AsString());
466 LOG(info) << "Total Events:\t" << fNTotalEvents;
467 LOG(info) << "nSignal Events:\t" << fNSignalEvents;
468 // Int_t shift = GetUTCShift(fRunEndTime);
469 // if ((shift != tai_utc_dif)) {
470 // LOGF(info, "start dif %d end dif %d", tai_utc_dif, shift);
471 // fprintf(stderr, ANSI_COLOR_RED "Critical Warning! Leap second added during the %i run!\n\n"
472 // ANSI_COLOR_RESET, fRunId);
473 }
474 // fRunEndTime = TTimeStamp(time_t(fTime_s - shift), fTime_ns);
475 // fRawTree->Fill();
476
478 LOG(info) << "Read " << fNTotalEvents << " events; " << fCurentPositionRawFile << " bytes ("
479 << fCurentPositionRawFile / 1024. / 1024. << " Mb)";
480 fRawTree->Write();
481#ifdef MULTITHREAD
482 fThreads->Terminate();
483#endif
484 // closing first to write fRawTreeSpills
485 Close();
486 runHeader->SetSpillMap(move(fSpillMap));
487 fRootFileOut->WriteObject(runHeader.get(), fRawRunHdrName.Data());
488 fRootFileOut->WriteObject(metadata.get(), fMetadataName.Data());
489 fRootFileOut->Close();
490
491 // KG: ADD RAW FILE METADATA TO THE CONDITION DATABASE IF NOT EXISTS
492 try {
493 int period_id = (int)fPeriodId, run_id = (int)fRunId, start_event = (int)fStartEventId,
494 end_event = (int)fEventId,
495 event_count = fNSignalEvents; // fNevents
496
497 // extract raw filename from the full path: the archive extension is dropped
498 TString raw_filename =
499 BmnCompressionRemoveArchiveExtension(fs::path(fRawFileName.Data()).filename()).string().c_str();
500 // check if there is already metadata for a file with the same name
501 TObjArray* pRawFiles = UniRawFile::GetRawFiles(raw_filename);
502 if ((pRawFiles != nullptr) && (pRawFiles->GetEntries() == 0)) {
503 if (UniRawFile::CheckRawFileExists(period_id, run_id, start_event, end_event) > 0)
504 cout << "CRITICAL WARNING: there are overlaps in events for the new file metadata: " << fRawFileName
505 << " (" << period_id << ":" << run_id << " " << start_event << "-" << end_event << ")" << endl
506 << "PLEASE, SEND THE INFO TO THE SOFTWARE COORDINATOR" << endl;
507
508 TDatime fFileStartDate(Int_t(fRunStartTime.GetDate(kFALSE)), Int_t(fRunStartTime.GetTime(kFALSE)));
509 TDatime fFileEndDate(Int_t(fRunEndTime.GetDate(kFALSE)), Int_t(fRunEndTime.GetTime(kFALSE)));
510
512 TString* pFileHash = nullptr;
513 if (strFileHash != "")
514 pFileHash = new TString(strFileHash);
515 else
516 cout << "WARNING: a problem occurred while calculating checksum for the raw file: " << fRawFileName
517 << endl;
518
519 UniRawFile* pRawFile =
520 UniRawFile::CreateRawFile(period_id, run_id, start_event, end_event, fFileStartDate, fFileEndDate,
521 fRawFileName, event_count, fLengthRawFile, pFileHash);
522 if (pRawFile) {
523 // int sum_event_count = UniRawFile::GetSumEventCount(period_id, run_id);
524 // if (sum_event_count > (pRun->GetEventCount() ? (*pRun->GetEventCount()) : 0))
525 // pRun->SetEventCount(&sum_event_count);
526 cout << "Raw file information has been successfully added to the Condition Database for run "
527 << period_id << ":" << run_id << " and event interval " << start_event << "-" << end_event << endl;
528 delete pRawFile;
529 }
530
531 if (pFileHash)
532 delete pFileHash;
533 } // if ((pRawFiles != nullptr) && (pRawFiles->GetEntries() == 0))
534 else
535 {
536 if (pRawFiles != nullptr) {
537 if (pRawFiles->GetEntries() > 1)
538 cout << "CRITICAL WARNING: there are more than one records for the file metadata: " << fRawFileName
539 << endl
540 << "PLEASE, SEND THE INFO TO THE SOFTWARE COORDINATOR" << endl;
541 else {
542 UniRawFile* pExistingRawFile = (UniRawFile*)pRawFiles->At(0);
543 if (pExistingRawFile->GetStartEvent() != start_event)
544 cout << "CRITICAL WARNING: there are different start event for the file metadata: "
545 << fRawFileName << " (" << period_id << ":" << run_id << " " << start_event << "-"
546 << end_event << ")" << endl
547 << "PLEASE, SEND THE INFO TO THE SOFTWARE COORDINATOR" << endl;
548 else if (pExistingRawFile->GetEndEvent() < end_event)
549 cout << "CRITICAL WARNING: the existing file metadata has 'end event' less than: "
550 << fRawFileName << " (" << period_id << ":" << run_id << " " << start_event << "-"
551 << end_event << ")" << endl
552 << "PLEASE, SEND THE INFO TO THE SOFTWARE COORDINATOR" << endl;
553 }
554 }
555 }
556
557 if (pRawFiles)
558 delete pRawFiles;
559 } catch (std::exception& ex) {
560 printf("Exception of working with the Condition Database: %s\n", ex.what());
561 }
562
563 LOG(info) << "Real time " << workTime_real << " s, CPU time " << workTime_cpu << " s for Converter\n";
564 return kBMNSUCCESS;
565}
566
567BmnStatus BmnRawSource::ConvertRawToRootIterate(const uint32_t* buf, uint32_t len)
568{
569 fEventId = buf[0];
570 // printf("EventID = %d\n", fEventId);
571 // if (fEventId <= 0) return kBMNERROR;
572 return ProcessEvent(buf, len);
573}
574
576{
577 while (kTRUE) {
578 // if (wait_file(4 * kWORDSIZE, limit) == kBMNERROR) {
579 // return kBMNTIMEOUT;
580 // LOGF(error, "file timeout");
581 // }
584 if (cst == kBMNSUCCESS)
585 return kBMNSUCCESS;
586 if (cst == kBMNCONTINUE)
587 continue;
588 else
589 return kBMNERROR;
590 }
591 return kBMNSUCCESS;
592}
593
595{
596 // TStopwatch sw;
597 // sw.Start();
599 if (fMaxEvent > 0 && fNSignalEvents >= fMaxEvent)
600 return kBMNERROR;
601 if (fFileReader->Read(&fDat, sizeof(fDat)) != sizeof(fDat))
602 return kBMNERROR;
603 // The following kills compressed files while the previous condition is enough to know if we succeeded
604 // fCurentPositionRawFile = fFileReader->Tell();
605 // if (fCurentPositionRawFile >= fLengthRawFile)
606 // return kBMNERROR;
607 switch (fDat) {
608 case SYNC_EVENT:
609 case SYNC_EVENT_OLD:
611 LOGF(debug, ANSI_COLOR_BLUE "SYNC_EVENT %08X" ANSI_COLOR_RESET, fDat);
612 // read number of bytes in event
613 if (fFileReader->Read(&fDat, sizeof(fDat)) != sizeof(fDat))
614 return kBMNERROR;
615 if (fDat % kNBYTESINWORD) {
616 LOGF(error, "WTF?? in the main event: fDat == %u", fDat);
617 }
618 // LOGF(info, ANSI_COLOR_BLUE "SYNC_EVENT" ANSI_COLOR_RESET " %5u bytes", fDat);
619 if (fPeriodId <= 7)
620 fDat += 4;
621 // printf("ev length %d\n", fDat);
622 // read array of current event data and process them
623 if (fFileReader->Read(data, fDat) != (int64_t)fDat)
624 return kBMNERROR;
625 // we still need to use `fDat /= 4` as it will be used in the following function
626 fDat /= 4;
627 fEventId = data[0];
628 LOGF(debug, ANSI_COLOR_BLUE "iEv = %u" ANSI_COLOR_RESET, fEventId);
629 if (fEventId <= 0)
630 return kBMNCONTINUE; // skip bad events
631#ifdef MULTITHREAD
633#else
635#endif
636
637 // LOGF(trace, "evType %d", fCurEvType);
638 // LOGF(debug, "eventHeaderDAQ %p", (void*) eventHeaderDAQ);
639 if (!isTaskMode) {
640 // LOGF(debug, "fRawTree %p", (void*) fRawTree);
641 // LOGF(debug, "fRawTree %s", fRawTree->GetName());
642 // if (fRootFileOut)
643#ifndef MULTITHREAD
644 /*Int_t fr = */ fRawTree->Fill();
645#endif
646 }
647 LOGF(debug1, "isSpillStart %d", isSpillStart);
648 if (isSpillStart == kTRUE)
651 nSpillEvents++;
652 break;
653 case SYNC_EOS:
655 case SYNC_STAT:
656 LOGF(debug, ANSI_COLOR_BLUE "SYNC_STAT %08X" ANSI_COLOR_RESET, fDat);
657 if (fDat == SYNC_STAT)
659 // read number of bytes in event
660 if (fFileReader->Read(&fDat, sizeof(fDat)) != sizeof(fDat))
661 return kBMNERROR;
662 if (fDat % kNBYTESINWORD) {
663 LOGF(error, "WTF?? in the STAT: fDat == %u", fDat);
664 }
665 LOGF(debug3, "STAT ev length bytes %d", fDat);
666 if (fPeriodId <= 7)
667 fDat += 4;
668 // read array of current event data and process them
669 if (fFileReader->Read(data, fDat) != (int64_t)fDat)
670 return kBMNERROR;
671 // we still need to use `fDat /= 4` as it will be used in the following function
672 fDat /= 4;
674 break;
675 case SYNC_RUN_START:
676 LOGF(info, "RUN START");
677 case SYNC_RUN_STOP:
678 if (fDat == SYNC_RUN_STOP)
679 LOGF(info, "RUN STOP");
680 if (fFileReader->Read(&fDat, sizeof(fDat)) != sizeof(fDat))
681 return kBMNERROR;
682 if (fFileReader->Read(data, fDat) != fDat)
683 return kBMNERROR;
685 break;
686 case SYNC_FILE_BEGIN:
687 LOGF(info, "FILE BEGIN");
688 case SYNC_FILE_END:
689 if (fDat == SYNC_FILE_END)
690 LOGF(info, "FILE END");
691 if (fFileReader->Read(&fDat, sizeof(fDat)) != sizeof(fDat))
692 return kBMNERROR;
693 if (fFileReader->Read(data, fDat) != fDat)
694 return kBMNERROR;
696 break;
697 case SYNC_JSON:
698 if (fFileReader->Read(&fDat, sizeof(fDat)) != sizeof(fDat))
699 return kBMNERROR;
700 LOGF(debug, "SYNC JSON len %u", fDat);
701 if (fFileReader->Read(data, fDat) != fDat)
702 return kBMNERROR;
704 break;
705 default:
706 LOGF(error, "unrecognized sync %08X", fDat);
707 break;
708 }
710 // sw.Stop();
711 // converterTime += sw.RealTime();
712 return kBMNSUCCESS;
713}
714
716{
717 // printf("Fill spill! msc count %d\n", msc->GetEntriesFast());
718 if (fRawTreeSpills && ((msc->GetEntriesFast() > 0) || (t0raw->GetEntriesFast() > 0))) {
719 fRawTreeSpills->Fill();
720 // t0raw->Delete();
721 // msc->Delete();
722 }
723}
724
725void BmnRawSource::QuickProcessEvent(const uint32_t* d, uint32_t len)
726{
727 // Getting a free thread
728 BmnConverterThread* tmp = (BmnConverterThread*)fThreads->GetWaitingThread();
729 // Copying data to the free thread
730 // tmp->SetData(len, d, fCurEvType, fRunId, fPeriodId, fEventId, fTime_s, fTime_ns, 0);
731 tmp->Execute();
732}
733
734BmnStatus BmnRawSource::ProcessEvent(const uint32_t* d, uint32_t len)
735{
736 TStopwatch timer;
737 Double_t rtime;
738 Double_t ctime;
739 timer.Start();
742 if ((fNSignalEvents % 5000 == 0) && (fCurEvType != kBMNSTAT) && (fEventId > 0))
743 LOG(info) << "Converted signal events: " << fNSignalEvents
744 << ". Total events (including stat): " << fNTotalEvents;
745 // } else if (fVerbose == 0)
746 // DrawBar(fCurentPositionRawFile, fLengthRawFile);
747
748 uint32_t idx = 1;
749 // BmnEventType evType = kBMNPAYLOAD;
750
751 BmnTrigInfo trigInfo;
752 while (idx < len) {
753 Bool_t recognized = kTRUE;
754 const DeviceHeader* dh = reinterpret_cast<const DeviceHeader*>(d + idx);
755 LOGF(debug2, "[%u / %u]", idx, len);
756 // dh->Print();
757 uint32_t serial = dh->Serial;
758 uint8_t id = dh->DeviceId;
759 uint32_t payload = dh->GetNWords();
760 idx += sizeof(DeviceHeader) / kNBYTESINWORD;
761 if (payload > 2000000) {
762 dh->Print();
763 LOGF(warn, "Event %d:\n serial = 0x%06X\n id = Ox%02X\n payload = %d", fEventId, serial, id, payload);
764 break;
765 }
766 if (fCurEvType == kBMNSTAT)
767 LOGF(debug4, "STAT iev %7u idx %6u/%6u idev %02X serial 0x%08X payload %4u", fEventId, idx, len, id,
768 serial, payload);
769 switch (id) {
770 case kTQDC16VS_E:
771 FillTQDC_E(&d[idx], serial, payload);
772 break;
773 case kTDC72VXS: // Trig & ToF400 VXS TDC
774 case kTDC64VHLE_E: // ToF700 VHL TDC
775 FillTDC72VXS(&d[idx], serial, payload, id);
776 break;
777 case kTTVXS:
778 FillTTVXS(&d[idx], serial, payload);
779 break;
780 case kGENERIC_DEVICE:
781 ProcessGenericDevice(&d[idx], dh);
782 break;
783 case kMSC16VE_E:
784 if (msc)
785 FillMSC16VE_E(&d[idx], dh);
786 break;
787 case kADC64VE_XGE:
788 case kADC64VE: {
789 // printf("VE id 0x%02X Serial 0x%08X\n", id, serial);
790 BmnStatus ret = BmnConverterTools::Process_ADC64<int16_t>(&d[idx], payload, serial,
791 [&](Int_t n_samples) -> TClonesArray* {
792 switch (n_samples) {
793 case 32:
794 return adc32;
795 break;
796 case 64:
797 return adc64;
798 break;
799 case 128:
800 return adc128;
801 break;
802 default:
803 return nullptr;
804 break;
805 }
806 });
807 if (ret == kBMNERROR)
808 LOGF(warning, "Malformed data from ADC64VE %08X in the event %u", serial, fEventId);
809 break;
810 }
811 case kADC64WR: {
812 // printf("WR id 0x%02X Serial 0x%08X\n", id, serial);
814 &d[idx], payload, serial, [&](Int_t n_samples) -> TClonesArray* { return adc; });
815 if (ret == kBMNERROR)
816 LOGF(warning, "Malformed data from ADC64WR %08X in the event %u", serial, fEventId);
817 break;
818 }
819 case kFVME:
820 Process_FVME(&d[idx], payload, serial, trigInfo);
821 break;
822 case kHRB:
823 Process_HRB(&d[idx], payload, serial);
824 break;
825 case kUT24VE_TRC:
826 FillUT24VE_TRC(&d[idx], serial, payload);
827 break;
828 case kVIRTUAL_DEVICE:
829 FillVirtualDevice(&d[idx], dh);
830 break;
831 default:
832 // printf("Device id %02X not recognized\n", id);
833 recognized = kFALSE;
834 break;
835 }
836 if (payload + idx > len) {
837 printf(
838 "Error in the event #%d: 0x%08X : %2X device payload length mismatch! pauload %5u idx/len: %5u/%5u \n",
839 fEventId, serial, id, payload, idx, len);
840 return kBMNERROR;
841 } else {
842 if (recognized)
843 idx += payload;
844 else
845 idx--;
846 }
847 }
848 if (time_slice_map.size())
849 FillVSP(nullptr);
852 LOGF(info, "Run start ts %s", fRunStartTime.AsString());
853 }
854 eventHeaderDAQ->SetRunId(fRunId);
855 eventHeaderDAQ->SetPeriodId(fPeriodId);
856 eventHeaderDAQ->SetEventId(fEventId);
857 eventHeaderDAQ->SetEventTimeTS(TTimeStamp(time_t(fTime_s), fTime_ns));
858 eventHeaderDAQ->SetEventTime(TTimeStamp(time_t(fTime_s), fTime_ns).AsDouble());
859 eventHeaderDAQ->SetEventType(fCurEvType);
860 eventHeaderDAQ->SetTripWord(kFALSE);
861 eventHeaderDAQ->SetTrigInfo(trigInfo);
862 eventHeaderDAQ->SetSpillStart(isSpillStart);
863 if ((fCurEvType == kBMNSTAT) || (fCurEvType == kBMNEOS))
864 eventHeaderDAQ->SetEventId(0);
865 // printf("Event Type %d\n", fCurEvType);
866 timer.Stop();
867 rtime = timer.RealTime();
868 ctime = timer.CpuTime();
869 workTime_cpu += rtime;
870 workTime_real += ctime;
871 if (fRunStartTime == TimeZero)
873 // printf("\nReal time %f s, CPU time %f s Process Event\n", rtime, ctime);
875 return kBMNSUCCESS;
876}
877
878BmnStatus BmnRawSource::Process_FVME(const uint32_t* d, uint32_t len, uint32_t serial, BmnTrigInfo& trigInfo)
879{
880 LOGF(debug2, "FVME serial %08X len %u", serial, len);
881 if (fCurEvType == kBMNSTAT) {
883 LOGF(debug, "Stat FVME serial %08X efter iEv %u", serial, fEventId);
884 }
885 uint32_t modId = 0;
886 uint32_t slot = 0;
887 uint32_t type = 0;
888 for (uint32_t i = 0; i < len; i++) {
889 type = d[i] >> 28;
890 // if (fCurEvType == kBMNSTAT)
891 // printf(" type %02X i %u\n", type, i);
892 switch (type) {
893 case kEVHEADER:
894 // if (fCurEvType == kBMNSTAT)
895 // printf("Ev header \n");
896 break;
897 case kEVTRAILER:
898 // if (fCurEvType == kBMNSTAT)
899 // printf("Ev trailer\n");
900 return kBMNSUCCESS;
901 break;
902 case kSTATUS:
903 case kPADDING:
904 break;
905 case kMODHEADER:
906 modId = (d[i] >> 16) & 0x7F;
907 slot = (d[i] >> 23) & 0x1F;
908 // if (fCurEvType == kBMNSTAT)
909 // printf("\tmodid 0x%02X slot %d serial 0x%08X\n", modId, slot, serial);
910 break;
911 case kMODTRAILER:
912 // if (fCurEvType == kBMNSTAT)
913 // printf("\tmodule trailer\n");
914 if (!((d[i] >> 16) & 0x1))
915 printf(ANSI_COLOR_RED "Readout overflow error\n" ANSI_COLOR_RESET);
916 if (!((d[i] >> 17) & 0x1))
917 printf(ANSI_COLOR_RED "Readout error\n" ANSI_COLOR_RESET);
918 if (!((d[i] >> 18) & 0x1))
919 printf(ANSI_COLOR_RED "TTC error\n" ANSI_COLOR_RESET);
920 if (!((d[i] >> 19) & 0x1))
921 printf(ANSI_COLOR_RED "Access error\n" ANSI_COLOR_RESET);
922 modId = 0x00;
923 slot = 0x00;
924 break;
925 default: // data
926 {
927 // BmnStatus parsing_status(kBMNSUCCESS);
928 switch (modId) {
929 case kTDC64V:
930 case kTDC64VHLE:
931 case kTDC72VHL:
932 case kTDC32VL:
933 FillTDC(d, serial, slot, modId, i);
934 break;
935 case kTQDC16:
936 case kTQDC16VS:
937 FillTQDC(d, serial, slot, modId, i);
938 break;
939 case kMSC16V:
940 FillMSC(d, serial, slot, i);
941 break;
942 case kTRIG:
943 /*parsing_status = */ FillFVME2TMWR(d, serial, i, len);
944 break;
945 case kU40VE_RC:
946 FillU40VE(d, slot, i, trigInfo);
947 break;
948 }
949 }
950 }
951 }
952 return kBMNSUCCESS;
953}
954
955BmnStatus BmnRawSource::Process_HRB(const uint32_t* d, uint32_t len, uint32_t serial)
956{
957 // uint32_t evId = d[0];
958 uint32_t tH = d[1];
959 uint32_t tL = d[2];
960 uint32_t nWords = 4; // 4 words per plane (per 96 channels, why 4 words - 3 is enough???)
961 uint32_t nSmpl = (len - 3) / nWords; // 3 words are read now. Why divide by 4 (To ask Vadim)
962
963 for (uint32_t iSmpl = 0; iSmpl < nSmpl; ++iSmpl) {
964 for (uint32_t iWord = 0; iWord < nWords; ++iWord) {
965 uint32_t word32 = d[3 + iWord + iSmpl * nWords];
966 for (Int_t iCh = 0; iCh < 32; ++iCh) {
967 if (word32 & BIT(iCh)) {
968 TClonesArray& ar_hrb = *hrb;
969 new (ar_hrb[hrb->GetEntriesFast()]) BmnHRBDigit(serial, iCh + 32 * iWord, iSmpl, tH, tL);
970 }
971 }
972 }
973 }
974
975 return kBMNSUCCESS;
976}
977
978BmnStatus BmnRawSource::FillU40VE(const uint32_t* d, uint32_t slot, uint32_t& idx, BmnTrigInfo& trigInfo)
979{
980 uint32_t type = d[idx] >> 28;
981 // printf("\t\tU40VE start type %u slot %u idx %u\n", type, slot, idx);
982 Bool_t countersDone = kFALSE;
983 while (type == kWORDTAI || type == kWORDTRIG || type == kWORDAUX) {
984 if (fPeriodId > 4 && type == kWORDTRIG && slot == kEVENTTYPESLOT) {
985 fCurEvType = ((d[idx] & BIT(3)) >> 3) ? kBMNPEDESTAL : kBMNPAYLOAD;
986 // uint32_t trigSrc = ((d[idx] >> 16) & (BIT(8) - 1));
987 // printf("EvId %6u trig source %u evType %d\n", fEventId, trigSrc, evType);
988 // if (!( ((d[idx]>>10) & 0x1) ^ (fPeriodId >= 7 && fBmnSetup == kBMNSETUP)))
989 // printf("Ev not Good!\n");
990 // printf("evGood %d\n", (d[idx] & BIT(10)));
991 }
992 if (type == kWORDAUX && !countersDone) {
993 trigInfo.SetTrigCand(d[idx + 0] & 0xFFFFFFF);
994 trigInfo.SetTrigAccepted(d[idx + 1] & 0xFFFFFFF);
995 trigInfo.SetTrigBefo(d[idx + 2] & 0xFFFFFFF);
996 trigInfo.SetTrigAfter(d[idx + 3] & 0xFFFFFFF);
997 trigInfo.SetTrigRjct(d[idx + 4] & 0xFFFFFFF);
998 trigInfo.SetTrigAll(d[idx + 5] & 0xFFFFFFF);
999 trigInfo.SetTrigAvail(d[idx + 6] & 0xFFFFFFF);
1000 idx += 4;
1001 countersDone = kTRUE;
1002 }
1003 idx++; // go to the next DATA-word
1004 type = d[idx] >> 28;
1005 // printf("\t type %u slot %u idx %u\n", type, slot, idx);
1006 }
1007
1008 return kBMNSUCCESS;
1009}
1010
1011BmnStatus BmnRawSource::FillTDC(const uint32_t* d, uint32_t serial, uint32_t slot, uint32_t modId, uint32_t& idx)
1012{
1013 uint32_t type = d[idx] >> 28;
1014 while (type != kMODTRAILER) { // data will be finished when module trailer appears
1015 if (type == TDC_ERROR) {
1016 if (fVerbose == 0) {
1017 LOGF(warning, "TDC (modID 0x%02X serial 0x%08X slot %d tdcID %d) error flags: 0x%04X", modId, serial,
1018 slot, ((d[idx] >> 24) & 0xF), (d[idx] & ((1 << 15) - 1)));
1019 if ((d[idx] & BIT(12)) || (d[idx] & BIT(13))) {
1020 LOGF(warning, "TDC data loss in 0x%08X ", serial);
1021 return kBMNERROR;
1022 }
1023 }
1024 }
1025 if (type == TDC_LEADING || type == TDC_TRAILING) {
1026 uint32_t tdcId = (d[idx] >> 24) & 0xF;
1027 uint32_t time =
1028 (modId == kTDC64V) ? (d[idx] & 0x7FFFF) : ((d[idx] & 0x7FFFF) << 2) | ((d[idx] & 0x180000) >> 19);
1029 uint32_t channel = (modId == kTDC64V) ? (d[idx] >> 19) & 0x1F : (d[idx] >> 21) & 0x7;
1030 // if (modId == kTDC64V && tdcId == 2) channel += 32;
1031 TClonesArray& ar_tdc = *tdc;
1032 new (ar_tdc[tdc->GetEntriesFast()])
1033 BmnTDCDigit(serial, modId, slot, (type == TDC_LEADING), channel, tdcId, time);
1034 if (fCurEvType == kBMNSTAT)
1035 LOGF(debug4, "tdc %08X : %d channel %d", serial, slot, channel);
1036 }
1037 idx++; // go to the next DATA-word
1038 type = d[idx] >> 28;
1039 }
1040 return kBMNSUCCESS;
1041}
1042
1043BmnStatus BmnRawSource::FillTQDC(const uint32_t* d, uint32_t serial, uint32_t slot, uint32_t modId, uint32_t& idx)
1044{
1045 uint32_t type = d[idx] >> 28;
1046 UShort_t trigTimestamp = 0;
1047 UShort_t adcTimestamp = 0;
1048 UShort_t tdcTimestamp = 0;
1049 // uint32_t iSampl = 0;
1050 uint32_t channel = 0;
1051 // Short_t valI[ADC_SAMPLING_LIMIT];
1052 vector<int16_t> valI;
1053 Bool_t inADC = kFALSE;
1054 while (type != kMODTRAILER) {
1055 if (type == TDC_ERROR) {
1056 if (fVerbose == 0) {
1057 LOGF(warning, "In event %8u: TDC (serial 0x%08X slot %d tdcID %d) error flags: 0x%04X", fEventId,
1058 serial, slot, ((d[idx] >> 24) & ((1 << 4) - 1)), (d[idx] & ((1 << 15) - 1)));
1059 if ((d[idx] & BIT(12)) || (d[idx] & BIT(13))) {
1060 LOGF(warning, "\tTQDC data loss in 0x%08X ", serial);
1061 return kBMNERROR;
1062 }
1063 }
1064 }
1065 uint32_t mode = (d[idx] >> 26) & 0x3;
1066 if (!inADC) { // printf("type %d mode %d word %0X\n", type, mode, d[idx]);
1067 if ((mode == 0) && (type == TDC_LEADING || type == TDC_TRAILING)) { // TDC time
1068 channel = (d[idx] >> 19) & 0x1F;
1069 uint32_t time = ((d[idx] & 0x7FFFF) << 2) | ((d[idx] >> 24) & 0x3); // in 25 ps
1070 // printf("TDC time %d channel %d\n", time, channel);
1071 new ((*tqdc_tdc)[tqdc_tdc->GetEntriesFast()])
1072 BmnTDCDigit(serial, modId, slot, (type == TDC_LEADING), channel, 0, time, tdcTimestamp);
1073 // printf("tqdc tdc %08X : %d channel %d\n", serial, slot, channel);
1074 } else if ((type == 4) && (mode != 0)) { // Trig | ADC Timestamp
1075 channel = (d[idx] >> 19) & 0x1F;
1076 if (d[idx] & BIT(16)) { // ADC TS
1077 adcTimestamp = d[idx] & 0xFFFF;
1078 inADC = kTRUE;
1079 } else { // Trig TS
1080 trigTimestamp = d[idx] & 0xFFFF;
1081 }
1082 } else if (type == TDC_EV_HEADER) {
1083 tdcTimestamp = d[idx] & 0xFFF;
1084 // uint32_t iEv = (d[idx] >> 12) & 0xFFF;
1085 // printf("TDC ev header: %d\n", iEv);
1086 } else if (type == TDC_EV_TRAILER) {
1087 // uint32_t iEv = (d[idx] >> 12) & 0xFFF;
1088 // printf("TDC ev trailer: %d\n", iEv);
1089 }
1090 } else {
1091 if ((type == 5) && (mode == 2) /* && (iSampl < ADC_SAMPLING_LIMIT)*/) {
1092 Short_t val = (d[idx] & ((1 << 14) - 1)) - (1 << (14 - 1));
1093 // valI[iSampl++] = val;
1094 valI.push_back(val);
1095 } else {
1096 new ((*tqdc_adc)[tqdc_adc->GetEntriesFast()])
1097 BmnTQDCADCDigit(serial, channel, slot, std::move(valI), trigTimestamp, adcTimestamp);
1098 inADC = kFALSE;
1099 --idx;
1100 // printf("tqdc adc %08X : %d channel %d\n", serial, slot, channel);
1101 }
1102 }
1103 type = d[++idx] >> 28;
1104 }
1105 return kBMNSUCCESS;
1106}
1107
1109 uint32_t serial,
1110 uint8_t channel,
1111 uint16_t& len,
1112 TClonesArray* ar)
1113{
1114 vector<int16_t> valI;
1115 const uint8_t NBytesInSample = 2;
1116 uint16_t iWord = 0;
1117 while (iWord < len) {
1118 uint16_t adcTS = d[iWord] & (BIT(16) - 1);
1119 uint16_t SigLen = d[iWord] >> 16;
1120 uint16_t NSamples = SigLen / NBytesInSample;
1121 uint16_t NSampleWords = SigLen / kNBYTESINWORD + ((SigLen % kNBYTESINWORD) ? 1 : 0);
1122 // printf("SigLen %3u adc len %2u ts %3u NSampleWords %u\n", SigLen, NSamples, adcTS, NSampleWords);
1123 if (iWord + NSampleWords + 1 > len) {
1124 LOGF(error, "TQDC ADC wrong payload length! iWord %u SigLen %u len %u", iWord, SigLen, len);
1125 return kBMNERROR;
1126 }
1127 uint16_t iSampleWord = 0;
1128 while (iSampleWord++ < NSampleWords) {
1129 int16_t adcLo = static_cast<int16_t>(d[iWord + iSampleWord] & (BIT(16) - 1));
1130 int16_t adcHi = static_cast<int16_t>(d[iWord + iSampleWord] >> 16);
1131 valI.push_back(adcLo);
1132 if (valI.size() < NSamples)
1133 valI.push_back(adcHi);
1134 }
1135 if (NSamples) // no slot id for ethernet
1136 new ((*ar)[ar->GetEntriesFast()]) BmnTQDCADCDigit(serial, channel, 0, move(valI), 0, adcTS);
1137 iWord += iSampleWord;
1138 }
1139 return kBMNSUCCESS;
1140}
1141
1143 uint32_t serial,
1144 uint16_t& len,
1145 TClonesArray* ar,
1146 uint32_t modid = 0)
1147{
1148 // uint16_t tdcTS = 0;
1149 // uint8_t tdcId = 0;
1150 uint16_t tdcLine = 0;
1151 while (tdcLine < len) {
1152 uint32_t word = d[tdcLine];
1153 uint32_t bt = word >> 28;
1154 switch (bt) {
1155 case TDC_EV_HEADER: {
1156 // uint16_t evId = (word >> 12) & (BIT(12) - 1);
1157 // tdcId = (word >> 24) & (BIT(4) - 1);
1158 // tdcTS = word & (BIT(12) - 1);
1159 // printf("\tTDC header ev %u TS %u\n", evId, tdcTS);
1160 break;
1161 }
1162 case TDC_EV_TRAILER: {
1163 // uint16_t evId = (word >> 12) & (BIT(12) - 1);
1164 // uint16_t tdcWC = word & (BIT(12) - 1);
1165 // printf("\tTDC trailer ev %u WC %u\n", evId, tdcWC);
1166 break;
1167 }
1168 case TDC_LEADING:
1169 case TDC_TRAILING: {
1170 uint8_t channel = (word >> 21) & (BIT(7) - 1);
1171 // uint16_t time = (word>>2) & (BIT(19) - 1);
1172 uint32_t time = word & (BIT(21) - 1);
1173 // printf("\tTDC %s ch %u id %d time %u\n", (bt == TDC_LEADING) ? "leading" : "trailing",
1174 // channel, tdcId, time);
1175 new ((*ar)[ar->GetEntriesFast()]) BmnTDCDigit(serial, modid, 0, (bt == TDC_LEADING), channel,
1176 0 /*tdcId*/, time, 0 /*tdcTS*/); // ignore tdcId in TQDC
1177 break;
1178 }
1179 case TDC_ERROR:
1180 LOGF(warning, "TDC (serial 0x%08X tdcID %d) in event %u error flags: 0x%04X %s", serial,
1181 ((word >> 24) & ((1 << 4) - 1)), fEventId, (word & ((1 << 15) - 1)),
1182 ((word & BIT(12)) || (word & BIT(13))) ? "data lost" : "");
1183 break;
1184 }
1185 tdcLine++;
1186 }
1187 return kBMNSUCCESS;
1188}
1189
1190BmnStatus BmnRawSource::FillTQDC_E(const uint32_t* d, uint32_t serial, uint32_t& len)
1191{
1192 uint32_t index = 0;
1193 // MStreamHeader* ms = reinterpret_cast<MStreamHeader*> (d);
1194 index += sizeof(MStreamHeader) / kNBYTESINWORD;
1195 // ms->Print();
1196 const MStreamTAI* ms0 = reinterpret_cast<const MStreamTAI*>(d + index);
1197 if (ms0->valid())
1198 FillWR(serial, fEventId, ms0->Sec, ms0->NSec);
1199 index += sizeof(MStreamTAI) / kNBYTESINWORD;
1200 // printf("len %u msHeader len %u\n", len, ms.Len / kNBYTESINWORD);
1201 // printf("taiFlags %u TAI %s\n",
1202 // ms0->Flags, TTimeStamp(time_t(ms0->Sec), ms0->NSec).AsString());
1203 while (index < len) {
1204 const TqdcDataHeader* th = reinterpret_cast<const TqdcDataHeader*>(d + index);
1205 index += sizeof(TqdcDataHeader) / kNBYTESINWORD;
1206 // printf("TQDC DataType %u channel %2u adcBits %u len %4u %8X\n", th->DataType, th->Chan,
1207 // th->AdcBits, th->Len,*th);
1208 uint16_t blockLen = th->Len / kNBYTESINWORD;
1209 switch (th->DataType) {
1210 case kMSTREAM_TYPE_TDC:
1211 FillBlockTDC(d + index, serial, blockLen, tqdc_tdc);
1212 break;
1213 case kMSTREAM_TYPE_ADC:
1214 FillBlockADC(d + index, serial, th->Chan, blockLen, tqdc_adc);
1215 break;
1216 default:
1217 printf("Wrong TQDC data type %u !\n", th->DataType);
1218 break;
1219 }
1220 index += blockLen;
1221 }
1222 return kBMNSUCCESS;
1223}
1224
1225BmnStatus BmnRawSource::FillTDC72VXS(const uint32_t* d, uint32_t serial, uint32_t& len, uint32_t modid = 0)
1226{
1227 uint32_t index = 0;
1228 // MStreamHeader* ms = reinterpret_cast<MStreamHeader*> (d);
1229 index += sizeof(MStreamHeader) / kNBYTESINWORD;
1230 // ms->Print();
1231 const MStreamTAI* ms0 = reinterpret_cast<const MStreamTAI*>(d + index);
1232 if (ms0->valid())
1233 FillWR(serial, fEventId, ms0->Sec, ms0->NSec);
1234 // printf("taiFlags %u TAI %s\n",
1235 // ms0->Flags, TTimeStamp(time_t(ms0->Sec), ms0->NSec).AsString());
1236 index += sizeof(MStreamTAI) / kNBYTESINWORD;
1237 while (index < len) {
1238 uint8_t dtype = d[index] >> 28;
1239 bool overflow = d[index] & BIT(16);
1240 uint16_t blockLen = (d[index++] & (BIT(16) - 1)) / kNBYTESINWORD;
1241 if (!overflow)
1242 switch (dtype) {
1243 case kMSTREAM_TYPE_TDC:
1244 // printf("TDC at index %4u len %4u\n", index, blockLen);
1245 FillBlockTDC(d + index, serial, blockLen, tdc, modid);
1246 break;
1247 case kMSTREAM_TYPE_STAT:
1248 break;
1249 default:
1250 printf("Wrong VXS data type %u !\n", dtype);
1251 break;
1252 }
1253 index += blockLen;
1254 }
1255 return kBMNSUCCESS;
1256}
1257
1258BmnStatus BmnRawSource::FillTTVXS(const uint32_t* d, uint32_t serial, uint32_t& len)
1259{
1260 uint32_t index = 0;
1261 // MStreamHeader* ms = reinterpret_cast<MStreamHeader*> (d);
1262 index += sizeof(MStreamHeader) / kNBYTESINWORD;
1263 // ms->Print();
1264 const MStreamTAI* ms0 = reinterpret_cast<const MStreamTAI*>(d + index);
1265 index += sizeof(MStreamTAI) / kNBYTESINWORD;
1266 if (ms0->valid())
1267 FillWR(serial, fEventId, ms0->Sec, ms0->NSec);
1268 // LOGF(debug, "ts :\t %s TTVXS 0x%08X valid %d",
1269 // TTimeStamp(time_t(ms0->Sec), ms0->NSec).AsString(), serial, ms0->valid());
1270 // LOGF(debug, "ts :\t %10u %9u TTVXS 0x%08X", ms0->Sec, ms0->NSec, serial);
1271 while (index < len) {
1272 uint8_t dtype = d[index] >> 28;
1273 bool overflow = d[index] & BIT(16);
1274 uint16_t blockLen = (d[index++] & (BIT(16) - 1)) / kNBYTESINWORD;
1275 // printf("type 0x%02X len %4u\n", dtype, blockLen);
1276 if (!overflow)
1277 switch (dtype) {
1278 case kMSTREAM_TYPE_TRIG: {
1279 // printf("Trig at index %4u len %4u\n", index, blockLen);
1280 // uint8_t trigType = (d[index] << 8) & (BIT(8) - 1);
1281 // uint8_t trigSrc = d[index] & (BIT(8) - 1);
1282 // printf("Trig type %4u src %4u\n", trigType, trigSrc);
1283 } break;
1284 case kMSTREAM_TYPE_STAT:
1285 break;
1286 default:
1287 printf("Wrong TTVXS data type %u !\n", dtype);
1288 break;
1289 }
1290 index += blockLen;
1291 }
1292 return kBMNSUCCESS;
1293}
1294
1295BmnStatus BmnRawSource::ProcessGenericDevice(const uint32_t* d, const DeviceHeader* dev_hdr)
1296{
1297 // dev_hdr->Print();
1298 if ((dev_hdr->Serial & 0x00FFFFFF) == kVSP_SERIALS)
1299 return MapVSP(d, dev_hdr);
1300 else if (dev_hdr->Serial == kHGND_SERIALS)
1301 return FillTDC250HGND(d, dev_hdr->Serial, dev_hdr->Len);
1302 else
1303 LOGF(error, "BmnRawSource::ProcessGenericDevice: Unknown device serial 0x%08X", dev_hdr->Serial);
1304
1305 return kBMNSUCCESS;
1306}
1307
1308BmnStatus BmnRawSource::FillTDC250HGND(const uint32_t* d, uint32_t serial, uint32_t len)
1309{
1310 if (!d || len == 0)
1311 return kBMNSUCCESS;
1312
1313 const uint16_t* words = reinterpret_cast<const uint16_t*>(d);
1314 size_t total_words = len / sizeof(uint16_t);
1315
1316 if (FairLogger::GetLogger()->IsLogNeeded(fair::Severity::debug4)) {
1317 for (size_t i = 0; i < total_words; ++i)
1318 LOGF(debug4, "0x%04x", words[i]);
1319 }
1320
1321 size_t index = 0;
1322 std::vector<uint16_t> event_words;
1323 std::unique_ptr<BmnHgndRaw::FIFO_block> event;
1324
1325 while (index < total_words) {
1326 auto* word = words + index;
1328 LOGF(error, "BmnRawSource::FillTDC250HGND: Wrong header 0x%04X", *word);
1329 return kBMNERROR;
1330 }
1331
1332 auto event_type = BmnHgndRaw::Block::get_event_packet_version(*word);
1333 uint32_t event_length = BmnHgndRaw::Block::get_block_size(event_type); // in 16-bit words
1334
1335 LOGF(debug4, "Event type %d, 16bit words %d (index=%zu, total=%zu)", (uint32_t)event_type, event_length, index,
1336 total_words);
1337
1338 if (index + event_length > total_words) {
1339 LOGF(error, "BmnRawSource::FillTDC250HGND: Event block overruns buffer");
1340 return kBMNERROR;
1341 }
1342
1343 event_words.assign(word, word + event_length);
1344 if (FairLogger::GetLogger()->IsLogNeeded(fair::Severity::debug4)) {
1345 for (size_t i = 0; i < event_words.size(); ++i) {
1346 LOGF(debug4, "0x%04x", event_words[i]);
1347 }
1348 }
1349
1350 if (event_type == BmnHgndRaw::Block::EventPacketVersion::V1) {
1351 event = std::make_unique<BmnHgndRaw::Event_type_1>(event_words);
1352 } else if (event_type == BmnHgndRaw::Block::EventPacketVersion::V2) {
1353 event = std::make_unique<BmnHgndRaw::Event_type_2>(event_words);
1354 if (!event->validate()) {
1355 LOGF(error, "BmnRawSource::FillTDC250HGND: Event block validation failed");
1356 return kBMNERROR;
1357 }
1358
1359 auto* ev2 = dynamic_cast<BmnHgndRaw::Event_type_2*>(event.get());
1360 if (!ev2) {
1361 LOGF(error, "BmnRawSource::FillTDC250HGND: Event cast to Event_type_2 failed");
1362 return kBMNERROR;
1363 }
1364
1365 uint8_t trise_100ps = ev2->TDC_rise_time; // raw time rise
1366 uint8_t tfall_100ps = ev2->TDC_falling_time; // raw time fall
1367 int64_t time_sec = ev2->timestamp >> 31; // WR timestamp, seconds part
1368 time_sec -= tai_utc_dif;
1369 uint64_t time_nsec = ((ev2->timestamp & 0x7ffffff0) >> 4) * 32; // WR timestamp, ns part. 32ns step
1370 uint16_t time_100ps =
1371 (ev2->timestamp & 0xf) * 32 + trise_100ps; // 3.2ns step + 100ps step subns part. trise
1372 uint16_t plen_100ps =
1373 (ev2->pulse_length + 1) * 32 + tfall_100ps - trise_100ps; // pulse len x100ps +fall -rise
1374
1375 LOGF(debug4, "ch_num = 0x%02X", ev2->channel_number);
1376 LOGF(debug4, "timestamp = 0x%016lX", ev2->timestamp);
1377 LOGF(debug4, "time_sec = 0x%08X", time_sec);
1378 LOGF(debug4, "time_nsec = 0x%08X", time_nsec);
1379 LOGF(debug4, "trise_100ps = 0x%02X", trise_100ps);
1380 LOGF(debug4, "tfall_100ps = 0x%02X", tfall_100ps);
1381 LOGF(debug4, "time_100ps = 0x%04X", time_100ps);
1382 LOGF(debug4, "plen_100ps = 0x%04X", plen_100ps);
1383 LOGF(debug4, "global_ch = 0x%04X", ev2->channel_number_global);
1384
1385 new ((*tdc_hgnd)[tdc_hgnd->GetEntriesFast()])
1386 BmnAbstractTDCDigit(serial, ev2->channel_number_global, time_sec, time_nsec, time_100ps, plen_100ps);
1387 } else {
1388 LOGF(error, "BmnRawSource::FillTDC250HGND: Wrong event type");
1389 return kBMNERROR;
1390 }
1391
1392 index += event_length;
1393 }
1394
1395 return kBMNSUCCESS;
1396}
1397
1398BmnStatus BmnRawSource::MapVSP(const uint32_t* d, const DeviceHeader* dev_hdr)
1399{
1400 LOGF(debug, "MapVSP");
1401 if (dev_hdr->GetNWords() < 3) {
1402 LOGF(warning, "Empty VSP block");
1403 return kBMNERROR;
1404 }
1405 uint8_t iComp = (dev_hdr->Serial & 0xFF000000) >> 24;
1406 time_slice_map[iComp] = d;
1407 return kBMNSUCCESS;
1408}
1409
1411{
1412 LOGF(debug, "FillVSP");
1413 const uint8_t kuMaxComps = 10; // maximum AFCKs (comps)
1414 uint16_t fvuCurrentTsMsbCycle[kuMaxComps] = {}; // FLES Timestamp cycling
1415 uint64_t fvulCurrentTsMsb[kuMaxComps] = {}; // FLES Ts_Msb buffer values
1416 unique_ptr<fles::StorableTimeslice> stti(new fles::StorableTimeslice(1));
1417 uint8_t nComp = time_slice_map.size();
1418 // if (nComp != 2)
1419 // LOGF(warning, "\t ncomps = %lu", nComp);
1420 // append components with a single timeslice
1421 for (uint8_t iw01 = 0; iw01 < nComp; iw01++)
1422 (*stti).append_component(1);
1423 // append microslice #0 to each component
1424 for (auto& el : time_slice_map) {
1425 uint8_t iw01 = el.first;
1426 auto* mslice_descr = el.second;
1427 (*stti).append_microslice(iw01, 0, *((fles::MicrosliceDescriptor*)mslice_descr),
1428 (uint8_t*)mslice_descr + sizeof(fles::MicrosliceDescriptor));
1429 }
1430 for (uint8_t uw02 = 0; uw02 < nComp; uw02++) {
1431 // microslice descriptor #0 (must be only one microslice) of component (FEB) #uw02
1432 const fles::MicrosliceDescriptor& msd = (*stti).descriptor(uw02, 0);
1433 // get the current DPB idx
1434 uint16_t fuCurrentEquipmentId = static_cast<uint16_t>(msd.eq_id);
1435 uint16_t fusCurrentDpbIdx = static_cast<uint32_t>(fuCurrentEquipmentId & 0xFFFF);
1436
1437 // get the trigger number from microslice
1438 uint64_t tgn = msd.idx;
1439 if (tgn != fEventId)
1440 LOGF(warning, "!!! Misplaced VSP event! tgn = %lu while EventId = %u !!!\n", tgn, fEventId);
1441 uint32_t tgNev = static_cast<uint32_t>(tgn); // Ex24
1442 // printf("fles tgN = %lu\t",tgn); printf("fles CurrDpbId = %u\n", fusCurrentDpbIdx);
1443 // if ( tgn% kuUpdateTgN==0 ) {
1444 // printf("ev. tgN = %u\t",tgNev);
1445 // printf("fles tgN = %lu\t",tgn);
1446 // printf("fles CurrDpbId = %u\n", fusCurrentDpbIdx);}
1447 // do what is needed with the microslice
1448
1449 uint32_t size = 0; // the buffer size of the Microslice
1450 uint32_t uNbMessages = 0; // the number of complete messages
1451 // double dTriggerTime = 0; // TrigTime in ns
1452 uint64_t uiTrgTimeFLES = 0; // TrigTime in clocks
1453 uint64_t uiHitTimeFLES = 0; // Hits Time in clocks
1454
1455 size = msd.size;
1456 static const uint32_t kuBytesPerMessage = 4;
1457 // Compute the number of complete messages in the input microslice buffer
1458 uNbMessages = (size - (size % kuBytesPerMessage)) / kuBytesPerMessage;
1459 // Prepare variables for the loop on contents
1460 // const uint32_t* pInBuff = reinterpret_cast<const uint32_t*>( (*stti).content(0,0) );
1461 const uint32_t* pInBuff = reinterpret_cast<const uint32_t*>((*stti).content(uw02, 0));
1462
1463 // uiTrgTimeFLES = 0;
1464 uint64_t uiTrgTime_TsMsb = 0;
1465 uint64_t uiHitTime_TsMsb = 0;
1466 uint64_t uiTrgTime_Epoch = 0;
1467
1468 uint16_t uiTsMsbMessageNumber = 0; // to take only the 1st TsMsb message
1469 uint16_t uiEpochMessageNumber = 0; // to take only the 1st TsMsb message
1470
1471 uint16_t usHitMissedEvts = 0; // local counter of Hits with the Missed Events Flag
1472 if (uNbMessages == 0)
1473 continue;
1474 BmnVspRawDigit* dig = new ((*vsp)[vsp->GetEntriesFast()]) BmnVspRawDigit(tgn, fusCurrentDpbIdx);
1475
1476 for (uint32_t uIdx = 0; uIdx < uNbMessages; ++uIdx) {
1477 // Fill message
1478 uint32_t ulData = static_cast<uint32_t>(pInBuff[uIdx]);
1479
1480 stsxyter::Message mess(static_cast<uint32_t>(ulData & 0xFFFFFFFF));
1481 stsxyter::MessType typeMess = mess.GetMessType();
1482 // if (fbTxtFileOutEna) *foutHitInfoUNI << "typeMess " << static_cast< uint16_t >( typeMess) << std::endl;
1483 switch (typeMess) {
1485 // The first message in the TS is a special ones: EPOCH
1486 uiEpochMessageNumber++;
1487 // dTriggerTime = mess.GetEpochVal() * stsxyter::kdClockCycleNs;
1488 if (uiEpochMessageNumber == 1)
1489 uiTrgTime_Epoch = mess.GetEpochVal(); // all 29 bits, may24
1490 else
1491 printf("fles WARNING: more than one EPOCH message in event tgN = %lu, exactly: %u\n", tgn,
1492 uiEpochMessageNumber);
1493 break;
1494 }
1496 uiTsMsbMessageNumber++;
1497 uint64_t uVal = mess.GetTsMsbValBinning();
1498 if (uVal < fvulCurrentTsMsb[uw02]) {
1499 printf("TsMsbCycle: event trigger# %u", tgNev);
1500 printf("\tDPB: %u, Old TsMsb= %lu, new TsMsb=%lu, Old MsbCy=%u\n", uw02, fvulCurrentTsMsb[uw02],
1501 uVal, fvuCurrentTsMsbCycle[uw02]);
1502
1503 if ((fvulCurrentTsMsb[uw02] - uVal) > 10000000)
1504 fvuCurrentTsMsbCycle[uw02]++;
1505
1506 } // if( uVal < fvulCurrentTsMsb[uw02] )
1507 fvulCurrentTsMsb[uw02] = uVal;
1508 uiHitTime_TsMsb = uVal << 10; // shift to 10 bits;
1509 uiHitTime_TsMsb += static_cast<uint64_t>(stsxyter::kulTsCycleNbBinsBinning)
1510 * fvuCurrentTsMsbCycle[uw02]; // TsMsbCycle added
1511 if (uiTsMsbMessageNumber == 1) {
1512 uiTrgTime_TsMsb =
1513 uiHitTime_TsMsb & 0xFFE0000000; // remove the lower 29 bits, the faster procedure
1514 }
1515 break;
1516 } // case stsxyter::MessType::TsMsb :
1518 uint16_t usRawTs = static_cast<uint16_t>(mess.GetHitTimeBinning());
1519 uiHitTimeFLES = uiHitTime_TsMsb + static_cast<uint64_t>(usRawTs);
1520 uint16_t usElinkIdx = mess.GetLinkIndexHitBinning();
1521 uint16_t usChan = mess.GetHitChannel();
1522 uint16_t usRawAdc = mess.GetHitAdc();
1523
1524 if (mess.IsHitMissedEvts())
1525 usHitMissedEvts++;
1526 dig->AppendHit(uiHitTimeFLES, usElinkIdx, usChan, usRawAdc);
1527 break;
1528 }
1529 default:
1530 break;
1531 } // switch( typeMess )
1532
1533 } // for( uint32_t uIdx = 0; uIdx < uNbMessages; ++uIdx )
1534 dig->SetTHitMissedEvts(usHitMissedEvts);
1535 uiTrgTimeFLES = uiTrgTime_TsMsb + uiTrgTime_Epoch;
1536 dig->SetTTrigTime(uiTrgTimeFLES);
1537 }
1538 time_slice_map.clear();
1539 return kBMNSUCCESS;
1540}
1541
1542BmnStatus BmnRawSource::FillMSC16VE_E(const uint32_t* d, const DeviceHeader* dev_hdr)
1543{
1544 // msc->Delete();
1545 uint32_t index = 0;
1546 const uint32_t len = dev_hdr->GetNWords();
1547 const MSC16VE_EHeader* ms = reinterpret_cast<const MSC16VE_EHeader*>(d);
1548 index += sizeof(MSC16VE_EHeader) / kNBYTESINWORD;
1549 // ms->Hdr.Print();
1550 if (ms->Hdr.Len > (len - 1)) {
1551 LOGF(error, "MSC header payload length mismatch!");
1552 return kBMNERROR;
1553 }
1554 // LOGF(info, "MSC TAI\t%s taiFlags %u ",
1555 // TTimeStamp(time_t(ms->Tai.Sec), ms->Tai.NSec).AsString(), ms->Tai.Flags);
1556 // LOGF(info, "MSC ver %u CntrBitsNum %u SliceInt %3u ns ChanNum %2u ExtCondNum %u",
1557 // ms->GetVersion(), ms->NCntrBits, ms->SliceInt, ms->ChanNumber, ms->ExtCondCnt);
1558 Bool_t hasValues = kFALSE;
1559 std::array<uint8_t, MSC_N_COUNTERS> cntrs = {};
1560 switch (ms->GetVersion()) {
1561 case 1: {
1562 const uint8_t NumsInWord = 4;
1563 while (index < len) {
1564 uint8_t type = d[index] >> 28;
1565 // printf(" index %4u len %4u type %u\n", index, len, type);
1566 if (type == MSC_TIME_SLICE_INFO) {
1567 if (hasValues) {
1568 uint32_t ext_cond = (d[index] >> 24) & (BIT(4) - 1);
1569 uint32_t sliceNum = (d[index]) & (BIT(24) - 1);
1570 auto sc_time_shift = ms->SliceInt * sliceNum * 1ns;
1571 SysPoint p{(ms->Tai.Sec - tai_utc_dif) * 1s + ms->Tai.NSec * 1ns + sc_time_shift};
1572 LOGF(debug, "MSC ext_cond %2u sliceNum %7u time %s", ext_cond, sliceNum,
1574 new ((*msc)[msc->GetEntriesFast()])
1575 BmnMSCDigit<uint8_t>(dev_hdr->Serial, 0, cntrs, fEventId, p, ext_cond);
1576 hasValues = kFALSE;
1577 memset(cntrs.data(), 0, sizeof(UChar_t) * MSC_N_COUNTERS);
1578 }
1579 } else {
1580 for (uint8_t i = 0; i < NumsInWord; i++) {
1581 uint32_t cnt = (d[index] >> (i * ms->NCntrBits)) & (BIT(ms->NCntrBits) - 1);
1582 cntrs[type * NumsInWord + i] = cnt;
1583 // LOGF(info,"\tcnt[%2u] = %2u", (type * NumsInWord + i), cnt);
1584 hasValues = kTRUE;
1585 }
1586 }
1587 index++;
1588 }
1589 } break;
1590 case 2: {
1591 if (ms->Hdr.Len <= 1 + (sizeof(MSC16VE_EHeader) - sizeof(MStreamHeader)) / kNBYTESINWORD)
1592 break; // empty record
1593 uint32_t n_slices = ms->Hdr.Len - 1 - (sizeof(MSC16VE_EHeader) - sizeof(MStreamHeader)) / kNBYTESINWORD;
1594 uint32_t missing_hits = d[index++];
1595 if (missing_hits)
1596 LOGF(info, "missing_hits %3u !!!", missing_hits);
1597 SysPoint point{(ms->Tai.Sec - tai_utc_dif) * 1s + ms->Tai.NSec * 1ns};
1598 BmnMSCZSDigit<uint8_t>* dig = new ((*msc)[msc->GetEntriesFast()])
1599 BmnMSCZSDigit<uint8_t>(dev_hdr->Serial, ms->ChanNumber, point, n_slices, missing_hits);
1600 vector<uint8_t>& vals = dig->GetValues();
1601 auto& times = dig->GetTimes();
1602 vector<uint8_t>& conds = dig->GetExtCond();
1603 int32_t istart = index;
1604 while (index < len) {
1605 uint8_t cnt = d[index] & (BIT(ms->NCntrBits) - 1);
1606 uint8_t ext_cond = (d[index] >> ms->NCntrBits) & (BIT(ms->ExtCondCnt) - 1);
1607 uint32_t sliceNum = d[index] >> (ms->NCntrBits + ms->ExtCondCnt);
1608 auto sc_time_shift = ms->SliceInt * sliceNum * 1ns;
1609 SysPoint point_slice{point + sc_time_shift};
1610 int32_t iVal = index - istart;
1611 // LOGF(info, "iVal %4u", iVal);
1612 vals[iVal] = cnt;
1613 // times[iVal] = point_slice;
1614 times[iVal] = BmnFunctionSet::TimePoint2TS(point_slice);
1615 conds[iVal] = ext_cond;
1616 LOGF(debug, "MSC ext_cond %2u cnt %2u sliceNum %7u time %s", ext_cond, cnt, sliceNum,
1617 BmnFunctionSet::TimePoint2String(point_slice).c_str());
1618 index++;
1619 }
1620 } break;
1621 default:
1622 LOGF(warning, "MSC16 ver $u not implemented", ms->GetVersion());
1623 return kBMNERROR;
1624 break;
1625 }
1626 return kBMNSUCCESS;
1627}
1628
1629BmnStatus BmnRawSource::FillVirtualDevice(const uint32_t* d, const DeviceHeader* dh)
1630{
1631 LOGF(info, "Found virtual device 0x%08X block", dh->Serial);
1632 if (dh->Serial != SERIAL_TO_CFG) {
1633 LOGF(info, "Not T0 device");
1634 return kBMNSUCCESS;
1635 }
1637 std::ofstream outfile(Form("virt_device_run_%u_%08X_%02X_%s_t_%ld_%ld.txt", fRunId, dh->Serial, dh->DeviceId,
1638 fSubName.Data(), fTime_s, fTime_ns),
1639 ios::out | ios::binary);
1640 for (uint32_t i = 0; i < kT0_BIN_BLOCK_WORDS; i++)
1641 outfile << std::hex << d[i];
1642 outfile.write(reinterpret_cast<const char*>(d) + kT0_BIN_BLOCK_BYTES, dh->Len - kT0_BIN_BLOCK_BYTES);
1643 }
1644 BmnT0Raw* lastT0 = BmnConverterTools::Process_T0Raw(d, dh->Len, t0raw);
1645 auto tsle = lastT0->GetTime() - BmnFunctionSet::TimeStamp2TP(TTimeStamp(time_t(fTime_s), fTime_ns));
1646 // Get time since last event
1647 // (surely it will be incorrect for several ns, but at average precise enough to assign it to the spill)
1648 lastT0->SetTimeSinceLastEvNs(duration_cast<nanoseconds>(tsle).count());
1649 return kBMNSUCCESS;
1650}
1651
1652BmnStatus BmnRawSource::FillUT24VE_TRC(const uint32_t* d, uint32_t& serial, uint32_t& len)
1653{
1654 uint32_t index = 0;
1655 const MStreamHeader* ms = reinterpret_cast<const MStreamHeader*>(d);
1656 index += sizeof(MStreamHeader) / kNBYTESINWORD;
1657 // ms->Print();
1658 // start bit input time in the MStreamTAI, and should be the 4th word timeslice
1659 auto* ms0 = reinterpret_cast<const MStreamTAI*>(d + index);
1660 if (ms0->valid()) {
1661 BmnSyncDigit* sd = FillWR(serial, fEventId, ms0->Sec, ms0->NSec);
1662 fTime_ns = sd->GetTime_ns();
1663 fTime_s = sd->GetTime_sec();
1664 }
1665 index += sizeof(MStreamTAI) / kNBYTESINWORD;
1666 if (ms->Len / kNBYTESINWORD > len)
1667 LOGF(error, "UT24VE-TRC Error! MSHeader payload length larger than from device header!");
1668 fCurEvType = (d[index] & BIT(16)) ? kBMNPEDESTAL : kBMNPAYLOAD;
1669 // bool randomTrigger = d[index] & BIT(17);
1670 // bool periodicTrigger = d[index] & BIT(18);
1671 // bool externalTTL = d[index] & BIT(19);
1672 LOGF(debug, "FillUT24VE_TRC etype %u WR %08X ts: %s", (uint32_t)fCurEvType, serial,
1673 TTimeStamp(time_t(fTime_s), fTime_ns).AsString());
1674 eventHeaderDAQ->SetInputSignalsAR(d[index++]);
1675 eventHeaderDAQ->SetInputSignalsBR(d[index]);
1676 vector<uint32_t>& vec = eventHeaderDAQ->GetInputSignalsVector();
1677 while (++index < len) {
1678 uint32_t sig_states = d[index];
1679 vec.push_back(sig_states);
1680 bitset<32> sig_states_bs(sig_states);
1681 LOGF(debug2, "TRC states d[%3u] %s", index, sig_states_bs.to_string());
1682 }
1683 return kBMNSUCCESS;
1684}
1685
1686BmnSyncDigit* BmnRawSource::FillWR(uint32_t serial, uint64_t iEvent, int64_t t_sec, int64_t t_ns)
1687{
1688 // LOGF(debug4, "Fill WR %08X", serial);
1689 // LOGF(info, "Fill WR %08X RS ts %s", serial, TTimeStamp(time_t(t_sec), t_ns).AsString());
1690 if (tai_utc_dif == 0) {
1691 tai_utc_dif = GetUTCShift(TTimeStamp(time_t(t_sec), t_ns));
1692 if (tai_utc_dif == 0)
1693 LOGF(warn, "Possibly wrong state of %08X", serial);
1694 }
1695 return new ((*sync)[sync->GetEntriesFast()]) BmnSyncDigit(serial, iEvent, t_sec - tai_utc_dif, t_ns);
1696}
1697
1698BmnStatus BmnRawSource::FillFVME2TMWR(const uint32_t* d, uint32_t serial, uint32_t& idx, uint32_t& len)
1699{
1700 while (idx < len) {
1701 uint32_t word = d[idx];
1702 uint32_t id = word >> 28;
1703 switch (id) {
1704 case TMWR_TAI: {
1705 uint32_t d0 = d[idx + 0];
1706 uint32_t d1 = d[idx + 1];
1707 uint32_t d2 = d[idx + 2];
1708 uint32_t d3 = d[idx + 3];
1709 if ((d0 >> 28) != 2 || (d1 >> 28) != 2 || (d2 >> 28) != 2 || (d3 >> 28) != 2)
1710 return kBMNERROR; // check TAI code
1711 int64_t ts_t0_s = -1;
1712 int64_t ts_t0_ns = -1;
1713 int64_t GlobalEvent = -1;
1714 ts_t0_ns = (d0 & 0x0FFFFFFF) | ((d1 & 0x3) << 28);
1715 ts_t0_s = ((d1 >> 4) & 0xFFFFFF) | ((d2 & 0xFFFF) << 24);
1716 GlobalEvent = ((d3 & 0x0FFFFFFF) << 12) | ((d2 >> 16) & 0xFFF);
1717 BmnSyncDigit* sd = FillWR(serial, GlobalEvent, ts_t0_s, ts_t0_ns);
1718 if (fPeriodId < 8) {
1719 fTime_ns = sd->GetTime_ns();
1720 fTime_s = sd->GetTime_sec();
1721 }
1722 idx += 4;
1723 LOGF(debug2, "ts :\t %10lli %9lli TMWR 0x%08X", ts_t0_s, ts_t0_ns, serial);
1724 } break;
1725 case TMWR_REL_TS: {
1726 uint32_t d0 = d[idx + 0];
1727 uint32_t d1 = d[idx + 1];
1728 if (((d0 >> 28) != 4) || ((d1 >> 28) != 5))
1729 return kBMNERROR;
1730 // Int_t rts(((d0 & (BIT(24) - 1)) << 8) | ((d1 >> 20) & (BIT(8) - 1)));
1731 // uint32_t ext_word((d1 >> 16) & (BIT(4) - 1));
1732 // uint32_t trg_word(d1 & (BIT(16) - 1));
1733 idx += 2;
1734 // printf("rts %7d ext_tr word %u tr word %u\n" , rts, ext_word, trg_word);
1735 } break;
1737 case TMWR_EOS_CNT: {
1738 // uint32_t d0 = d[idx + 0];
1739 // uint32_t logic_cnt(d0 & (BIT(28) - 1));
1740 // printf("logic_cnt %7u %s\n" , logic_cnt, id == TMWR_EOS_CNT_MATCHED ? "matched" :
1741 // "");
1742 idx++;
1743 } break;
1744 case TMWR_PULSE:
1745 case TMWR_REL_TS_TB:
1746 idx++; // just skip
1747 break;
1748 case kMODTRAILER:
1749 case kSTATUS:
1750 case kPADDING:
1751 idx--;
1752 return kBMNSUCCESS;
1753 default:
1754 printf("unrecognized TMWR id %u\n", id);
1755 idx++;
1756 break;
1757 }
1758 }
1759 return kBMNSUCCESS;
1760}
1761
1762BmnStatus BmnRawSource::FillMSC(const uint32_t* d, uint32_t serial, uint32_t slot, uint32_t& idx)
1763{
1764 uint32_t type = d[idx] >> 28;
1765 uint32_t iCnt = 0;
1766 BmnMSCDigit<uint32_t>* dig = new ((*msc)[msc->GetEntriesFast()]) BmnMSCDigit<uint32_t>(serial, slot, fEventId);
1767 std::array<uint32_t, MSC_N_COUNTERS>& cntrArrCur = dig->GetValue();
1768 // printf("MSC type %u serial %08X last eventID = %6u\n", type, serial, fEventId);
1769 while (type < 6) {
1770 if (type < 5) {
1771 // uint32_t cnt3 = (d[idx] >> 21) & (BIT(8) - 1);
1772 // uint32_t cnt2 = (d[idx] >> 14) & (BIT(8) - 1);
1773 // uint32_t cnt1 = (d[idx] >> 7) & (BIT(8) - 1);
1774 // uint32_t cnt0 = d[idx] & (BIT(8) - 1);
1775 // printf("type = %u %06u %06u %06u %06u \n", type, cnt3, cnt2, cnt1, cnt0);
1776 } else if (type == 5) {
1777 uint32_t cnt = d[idx] & (BIT(28) - 1);
1778 if (iCnt >= MSC_N_COUNTERS)
1779 continue;
1780 cntrArrCur[iCnt++] = cnt;
1781 // printf("\ttype = %u arr[%2u] = %8u\n", type, iCnt - 1, cntrArrCur[iCnt - 1]);
1782 }
1783 type = (d[++idx] >> 28) & (BIT(5) - 1);
1784 }
1785
1786 return kBMNSUCCESS;
1787};
1788
1790{
1791 sync->Delete();
1792 tdc->Delete();
1793 tqdc_adc->Delete();
1794 tqdc_tdc->Delete();
1795 hrb->Delete();
1796 tdc_hgnd->Delete();
1797 adc32->Delete();
1798 adc64->Delete();
1799 adc128->Delete();
1800 adc->Delete();
1801 vsp->Delete();
1802 eventHeaderDAQ->Clear();
1803}
1804
1806{
1807 if (fRawTreeSpills) {
1808 msc->Delete();
1809 t0raw->Delete();
1810 }
1811}
1812
1814{
1815 // Double_t fSize = Double_t(fLengthRawFile / 1024. / 1024.);
1816 // Int_t nEv = fNTotalEvents;
1817
1818 // if (!UniRun::GetRun(fPeriodId, fRunId))
1819 // UniRun::CreateRun(fPeriodId, fRunId, fRawFileName, "", nullptr, nullptr, fRunStartTime, &fRunEndTime,
1820 // &nEv, nullptr, &fSize, nullptr);
1821
1822 return kBMNSUCCESS;
1823}
1824
1826{
1827 fRunId = 0;
1828 TPRegexp re(".+\\.root");
1829 if (re.MatchB(name)) {
1830 TFile* fRootFileIn = new TFile(name, "READ");
1831 if (fRootFileIn->IsOpen()) {
1832 DigiRunHeader* ptrRH = (DigiRunHeader*)fRootFileIn->Get(fRawRunHdrName);
1833 if (ptrRH) {
1834 fRunId = ptrRH->GetRunId();
1835 LOGF(info, "fRunId %u from raw root run header", fRunId);
1836 }
1837 if (fRunId == 0) {
1838 BmnEventHeader* tempHdr = nullptr;
1839 TTree* RawTree = (TTree*)fRootFileIn->Get("BMN_RAW");
1840 if (RawTree) {
1841 RawTree->SetBranchAddress("BmnEventHeader.", &tempHdr);
1842 if (RawTree->GetEntriesFast()) {
1843 RawTree->GetEntry(0);
1844 fRunId = tempHdr->GetRunId();
1845 LOGF(info, "fRunId %u from raw root BmnEventHeader", fRunId);
1846 fRootFileName = name;
1847 }
1848 delete RawTree;
1849 }
1850 }
1851 fRootFileIn->Close();
1852 }
1853 delete fRootFileIn;
1854 if (fRunId > 0) {
1855 isRawRootInputFile = true;
1856 return fRunId;
1857 }
1858 }
1859
1860 FILE* file = fopen(name.Data(), "rb");
1861 if (file == nullptr) {
1862 LOGF(error, "File %s is not open!!!", name.Data());
1863 return 0;
1864 }
1865 uint32_t word;
1866 Int_t cntr = 0;
1867 while (fread(&word, kWORDSIZE, 1, file)) {
1868 if (cntr == 20) {
1869 printf("After checking %d words in input file run number not found!\n", cntr);
1870 printf("Let's get run number from file name\n");
1871 break;
1872 }
1873 if (word == RECORD_RUN_NUMBER) {
1874 if (fread(&word, kWORDSIZE, 1, file) != 1)
1875 break; // skip word
1876 if (fread(&fRunId, kWORDSIZE, 1, file) != 1)
1877 break;
1878 return fRunId;
1879 }
1880 cntr++;
1881 }
1882 fclose(file);
1883 if (fRunId <= 0) {
1884 TPRegexp(".*\\w+_\\w+_\\w+_(\\d+)[^/]*\\.data").Substitute(name, "$1");
1885 return name.Atoi();
1886
1887 } else
1888 return fRunId;
1889}
1890
1892{
1893 leaps.insert(pair<TTimeStamp, Int_t>(TTimeStamp(1972, 1, 1, 0, 0, 9), 10));
1894 leaps.insert(pair<TTimeStamp, Int_t>(TTimeStamp(1972, 7, 1, 0, 0, 10), 11));
1895 leaps.insert(pair<TTimeStamp, Int_t>(TTimeStamp(1973, 1, 1, 0, 0, 11), 12));
1896 leaps.insert(pair<TTimeStamp, Int_t>(TTimeStamp(1974, 1, 1, 0, 0, 12), 13));
1897 leaps.insert(pair<TTimeStamp, Int_t>(TTimeStamp(1975, 1, 1, 0, 0, 13), 14));
1898 leaps.insert(pair<TTimeStamp, Int_t>(TTimeStamp(1976, 1, 1, 0, 0, 14), 15));
1899 leaps.insert(pair<TTimeStamp, Int_t>(TTimeStamp(1977, 1, 1, 0, 0, 15), 16));
1900 leaps.insert(pair<TTimeStamp, Int_t>(TTimeStamp(1978, 1, 1, 0, 0, 16), 17));
1901 leaps.insert(pair<TTimeStamp, Int_t>(TTimeStamp(1979, 1, 1, 0, 0, 17), 18));
1902 leaps.insert(pair<TTimeStamp, Int_t>(TTimeStamp(1980, 1, 1, 0, 0, 18), 19));
1903 leaps.insert(pair<TTimeStamp, Int_t>(TTimeStamp(1981, 7, 1, 0, 0, 19), 20));
1904 leaps.insert(pair<TTimeStamp, Int_t>(TTimeStamp(1982, 7, 1, 0, 0, 20), 21));
1905 leaps.insert(pair<TTimeStamp, Int_t>(TTimeStamp(1983, 7, 1, 0, 0, 21), 22));
1906 leaps.insert(pair<TTimeStamp, Int_t>(TTimeStamp(1985, 7, 1, 0, 0, 22), 23));
1907 leaps.insert(pair<TTimeStamp, Int_t>(TTimeStamp(1988, 1, 1, 0, 0, 23), 24));
1908 leaps.insert(pair<TTimeStamp, Int_t>(TTimeStamp(1990, 1, 1, 0, 0, 24), 25));
1909 leaps.insert(pair<TTimeStamp, Int_t>(TTimeStamp(1991, 1, 1, 0, 0, 25), 26));
1910 leaps.insert(pair<TTimeStamp, Int_t>(TTimeStamp(1992, 7, 1, 0, 0, 26), 27));
1911 leaps.insert(pair<TTimeStamp, Int_t>(TTimeStamp(1993, 7, 1, 0, 0, 27), 28));
1912 leaps.insert(pair<TTimeStamp, Int_t>(TTimeStamp(1994, 7, 1, 0, 0, 28), 29));
1913 leaps.insert(pair<TTimeStamp, Int_t>(TTimeStamp(1996, 1, 1, 0, 0, 29), 30));
1914 leaps.insert(pair<TTimeStamp, Int_t>(TTimeStamp(1997, 7, 1, 0, 0, 30), 31));
1915 leaps.insert(pair<TTimeStamp, Int_t>(TTimeStamp(1999, 1, 1, 0, 0, 31), 32));
1916 leaps.insert(pair<TTimeStamp, Int_t>(TTimeStamp(2006, 1, 1, 0, 0, 32), 33));
1917 leaps.insert(pair<TTimeStamp, Int_t>(TTimeStamp(2009, 1, 1, 0, 0, 33), 34));
1918 leaps.insert(pair<TTimeStamp, Int_t>(TTimeStamp(2012, 7, 1, 0, 0, 34), 35));
1919 leaps.insert(pair<TTimeStamp, Int_t>(TTimeStamp(2015, 7, 1, 0, 0, 35), 36));
1920 leaps.insert(pair<TTimeStamp, Int_t>(TTimeStamp(2017, 1, 1, 0, 0, 36), 37));
1921 utc_valid = TTimeStamp(2026, 12, 30, 0, 0, 1);
1922 return kBMNSUCCESS;
1923}
1924
1926{
1927 if (t < leaps.begin()->first) {
1928 LOGF(warning, "Wrong time! %s", t.AsString());
1929 return 0;
1930 }
1931 if (t > utc_valid)
1932 LOGF(warning, "Warning! Leap seconds table expired!");
1933 Int_t shift = 0;
1934 auto it = leaps.lower_bound(t);
1935 if ((it == leaps.end()))
1936 it--;
1937 else if (it->first > t)
1938 it--;
1939 shift = it->second;
1940 return shift;
1941}
1942
1944{
1945 if (fDecoderConfigFileName.length() == 0)
1946 fDecoderConfigFileName = string(getenv("VMCWORKDIR")) + "/config/bmnconf.json";
1947 pt::read_json(fDecoderConfigFileName, conf);
1948 fExportJsonBlocks = conf.get<bool>("Decoder.ExportJson", false);
1949 fExportExternalSpillStat = conf.get<bool>("Decoder.ExportExternalSpillStat", false);
1950 return kBMNSUCCESS;
1951}
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
double Double_t
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
@ kBMNCONTINUE
Definition BmnEnums.h:98
@ 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
@ kBMNEMPTY
No event (wrong sync word or metadata payload).
Definition BmnEnums.h:148
std::chrono::time_point< SysClock > SysPoint
#define ANSI_COLOR_RED
Definition BmnMath.h:16
#define ANSI_COLOR_RESET
Definition BmnMath.h:18
#define ANSI_COLOR_BLUE
Definition BmnMath.h:17
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 SYNC_RUN_START
Definition RawTypes.h:10
const uint32_t kFVME
Definition RawTypes.h:66
const uint32_t kTTVXS
Definition RawTypes.h:55
const uint32_t SYNC_EVENT
Definition RawTypes.h:5
const uint32_t TDC_ERROR
Definition RawTypes.h:86
const uint32_t RECORD_RUN_NUMBER
Definition RawTypes.h:14
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 SYNC_EOS
Definition RawTypes.h:8
const uint32_t SYNC_STAT
Definition RawTypes.h:7
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 SYNC_JSON
Definition RawTypes.h:9
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 SYNC_RUN_STOP
Definition RawTypes.h:11
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 SYNC_FILE_BEGIN
Definition RawTypes.h:12
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 SYNC_FILE_END
Definition RawTypes.h:13
const uint32_t SYNC_EVENT_OLD
Definition RawTypes.h:6
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
const size_t kWORDSIZE
Definition RawTypes.h:18
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 TString GetSubNameAfterRunId(TString name)
static BmnStatus ParseRawFileName(const TString &s, BmnFileProp &prop)
static BmnStatus ParseJsonConfig(json &j, BmnTrigConfig &trig_conf)
static BmnStatus ParseComplexTLV(const uint32_t *buf, UInt_t &len, UInt_t &runId)
static SpillStatus ParseJsonStatus(json &j, Int_t tai_utc_dif=0)
uint32_t GetRunId() const
Definition BmnFileProp.h:22
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()
Class BmnMetadataRaw for the configuration and raw spill information.
Bool_t fSaveOutput
BmnStatus FinishRun()
BmnStatus FillTDC(const uint32_t *d, uint32_t serial, uint32_t slot, uint32_t modId, uint32_t &idx)
BmnStatus FillBlockADC(const uint32_t *d, uint32_t serial, uint8_t channel, uint16_t &len, TClonesArray *ar)
uint32_t fNTotalEvents
map< SysPoint, BmnSpillInfo > fSpillMap
const TTimeStamp TimeZero
TString fRootFileName
BmnStatus ConvertRawToRoot()
TClonesArray * sync
BmnIFileReader * fFileReader
TClonesArray * tdc
BmnStatus FillU40VE(const uint32_t *d, uint32_t slot, uint32_t &idx, BmnTrigInfo &spillInfo)
Int_t GetUTCShift(TTimeStamp t)
uint32_t syncCounter
BmnStatus FillTQDC(const uint32_t *d, uint32_t serial, uint32_t slot, uint32_t modId, uint32_t &idx)
TTimeStamp fRunStartTime
BmnStatus ProcessEvent(const uint32_t *data, uint32_t len)
BmnStatus FillFVME2TMWR(const uint32_t *d, uint32_t serial, uint32_t &idx, uint32_t &len)
TString fMetadataName
BmnStatus LoadConfig()
BmnStatus FillTDC250HGND(const uint32_t *d, uint32_t serial, uint32_t len)
Parse custom HGND TDC data block.
TClonesArray * adc
TString fSubName
string fDecoderConfigFileName
virtual void Reset() override
int64_t fTime_s
BmnStatus ConvertStatEvent(const uint32_t *buf, uint32_t &len)
BmnStatus ConvertRawToRootIterate(const uint32_t *buf, uint32_t len)
void FinalizeStat()
Finishes the spill during raw conversion.
void RegisterSpillBranches()
BmnRawSource(vector< TString > files, uint32_t period=8)
TTree * fRawTree
BmnStatus ProcessGenericDevice(const uint32_t *d, const DeviceHeader *dev_hdr)
Bool_t fExportExternalSpillStat
TClonesArray * msc
uint32_t fDat
BmnStatus FillMSC(const uint32_t *d, uint32_t serial, uint32_t slot, uint32_t &idx)
Old MSC format (periodId < 8, one record for spill).
BmnStatus Process_FVME(const uint32_t *data, uint32_t len, uint32_t serial, BmnTrigInfo &spillInfo)
TClonesArray * tqdc_adc
TClonesArray * tdc_hgnd
std::map< uint8_t, const uint32_t * > time_slice_map
uint32_t fRunId
BmnEventType fCurEvType
pt::ptree conf
unique_ptr< DigiRunHeader > runHeader
TClonesArray * hrb
uint32_t fMaxEvent
virtual ~BmnRawSource() override
TClonesArray * t0raw
void ClearRawSpillArrays()
uint32_t fPeriodId
BmnThreadManager< BmnConverterThread > * fThreads
BmnEventHeader * eventHeaderDAQ
TClonesArray * vsp
BmnSpillHeader * spillHeader
map< TTimeStamp, Int_t > leaps
BmnStatus InitUTCShift()
BmnStatus InitConverter()
TFile * fRootFileOut
void QuickProcessEvent(const uint32_t *d, uint32_t len)
uint32_t fEventId
TClonesArray * adc32
Bool_t fExportJsonBlocks
int64_t fLengthRawFile
BmnStatus ConvertRawToRootIterateFileRead()
TString fRawRunHdrName
BmnStatus FillTDC72VXS(const uint32_t *d, uint32_t serial, uint32_t &len, uint32_t modid)
https://afi.jinr.ru/TDC72VXS_DataFormat
void RegisterBranches()
int64_t fTime_ns
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.
TClonesArray * adc64
uint32_t nSpillEvents
BmnStatus ParseJsonTLV(const uint32_t *buf, uint32_t &len)
BmnStatus FillBlockTDC(const uint32_t *d, uint32_t serial, uint16_t &len, TClonesArray *ar, uint32_t modid)
Double_t workTime_real
BmnStatus MapVSP(const uint32_t *d, const DeviceHeader *dev_hdr)
Parse VSP data block.
virtual void Close() override
BmnStatus FillVSP(TClonesArray *ar)
BmnEventType fPrevEvType
Int_t GetRunIdFromFile(TString name)
BmnStatus FillTTVXS(const uint32_t *d, uint32_t serial, uint32_t &len)
https://afi.jinr.ru/TTVXS_DataFormat
BmnStatus FillMSC16VE_E(const uint32_t *d, const DeviceHeader *dev_hdr)
Parse MSC16VE-E MStream data block https://afi.jinr.ru/DataFormatMSC_ETH https://afi....
TClonesArray * tqdc_tdc
void BranchRegFun(TString name, BrType **ar, TTree *tree=nullptr)
TTimeStamp fRunEndTime
virtual bool Init() override
unique_ptr< BmnMetadataRaw > metadata
uint32_t fSpillCntr
TTimeStamp utc_valid
TTree * fRawTreeSpills
Double_t workTime_cpu
BmnSyncDigit * FillWR(uint32_t iSerial, uint64_t iEvent, int64_t t_sec, int64_t t_ns)
int64_t fCurentPositionRawFile
bool isRawRootInputFile
TString fRawFileName
BmnStatus FillVirtualDevice(const uint32_t *d, const DeviceHeader *dh)
uint32_t data[10000000]
uint32_t fStartEventId
virtual Int_t ReadEvent(uint32_t i=0) override
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 Process_HRB(const uint32_t *data, uint32_t len, uint32_t serial)
uint32_t fNSignalEvents
BmnStatus ConvertRawToRootIterateFile(uint32_t limit=WAIT_LIMIT)
TClonesArray * adc128
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)
uint64_t GetRunId()
Get the run ID.
T * Get(const char *namecycle)
virtual Bool_t IsOpen() const
void Close(Option_t *option="") override
Int_t GetEntriesFast() const
Int_t GetEntries() const override
TObject * At(Int_t idx) const override
static TClass * Class()
Bool_t MatchB(const TString &s, const TString &mods="", Int_t start=0, Int_t nMaxMatch=10)
Int_t Substitute(TString &s, const TString &replace, const TString &mods="", Int_t start=0, Int_t nMatchMax=10)
Double_t RealTime()
void Start(Bool_t reset=kTRUE)
Double_t CpuTime()
void Stop()
Int_t Atoi() const
const char * Data() const
const char * AsString(const Option_t *option="") const
virtual Int_t GetEntry(Long64_t entry, Int_t getall=0)
virtual Long64_t GetEntriesFast() const
Int_t SetBranchAddress(const char *bname, T **add, TBranch **ptr=nullptr)
/home/soul/bmnroot/database/uni_db1/UniRawFile.h Class for the table: raw_file
Definition UniRawFile.h:19
static int CheckRawFileExists(int file_id)
check raw file exists in the database: 1- true, 0 - false, <0 - database operation error
static UniRawFile * CreateRawFile(int period_number, int run_number, int start_event, int end_event, TDatime start_datetime, TDatime end_datetime, TString file_path, int event_count, int64_t file_size, TString *file_hash)
add new raw file to the database
int GetEndEvent()
get end event of the current raw file
Definition UniRawFile.h:104
static TObjArray * GetRawFiles(int period_number, int run_number)
get array of raw files (UniRawFile*) corresponding to the period:run number ordered by start_event as...
static TString CalculateFileHash(TString file_path)
calculate and return (in hex string format) cheсksum for a given file use Adler32 algorithm if zlib l...
int GetStartEvent()
get start event of the current raw file
Definition UniRawFile.h:102
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).
BmnIFileReader * BmnCompressionCreateNewSuitableReaderForAFile(const std::filesystem::path &aFilePath, const BmnFileType aPreferredTypeForThisAlgorithm=BmnFileType::Unknown)
std::filesystem::path BmnCompressionRemoveArchiveExtension(std::filesystem::path aFilePath)
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.
SysPoint stop_ts
SysPoint start_ts
Class SpillStatus raw spill status from JSON block.
Definition SpillStatus.h:20
SysPoint start_ts
Definition SpillStatus.h:39
bool times_valid
Definition SpillStatus.h:46
SysPoint stop_ts
Definition SpillStatus.h:40
Microslice descriptor struct.
uint64_t idx
Microslice index / start time.
uint32_t size
Content size (bytes).
uint16_t eq_id
Equipment identifier.