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