Hall A ROOT/C++ Analyzer (podd)
Loading...
Searching...
No Matches
CodaDecoder.cxx
Go to the documentation of this file.
1
2//
3// CodaDecoder
4//
5// Object-oriented version of decoder
6// Sept, 2014 R. Michaels
7//
9
10#include "CodaDecoder.h"
11#include "THaCrateMap.h"
12#include "THaBenchmark.h"
13#include "THaUsrstrutils.h"
14#include "DAQconfig.h"
15#include "Helper.h"
16#include "TError.h"
17#include "TList.h"
18#include <iostream>
19#include <stdexcept>
20#include <algorithm>
21#include <utility>
22#include <cstring>
23#include <sstream>
24#include <iomanip>
25
26using namespace std;
27
28namespace Decoder {
29
30static constexpr auto MAXROCSLOT_FB = MAXROC * MAXSLOT_FB;
31
32//_____________________________________________________________________________
34 : nroc(0)
35 , irn(MAXROC, 0)
36 , fbfound(MAXROCSLOT_FB, false)
37 , psfact(MAX_PSFACT, kMaxUInt)
38 , buffmode{false}
39 , synchmiss{false}
40 , synchextra{false}
41 , fdfirst(true)
42 , chkfbstat(1)
43 , blkidx(0)
44 , fMultiBlockMode{false}
45 , fBlockIsDone{false}
46 , tsEvType{0}
47 , bank_tag{0}
48 , block_size{0}
49{
50 bankdat.reserve(32);
51 // Please leave these 3 lines for me to debug if I need to. thanks, Bob
52#ifdef WANTDEBUG
53 fDebugFile = new ofstream();
54 fDebugFile->open("bobstuff.txt");
55 *fDebugFile<< "Debug my stuff "<<endl<<endl;
56#endif
58}
59
60//_____________________________________________________________________________
61#ifndef WANTDEBUG
63#else
65{
66 delete fDebugFile; fDebugFile = nullptr;
67}
68#endif
69
70//_____________________________________________________________________________
72{
73 // To get the prescale factors for trigger number "trigger_type"
74 // (valid types are 1,2,3...)
75 if ( (trigger_type > 0) && (trigger_type <= MAX_PSFACT)) {
76 return psfact[trigger_type - 1];
77 }
78 if (fDebug > 0) {
79 Warning( "CodaDecoder::GetPrescaleFactor", "Requested prescale factor for "
80 "undefined trigger type %d", trigger_type );
81 }
82 return 0;
83}
84
85//_____________________________________________________________________________
87{
88 Int_t ret = THaEvData::Init();
89 if( ret != HED_OK ) return ret;
91 auto* cfg = DAQInfoExtra::GetFrom(fExtra);
92 if( cfg )
93 cfg->clear();
94 return ret;
95}
96
97//_____________________________________________________________________________
99{
100 // Main engine for decoding, called by public LoadEvent() methods
101
102 assert(evbuffer);
103
104 if (fDebugFile) {
105 *fDebugFile << "CodaDecode:: Loading event ... " << endl
106 << "evbuffer ptr " << hex << evbuffer << dec << endl;
107 }
108
109 if (fDataVersion <= 0) {
110 cerr << "CODA version not set (=" << fDataVersion << "). "
111 << "Do SetCodaVersion(codaData->getCodaVersion()) first" << endl;
112 return HED_FATAL;
113 }
114 if (fDataVersion != 2 && fDataVersion != 3) {
115 cerr << "Unsupported CODA version = " << fDataVersion << "). Need 2 or 3."
116 << "Cannot analyze these data. Twonk."<<endl;
117 return HED_FATAL;
118 }
119
120 if( DataCached() ) {
121 if( evbuffer[0]+1 != event_length ) {
122 throw std::logic_error("Event buffer changed while processing multiblock "
123 "data. Do not read new events while DataCached() "
124 "returns true!");
125 }
126 if( ++blkidx >= block_size ) {
127 throw std::logic_error("Attempt to decode more events in block than "
128 "available (blkidx >= block_size). Logic error. "
129 "Call expert.");
130 }
131
132 if( fDataVersion == 3 )
134 ++event_num; // _should_ be sequential
135 return LoadFromMultiBlock();
136 }
137
138 buffer = evbuffer;
139 event_length = evbuffer[0]+1; // in longwords (4 bytes)
140 event_type = 0;
141 data_type = 0;
142 trigger_bits = 0;
143 evt_time = 0;
144 bankdat.clear();
145 blkidx = 0;
146
147 // Determine event type
148 if (fDataVersion == 2) {
149 event_type = evbuffer[1]>>16;
150 } else { // CODA version 3
151 interpretCoda3(evbuffer); // this defines event_type
152 }
153 if(fDebugFile) {
154 *fDebugFile << "CodaDecode:: dumping "<<endl;
155 dump(evbuffer);
156 }
157
158 Int_t ret = HED_OK;
159
160 if (event_type == PRESTART_EVTYPE ) {
161 // Usually prestart is the first 'event'. Call SetRunTime() to
162 // re-initialize the crate map since we now know the run time.
163 // This won't happen for split files (no prestart). For such files,
164 // the user should call SetRunTime() explicitly.
165 SetRunTime(evbuffer[2]);
166 run_num = evbuffer[3];
167 run_type = evbuffer[4];
168 if (fDebugFile) {
169 *fDebugFile << "Prestart Event : run_num " << run_num
170 << " run type " << run_type
171 << " event_type " << event_type
172 << " run time " << fRunTime
173 << endl;
174 }
175 }
176
178 if (fDataVersion == 2) {
179 ret = prescale_decode_coda2(evbuffer);
180 } else {
181 ret = prescale_decode_coda3(evbuffer);
182 }
183 if (ret != HED_OK ) return ret;
184 }
185
187 if( fDataVersion > 2 ) {
188 if( (ret = daqConfigDecode(evbuffer)) != HED_OK )
189 return ret;
190 } else {
191 cerr << "Warning: Event type " << event_type << " decoding only "
192 << "supported for CODA data version 3 or higher" << endl;
193 }
194 }
195
196 else if( event_type <= MAX_PHYS_EVTYPE && !PrescanModeEnabled() ) {
197 if( fDataVersion == 3 &&
198 (ret = trigBankDecode(evbuffer)) != HED_OK ) {
199 return ret;
200 }
201 ret = physics_decode(evbuffer);
202 }
203
204 return ret;
205}
206
207//_____________________________________________________________________________
209{
210 assert(fMap || fNeedInit);
211 if( first_decode || fNeedInit ) {
212 Int_t ret = Init();
213 if( ret != HED_OK )
214 return ret;
215 }
216 assert(fMap);
217 if( fDoBench ) fBench->Begin("clearEvent");
218 for( auto i : fSlotClear )
219 crateslot[i]->clearEvent();
220 if( fDoBench ) fBench->Stop("clearEvent");
221
222 if( fDataVersion == 3 ) {
224 FindRocsCoda3(evbuffer);
225 } else {
226 event_num = evbuffer[4];
227 FindRocs(evbuffer);
228 }
229
230 if( fdfirst && fDebugFile ) {
231 fdfirst = false;
232 CompareRocs();
233 }
234
235 // Decode each ROC
236 // From this point onwards there is no diff between CODA 2.* and CODA 3.*
237
238 for( UInt_t i = 0; i < nroc; i++ ) {
239
240 UInt_t iroc = irn[i];
241 const RocDat_t& ROC = rocdat[iroc];
242 UInt_t ipt = ROC.pos + 1;
243 UInt_t iptmax = ROC.pos + ROC.len; // last word of data
244
245 if( fMap->isFastBus(iroc) ) { // checking that slots found = expected
246 if( GetEvNum() > 200 && chkfbstat < 3 ) chkfbstat = 2;
247 if( chkfbstat == 1 ) ChkFbSlot(iroc, evbuffer, ipt, iptmax);
248 if( chkfbstat == 2 ) {
249 ChkFbSlots();
250 chkfbstat = 3;
251 }
252 }
253
254 // If at least one module is in a bank, must split the banks for this roc
255
256 Int_t status;
257 if( fMap->isBankStructure(iroc) ) {
258 if( fDebugFile )
259 *fDebugFile << "\nCodaDecode::Calling bank_decode "
260 << iroc << " " << ipt << " " << iptmax
261 << endl;
262 try {
263 status = bank_decode(iroc, evbuffer, ipt, iptmax);
264 }
265 catch( const logic_error& e ) {
266 Error("CodaDecoder::bank_decode", "ERROR: %s", e.what());
267 return HED_ERR;
268 }
269 if( status != HED_OK )
270 return status;
271 }
272
273 if( !fMap->isAllBanks(iroc) ) {
274 if( fDebugFile )
275 *fDebugFile << "\nCodaDecode::Calling roc_decode "
276 << iroc << " " << ipt << " " << iptmax
277 << endl;
278
279 try {
280 status = roc_decode(iroc, evbuffer, ipt, iptmax);
281 }
282 catch( const logic_error& e ) {
283 Error("CodaDecoder::roc_decode", "ERROR: %s", e.what());
284 return HED_ERR;
285 }
286 if( status != HED_OK )
287 return status;
288 }
289 }
290 // Print summary of discovered banks
291 constexpr UInt_t bankinfo_bit = 65;
292 if( !fMsgPrinted.TestBitNumber(bankinfo_bit) ) {
293 if( !bankdat.empty() ) {
295 // Unless we are debugging, print just once at start of run
296 if( fDebug < 2 )
297 fMsgPrinted.SetBitNumber(bankinfo_bit);
298 }
299 }
300 return HED_OK;
301}
302
303//_____________________________________________________________________________
305{
306 // Extract basic information from a CODA3 event
307 tbank.Clear();
308 tsEvType = 0;
309
310 bank_tag = (evbuffer[1] & 0xffff0000) >> 16;
311 data_type = (evbuffer[1] & 0xff00) >> 8;
312 block_size = evbuffer[1] & 0xff;
313
315
316 if( bank_tag < 0xff00 ) { // User event type
317 if( fDebug > 1 ) // if set, character data gets printed.
318 debug_print(evbuffer);
319
320 if( fDebugFile )
321 *fDebugFile << " User defined event type " << event_type << endl;
322 }
323 if( fDebugFile )
324 *fDebugFile << "CODA 3 Event type " << event_type << " trigger_bits "
325 << trigger_bits << " tsEvType " << tsEvType
326 << " evt_time " << GetEvTime() << endl;
327
328 return HED_OK;
329}
330
331//_____________________________________________________________________________
333{
334 UInt_t evtyp{};
335
336 if( tag >= 0xff00 ) { // CODA Reserved bank type
337 switch( tag ) {
338 case 0xffd1:
339 evtyp = PRESTART_EVTYPE;
340 break;
341 case 0xffd2:
342 evtyp = GO_EVTYPE;
343 break;
344 case 0xffd4:
345 evtyp = END_EVTYPE;
346 break;
347 case 0xff50:
348 case 0xff58: // Physics event with sync bit
349 case 0xFF78:
350 case 0xff70:
351 evtyp = 1; // for CODA 3.* physics events are type 1.
352 break;
353 default: // Undefined CODA 3 event type
354 cerr << "CodaDecoder:: WARNING: Undefined CODA 3 event type, tag = "
355 << "0x" << hex << tag << dec << endl;
356 evtyp = 0;
357 //FIXME evtyp = 0 could also be a user event type ...
358 // maybe throw an exception here?
359 }
360 } else { // User event type
361 evtyp = tag; // ET-insertions
362 }
363
364 return evtyp;
365}
366
367//_____________________________________________________________________________
369{
370 // CODA3: Load tsEvType, evt_time, and trigger_bits for i-th event
371 // in event block buffer. index_buffer must be < block size.
372
373 assert(i < tbank.blksize);
374 if( i >= tbank.blksize )
375 return -1;
376 tsEvType = tbank.evType[i]; // event type (configuration-dependent)
377 if( tbank.evTS )
378 evt_time = tbank.evTS[i]; // event time (4ns clock, I think)
379 else if( tbank.TSROC ) {
380 UInt_t struct_size = tbank.withTriggerBits() ? 3 : 2;
381 evt_time = *(const uint64_t*) (tbank.TSROC + struct_size * i);
382 // Only the lower 48 bits seem to contain the time
383 evt_time &= 0x0000FFFFFFFFFFFF;
384 }
385 if( tbank.withTriggerBits() )
386 trigger_bits = tbank.TSROC[2 + 3 * i]; // trigger bits
387
388 return 0;
389}
390
391//_____________________________________________________________________________
393{
394 // Decode the CODA3 trigger bank. Copy relevant data to member variables.
395 // This will initialize the crate map.
396
397 const char* const here = "CodaDecoder::trigBankDecode";
398
399 // If necessary, initialize the crate map (for TS ROC)
400 assert(fMap || fNeedInit);
401 if( first_decode || fNeedInit ) {
402 Int_t ret = Init();
403 if( ret != HED_OK )
404 return ret;
405 }
406 assert(fMap);
407
408 // Decode trigger bank (bank of segments at start of physics event)
409 if( block_size == 0 ) {
410 Error(here, "CODA 3 format error: Physics event with block size 0");
411 return HED_ERR;
412 }
413 try {
414 tbank.Fill(evbuffer + 2, block_size, fMap->getTSROC());
415 }
416 catch( const coda_format_error& e ) {
417 Error(here, "CODA 3 format error: %s", e.what() );
418 return HED_ERR;
419 }
420
421 // Copy pertinent data to member variables for faster retrieval
422 LoadTrigBankInfo(0); // Load data for first event in block
423
424 return HED_OK;
425}
426
427//_____________________________________________________________________________
428Int_t CodaDecoder::BankInfo::Fill( // NOLINT(misc-no-recursion)
429 const UInt_t* evbuf, UInt_t pos, UInt_t len )
430{
431 if( !evbuf ) {
432 return status_ = kBadArg;
433 }
434 if( len < 3 ) { // Expect at least 1 bank header + 1 payload word
435 return status_ = kBadArg;
436 }
437 // Bank length
438 const auto* p = evbuf + pos;
439 UInt_t blen = *p; // number of 32-bit words following this length word
440 if( blen < 2 || blen + 1 > len ) {
441 len_ = blen;
442 return status_ = kBadLen;
443 }
444
445 // Bank header
446 ++p;
447 UInt_t tag = (*p & 0xFFFF0000) >> 16;
448 UInt_t npad = (*p & 0x0000C000) >> 14;
449 UInt_t dtyp = (*p & 0x00003F00) >> 8;
450 UInt_t blksz = (*p & 0x000000FF);
451 // First word of payload
452 ++p;
453 status_ = kOK;
454 switch( dtyp ) {
455 case 0x08: // float64_t (double)
456 case 0x09: // int64_t
457 case 0x0A: // uint64_t
458 case 0x00: // 32-bit unknown
459 case 0x01: // uint32_t
460 case 0x02: // float32_t
461 case 0x0B: // int32_t
462 if( npad != 0 ) {
463 npad_ = npad;
465 }
466 break;
467
468 case 0x04: // int16_t
469 case 0x05: // uint16_t
470 if( npad != 0 && npad != 2 ) {
471 npad_ = npad;
473 }
474 break;
475
476 case 0x03: // int8_t (char)
477 case 0x06: // int8_t (signed char)
478 case 0x07: // uint8_t (unsigned char)
479 break;
480
481 case 0x10: // Bank
482 if( otag_ == 0 )
483 otag_ = tag;
484 return Fill(evbuf, pos+2, blen-1);
485 break;
486
487 default: // Segments, composite, etc. not yet supported
488 dtyp_ = dtyp;
489 return status_ = kUnsupType;
490 }
491 pos_ = pos+2;
492 len_ = blen-1;
493 tag_ = tag;
494 dtyp_ = dtyp;
495 npad_ = npad;
496 blksz_ = blksz;
497 return status_;
498}
499
500//_____________________________________________________________________________
502{
503 switch( status_ ) {
504 case kOK:
505 return "OK";
506 case kBadArg:
507 return "Bad argument";
508 case kBadLen:
509 return "Invalid length";
510 case kBadPad:
511 return "Invalid padding size";
512 case kUnsupType:
513 return "Unsupported data type";
514 }
515 // Not reached
516 assert(false);
517 return "Unknown error";
518}
519
520//_____________________________________________________________________________
522{
523 static const char* typtxt[] = {
524 "32-bit unknown",
525 "uint32_t",
526 "float",
527 "char",
528 "int16_t",
529 "uint16_t",
530 "int8_t",
531 "uint8_t",
532 "double",
533 "int64_t",
534 "uint64_t",
535 "int32_t",
536 "TAGSEGMENT",
537 "SEGMENT",
538 "BANK",
539 "Composite",
540 "BANK"
541 };
542 if( dtyp_ <= 0x10 )
543 return typtxt[dtyp_];
544 if( dtyp_ == 0x20 )
545 return "SEGMENT";
546 if( dtyp_ == 0x21 )
547 return "Hollerit";
548 if( dtyp_ == 0x22 )
549 return "N value";
550 return "Unknown";
551}
552
553//_____________________________________________________________________________
555{
556 switch( dtyp_ ) {
557 case 0x08: // float64_t (double)
558 case 0x09: // int64_t
559 case 0x0A: // uint64_t
560 return k64bit;
561 case 0x00: // 32-bit unknown
562 case 0x01: // uint32_t
563 case 0x02: // float32_t
564 case 0x0B: // int32_t
565 return k32bit;
566 case 0x04: // int16_t
567 case 0x05: // uint16_t
568 return k16bit;
569 case 0x03: // int8_t (char)
570 case 0x06: // int8_t (signed char)
571 case 0x07: // uint8_t (unsigned char)
572 return k8bit;
573 default:
574 return kUndef;
575 }
576}
577
578//_____________________________________________________________________________
580{
581 switch( dtyp_ ) {
582 case 0x02: // float32_t (float)
583 case 0x08: // float64_t (double)
584 return kFloat;
585 default:
586 return kInteger;
587 }
588}
589
590//_____________________________________________________________________________
592{
593 switch( dtyp_ ) {
594 case 0x02: // float32_t
595 case 0x04: // int16_t
596 case 0x06: // int8_t (signed char)
597 case 0x08: // float64_t (double)
598 case 0x09: // int64_t
599 case 0x0B: // int32_t
600 return kSigned;
601 case 0x01: // uint32_t
602 case 0x05: // uint16_t
603 case 0x07: // uint8_t (unsigned char)
604 case 0x0A: // uint64_t
605 return kUnsigned;
606 case 0x00: // 32-bit unknown
607 case 0x03: // int8_t (char)
608 default:
609 return kUnknown;
610 }
611}
612
613
614//_____________________________________________________________________________
616{
617 // Decode DAQ configuration event. This is usually a dump of several
618 // database files, one segment of type string per file.
619 // Each such segment is saved as a (longish) string internally.
620 // Also parses the VTP configuration file (the first of the strings)
621 // into key/value pairs.
622
623 const char* const here = "CodaDecoder::daqConfigDecode";
624
625 if( !evbuf )
626 return HED_FATAL;
627 auto* cfg = DAQInfoExtra::GetFrom(fExtra);
628 if( !cfg )
629 return HED_ERR;
630 size_t nbefore = cfg->strings.size();
631
632#define CFGEVT1 Decoder::DAQCONFIG_FILE1
633#define CFGEVT2 Decoder::DAQCONFIG_FILE2
634 assert(bank_tag == CFGEVT1 || bank_tag == CFGEVT2); // else bug in LoadEvent
635 if( (bank_tag != CFGEVT1 && bank_tag != CFGEVT2) ) {
636 Error(here, "Invalid bank tag word %#x in event type %u",
637 *(evbuf + 1), event_type);
638 return HED_ERR;
639 }
640 UInt_t pos = 0;
641 while( pos < event_length ) {
642 auto bankinfo = GetBank(evbuf, pos, event_length);
643 if( bankinfo.status_ != BankInfo::kOK ) {
644 Error( here, "Bank decoding error %s", bankinfo.Errtxt());
645 return HED_ERR;
646 }
647 pos = bankinfo.pos_;
648 auto len = bankinfo.len_;
649 assert(pos + len <= event_length);
650 if( bankinfo.GetDataSize() == BankInfo::k8bit ) {
651 const auto* c = reinterpret_cast<const char*>(evbuf + pos);
652 cfg->strings.emplace_back(c, c + 4 * bankinfo.len_ - bankinfo.npad_);
653 } else {
654 Warning(here, "Unsupported data type %#x in event type %u",
655 bankinfo.dtyp_, event_type);
656 }
657 pos += bankinfo.len_;
658 }
659 // Parse first string to key/value pairs
660 const size_t iparse = 0;
661 if( iparse >= nbefore )
662 cfg->parse(0);
663
664 return HED_OK;
665}
666
667//_____________________________________________________________________________
668void CodaDecoder::debug_print( const UInt_t* evbuffer ) const
669{
670 // checks of ET-inserted data
671 Int_t print_it=0;
672
673 switch( event_type ) {
674
675 case EPICS_EVTYPE:
676 cout << "EPICS data "<<endl;
677 print_it=1;
678 break;
679 case PRESCALE_EVTYPE:
680 cout << "Prescale data "<<endl;
681 print_it=1;
682 break;
683 case DAQCONFIG_FILE1:
684 cout << "DAQ config file 1 "<<endl;
685 print_it=1;
686 break;
687 case DAQCONFIG_FILE2:
688 cout << "DAQ config file 2 "<<endl;
689 print_it=1;
690 break;
691 case SCALER_EVTYPE:
692 cout << "LHRS scaler event "<<endl;
693 print_it=1;
694 break;
695 case SBSSCALER_EVTYPE:
696 cout << "SBS scaler event "<<endl;
697 print_it=1;
698 break;
699 case HV_DATA_EVTYPE:
700 cout << "High voltage data event "<<endl;
701 print_it=1;
702 break;
703 default:
704 // something else ?
705 cout << endl << "--- Special event type " << event_type << endl << endl;
706 }
707 if(print_it) {
708 char *cbuf = (char *)evbuffer; // These are character data
709 size_t elen = sizeof(int)*(evbuffer[0]+1);
710 cout << "Dump of event buffer . Len = "<<elen<<endl;
711 // This dump will look exactly like the text file that was inserted.
712 for (size_t ii=0; ii<elen; ii++) cout << cbuf[ii];
713 }
714}
715
716//_____________________________________________________________________________
718{
719 // Pretty-print bank info in 'bankdat'.
720
721 // Sort banks by ROC, then position in buffer
722 auto banks = bankdat;
723 std::sort(ALL(banks), []( const BankDat_t& a, const BankDat_t& b ) -> bool {
724 if( (a.key >> 16) < (b.key >> 16) )
725 return true;
726 else if( (a.key >> 16) > (b.key >> 16) )
727 return false;
728 return a.pos < b.pos;
729 });
730
731 UInt_t sum = 0;
732 cout << "Banks found (event " << event_num << "):" << endl;
733 cout << " roc bank pos len" << endl;
734 for( const auto& b : banks ) {
735 UInt_t bank = b.key & 0xFFFF;
736 UInt_t roc = b.key >> 16;
737 cout << dec << setw(4) << roc
738 << setw(6) << bank
739 << setw(8) << b.pos
740 << setw(8) << b.len
741 << endl;
742 sum += b.len;
743 }
744 cout << "Sum" << setw(23) << sum << endl;
745}
746
747//_____________________________________________________________________________
748uint32_t CodaDecoder::TBOBJ::Fill( const uint32_t* evbuffer,
749 uint32_t blkSize, uint32_t tsroc )
750{
751 if( blkSize == 0 )
752 throw std::invalid_argument("CODA block size must be > 0");
753 start = evbuffer;
754 blksize = blkSize;
755 len = evbuffer[0] + 1;
756 tag = (evbuffer[1] & 0xffff0000) >> 16;
757 nrocs = evbuffer[1] & 0xff;
758
759 const uint32_t* p = evbuffer + 2;
760 // Segment 1:
761 // uint64_t event_number
762 // uint64_t run_info if withRunInfo
763 // uint64_t time_stamp[blkSize] if withTimeStamp
764 {
765 uint32_t slen = *p & 0xffff;
766 if( slen != 2*(1 + (withRunInfo() ? 1 : 0) + (withTimeStamp() ? blkSize : 0)))
767 throw coda_format_error("Invalid length for Trigger Bank seg 1");
768 const auto* q = (const uint64_t*) (p + 1);
769 evtNum = *q++;
770 runInfo = withRunInfo() ? *q++ : 0;
771 evTS = withTimeStamp() ? q : nullptr;
772 p += slen + 1;
773 }
774 if( p-evbuffer >= len )
775 throw coda_format_error("Past end of bank after Trigger Bank seg 1");
776
777 // Segment 2:
778 // uint16_t event_type[blkSize]
779 // padded to next 32-bit boundary
780 {
781 uint32_t slen = *p & 0xffff;
782 if( slen != (blkSize-1)/2 + 1 )
783 throw coda_format_error("Invalid length for Trigger Bank seg 2");
784 evType = (const uint16_t*) (p + 1);
785 p += slen + 1;
786 }
787
788 // nroc ROC segments containing timestamps and optional
789 // data like trigger latch bits:
790 // struct {
791 // uint64_t roc_time_stamp; // Lower 48 bits only seem to be the time.
792 // uint32_t roc_trigger_bits; // Optional. Typically only in TSROC.
793 // } roc_segment[blkSize];
794 TSROC = nullptr;
795 tsrocLen = 0;
796 for( uint32_t i = 0; i < nrocs; ++i ) {
797 if( p-evbuffer >= len )
798 throw coda_format_error("Past end of bank while scanning trigger bank segments");
799 uint32_t slen = *p & 0xffff;
800 uint32_t rocnum = (*p & 0xff000000) >> 24;
801 if( rocnum == tsroc ) {
802 TSROC = p + 1;
803 tsrocLen = slen;
804 break;
805 }
806 p += slen + 1;
807 }
808
809 return len;
810}
811
812//_____________________________________________________________________________
814{
815 // Check if roc/slot belongs to a bank. If so, check if this bank
816 // has been found in the current event. Return pointer to the corresponding
817 // bank data if found, otherwise nullptr.
818 // Internal function used by bank_decode() and LoadFromMultiBlock().
819
820 Int_t bank = fMap->getBank(roc, slot);
821 assert(bank < MAXBANK); // bank numbers are uint16_t
822 if( bank < 0 )
823 return nullptr;
824 UInt_t key = (roc << 16) + bank;
825 auto theBank = find(ALL(bankdat), key);
826 if( theBank == bankdat.end() )
827 // Bank defined in crate map but not present in this event
828 return nullptr;
829 return &(*theBank);
830}
831
832//_____________________________________________________________________________
834{
835 // LoadFromMultiBlock : This assumes some slots are in multiblock mode.
836 // For modules that are in multiblock mode, the next event is loaded.
837 // For other modules not in multiblock mode (e.g. scalers) or other data
838 // (e.g. flags) the data remain "stale" until the next block of events.
839
840 if( !fMultiBlockMode || fBlockIsDone ) {
841 Error("CodaDecoder::LoadFromMultiBlock",
842 "Not in multiblock mode or block already done. Logic error. "
843 "Call expert.");
844 return HED_ERR;
845 }
846 if( first_decode || fNeedInit ) {
847 Error("CodaDecoder::LoadFromMultiBlock",
848 "Uninitialized while processing event blocks. Logic error. "
849 "Call expert.");
850 return HED_ERR;
851 }
852
853 for( auto i : fSlotClear ) {
854 auto* mod = crateslot[i]->GetModule();
855 if( mod && mod->IsMultiBlockMode() )
856 crateslot[i]->clearEvent();
857 }
858
859 for( UInt_t i = 0; i < nroc; i++ ) {
860 UInt_t roc = irn[i];
861 for( auto slot : fMap->GetUsedSlots(roc) ) {
862 assert(fMap->slotUsed(roc, slot));
863 // Skip modules in banks if the bank is not present in the current event
864 if( fMap->getBank(roc, slot) >= 0 && !CheckForBank(roc, slot) )
865 continue;
866 auto* sd = crateslot[idx(roc, slot)].get();
867 auto* mod = sd->GetModule();
868 if( !mod )
869 continue;
870 // for CODA3, cross-check the block size (found in trigger bank and, separately, in modules)
871 if( fDataVersion > 2 ) {
872 auto module_blksz = mod->GetBlockSize();
873 if( fDebugFile )
874 *fDebugFile << "cross chk blk size " << roc << " " << slot << " "
875 << module_blksz << " " << block_size << endl;
876 if( module_blksz != block_size ) {
877 cerr << "ERROR::CodaDecoder:: inconsistent block size between trig. bank and module "
878 << " in roc/slot = " << roc << "/" << slot << " (\"" << mod->GetName() << "\"), "
879 << "trigger bank = " << block_size << ", module = " << module_blksz
880 << ". Ignoring module for this event."
881 << endl;
882 continue;
883 }
884 }
885 if( mod->IsMultiBlockMode() ) {
886 sd->LoadNextEvBuffer();
887 // Presumes that all modules have the same global block size (see check above)
888 if( sd->BlockIsDone() )
889 fBlockIsDone = true;
890 }
891 // else {
892 // Not really sure what to do with a module that isn't in multi-block mode
893 // while others are ...
894 // }
895 }
896 }
897 return HED_OK;
898}
899
900//_____________________________________________________________________________
902 UInt_t ipt, UInt_t istop )
903{
904 // Decode a Readout controller
905 assert( evbuffer && fMap );
906 if( roc >= MAXROC ) {
907 ostringstream ostr;
908 ostr << "ROC number " << roc << " out of range";
909 throw logic_error(ostr.str());
910 }
911 if( istop >= event_length )
912 throw logic_error("Stop point exceeds event length (?!)");
913
914 synchmiss = false;
915 synchextra = false;
916 buffmode = false;
917 fBlockIsDone = false;
918
919 if( ipt+1 >= istop )
920 return HED_OK;
921
922 if( fDoBench ) fBench->Begin("roc_decode");
923 Int_t retval = HED_OK;
924 try {
925 UInt_t Nslot = fMap->getNslot(roc);
926 if( Nslot == 0 || Nslot == kMaxUInt ) {
927 // Found data for a ROC which is not defined in the crate map.
928 // Just ignore it. Do debug log occurrences and warn user once about it.
929 if( fDebugFile ) {
930 *fDebugFile << "CodaDecode:: roc_decode:: WARNING: Undefined ROC # "
931 << dec << roc << ", event " << event_num << endl;
932 }
933 UInt_t ibit = roc;
934 if( !fMsgPrinted.TestBitNumber(ibit) ) {
935 Warning("roc_decode", "ROC %d found in data but NOT in cratemap. "
936 "Ignoring it.", roc);
938 }
939 return HED_OK;
940 }
941
942 if( fDebugFile )
943 *fDebugFile << "CodaDecode:: roc_decode:: roc# " << dec << roc
944 << " nslot " << Nslot << endl;
945
946 assert(fMap->GetUsedSlots(roc).size() == Nslot); // else bug in THaCrateMap
947
948 // Build the to-do list of slots based on the contents of the crate map
949 vector<pair<UInt_t,THaSlotData*>> slots_todo; slots_todo.reserve(Nslot);
950 for( auto slot : fMap->GetUsedSlots(roc) ) {
951 assert(fMap->slotUsed(roc, slot)); // else bug in THaCrateMap
952 // ignore bank structure slots; they are decoded with bank_decode
953 if( fMap->getBank(roc, slot) >= 0 )
954 continue;
955 slots_todo.emplace_back(slot,crateslot[idx(roc,slot)].get());
956 }
957 // Quit if nothing to do (all bank structure slots, decoded in bank_decode)
958 if( slots_todo.empty() )
959 return HED_OK;
960
961 // higher slot # appears first in multiblock mode
962 // the decoding order improves efficiency
963 bool is_fastbus = fMap->isFastBus(roc);
964 if( is_fastbus )
965 std::reverse( ALL(slots_todo) );
966
967 // Crawl through this ROC's data block. Each word is tested against all the
968 // defined modules (slots) in the crate for a match with the expected slot
969 // header. If a match is found, this word is the slot header. Zero or more
970 // words following the slot header represent the data for the slot. These
971 // data are loaded into the module's internal storage, and the corresponding
972 // slot is removed from the search list. The search for the remaining slots
973 // then resumes at the first word after the data.
974 const UInt_t* p = evbuffer + ipt; // Points to ROC ID word (1 before data)
975 const UInt_t* pstop = evbuffer + istop; // Points to last word of data
976 UInt_t nextidx = 0;
977
978 while( p++ < pstop ) {
979 if( fDebugFile )
980 *fDebugFile << "CodaDecode::roc_decode:: evbuff " << (p - evbuffer)
981 << " " << hex << *p << dec << endl;
982
983 if( is_fastbus && LoadIfFlagData(p) )
984 continue;
985
986 bool update_nextidx = true;
987 for( UInt_t i = nextidx; i < slots_todo.size(); ++i ) {
988 UInt_t slot = slots_todo[i].first;
989 // ignore bank structure slots; they are decoded with bank_decode
990 if( slot == kMaxUInt )
991 continue;
992 auto* sd = slots_todo[i].second;
993
994 if( fDebugFile )
995 *fDebugFile << "roc_decode:: slot logic " << roc << " " << slot;
996
997 // Check if data word at p belongs to the module at the current slot
998 UInt_t nwords = sd->LoadIfSlot(p, pstop);
999
1000 if( sd->IsMultiBlockMode() )
1001 fMultiBlockMode = true;
1002 if( sd->BlockIsDone() )
1003 fBlockIsDone = true;
1004
1005 if( fDebugFile )
1006 *fDebugFile << "CodaDecode:: roc_decode:: after LoadIfSlot "
1007 << p + ((nwords > 0) ? nwords - 1 : 0) << " " << pstop
1008 << " " << hex << *p << " " << dec << nwords << endl;
1009
1010 if( nwords > 0 ) {
1011 if( fDebugFile )
1012 *fDebugFile << "CodaDecode:: slot " << slot << " is DONE "
1013 << nwords << endl;
1014 // Data for this slot found and loaded. Advance to next data block.
1015 p += nwords-1;
1016 slots_todo[i].first = kMaxUInt; // Mark slot as done
1017 if( update_nextidx )
1018 nextidx = i+1;
1019 break;
1020 } else if( update_nextidx ) {
1021 nextidx = i;
1022 update_nextidx = false;
1023 }
1024 }
1025 } //end while(p++<pstop)
1026 }
1027 catch( const exception& e ) {
1028 cerr << e.what() << endl;
1029 retval = HED_ERR;
1030 }
1031
1032 if( fDoBench ) fBench->Stop("roc_decode");
1033 return retval;
1034}
1035
1036//_____________________________________________________________________________
1038 UInt_t ipt, UInt_t istop )
1039{
1040 // Split a roc into banks, if using bank structure
1041 // Then loop over slots and decode it from a bank if the slot
1042 // belongs to a bank.
1043 assert( evbuffer && fMap );
1044 if( roc >= MAXROC ) {
1045 ostringstream ostr;
1046 ostr << "ROC number " << roc << " out of range";
1047 throw logic_error(ostr.str());
1048 }
1049 if( istop >= event_length )
1050 throw logic_error("Stop point exceeds event length (?!)");
1051
1052 if (!fMap->isBankStructure(roc))
1053 return HED_OK;
1054
1055 if( fDoBench ) fBench->Begin("bank_decode");
1056 if (fDebugFile)
1057 *fDebugFile << "CodaDecode:: bank_decode ... " << roc << " " << ipt
1058 << " " << istop << endl;
1059
1060 fBlockIsDone = false;
1061 UInt_t pos = ipt+1; // ipt points to ROC ID word
1062 while (pos < istop) {
1063 UInt_t len = evbuffer[pos];
1064 UInt_t head = evbuffer[pos+1];
1065 UInt_t bank = head >> 16;
1066 if( fDebugFile )
1067 *fDebugFile << "bank 0x" << hex << bank << " head 0x" << head
1068 << " len 0x" << len << dec << endl;
1069
1070 UInt_t key = (roc << 16) + bank;
1071 // Bank numbers only appear once, else bug in CODA or corrupt input
1072 assert( find(ALL(bankdat), key) == bankdat.end());
1073 // If len == 0, bug in CODA or corrupt input
1074 assert( len > 0 );
1075 if( len > 0 )
1076 bankdat.emplace_back(key, pos + 2, len - 1);
1077 pos += len+1;
1078 }
1079
1080 for( auto slot : fMap->GetUsedSlots(roc) ) {
1081 assert(fMap->slotUsed(roc,slot));
1082 Int_t bank = fMap->getBank(roc, slot);
1083 auto* theBank = CheckForBank(roc, slot);
1084 if( !theBank )
1085 continue; // skip non-bank mode modules and banks not found in present event
1086 if (fDebugFile)
1087 *fDebugFile << "CodaDecoder::bank_decode: loading bank "
1088 << roc << " " << slot << " " << bank << " "
1089 << theBank->pos << " " << theBank->len << endl;
1090 auto* sd = crateslot[idx(roc, slot)].get();
1091 sd->LoadBank(evbuffer, theBank->pos, theBank->len);
1092 if( sd->IsMultiBlockMode() )
1093 fMultiBlockMode = true;
1094 if( sd->BlockIsDone() )
1095 fBlockIsDone = true;
1096 }
1097
1098 if( fDoBench ) fBench->Stop("bank_decode");
1099 return HED_OK;
1100}
1101
1102//_____________________________________________________________________________
1104 UInt_t offset, UInt_t num ) const
1105{
1106 if( fDebug > 1 )
1107 cout << "Into FillBankData v1 " << dec << roc << " " << bank << " "
1108 << offset << " " << num << endl;
1109 if( fDebugFile )
1110 *fDebugFile << "Check FillBankData " << roc << " " << bank << endl;
1111
1112 if( roc >= MAXROC )
1113 return HED_ERR;
1114 UInt_t jk = (roc << 16) + bank;
1115 auto bankInfo = find(ALL(bankdat), jk);
1116 if( bankInfo == bankdat.end() ) {
1117 cerr << "FillBankData::ERROR: bankdat not in current event "<<endl;
1118 return HED_ERR;
1119 }
1120 UInt_t pos = bankInfo->pos;
1121 UInt_t len = bankInfo->len;
1122 if( fDebug > 1 )
1123 cout << "FillBankData: pos, len " << pos << " " << len << endl;
1124 if( fDebugFile )
1125 *fDebugFile << "FillBankData pos, len " << pos << " " << len << endl;
1126 assert( pos < event_length && pos+len <= event_length ); // else bug in bank_decode
1127 if( offset+2 > len )
1128 return HED_ERR;
1129 if( num > len )
1130 num = len;
1131 UInt_t ilo = pos + offset;
1132 assert( ilo < event_length ); // else offset not correctly checked above
1133 UInt_t ihi = pos + offset + num;
1134 if( ihi > event_length )
1135 ihi = event_length;
1136 memcpy(rdat, buffer+ilo, ihi-ilo);
1137
1138 return HED_OK;
1139}
1140
1141//_____________________________________________________________________________
1143{
1144 // Need to generalize this ... too Hall A specific
1145 //
1146 // Looks for buffer mode and synch problems. The latter are recoverable
1147 // but extremely rare, so I haven't bothered to write recovery a code yet,
1148 // but at least this warns you.
1149 // Returns 0 if no flag data detected, != 0 otherwise
1150 assert( evbuffer );
1151 UInt_t word = *evbuffer;
1152 if (fDebugFile)
1153 *fDebugFile << "CodaDecode:: TestBit on : Flag data ? "
1154 << hex << word << dec << endl;
1155 UInt_t stdslot = word >> 27;
1156 if( stdslot > 0 && stdslot < MAXSLOT_FB )
1157 return 0; // non-flag data
1158
1159 Int_t ret = 1;
1160 UInt_t upword = word >> 16; // upper 16 bits
1161 word &= 0xffff; // lower 16 bits
1162 switch( upword ) {
1163 case 0xdc00:
1164 if( word == 0x00ff ) // word == 0xdc0000ff
1165 synchmiss = true;
1166 break;
1167 case 0xdcfe:
1168 synchextra = true;
1169 if( fDebug > 0 ) {
1170 UInt_t slot = word >> 11;
1171 UInt_t nhit = word & 0x7ff;
1172 cout << "CodaDecoder: WARNING: Fastbus slot ";
1173 cout << slot << " has extra hits " << nhit << endl;
1174 }
1175 break;
1176 case 0xfaaa:
1177 break;
1178 case 0xfabc:
1179 if( fDebug > 0 && (synchmiss || synchextra) ) {
1180 UInt_t datascan = *(evbuffer+3);
1181 cout << "CodaDecoder: WARNING: Synch problems !" << endl;
1182 cout << "Data scan word 0x" << hex << datascan << dec << endl;
1183 }
1184 break;
1185 case 0xfabb:
1186 buffmode = false;
1187 break;
1188 case 0xfafb:
1189 if( (word >> 8) == 0xbf ) { // word & 0xffffff00 == 0xfafbbf00
1190 buffmode = true;
1191 // synchflag = word&0xff; // not used
1192 }
1193 break;
1194 default:
1195 break;
1196 }
1197 return ret;
1198}
1199
1200
1201//_____________________________________________________________________________
1203
1204// The (old) decoding of CODA 2.* event buffer to find pointers and lengths of ROCs
1205// ROC = ReadOut Controller, synonymous with "crate".
1206
1207 assert( evbuffer );
1208#ifdef FIXME
1209 if( fDoBench ) fBench->Begin("physics_decode");
1210#endif
1211 Int_t status = HED_OK;
1212
1213 // The following line is not meaningful for CODA3
1214 if( (evbuffer[1]&0xffff) != 0x10cc ) std::cout<<"Warning, header error"<<std::endl;
1215 if( event_type > MAX_PHYS_EVTYPE ) std::cout<<"Warning, Event type makes no sense"<<std::endl;
1216 for_each(ALL(rocdat), []( RocDat_t& ROC ) { ROC.clear(); });
1217 // Set pos to start of first ROC data bank
1218 UInt_t pos = evbuffer[2]+3; // should be 7
1219 nroc = 0;
1220 while( pos+1 < event_length && nroc < MAXROC ) {
1221 UInt_t len = evbuffer[pos];
1222 UInt_t iroc = (evbuffer[pos+1]&0xff0000)>>16;
1223 if( iroc>=MAXROC ) {
1224#ifdef FIXME
1225 if(fDebug>0) {
1226 cout << "ERROR in EvtTypeHandler::FindRocs "<<endl;
1227 cout << " illegal ROC number " <<dec<<iroc<<endl;
1228 }
1229 if( fDoBench ) fBench->Stop("physics_decode");
1230#endif
1231 return HED_ERR;
1232 }
1233 // Save position and length of each found ROC data block
1234 rocdat[iroc].pos = pos;
1235 rocdat[iroc].len = len;
1236 irn[nroc++] = iroc;
1237 pos += len+1;
1238 }
1239
1240 if (fDebugFile) {
1241 *fDebugFile << "CodaDecode:: num rocs "<<dec<<nroc<<endl;
1242 for( UInt_t i = 0; i < nroc; i++ ) {
1243 UInt_t iroc = irn[i];
1244 *fDebugFile << " CodaDecode:: roc num "<<iroc<<" pos "<<rocdat[iroc].pos<<" len "<<rocdat[iroc].len<<endl;
1245 }
1246 }
1247
1248 return status;
1249
1250}
1251
1252//_____________________________________________________________________________
1254
1255// Find the pointers and lengths of ROCs in CODA3
1256// ROC = ReadOut Controller, synonymous with "crate".
1257// Earlier we had decoded the Trigger Bank in method trigBankDecode.
1258// This filled the tbank structure.
1259// For CODA3, the ROCs start after the Trigger Bank.
1260
1261 UInt_t pos = 2 + tbank.len;
1262 nroc=0;
1263
1264 for_each(ALL(rocdat), []( RocDat_t& ROC ) { ROC.clear(); });
1265
1266 while (pos+1 < event_length) {
1267 UInt_t len = evbuffer[pos]; /* total Length of ROC Bank data */
1268 UInt_t iroc = (evbuffer[pos+1]&0x0fff0000)>>16; /* ID of ROC is 12 bits*/
1269 if( iroc >= MAXROC ) {
1270 return HED_ERR;
1271 }
1272 rocdat[iroc].len = len;
1273 rocdat[iroc].pos = pos;
1274 irn[nroc] = iroc;
1275 pos += len+1;
1276 nroc++;
1277 }
1278
1279 /* Sanity check: Check if number of ROCs matches */
1280 if(nroc != tbank.nrocs) {
1281 printf(" ****ERROR: Trigger and Physics Block sizes do not match (%d != %d)\n",nroc,tbank.nrocs);
1282// If you are reading a data file originally written with CODA 2 and then
1283// processed (written out) with EVIO 4, it will segfault. Do as it says below.
1284 printf("This might indicate a file written with EVIO 4 that was a CODA 2 file\n");
1285 printf("Try analyzer->SetCodaVersion(2) in the analyzer script.\n");
1286 return HED_ERR;
1287 }
1288
1289 if (fDebugFile) { // debug
1290
1291 *fDebugFile << endl << " FindRocsCoda3 :: Starting Event number = " << dec << tbank.evtNum;
1292 *fDebugFile << endl;
1293 *fDebugFile << " Trigger Bank Len = "<<tbank.len<<" words "<<endl;
1294 *fDebugFile << " There are "<<nroc<<" ROCs"<<endl;
1295 for( UInt_t i = 0; i < nroc; i++ ) {
1296 *fDebugFile << " ROC ID = "<<irn[i]<<" pos = "<<rocdat[irn[i]].pos
1297 <<" Len = "<<rocdat[irn[i]].len<<endl;
1298 }
1299 *fDebugFile << " Trigger BANK INFO, TAG = "<<hex<<tbank.tag<<dec<<endl;
1300 *fDebugFile << " start "<<hex<<tbank.start<<" blksize "<<dec<<tbank.blksize
1301 <<" len "<<tbank.len<<" tag "<<tbank.tag<<" nrocs "<<tbank.nrocs<<" evtNum "<<tbank.evtNum;
1302 *fDebugFile << endl;
1303 *fDebugFile << " Event # Time Stamp Event Type"<<endl;
1304 for( UInt_t i = 0; i < tbank.blksize; i++ ) {
1305 if( tbank.evTS ) {
1306 *fDebugFile << " "<<dec<<tbank.evtNum+i<<" "<<tbank.evTS[i]<<" "<<tbank.evType[i];
1307 *fDebugFile << endl;
1308 } else {
1309 *fDebugFile << " "<<tbank.evtNum+i<<"(No Time Stamp) "<<tbank.evType[i];
1310 *fDebugFile << endl;
1311 }
1312 *fDebugFile << endl<<endl;
1313 }
1314 }
1315
1316 return 1;
1317
1318}
1319
1320//_____________________________________________________________________________
1321// To initialize the THaSlotData member on first call to decoder
1323{
1324 // Initialize all slots defined in the crate map as "used".
1325 //
1326 // This defeats the clever on-demand mechanism of the original decoder,
1327 // which would only allocate resources for a crate/slot if data for that
1328 // slot were actually encountered in the data stream. Now, resources
1329 // are allocated for everything, whether actually active or not.
1330 // The advantage is that one can configure the module objects associated
1331 // with each crate/slot. Of course, that could be done via database
1332 // parameters as well. Presumably the resource waste is minor on today's
1333 // computers, so fine.
1334
1335 if(!fMap) return HED_ERR;
1336
1337 try {
1338 for( auto iroc : fMap->GetUsedCrates() ) {
1339 assert(fMap->crateUsed(iroc));
1340 for( auto islot : fMap->GetUsedSlots(iroc) ) {
1341 assert(fMap->slotUsed(iroc, islot));
1342 makeidx(iroc, islot);
1343 if( fDebugFile )
1344 *fDebugFile << "CodaDecode:: crate, slot " << iroc << " " << islot
1345 << " Dev type = " << crateslot[idx(iroc, islot)]->devType()
1346 << endl;
1347 }
1348 }
1349 }
1350 catch( const exception& e ) {
1351 cerr << e.what() << endl;
1352 return HED_FATAL;
1353 }
1354
1355 if (fDebugFile)
1356 *fDebugFile << "CodaDecode:: fNSlotUsed "<<fSlotUsed.size()<<endl;
1357
1358 // Update lists of used/clearable slots in case crate map changed
1359 return THaEvData::init_slotdata();
1360}
1361
1362
1363//_____________________________________________________________________________
1364void CodaDecoder::dump(const UInt_t* evbuffer) const
1365{
1366 if( !evbuffer ) return;
1367 if ( !fDebugFile ) return;
1368 *fDebugFile << "\n\n Raw Data Dump " << endl;
1369 *fDebugFile << "\n Event number " << dec << event_num;
1370 *fDebugFile << " length " << event_length << " type " << event_type << endl;
1371 UInt_t ipt = 0;
1372 for( UInt_t j = 0; j < (event_length/5); j++ ) {
1373 *fDebugFile << dec << "\n evbuffer[" << ipt << "] = ";
1374 for( UInt_t k = j; k < j+5; k++ ) {
1375 *fDebugFile << hex << evbuffer[ipt++] << " ";
1376 }
1377 }
1378 if (ipt < event_length) {
1379 *fDebugFile << dec << "\n evbuffer[" << ipt << "] = ";
1380 for( UInt_t k = ipt; k < event_length; k++ ) {
1381 *fDebugFile << hex << evbuffer[ipt++] << " ";
1382 }
1383 *fDebugFile << endl;
1384 }
1385 *fDebugFile<<dec<<endl;
1386}
1387
1388//_____________________________________________________________________________
1390{
1391 if (!fMap || !fDebugFile) return;
1392 *fDebugFile<< "Comparing cratemap rocs with found rocs"<<endl;
1393 for( UInt_t i = 0; i < nroc; i++ ) {
1394 UInt_t iroc = irn[i];
1395 if( !fMap->crateUsed(iroc) ) {
1396 *fDebugFile << "ERROR CompareRocs:: roc " << iroc << " in data but not in map" << endl;
1397 }
1398 }
1399 for( UInt_t iroc1 = 0; iroc1 < MAXROC; iroc1++ ) {
1400 if( !fMap->crateUsed(iroc1) ) continue;
1401 Bool_t ifound = false;
1402 for( UInt_t i=0; i<nroc; i++ ) {
1403 UInt_t iroc2 = irn[i];
1404 if (iroc1 == iroc2) {
1405 ifound = true;
1406 break;
1407 }
1408 }
1409 if (!ifound) *fDebugFile << "ERROR: CompareRocs: roc "<<iroc1<<" in cratemap but not found data"<<endl;
1410 }
1411}
1412
1413//_____________________________________________________________________________
1414void CodaDecoder::ChkFbSlot( UInt_t roc, const UInt_t* evbuffer, UInt_t ipt,
1415 UInt_t istop )
1416{
1417 const UInt_t* p = evbuffer+ipt; // Points to ROC ID word (1 before data)
1418 const UInt_t* pstop = evbuffer+istop; // Points to last word of data in roc
1419 while( p++ < pstop ) {
1420 UInt_t slot = *p >> 27; // A "self-reported" slot.
1421 if( slot == 0 || slot >= MAXSLOT_FB ) // Used for diagnostic data words
1422 continue;
1423 UInt_t index = MAXSLOT_FB*roc + slot;
1424 if( slot > 0 && index < MAXROCSLOT_FB )
1425 fbfound[index] = true;
1426 }
1427}
1428
1429//_____________________________________________________________________________
1431{
1432 // This checks the fastbus slots to see if slots are appearing in both the
1433 // data and the cratemap. If they appear in one but not the other, a warning
1434 // is issued, which usually means the cratemap is wrong.
1435 for( UInt_t iroc = 0; iroc < MAXROC; iroc++ ) {
1436 if( !fMap->isFastBus(iroc) ) continue;
1437 for( UInt_t islot = 0; islot < MAXSLOT_FB; islot++ ) {
1438 UInt_t index = MAXSLOT_FB * iroc + islot;
1439 bool inEvent = fbfound[index], inMap = fMap->slotUsed(iroc, islot);
1440 if( inEvent ) {
1441 if( inMap ) {
1442 if (fDebugFile)
1443 *fDebugFile << "FB slot in cratemap and in data. (good!). "
1444 << "roc = "<<iroc<<" slot = "<<islot<<endl;
1445 } else {
1446 if (fDebugFile)
1447 *fDebugFile << "FB slot in data, but NOT in cratemap (bad!). "
1448 << "roc = "<<iroc<<" slot = "<<islot<<endl;
1449 Warning("ChkFbSlots", "Fastbus module in (roc,slot) = (%d,%d) "
1450 "found in data but NOT in cratemap !", iroc, islot);
1451 }
1452 } else if( inMap ) {
1453 if (fDebugFile)
1454 *fDebugFile << "FB slot NOT in data, but in cratemap (bad!). "
1455 << "roc = "<<iroc<<" slot = "<<islot<<endl;
1456 // Why do we care? If the cratemap has info about additional hardware
1457 // that just wasn't read out by the DAQ, so what?
1458 //Warning("ChkFbSlots", "Fastbus module in (roc,slot) = = (%d,%d) "
1459 // "found in cratemap but NOT in data !", iroc, islot);
1460 }
1461 }
1462 }
1463}
1464
1465//_____________________________________________________________________________
1467{
1468 // Set run time and re-initialize crate map (and possibly other
1469 // database parameters) for the new time.
1470
1471 if( fRunTime == tloc )
1472 return;
1473 fRunTime = tloc;
1474 fNeedInit = true; // force re-init
1475}
1476
1477//_____________________________________________________________________________
1479{
1480 // Decodes prescale factors from either
1481 // TS_PRESCALE_EVTYPE(default) = PS factors
1482 // read from Trig. Super. registers (since 11/03)
1483 // - or -
1484 // PRESCALE_EVTYPE = PS factors from traditional
1485 // "prescale.dat" file.
1486
1487 assert( evbuffer );
1488 assert( event_type == TS_PRESCALE_EVTYPE ||
1490 const UInt_t HEAD_OFF1 = 2;
1491 const UInt_t HEAD_OFF2 = 4;
1492 static const char* const pstr[] = { "ps1", "ps2", "ps3", "ps4",
1493 "ps5", "ps6", "ps7", "ps8",
1494 "ps9", "ps10", "ps11", "ps12" };
1495 // TS registers -->
1497 // this is more authoritative
1498 for( UInt_t j = 0; j < 8; j++ ) {
1499 UInt_t k = j + HEAD_OFF1;
1500 UInt_t ps = 0;
1501 if( k < event_length ) {
1502 ps = evbuffer[k];
1503 if( psfact[j] != 0 && ps != psfact[j] ) {
1504 Warning("prescale_decode","Mismatch in prescale factor: "
1505 "Trig %u oldps %u TS_PRESCALE %d. Setting to TS_PRESCALE",
1506 j+1,psfact[j],ps);
1507 }
1508 }
1509 psfact[j]=ps;
1510 if (fDebug > 1)
1511 cout << "%% TS psfact "<<dec<<j<<" "<<psfact[j]<<endl;
1512 }
1513 }
1514 // "prescale.dat" -->
1515 else if( event_type == PRESCALE_EVTYPE ) {
1516 if( event_length <= HEAD_OFF2 )
1517 return HED_ERR; //oops, event too short?
1518 THaUsrstrutils sut;
1519 sut.string_from_evbuffer(evbuffer+HEAD_OFF2, event_length-HEAD_OFF2);
1520 for(Int_t trig=0; trig<MAX_PSFACT; trig++) {
1521 UInt_t ps = sut.getint(pstr[trig]);
1522 UInt_t psmax = 65536; // 2^16 for trig > 3
1523 if (trig < 4) psmax = 16777216; // 2^24 for 1st 4 trigs
1524 if (trig > 7) ps = 1; // cannot prescale trig 9-12
1525 ps = ps % psmax;
1526 if (psfact[trig]==kMaxUInt) // not read before
1527 psfact[trig] = ps;
1528 else if (ps != psfact[trig]) {
1529 Warning("prescale_decode","Mismatch in prescale factor: "
1530 "Trig %d oldps %d prescale.dat %d, Keeping old value",
1531 trig+1,psfact[trig],ps);
1532 }
1533 if (fDebug > 1)
1534 cout << "** psfact[ "<<trig+1<< " ] = "<<psfact[trig]<<endl;
1535 }
1536 }
1537
1538 // Ok in any case
1539 return HED_OK;
1540}
1541
1542//_____________________________________________________________________________
1544{
1545 // Decodes prescale factors from either
1546 // TS_PRESCALE_EVTYPE(default) = PS factors
1547 // This version is for CODA 3 data.
1548 // 0 means no prescaling, what we called "1" before.
1549 // -1 means the trigger is disabled. "infinite" prescale
1550 // otherwise the value is 2^(ps-1) + 1.
1551 // ps ..... prescale factor
1552 // 1 ....... 2
1553 // 2 ....... 3
1554 // 3 ....... 5
1555 // 5 ....... 17
1556 // 10 ....... 513
1557
1558 static const char* const here = "prescale_decode_coda3";
1559
1560 assert( evbuffer );
1561 assert( event_type == TS_PRESCALE_EVTYPE ||
1563 const UInt_t HEAD_OFF1 = 2;
1564 const UInt_t HEAD_OFF2 = 4;
1565 UInt_t super_big = 999999;
1566 static const char* const pstr[] = { "ps1", "ps2", "ps3", "ps4",
1567 "ps5", "ps6", "ps7", "ps8",
1568 "ps9", "ps10", "ps11", "ps12" };
1569 // TS registers -->
1570 // don't have these yet for CODA3. hmmm... that reminds me to do it.
1572 // this is more authoritative
1573 for( UInt_t j = 0; j < 8; j++ ) {
1574 UInt_t k = j + HEAD_OFF1;
1575 UInt_t ps = 0;
1576 if( k < event_length ) {
1577 ps = evbuffer[k];
1578 if( psfact[j] != 0 && ps != psfact[j] ) {
1579 Warning(here,"Mismatch in prescale factor: "
1580 "Trig %u oldps %u TS_PRESCALE %d. Setting to TS_PRESCALE",
1581 j+1,psfact[j],ps);
1582 }
1583 }
1584 psfact[j]=ps;
1585 if (fDebug > 1)
1586 cout << "%% TS psfact "<<dec<<j<<" "<<psfact[j]<<endl;
1587 }
1588 }
1589 // "prescale.dat" -->
1590 else if( event_type == PRESCALE_EVTYPE ) {
1591 if( event_length <= HEAD_OFF2 )
1592 return HED_ERR; //oops, event too short?
1593 THaUsrstrutils sut;
1594 sut.string_from_evbuffer(evbuffer+HEAD_OFF2, event_length-HEAD_OFF2);
1595
1596 for( Int_t trig = 0; trig < MAX_PSFACT; trig++ ) {
1597 long ps = sut.getSignedInt(pstr[trig]);
1598 if( ps == -1 ) {
1599 // The trigger is actually off, not just "super big" but infinite.
1600 ps = super_big;
1601 } else if( ps == 0 ) {
1602 ps = 1;
1603 } else if( ps >= 1 && ps <= 16 ) {
1604 // ps = 2^(val-1)+1 (sic)
1605 ps = 1 + (1U << (ps - 1));
1606 } else { // ps > 16 or ps < -1
1607 // ps has 4 bits in hardware, so this indicates a misconfiguration
1608 Error(here, "Invalid prescale = %ld in prescale.dat. "
1609 "Must be between -1 and 16", ps);
1610 ps = -1;
1611 }
1612 if( psfact[trig] == kMaxUInt ) // not read before
1613 psfact[trig] = (UInt_t)ps;
1614 else if( ps != psfact[trig] ) {
1615 Warning(here, "Mismatch in prescale factor: "
1616 "Trig %d oldps %d prescale.dat %ld, Keeping old value",
1617 trig + 1, (Int_t)psfact[trig], ps);
1618 }
1619 if( fDebug > 1 )
1620 cout << "** psfact[ " << trig + 1 << " ] = " << psfact[trig] << endl;
1621 }
1622 }
1623
1624 // Ok in any case
1625 return HED_OK;
1626}
1627
1628//_____________________________________________________________________________
1630{
1631 if (version != 2 && version != 3) {
1632 cout << "ERROR::CodaDecoder::SetCodaVersion version " << version;
1633 cout << " must be 2 or 3 only." << endl;
1634 cout << "Not setting CODA version ! " << endl;
1635 return -1;
1636 }
1637 return (fDataVersion = version);
1638}
1639
1640//_____________________________________________________________________________
1641
1642} // namespace Decoder
1643
#define kOK
Definition BdataLoc.cxx:40
int Int_t
unsigned int UInt_t
#define c(i)
#define e(i)
bool Bool_t
const UInt_t kMaxUInt
winID h TVirtualViewer3D TVirtualGLPainter p
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h offset
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t b
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t index
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h Atom_t Int_t ULong_t ULong_t unsigned char prop_list Atom_t Atom_t Atom_t Time_t UChar_t len
#define CFGEVT1
#define CFGEVT2
static const char *const here
Definition THaVar.cxx:64
float * q
kUnknown
kUndef
static DAQconfig * GetFrom(TObject *p)
static void AddTo(TObject *&p, TObject *obj=nullptr)
Definition DAQconfig.cxx:61
uint32_t Fill(const uint32_t *evbuffer, uint32_t blkSize, uint32_t tsroc)
Int_t physics_decode(const UInt_t *evbuffer)
Int_t prescale_decode_coda2(const UInt_t *evbuffer)
Int_t prescale_decode_coda3(const UInt_t *evbuffer)
virtual Int_t LoadIfFlagData(const UInt_t *evbuffer)
BankDat_t * CheckForBank(UInt_t roc, UInt_t slot)
Int_t daqConfigDecode(const UInt_t *evbuf)
void ChkFbSlot(UInt_t roc, const UInt_t *evbuffer, UInt_t ipt, UInt_t istop)
std::vector< UInt_t > psfact
virtual void SetRunTime(ULong64_t tloc)
static BankInfo GetBank(const UInt_t *evbuf, UInt_t pos, UInt_t len)
Definition CodaDecoder.h:81
virtual Int_t init_slotdata()
virtual Int_t interpretCoda3(const UInt_t *buffer)
virtual UInt_t GetPrescaleFactor(UInt_t trigger) const
void PrintBankInfo() const
virtual Int_t LoadFromMultiBlock()
std::vector< BankDat_t > bankdat
Int_t roc_decode(UInt_t roc, const UInt_t *evbuffer, UInt_t ipt, UInt_t istop)
Int_t SetCodaVersion(Int_t version)
virtual Int_t FillBankData(UInt_t *rdat, UInt_t roc, Int_t bank, UInt_t offset=0, UInt_t num=1) const
std::vector< bool > fbfound
virtual Bool_t DataCached()
Definition CodaDecoder.h:36
Int_t bank_decode(UInt_t roc, const UInt_t *evbuffer, UInt_t ipt, UInt_t istop)
std::vector< UInt_t > irn
Int_t FindRocsCoda3(const UInt_t *evbuffer)
static UInt_t InterpretBankTag(UInt_t tag)
virtual Int_t Init()
void dump(const UInt_t *evbuffer) const
virtual Int_t LoadEvent(const UInt_t *evbuffer)
void debug_print(const UInt_t *evbuffer) const
Int_t LoadTrigBankInfo(UInt_t index_buffer)
virtual Int_t trigBankDecode(const UInt_t *evbuffer)
Int_t FindRocs(const UInt_t *evbuffer)
void string_from_evbuffer(const UInt_t *evbuffer, UInt_t nlen)
long getSignedInt(const char *s) const
unsigned int getint(const char *s) const
Bool_t TestBitNumber(UInt_t bitnumber) const
void SetBitNumber(UInt_t bitnumber, Bool_t value=kTRUE)
Bool_t fDoBench
Definition THaEvData.h:215
UInt_t data_type
Definition THaEvData.h:207
TBits fMsgPrinted
Definition THaEvData.h:230
UInt_t run_num
Definition THaEvData.h:206
virtual Int_t Init()
std::ofstream * fDebugFile
Definition THaEvData.h:204
virtual Int_t init_slotdata()
Bool_t fNeedInit
Definition THaEvData.h:226
UInt_t run_type
Definition THaEvData.h:207
std::vector< UShort_t > fSlotClear
Definition THaEvData.h:213
virtual ULong64_t GetEvTime() const
Definition THaEvData.h:99
UInt_t idx(UInt_t crate, UInt_t slot) const
Definition THaEvData.h:241
std::vector< std::unique_ptr< Decoder::THaSlotData > > crateslot
Definition THaEvData.h:195
std::unique_ptr< Decoder::THaCrateMap > fMap
Definition THaEvData.h:183
virtual void FindUsedSlots()
std::unique_ptr< THaBenchmark > fBench
Definition THaEvData.h:216
ULong64_t fRunTime
Definition THaEvData.h:209
Int_t fDataVersion
Definition THaEvData.h:199
Bool_t first_decode
Definition THaEvData.h:197
UInt_t event_type
Definition THaEvData.h:206
Bool_t PrescanModeEnabled() const
Definition THaEvData.h:397
Int_t fDebug
Definition THaEvData.h:228
std::vector< UShort_t > fSlotUsed
Definition THaEvData.h:212
TObject * fExtra
Definition THaEvData.h:232
ULong64_t evt_time
Definition THaEvData.h:210
virtual void makeidx(UInt_t crate, UInt_t slot)
UInt_t GetEvNum() const
Definition THaEvData.h:56
const UInt_t * buffer
Definition THaEvData.h:202
UInt_t trigger_bits
Definition THaEvData.h:207
UInt_t event_length
Definition THaEvData.h:206
std::array< RocDat_t, Decoder::MAXROC > rocdat
Definition THaEvData.h:192
UInt_t event_num
Definition THaEvData.h:206
virtual void Warning(const char *method, const char *msgfmt,...) const
virtual void Error(const char *method, const char *msgfmt,...) const
unsigned long long ULong64_t
static constexpr auto MAXROCSLOT_FB
static const UInt_t MAXSLOT_FB
Definition Decoder.h:36
static const UInt_t PRESTART_EVTYPE
Definition Decoder.h:40
static const UInt_t DAQCONFIG_FILE1
Definition Decoder.h:49
static const UInt_t END_EVTYPE
Definition Decoder.h:43
static const UInt_t SBSSCALER_EVTYPE
Definition Decoder.h:53
static const UInt_t HV_DATA_EVTYPE
Definition Decoder.h:54
static const UInt_t DAQCONFIG_FILE2
Definition Decoder.h:50
static const Int_t MAXBANK
Definition Decoder.h:34
static const UInt_t PRESCALE_EVTYPE
Definition Decoder.h:47
static const UInt_t GO_EVTYPE
Definition Decoder.h:41
static const UInt_t SCALER_EVTYPE
Definition Decoder.h:52
static const UInt_t EPICS_EVTYPE
Definition Decoder.h:46
static const UInt_t MAX_PHYS_EVTYPE
Definition Decoder.h:38
static const UInt_t TS_PRESCALE_EVTYPE
Definition Decoder.h:44
static const UInt_t MAXROC
Definition Decoder.h:33
start
STL namespace.
const char * Typtxt() const
Int_t Fill(const UInt_t *evbuf, UInt_t pos, UInt_t len)
const char * Errtxt() const
TArc a
ClassImp(TPyArg)