DABC (Data Acquisition Backbone Core)  2.9.9
hldprint.cxx
Go to the documentation of this file.
1 // $Id: hldprint.cxx 4773 2021-05-04 10:47:00Z linev $
2 
3 /********************************************************************
4  * The Data Acquisition Backbone Core (DABC)
5  ********************************************************************
6  * Copyright (C) 2009-
7  * GSI Helmholtzzentrum fuer Schwerionenforschung GmbH
8  * Planckstr. 1
9  * 64291 Darmstadt
10  * Germany
11  * Contact: http://dabc.gsi.de
12  ********************************************************************
13  * This software can be used under the GPL license agreements as stated
14  * in LICENSE.txt file which is part of the distribution.
15  ********************************************************************/
16 
17 #include <cstdio>
18 #include <cstring>
19 #include <map>
20 #include <vector>
21 #include <algorithm>
22 #include <ctime>
23 
24 #include "hadaq/api.h"
25 #include "dabc/Url.h"
26 #include "dabc/api.h"
27 
28 int usage(const char* errstr = nullptr)
29 {
30  if (errstr!=0) {
31  printf("Error: %s\n\n", errstr);
32  }
33 
34  printf("Utility for printing HLD events. 22.10.2018. S.Linev\n");
35  printf(" hldprint source [args]\n");
36  printf("Following sources are supported:\n");
37  printf(" hld://path/file.hld - HLD file reading\n");
38  printf(" file.hld - HLD file reading (file extension MUST be '.hld')\n");
39  printf(" dabcnode - DABC stream server\n");
40  printf(" dabcnode:port - DABC stream server with custom port\n");
41  printf(" mbss://dabcnode/Transport - DABC transport server\n");
42  printf(" lmd://path/file.lmd - LMD file reading\n");
43  printf("Arguments:\n");
44  printf(" -tmout value - maximal time in seconds for waiting next event (default 5)\n");
45  printf(" -maxage value - maximal age time for events, if expired queue are cleaned (default off)\n");
46  printf(" -num number - number of events to print, 0 - all events (default 10)\n");
47  printf(" -all - print all events (equivalent to -num 0)\n");
48  printf(" -skip number - number of events to skip before start printing\n");
49  printf(" -event id - search for given event id before start printing\n");
50  printf(" -find id - search for given trigger id before start printing\n");
51  printf(" -sub - try to scan for subsub events (default false)\n");
52  printf(" -stat - accumulate different kinds of statistics (default false)\n");
53  printf(" -raw - printout of raw data (default false)\n");
54  printf(" -onlyerr - printout only TDC data with errors\n");
55  printf(" -cts id - printout raw data as CTS subsubevent (default none)\n");
56  printf(" -tdc id - printout raw data as TDC subsubevent (default none)\n");
57  printf(" -new id - printout raw data as new TDC subsubevent (default none)\n");
58  printf(" -adc id - printout raw data as ADC subsubevent (default none)\n");
59  printf(" -hub id - identify hub inside subevent (default none) \n");
60  printf(" -auto - automatically assign ID for TDCs (0x0zzz or 0x1zzz) and HUBs (0x8zzz) (default false)\n");
61  printf(" -range mask - select bits which are used to detect TDC or ADC (default 0xff)\n");
62  printf(" -onlyraw subsubid - printout of raw data only for specified subsubevent\n");
63  printf(" -onlytdc tdcid - printout raw data only of specified tdc subsubevent (default none)\n");
64  printf(" -onlych chid - print only specified TDC channel (default off)\n");
65  printf(" -onlynew subsubid - printout raw data only for specified TDC4 subsubevent\n");
66  printf(" -onlymonitor id - printout only event/subevent created by hadaq::Monitor module (default off) \n");
67  printf(" -skipintdc nmsg - skip in tdc first nmsgs (default 0)\n");
68  printf(" -tot boundary - minimal allowed value for ToT (default 20 ns)\n");
69  printf(" -stretcher value - approximate stretcher length for falling edge (default 20 ns)\n");
70  printf(" -ignorecalibr - ignore calibration messages (default off)\n");
71  printf(" -fullid value - printout only events with specified fullid (default all)\n");
72  printf(" -rate - display only events and data rate\n");
73  printf(" -bw - disable colors\n");
74  printf(" -allepoch - epoch should be provided for each channel (default off)\n");
75  printf(" -400 - new 400 MHz design, 12bit coarse, 9bit fine, min = 0x5, max = 0xc0\n");
76  printf(" -340 - new 340 MHz design, 12bit coarse, 9bit fine, min = 0x5, max = 0xc0\n");
77  printf(" -mhz value - new design with arbitrary MHz, 12bit coarse, 9bit fine, min = 0x5, max = 0xc0\n");
78  printf(" -fine-min value - minimal fine counter value, used for liner time calibration (default 31)\n");
79  printf(" -fine-max value - maximal fine counter value, used for liner time calibration (default 491)\n");
80  printf(" -fine-min4 value - minimal fine counter value TDC v4, used for liner time calibration (default 28)\n");
81  printf(" -fine-max4 value - maximal fine counter value TDC v4, used for liner time calibration (default 350)\n");
82  printf(" -bubble - display TDC data as bubble, require 19 words in TDC subevent\n");
83  printf(" -again [N=1] - repeat same printout N times, only for debug purposes\n\n");
84  printf("Example - display only data from TDC 0x1226:\n\n");
85  printf(" hldprint localhost:6789 -num 1 -auto -onlytdc 0x1226\n\n");
86  printf("Show statistic over all events in HLD file:\n\n");
87  printf(" hldprint file.hld -all -stat\n");
88 
89  return errstr ? 1 : 0;
90 }
91 
93  decode_SingleSubev = 0x8 // subevent contains single sub-sub event
94 };
95 
97  tdckind_Reserved = 0x00000000,
98  tdckind_Header = 0x20000000,
99  tdckind_Debug = 0x40000000,
100  tdckind_Epoch = 0x60000000,
101  tdckind_Mask = 0xe0000000,
102  tdckind_Hit = 0x80000000, // normal hit message
103  tdckind_Hit1 = 0xa0000000, // hardware- corrected hit message, instead of 0x3ff
104  tdckind_Hit2 = 0xc0000000, // special hit message with regular fine time
105  tdckind_Calibr = 0xe0000000 // extra calibration message for hits
106 };
107 
108 enum { NumTdcErr = 6 };
109 
112  tdcerr_MissCh0 = 0x0002,
114  tdcerr_NoData = 0x0008,
115  tdcerr_Sequence = 0x0010,
116  tdcerr_ToT = 0x0020
117 };
118 
119 
120 const char *col_RESET = "\033[0m";
121 const char *col_BLACK = "\033[30m"; /* Black */
122 const char *col_RED = "\033[31m"; /* Red */
123 const char *col_GREEN = "\033[32m"; /* Green */
124 const char *col_YELLOW = "\033[33m"; /* Yellow */
125 const char *col_BLUE = "\033[34m"; /* Blue */
126 const char *col_MAGENTA = "\033[35m"; /* Magenta */
127 const char *col_CYAN = "\033[36m"; /* Cyan */
128 const char *col_WHITE = "\033[37m"; /* White */
129 
130 const char* TdcErrName(int cnt) {
131  switch (cnt) {
132  case 0: return "header";
133  case 1: return "ch0";
134  case 2: return "epoch";
135  case 3: return "nodata";
136  case 4: return "seq";
137  case 5: return "tot";
138  }
139  return "unknown";
140 }
141 
142 struct SubevStat {
143  long unsigned num{0}; // number of subevent seen
144  long unsigned sizesum{0}; // sum of all subevents sizes
145  bool istdc{false}; // indicate if it is TDC subevent
146  std::vector<long unsigned> tdcerr; // tdc errors
147  unsigned maxch{0}; // maximal channel ID
148 
149  double aver_size() { return num>0 ? sizesum / (1.*num) : 0.; }
150  double tdcerr_rel(unsigned n) { return (n < tdcerr.size()) && (num>0) ? tdcerr[n] / (1.*num) : 0.; }
151 
152  SubevStat() = default;
153  SubevStat(const SubevStat& src) : num(src.num), sizesum(src.sizesum), istdc(src.istdc), tdcerr(src.tdcerr), maxch(src.maxch) {}
154 
155  void accumulate(unsigned sz)
156  {
157  num++;
158  sizesum += sz;
159  }
160 
161  void IncTdcError(unsigned id)
162  {
163  if (tdcerr.empty())
164  tdcerr.assign(NumTdcErr, 0);
165  if (id < tdcerr.size()) tdcerr[id]++;
166  }
167 
168 };
169 
170 
171 double tot_limit(20.), tot_shift(20.), coarse_tmlen(5.);
172 unsigned fine_min = 31, fine_max = 491, fine_min4 = 28, fine_max4 = 350, skip_msgs_in_tdc = 0;
173 bool bubble_mode{false}, only_errors{false}, use_colors{true}, epoch_per_channel{false}, use_calibr{true}, use_400mhz{false};
174 int onlych = -1;
175 
176 const char *getCol(const char *col_name)
177 {
178  return use_colors ? col_name : "";
179 }
180 
181 const char* debug_name[32] = {
182  "Number of valid triggers",
183  "Number of release signals send",
184  "Number of valid timing triggers received",
185  "Valid NOtiming trigger number",
186  "Invalid trigger number",
187  "Multi timing trigger number",
188  "Spurious trigger number",
189  "Wrong readout number",
190  "Spike number",
191  "Idle time",
192  "Wait time",
193  "Total empty channels",
194  "Readout time",
195  "Timeout number",
196  "Temperature",
197  "RESERVED",
198  "Compile time 1",
199  "Compile time 2",
200  "debug 0x10010",
201  "debug 0x10011",
202  "debug 0x10100",
203  "debug 0x10101",
204  "debug 0x10110",
205  "debug 0x10111",
206  "debug 0x11000",
207  "debug 0x11001",
208  "debug 0x11010",
209  "debug 0x11011",
210  "debug 0x11100",
211  "debug 0x11101",
212  "debug 0x11110",
213  "debug 0x11111"
214 };
215 
216 unsigned BUBBLE_SIZE = 19;
217 
218 unsigned BubbleCheck(unsigned* bubble, int &p1, int &p2) {
219  p1 = 0; p2 = 0;
220 
221  unsigned pos = 0, last = 1, nflip = 0;
222 
223  int b1 = 0, b2 = 0;
224 
225  std::vector<unsigned> fliparr(BUBBLE_SIZE*16);
226 
227  for (unsigned n=0;n<BUBBLE_SIZE; n++) {
228  unsigned data = bubble[n] & 0xFFFF;
229  if (n < BUBBLE_SIZE-1) data = data | ((bubble[n+1] & 0xFFFF) << 16); // use word to recognize bubble
230 
231  // this is error - first bit always 1
232  if ((n==0) && ((data & 1) == 0)) { return -1; }
233 
234  for (unsigned b=0;b<16;b++) {
235  if ((data & 1) != last) {
236  if (last==1) {
237  if (p1==0) p1 = pos; // take first change from 1 to 0
238  } else {
239  p2 = pos; // use last change from 0 to 1
240  }
241  nflip++;
242  }
243 
244  fliparr[pos] = nflip; // remember flip counts to analyze them later
245 
246  // check for simple bubble at the beginning 1101000 or 0x0B in swapped order
247  // set position on last 1 ? Expecting following sequence
248  // 1110000 - here pos=4
249  // ^
250  // 1110100 - here pos=5
251  // ^
252  // 1111100 - here pos=6
253  // ^
254  if ((data & 0xFF) == 0x0B) b1 = pos+3;
255 
256  // check for simple bubble at the end 00001011 or 0xD0 in swapped order
257  // set position of 0 in bubble, expecting such sequence
258  // 0001111 - here pos=4
259  // ^
260  // 0001011 - here pos=5
261  // ^
262  // 0000011 - here pos=6
263  // ^
264  if ((data & 0xFF) == 0xD0) b2 = pos+5;
265 
266  // simple bubble at very end 00000101 or 0xA0 in swapped order
267  // here not enough space for two bits
268  if (((pos == BUBBLE_SIZE*16 - 8)) && (b2 == 0) && ((data & 0xFF) == 0xA0))
269  b2 = pos + 6;
270 
271 
272  last = (data & 1);
273  data = data >> 1;
274  pos++;
275  }
276  }
277 
278  if (nflip == 2) return 0; // both are ok
279 
280  if ((nflip == 4) && (b1>0) && (b2==0)) { p1 = b1; return 0x10; } // bubble in the begin
281 
282  if ((nflip == 4) && (b1==0) && (b2>0)) { p2 = b2; return 0x01; } // bubble at the end
283 
284  if ((nflip == 6) && (b1>0) && (b2>0)) { p1 = b1; p2 = b2; return 0x11; } // bubble on both side
285 
286  // up to here was simple errors, now we should do more complex analysis
287 
288  if (p1 < p2 - 8) {
289  // take flip count at the middle and check how many transitions was in between
290  int mid = (p2+p1)/2;
291  // hard error in the beginning
292  if (fliparr[mid] + 1 == fliparr[p2]) return 0x20;
293  // hard error in begin, bubble at the end
294  if ((fliparr[mid] + 3 == fliparr[p2]) && (b2>0)) { p2 = b2; return 0x21; }
295 
296  // hard error at the end
297  if (fliparr[p1] == fliparr[mid]) return 0x02;
298  // hard error at the end, bubble at the begin
299  if ((fliparr[p1] + 2 == fliparr[mid]) && (b1>0)) { p1 = b1; return 0x12; }
300  }
301 
302  return 0x22; // mark both as errors, should analyze better
303 }
304 
305 void PrintBubble(unsigned* bubble, unsigned len = 0) {
306  // print in original order, time from right to left
307  // for (unsigned d=BUBBLE_SIZE;d>0;d--) printf("%04x",bubble[d-1]);
308 
309  if (len==0) len = BUBBLE_SIZE;
310  // print in reverse order, time from left to right
311  for (unsigned d=0;d<len;d++) {
312  unsigned origin = bubble[d], swap = 0;
313  for (unsigned dd = 0;dd<16;++dd) {
314  swap = (swap << 1) | (origin & 1);
315  origin = origin >> 1;
316  }
317  printf("%04x",swap);
318  }
319 }
320 
321 void PrintBubbleBinary(unsigned* bubble, int p1 = -1, int p2 = -1) {
322  if (p1<0) p1 = 0;
323  if (p2<=p1) p2 = BUBBLE_SIZE*16;
324 
325  int pos = 0;
326  char sbuf[1000];
327  char* ptr = sbuf;
328 
329  for (unsigned d=0;d<BUBBLE_SIZE;d++) {
330  unsigned origin = bubble[d];
331  for (unsigned dd = 0;dd<16;++dd) {
332  if ((pos>=p1) && (pos<=p2))
333  *ptr++ = (origin & 0x1) ? '1' : '0';
334  origin = origin >> 1;
335  pos++;
336  }
337  }
338 
339  *ptr++ = 0;
340  printf("%s", sbuf);
341 }
342 
343 
344 bool PrintBubbleData(hadaq::RawSubevent* sub, unsigned ix, unsigned len, unsigned prefix)
345 {
346  unsigned sz = ((sub->GetSize() - sizeof(hadaq::RawSubevent)) / sub->Alignment());
347 
348  if (ix>=sz) return false;
349  if ((len==0) || (ix + len > sz)) len = sz - ix;
350 
351  if (prefix==0) return false;
352 
353  unsigned lastch = 0xFFFF;
354  unsigned bubble[190];
355  unsigned bcnt = 0, msg = 0, chid = 0;
356  int p1 = 0, p2 = 0;
357 
358  for (unsigned cnt=0;cnt<=len;cnt++,ix++) {
359  chid = 0xFFFF; msg = 0;
360  if (cnt<len) {
361  msg = sub->Data(ix);
362  if ((msg & tdckind_Mask) != tdckind_Hit) continue;
363  chid = (msg >> 22) & 0x7F;
364  }
365 
366  if (chid != lastch) {
367  if (lastch != 0xFFFF) {
368  printf("%*s ch%02u: ", prefix, "", lastch);
369  if (bcnt==BUBBLE_SIZE) {
370 
371  PrintBubble(bubble);
372 
373  int chk = BubbleCheck(bubble, p1, p2);
374  int left = p1-2;
375  int right = p2+1;
376  if ((chk & 0xF0) == 0x10) left--;
377  if ((chk & 0x0F) == 0x01) right++;
378 
379  if (chk==0) printf(" norm"); else
380  if (chk==0x22) {
381  printf(" corr "); PrintBubbleBinary(bubble, left, right);
382  } else
383  if (((chk & 0xF0) < 0x20) && ((chk & 0x0F) < 0x02)) {
384  printf(" bubb "); PrintBubbleBinary(bubble, left, right);
385  } else {
386  printf(" mixe "); PrintBubbleBinary(bubble, left, right);
387  }
388 
389  } else {
390  printf("bubble data error length = %u, expected %u", bcnt, BUBBLE_SIZE);
391  }
392 
393  printf("\n");
394  }
395  lastch = chid; bcnt = 0;
396  }
397 
398  bubble[bcnt++] = msg & 0xFFFF;
399  // printf("here\n");
400  }
401 
402  return true;
403 }
404 
405 
406 enum {
407  // with mask 1
408  newkind_TMDT = 0x80000000,
409  // with mask 3
410  newkind_Mask3 = 0xE0000000,
411  newkind_HDR = 0x20000000,
412  newkind_TRL = 0x00000000,
413  newkind_EPOC = 0x60000000,
414  // with mask 4
415  newkind_Mask4 = 0xF0000000,
416  newkind_TMDS = 0x40000000,
417  // with mask 6
418  newkind_Mask6 = 0xFC000000,
419  newkind_TBD = 0x50000000,
420  // with mask 8
421  newkind_Mask8 = 0xFF000000,
422  newkind_HSTM = 0x54000000,
423  newkind_HSTL = 0x55000000,
424  newkind_HSDA = 0x56000000,
425  newkind_HSDB = 0x57000000,
426  newkind_CTA = 0x58000000,
427  newkind_CTB = 0x59000000,
428  newkind_TEMP = 0x5A000000,
429  newkind_BAD = 0x5B000000,
430  // with mask 9
431  newkind_Mask9 = 0xFF800000,
432  newkind_TTRM = 0x5C000000,
433  newkind_TTRL = 0x5C800000,
434  newkind_TTCM = 0x5D000000,
435  newkind_TTCL = 0x5D800000,
436  // with mask 7
437  newkind_Mask7 = 0xFE000000,
438  newkind_TMDR = 0x5E000000
439 };
440 
441 
442 
443 
444 void PrintTdc4Data(hadaq::RawSubevent* sub, unsigned ix, unsigned len, unsigned prefix)
445 {
446  if (len == 0) return;
447 
448  unsigned sz = ((sub->GetSize() - sizeof(hadaq::RawSubevent)) / sub->Alignment());
449 
450  if (ix >= sz) return;
451  // here when len was 0 - rest of subevent was printed
452  if ((len==0) || (ix + len > sz)) len = sz - ix;
453 
454  unsigned wlen = 2;
455  if (sz>99) wlen = 3; else
456  if (sz>999) wlen = 4;
457 
458  unsigned ttype = 0;
459  uint64_t lastepoch = 0;
460  double coarse_unit = 1./2.8e8;
461  double localtm0 = 0.;
462 
463  char sbeg[1000], sdata[1000];
464 
465  for (unsigned cnt=0;cnt<len;cnt++,ix++) {
466  unsigned msg = sub->Data(ix);
467 
468  const char *kind = "unckn";
469 
470  sdata[0] = 0;
471 
472  if (prefix > 0) snprintf(sbeg, sizeof(sbeg), "%*s[%*u] %08x ", prefix, "", wlen, ix, msg);
473  if ((msg & newkind_TMDT) == newkind_TMDT) {
474  kind = "TMDT";
475  unsigned mode = (msg >> 27) & 0xF;
476  unsigned channel = (msg >> 21) & 0x3F;
477  unsigned coarse = (msg >> 9) & 0xFFF;
478  unsigned fine = msg & 0x1FF;
479 
480  if ((onlych >= 0) && (channel != onlych)) continue;
481 
482  double localtm = ((lastepoch << 12) | coarse) * coarse_unit;
483  if (fine > fine_max4)
484  localtm -= coarse_unit;
485  else if (fine > fine_min4)
486  localtm -= (fine - fine_min4) / (0. + fine_max4 - fine_min4) * coarse_unit;
487 
488  snprintf(sdata, sizeof(sdata), "mode:0x%x ch:%u coarse:%u fine:%u tm0:%6.3fns", mode, channel, coarse, fine, (localtm - localtm0)*1e9);
489  } else {
490  unsigned hdr3 = msg & newkind_Mask3;
491  unsigned hdr4 = msg & newkind_Mask4;
492  unsigned hdr6 = msg & newkind_Mask6;
493  unsigned hdr7 = msg & newkind_Mask7;
494  unsigned hdr8 = msg & newkind_Mask8;
495  unsigned hdr9 = msg & newkind_Mask9;
496  if (hdr3 == newkind_HDR) {
497  kind = "HDR";
498  unsigned major = (msg >> 24) & 0xF;
499  unsigned minor = (msg >> 20) & 0xF;
500  ttype = (msg >> 16) & 0xF;
501  unsigned trigger = msg & 0xFFFF;
502  snprintf(sdata, sizeof(sdata), "version:%u.%u typ:0x%x trigger:%u", major, minor, ttype, trigger);
503  } else
504  if (hdr3 == newkind_TRL) {
505 
506  switch (ttype) {
507  case 0x4:
508  case 0x6:
509  case 0x7:
510  case 0x8:
511  case 0x9:
512  case 0xE: {
513  kind = "TRLB";
514  unsigned eflags = (msg >> 24) & 0xF;
515  unsigned maxdc = (msg >> 20) & 0xF;
516  unsigned tptime = (msg >> 16) & 0xF;
517  unsigned freq = msg & 0xFFFF;
518  snprintf(sdata, sizeof(sdata), "eflags:0x%x maxdc:%u tptime:%u freq:%u", eflags, maxdc, tptime, freq);
519  break;
520  }
521  case 0xC: {
522  kind = "TRLC";
523  unsigned cpc = (msg >> 24) & 0x7;
524  unsigned ccs = (msg >> 20) & 0xF;
525  unsigned ccdiv = (msg >> 16) & 0xF;
526  unsigned freq = msg & 0xFFFF;
527  snprintf(sdata, sizeof(sdata), "cpc:0x%x ccs:0x%x ccdiv:%u freq:%5.3fMHz", cpc, ccs, ccdiv, freq*1e-2);
528  break;
529  }
530  case 0x0:
531  case 0x1:
532  case 0x2:
533  case 0xf:
534  default: {
535  kind = "TRLA";
536  unsigned platformid = (msg >> 20) & 0xff;
537  unsigned major = (msg >> 16) & 0xf;
538  unsigned minor = (msg >> 12) & 0xf;
539  unsigned sub = (msg >> 8) & 0xf;
540  unsigned numch = (msg & 0x7F) + 1;
541  snprintf(sdata, sizeof(sdata), "platform:0x%x version:%u.%u.%u numch:%u", platformid, major, minor, sub, numch);
542  }
543  }
544 
545  } else
546  if (hdr3 == newkind_EPOC) {
547  kind = "EPOC";
548  unsigned epoch = msg & 0xFFFFFFF;
549  bool err = (msg & 0x10000000) != 0;
550  snprintf(sdata, sizeof(sdata), "0x%07x%s", epoch, (err ? " errflag" : ""));
551  lastepoch = epoch;
552  } else
553  if (hdr4 == newkind_TMDS) {
554  kind = "TMDS";
555  unsigned channel = (msg >> 21) & 0x7F;
556  unsigned coarse = (msg >> 9) & 0xFFF;
557  unsigned pattern = msg & 0x1FF;
558 
559  double localtm = ((lastepoch << 12) | coarse) * coarse_unit;
560  unsigned mask = 0x100, cnt = 8;
561  while (((pattern & mask) == 0) && (cnt > 0)) {
562  mask = mask >> 1;
563  cnt--;
564  }
565  localtm -= coarse_unit/8*cnt;
566 
567  snprintf(sdata, sizeof(sdata), "ch:%u coarse:%u pattern:0x%03x tm0:%5.1f", channel, coarse, pattern, (localtm - localtm0)*1e9);
568  } else
569  if (hdr6 == newkind_TBD) kind = "TBD"; else
570  if (hdr8 == newkind_HSTM) kind = "HSTM"; else
571  if (hdr8 == newkind_HSTL) kind = "HSTL"; else
572  if (hdr8 == newkind_HSDA) kind = "HSDA"; else
573  if (hdr8 == newkind_HSDB) kind = "HSDB"; else
574  if (hdr8 == newkind_CTA) kind = "CTA"; else
575  if (hdr8 == newkind_CTB) kind = "CTB"; else
576  if (hdr8 == newkind_TEMP) kind = "TEMP"; else
577  if (hdr8 == newkind_BAD) kind = "BAD"; else
578  if (hdr9 == newkind_TTRM) kind = "TTRM"; else
579  if (hdr9 == newkind_TTRL) kind = "TTRL"; else
580  if (hdr9 == newkind_TTCM) kind = "TTCM"; else
581  if (hdr9 == newkind_TTCL) kind = "TTCL"; else
582  if (hdr7 == newkind_TMDR) {
583  kind = "TMDR";
584  unsigned mode = (msg >> 21) & 0xF;
585  unsigned coarse = (msg >> 9) & 0xFFF;
586  unsigned fine = msg & 0x1FF;
587  bool isrising = (mode == 0) || (mode == 2);
588 
589  double localtm = ((lastepoch << 12) | coarse) * coarse_unit;
590  if (fine > fine_max4)
591  localtm -= coarse_unit;
592  else if (fine > fine_min4)
593  localtm -= (fine - fine_min4) / (0. + fine_max4 - fine_min4) * coarse_unit;
594 
595  if (isrising) localtm0 = localtm;
596 
597  if (onlych > 0) continue;
598 
599  snprintf(sdata, sizeof(sdata), "mode:0x%x coarse:%u fine:%u tm:%6.3fns", mode, coarse, fine, isrising ? localtm*1e9 : (localtm - localtm0)*1e9);
600  }
601  }
602 
603  if (prefix > 0) printf("%s%s %s\n", sbeg, kind, sdata);
604  }
605 }
606 
607 
608 void PrintTdcData(hadaq::RawSubevent* sub, unsigned ix, unsigned len, unsigned prefix, unsigned& errmask, SubevStat *substat = nullptr)
609 {
610  if (len == 0) return;
611 
612  if (bubble_mode) {
613  PrintBubbleData(sub, ix, len, prefix);
614  return;
615  }
616 
617 
618  unsigned sz = ((sub->GetSize() - sizeof(hadaq::RawSubevent)) / sub->Alignment());
619  if (ix>=sz) return;
620 
621  unsigned msg0 = sub->Data(ix);
622  if (((msg0 & tdckind_Mask) == tdckind_Header) && (((msg0 >> 24) & 0xF) == 0x4)) {
623  PrintTdc4Data(sub, ix, len, prefix);
624  return;
625  }
626 
627 
628  // here when len was 0 - rest of subevent was printed
629  if ((len==0) || (ix + len > sz)) len = sz - ix;
630 
631  unsigned wlen = 2;
632  if (sz>99) wlen = 3; else
633  if (sz>999) wlen = 4;
634 
635  unsigned long long epoch(0);
636  double tm, ch0tm(0);
637 
638  errmask = 0;
639 
640  bool haschannel0(false);
641  unsigned channel(0), maxch(0), coarse(0), fine(0), ndebug(0), nheader(0), isrising(0), dkind(0), dvalue(0), rawtime(0);
642  int epoch_channel(-11); // -11 no epoch, -1 - new epoch, 0..127 - epoch assigned with specified channel
643 
644  static unsigned NumCh = 66;
645 
646  double last_rising[NumCh], last_falling[NumCh];
647  int leading_trailing[NumCh], num_leading[NumCh], num_trailing[NumCh];
648  bool seq_err[NumCh];
649  for (unsigned n=0;n<NumCh;n++) {
650  last_rising[n] = 0;
651  last_falling[n] = 0;
652  leading_trailing[n] = 0;
653  num_leading[n] = 0;
654  num_trailing[n] = 0;
655  seq_err[n] = false;
656  }
657 
658  unsigned bubble[100];
659  int bubble_len = -1, nbubble = 0;
660  unsigned bubble_ix = 0, bubble_ch = 0, bubble_eix = 0;
661 
662  char sbuf[100], sfine[100], sbeg[100];
663  unsigned calibr[2] = { 0xffff, 0xffff };
664  unsigned skip = skip_msgs_in_tdc;
665  int ncalibr = 2;
666  const char* hdrkind = "";
667  bool with_calibr = false, bad_fine = false;
668 
669  for (unsigned cnt=0;cnt<len;cnt++,ix++) {
670  unsigned msg = sub->Data(ix);
671  if (bubble_len>=0) {
672  bool israw = (msg & tdckind_Mask) == tdckind_Calibr;
673  if (israw) {
674  channel = (msg >> 22) & 0x7F;
675  if (bubble_len==0) { bubble_eix = bubble_ix = ix; bubble_ch = channel; }
676  if (bubble_ch == channel) { bubble[bubble_len++] = msg & 0xFFFF; bubble_eix = ix; }
677  }
678  if ((bubble_len >= 100) || (cnt==len-1) || (channel!=bubble_ch) || (!israw && (bubble_len > 0))) {
679  if (prefix>0) {
680  printf("%*s[%*u..%*u] Ch:%02x bubble: ", prefix, "", wlen, bubble_ix, wlen, bubble_eix, bubble_ch);
681  PrintBubble(bubble, (unsigned) bubble_len);
682  printf("\n");
683  nbubble++;
684  }
685  bubble_len = 0; bubble_eix = bubble_ix = ix;
686  if (bubble_ch != channel) {
687  bubble_ch = channel;
688  bubble[bubble_len++] = msg & 0xFFFF;
689  }
690  }
691  if (israw) continue;
692  bubble_len = -1; // no bubbles
693  }
694 
695  if (prefix > 0)
696  snprintf(sbeg, sizeof(sbeg), "%*s[%*u] %08x ", prefix, "", wlen, ix, msg);
697 
698  if (skip > 0) {
699  skip--;
700  continue;
701  }
702 
703  if ((cnt==skip_msgs_in_tdc) && ((msg & tdckind_Mask) != tdckind_Header)) errmask |= tdcerr_MissHeader;
704 
705  switch (msg & tdckind_Mask) {
706  case tdckind_Reserved:
707  if (prefix>0) printf("%s tdc trailer ttyp:0x%01x rnd:0x%02x err:0x%04x\n", sbeg, (msg >> 24) & 0xF, (msg >> 16) & 0xFF, msg & 0xFFFF);
708  break;
709  case tdckind_Header:
710  nheader++;
711  switch ((msg >> 24) & 0x0F) {
712  case 0x01: hdrkind = "double edges"; break;
713  case 0x0F: hdrkind = "bubbles"; bubble_len = 0; break;
714  default: hdrkind = "normal"; break;
715  }
716 
717  if (prefix > 0)
718  printf("%s tdc header fmt:0x01%x hwtyp:0x%02x %s\n", sbeg, ((msg >> 24) & 0x0F), ((msg >> 8) & 0xFF), hdrkind);
719  break;
720  case tdckind_Debug:
721  ndebug++;
722  dkind = (msg >> 24) & 0x1F;
723  dvalue = msg & 0xFFFFFF;
724  sbuf[0] = 0;
725  if (dkind == 0x10) rawtime = dvalue; else
726  if (dkind == 0x11) {
727  rawtime += (dvalue << 16);
728  time_t t = (time_t) rawtime;
729  snprintf(sbuf, sizeof(sbuf), " design 0x%08x %s", rawtime, ctime(&t));
730  int len = strlen(sbuf);
731  if (sbuf[len-1]==10) sbuf[len-1] = 0;
732  } else if (dkind == 0xE)
733  snprintf(sbuf, sizeof(sbuf), " %3.1fC", dvalue/16.);
734 
735  if (prefix > 0)
736  printf("%s tdc debug 0x%02x: 0x%06x %s%s\n", sbeg, dkind, dvalue, debug_name[dkind], sbuf);
737  break;
738  case tdckind_Epoch:
739  epoch = msg & 0xFFFFFFF;
740  tm = (epoch << 11) *5.;
741  epoch_channel = -1; // indicate that we have new epoch
742  if (prefix > 0) printf("%s epoch %u tm %6.3f ns\n", sbeg, msg & 0xFFFFFFF, tm);
743  break;
744  case tdckind_Calibr:
745  calibr[0] = msg & 0x3fff;
746  calibr[1] = (msg >> 14) & 0x3fff;
747  if (use_calibr) ncalibr = 0;
748  if ((prefix > 0) && (onlych < 0))
749  printf("%s tdc calibr v1 0x%04x v2 0x%04x\n", sbeg, calibr[0], calibr[1]);
750  break;
751  case tdckind_Hit:
752  case tdckind_Hit1:
753  case tdckind_Hit2:
754  channel = (msg >> 22) & 0x7F;
755  if (channel == 0) haschannel0 = true;
756  if (epoch_channel==-1) epoch_channel = channel;
757  isrising = (msg >> 11) & 0x1;
758  if (maxch<channel) maxch = channel;
759  if (channel < NumCh) {
760  if (isrising) {
761  num_leading[channel]++;
762  if (++leading_trailing[channel] > 1) seq_err[channel] = true;
763  } else {
764  if (--leading_trailing[channel] < 0) seq_err[channel] = true;
765  num_trailing[channel]++;
766  leading_trailing[channel] = 0;
767  }
768  }
769 
770  if ((epoch_channel == -11) || (epoch_per_channel && (epoch_channel != (int) channel))) errmask |= tdcerr_MissEpoch;
771 
772  bad_fine = false;
773 
774  coarse = (msg & 0x7FF);
775  fine = (msg >> 12) & 0x3FF;
776 
777  if (use_400mhz) {
778  coarse = (coarse << 1) | ((fine & 0x200) ? 1 : 0);
779  fine = fine & 0x1FF;
780  bad_fine = (fine == 0x1ff);
781  tm = ((epoch << 12) | coarse) * coarse_tmlen; // coarse time
782  } else {
783  bad_fine = (fine == 0x3ff);
784  tm = ((epoch << 11) | coarse) * coarse_tmlen; // coarse time
785  }
786 
787  with_calibr = false;
788  if (!bad_fine) {
789  if ((msg & tdckind_Mask) == tdckind_Hit2) {
790  if (isrising) {
791  tm -= fine*5e-3; // calibrated time, 5 ps/bin
792  } else {
793  tm -= (fine & 0x1FF)*10e-3; // for falling edge 10 ps binning is used
794  if (fine & 0x200) tm -= 0x800 * 5.; // in rare case time correction leads to epoch overflow
795  }
796  with_calibr = true;
797  } else if (ncalibr<2) {
798  // calibrated time, 5 ns correspond to value 0x3ffe or about 0.30521 ps/bin
799  double corr = calibr[ncalibr++]*5./0x3ffe;
800  if (!isrising) corr*=10.; // for falling edge correction 50 ns range is used
801  tm -= corr;
802  with_calibr = true;
803  } else {
804  tm -= coarse_tmlen * (fine > fine_min ? fine - fine_min : 0) / (0. + fine_max - fine_min); // simple approx of fine time from range 31-491
805  }
806  }
807 
808  sbuf[0] = 0;
809  if (isrising) {
810  last_rising[channel] = tm;
811  } else {
812  last_falling[channel] = tm;
813  if (last_rising[channel] > 0) {
814  double tot = last_falling[channel] - last_rising[channel];
815  bool cond = with_calibr ? ((tot >= 0) && (tot < tot_limit)) : ((tot >= tot_shift) && (tot < tot_shift + tot_limit));
816  if (!cond) errmask |= tdcerr_ToT;
817  snprintf(sbuf, sizeof(sbuf), " tot:%s%6.3f ns%s", getCol(cond ? col_GREEN : col_RED), tot, getCol(col_RESET));
818  last_rising[channel] = 0;
819  }
820  }
821 
822  if ((fine >= 600) && (fine != 0x3ff))
823  snprintf(sfine, sizeof(sfine), "%s0x%03x%s", getCol(col_RED), fine, getCol(col_RESET));
824  else
825  snprintf(sfine, sizeof(sfine), "0x%03x", fine);
826 
827  if ((prefix > 0) && ((onlych < 0) || ((unsigned) onlych == channel)))
828  printf("%s %s ch:%2u isrising:%u tc:0x%03x tf:%s tm:%6.3f ns%s\n",
829  sbeg, ((msg & tdckind_Mask) == tdckind_Hit) ? "hit " : (((msg & tdckind_Mask) == tdckind_Hit1) ? "hit1" : "hit2"),
830  channel, isrising, coarse, sfine, tm - ch0tm, sbuf);
831  if ((channel==0) && (ch0tm==0)) ch0tm = tm;
832  break;
833  default:
834  if (prefix > 0) printf("%s undefined\n", sbeg);
835  break;
836  }
837  }
838 
839  if (len < 2) { if (nheader!=1) errmask |= tdcerr_NoData; } else
840  if (!haschannel0 && (ndebug==0) && (nbubble==0)) errmask |= tdcerr_MissCh0;
841 
842  for (unsigned n=1;n<NumCh;n++)
843  if ((num_leading[n] > 0) && (num_trailing[n] > 0))
844  if (seq_err[n] || (num_leading[n]!=num_trailing[n]))
845  errmask |= tdcerr_Sequence;
846 
847  if (substat) {
848  if (substat->maxch < maxch) substat->maxch = maxch;
849  }
850 }
851 
852 void PrintCtsData(hadaq::RawSubevent* sub, unsigned ix, unsigned len, unsigned prefix)
853 {
854  unsigned sz = ((sub->GetSize() - sizeof(hadaq::RawSubevent)) / sub->Alignment());
855 
856  if ((ix>=sz) || (len==0)) return;
857  if ((len==0) || (ix + len > sz)) len = sz - ix;
858 
859  unsigned data = sub->Data(ix++); len--;
860  unsigned trigtype = (data & 0xFFFF);
861 
862  unsigned nInputs = (data >> 16) & 0xf;
863  unsigned nITCInputs = (data >> 20) & 0xf;
864  unsigned bIdleDeadTime = (data >> 25) & 0x1;
865  unsigned bTriggerStats = (data >> 26) & 0x1;
866  unsigned bIncludeTimestamp = (data >> 27) & 0x1;
867  unsigned nExtTrigFlag = (data >> 28) & 0x3;
868 
869  printf("%*sITC status bitmask: 0x%04x \n", prefix, "", trigtype);
870  printf("%*sNumber of inputs counters: %u \n", prefix, "", nInputs);
871  printf("%*sNumber of ITC counters: %u \n", prefix, "", nITCInputs);
872  printf("%*sIdle/dead counter: %s\n", prefix, "", bIdleDeadTime ? "yes" : "no");
873  printf("%*sTrigger statistic: %s\n", prefix, "", bTriggerStats ? "yes" : "no");
874  printf("%*sTimestamp: %s\n", prefix, "", bIncludeTimestamp ? "yes" : "no");
875 
876  // printing of inputs
877  for (unsigned ninp=0;ninp<nInputs;++ninp) {
878  unsigned wrd1 = sub->Data(ix++); len--;
879  unsigned wrd2 = sub->Data(ix++); len--;
880  printf("%*sInput %u level 0x%08x edge 0x%08x\n", prefix, "", ninp, wrd1, wrd2);
881  }
882 
883  for (unsigned ninp=0;ninp<nITCInputs;++ninp) {
884  unsigned wrd1 = sub->Data(ix++); len--;
885  unsigned wrd2 = sub->Data(ix++); len--;
886  printf("%*sITC Input %u level 0x%08x edge 0x%08x\n", prefix, "", ninp, wrd1, wrd2);
887  }
888 
889  if (bIdleDeadTime) {
890  unsigned wrd1 = sub->Data(ix++); len--;
891  unsigned wrd2 = sub->Data(ix++); len--;
892  printf("%*sIdle 0x%08x dead 0x%08x time\n", prefix, "", wrd1, wrd2);
893  }
894 
895  if (bTriggerStats) {
896  unsigned wrd1 = sub->Data(ix++); len--;
897  unsigned wrd2 = sub->Data(ix++); len--;
898  unsigned wrd3 = sub->Data(ix++); len--;
899  printf("%*sTrigger stats 0x%08x 0x%08x 0x%08x\n", prefix, "", wrd1, wrd2, wrd3);
900  }
901 
902  if (bIncludeTimestamp) {
903  unsigned wrd1 = sub->Data(ix++); len--;
904  printf("%*sTimestamp 0x%08x\n", prefix, "", wrd1);
905  }
906 
907  printf("%*sExternal trigger flag: 0x%x ", prefix, "", nExtTrigFlag);
908  if(nExtTrigFlag==0x1) {
909  data = sub->Data(ix++); len--;
910  unsigned fTrigSyncId = (data & 0xFFFFFF);
911  unsigned fTrigSyncIdStatus = data >> 24; // untested
912  printf("MBS VULOM syncid 0x%06x status 0x%02x\n", fTrigSyncId, fTrigSyncIdStatus);
913  } else if(nExtTrigFlag==0x2) {
914  // ETM sends four words, is probably a Mainz A2 recv
915  data = sub->Data(ix++); len--;
916  unsigned fTrigSyncId = data; // full 32bits is trigger number
917  // get status word
918  data = sub->Data(ix++); len--;
919  unsigned fTrigSyncIdStatus = data;
920  // word 3+4 are 0xdeadbeef i.e. not used at the moment, so skip it
921  ix += 2;
922  len -= 2;
923 
924  printf("MAINZ A2 recv syncid 0x%08x status 0x%08x\n", fTrigSyncId, fTrigSyncIdStatus);
925  } else if(nExtTrigFlag==0x0) {
926 
927  printf("SYNC ");
928 
929  if (sub->Data(ix) == 0xabad1dea) {
930  // [1]: D[31:16] -> sync pulse number
931  // D[15:0] -> absolute time D[47:32]
932  // [2]: D[31:0] -> absolute time D[31:0]
933  // [3]: D[31:0] -> period of sync pulse, in 10ns units
934  // [4]: D[31:0] -> length of sync pulse, in 10ns units
935 
936  unsigned fTrigSyncId = (sub->Data(ix+1) >> 16) & 0xffff;
937  long unsigned fTrigTm = (((uint64_t) (sub->Data(ix+1) & 0xffff)) << 32) | sub->Data(ix+2);
938  unsigned fSyncPulsePeriod = sub->Data(ix+3);
939  unsigned fSyncPulseLength = sub->Data(ix+4);
940 
941  printf(" id 0x%04x tm %lu period %u lentgh %u\n", fTrigSyncId, fTrigTm, fSyncPulsePeriod, fSyncPulseLength);
942 
943  ix += 5;
944  len -= 5;
945  } else {
946  printf("unknown word 0x%08x found, expects 0xabad1dea\n", sub->Data(ix));
947  }
948  } else {
949  printf(" NOT RECOGNIZED!\n");
950  }
951 
952  if ((len > 1) && ((sub->Data(ix) & tdckind_Header) == tdckind_Header)) {
953  unsigned errmask = 0;
954  PrintTdcData(sub, ix, len, prefix, errmask);
955  }
956 }
957 
958 
959 void PrintAdcData(hadaq::RawSubevent* sub, unsigned ix, unsigned len, unsigned prefix)
960 {
961  unsigned sz = ((sub->GetSize() - sizeof(hadaq::RawSubevent)) / sub->Alignment());
962 
963  if ((ix>=sz) || (len==0)) return;
964  if ((len==0) || (ix + len > sz)) len = sz - ix;
965 
966  unsigned wlen = 2;
967  if (sz>99) wlen = 3; else
968  if (sz>999) wlen = 4;
969 
970  for (unsigned cnt=0;cnt<len;cnt++,ix++) {
971  unsigned msg = sub->Data(ix);
972  if (prefix>0) printf("%*s[%*u] %08x ", prefix, "", wlen, ix, msg);
973  printf("\n");
974  }
975 }
976 
978 {
979 
980  unsigned trbSubEvSize = sub->GetSize() / 4 - 4, ix = 0;
981 
982  int cnt = 0;
983  while (ix < trbSubEvSize) {
984  unsigned addr1 = sub->Data(ix++);
985  unsigned addr2 = sub->Data(ix++);
986  unsigned value = sub->Data(ix++);
987 
988  printf(" %3d: %04x %04x = %08x\n", cnt++, addr1, addr2, value);
989 
990  }
991 
992 }
993 
994 bool printraw = false, printsub = false, showrate = false, reconnect = false, dostat = false, autoid = false;
995 unsigned idrange = 0xff, onlytdc = 0, onlynew = 0, onlyraw = 0, hubmask = 0, fullid = 0, adcmask = 0, onlymonitor = 0;
996 std::vector<unsigned> hubs, tdcs, ctsids, newtdcs;
997 
998 bool is_cts(unsigned id)
999 {
1000  return std::find(ctsids.begin(), ctsids.end(), id) != ctsids.end();
1001 }
1002 
1003 bool is_hub(unsigned id)
1004 {
1005  if (std::find(hubs.begin(), hubs.end(), id) != hubs.end()) return true;
1006 
1007  if (!autoid || ((id & 0xF000) != 0x8000)) return false;
1008 
1009  hubs.push_back(id);
1010 
1011  return true;
1012 }
1013 
1014 bool is_tdc(unsigned id)
1015 {
1016  if (std::find(tdcs.begin(), tdcs.end(), id) != tdcs.end()) return true;
1017 
1018  if (autoid) {
1019  if (((id & 0xF000) == 0x0000) || ((id & 0xF000) == 0x1000)) {
1020  tdcs.push_back(id);
1021  return true;
1022  }
1023  }
1024 
1025  for (unsigned n=0;n<tdcs.size();n++)
1026  if (((id & idrange) <= (tdcs[n] & idrange)) && ((id & ~idrange) == (tdcs[n] & ~idrange)))
1027  return true;
1028 
1029  return false;
1030 }
1031 
1032 bool is_newtdc(unsigned id)
1033 {
1034  if (std::find(newtdcs.begin(), newtdcs.end(), id) != newtdcs.end()) return true;
1035 
1036  for (unsigned n=0;n<newtdcs.size();n++)
1037  if (((id & idrange) <= (newtdcs[n] & idrange)) && ((id & ~idrange) == (newtdcs[n] & ~idrange)))
1038  return true;
1039 
1040  return false;
1041 
1042 }
1043 
1044 
1045 bool is_adc(unsigned id)
1046 {
1047  return ((adcmask!=0) && ((id & idrange) <= (adcmask & idrange)) && ((id & ~idrange) == (adcmask & ~idrange)));
1048 }
1049 
1050 int main(int argc, char* argv[])
1051 {
1052  if ((argc<2) || !strcmp(argv[1],"-help") || !strcmp(argv[1],"?")) return usage();
1053 
1054  long number = 10, skip = 0, nagain = 0;
1055  unsigned find_trigid = 0, find_eventid = 0;
1056  double tmout(-1.), maxage(-1.), debug_delay(-1), mhz(400.);
1057  bool dofind = false;
1058  unsigned tdcmask(0), ctsid(0);
1059 
1060  int n = 1;
1061  while (++n < argc) {
1062  if ((strcmp(argv[n],"-num")==0) && (n+1<argc)) { dabc::str_to_lint(argv[++n], &number); } else
1063  if (strcmp(argv[n],"-all")==0) { number = 0; } else
1064  if ((strcmp(argv[n],"-skip")==0) && (n+1<argc)) { dabc::str_to_lint(argv[++n], &skip); } else
1065  if ((strcmp(argv[n],"-event")==0) && (n+1<argc)) { dabc::str_to_uint(argv[++n], &find_eventid); dofind = true; } else
1066  if ((strcmp(argv[n],"-find")==0) && (n+1<argc)) { dabc::str_to_uint(argv[++n], &find_trigid); dofind = true; } else
1067  if ((strcmp(argv[n],"-cts")==0) && (n+1<argc)) { dabc::str_to_uint(argv[++n], &ctsid); ctsids.push_back(ctsid); } else
1068  if ((strcmp(argv[n],"-tdc")==0) && (n+1<argc)) { dabc::str_to_uint(argv[++n], &tdcmask); tdcs.push_back(tdcmask); } else
1069  if ((strcmp(argv[n],"-new")==0) && (n+1<argc)) { dabc::str_to_uint(argv[++n], &tdcmask); newtdcs.push_back(tdcmask); } else
1070  if ((strcmp(argv[n],"-range")==0) && (n+1<argc)) { dabc::str_to_uint(argv[++n], &idrange); } else
1071  if ((strcmp(argv[n],"-onlytdc")==0) && (n+1<argc)) { dabc::str_to_uint(argv[++n], &onlytdc); } else
1072  if ((strcmp(argv[n],"-onlych")==0) && (n+1<argc)) { dabc::str_to_int(argv[++n], &onlych); } else
1073  if ((strcmp(argv[n],"-onlynew")==0) && (n+1<argc)) { dabc::str_to_uint(argv[++n], &onlynew); } else
1074  if ((strcmp(argv[n],"-skipintdc")==0) && (n+1<argc)) { dabc::str_to_uint(argv[++n], &skip_msgs_in_tdc); } else
1075  if ((strcmp(argv[n],"-fine-min")==0) && (n+1<argc)) { dabc::str_to_uint(argv[++n], &fine_min); } else
1076  if ((strcmp(argv[n],"-fine-max")==0) && (n+1<argc)) { dabc::str_to_uint(argv[++n], &fine_max); } else
1077  if ((strcmp(argv[n],"-fine-min4")==0) && (n+1<argc)) { dabc::str_to_uint(argv[++n], &fine_min4); } else
1078  if ((strcmp(argv[n],"-fine-max4")==0) && (n+1<argc)) { dabc::str_to_uint(argv[++n], &fine_max4); } else
1079  if ((strcmp(argv[n],"-tot")==0) && (n+1<argc)) { dabc::str_to_double(argv[++n], &tot_limit); } else
1080  if ((strcmp(argv[n],"-stretcher")==0) && (n+1<argc)) { dabc::str_to_double(argv[++n], &tot_shift); } else
1081  if ((strcmp(argv[n],"-onlyraw")==0) && (n+1<argc)) { dabc::str_to_uint(argv[++n], &onlyraw); } else
1082  if ((strcmp(argv[n],"-adc")==0) && (n+1<argc)) { dabc::str_to_uint(argv[++n], &adcmask); } else
1083  if ((strcmp(argv[n],"-fullid")==0) && (n+1<argc)) { dabc::str_to_uint(argv[++n], &fullid); } else
1084  if ((strcmp(argv[n],"-hub")==0) && (n+1<argc)) { dabc::str_to_uint(argv[++n], &hubmask); hubs.push_back(hubmask); } else
1085  if ((strcmp(argv[n],"-onlymonitor")==0) && (n+1<argc)) { dabc::str_to_uint(argv[++n], &onlymonitor); } else
1086  if ((strcmp(argv[n],"-tmout")==0) && (n+1<argc)) { dabc::str_to_double(argv[++n], &tmout); } else
1087  if ((strcmp(argv[n],"-maxage")==0) && (n+1<argc)) { dabc::str_to_double(argv[++n], &maxage); } else
1088  if ((strcmp(argv[n],"-delay")==0) && (n+1<argc)) { dabc::str_to_double(argv[++n], &debug_delay); } else
1089  if ((strcmp(argv[n],"-mhz")==0) && (n+1<argc)) {
1090  dabc::str_to_double(argv[++n], &mhz);
1091  use_400mhz = true; coarse_tmlen = 1000./mhz; fine_min = 0x5; fine_max = 0xc0;
1092  } else
1093  if (strcmp(argv[n],"-bubble")==0) { bubble_mode = true; } else
1094  if (strcmp(argv[n],"-bubb18")==0) { bubble_mode = true; BUBBLE_SIZE = 18; } else
1095  if (strcmp(argv[n],"-bubb19")==0) { bubble_mode = true; BUBBLE_SIZE = 19; } else
1096  if (strcmp(argv[n],"-onlyerr")==0) { only_errors = true; } else
1097  if (strcmp(argv[n],"-raw")==0) { printraw = true; } else
1098  if (strcmp(argv[n],"-sub")==0) { printsub = true; } else
1099  if (strcmp(argv[n],"-auto")==0) { autoid = true; printsub = true; } else
1100  if (strcmp(argv[n],"-stat")==0) { dostat = true; } else
1101  if (strcmp(argv[n],"-rate")==0) { showrate = true; reconnect = true; } else
1102  if (strcmp(argv[n],"-bw")==0) { use_colors = false; } else
1103  if (strcmp(argv[n],"-sub")==0) { printsub = true; } else
1104  if (strcmp(argv[n],"-ignorecalibr")==0) { use_calibr = false; } else
1105  if (strcmp(argv[n],"-340")==0) { use_400mhz = true; coarse_tmlen = 1000./340.; fine_min = 0x5; fine_max = 0xc0; } else
1106  if (strcmp(argv[n],"-400")==0) { use_400mhz = true; coarse_tmlen = 1000./400.; fine_min = 0x5; fine_max = 0xc0; } else
1107  if ((strcmp(argv[n],"-help")==0) || (strcmp(argv[n],"?")==0)) return usage(); else
1108  if (strcmp(argv[n],"-again")==0) {
1109  if ((n+1 < argc) && (argv[n+1][0] != '-')) dabc::str_to_lint(argv[++n], &nagain);
1110  else nagain++;
1111  } else
1112  return usage("Unknown option");
1113  }
1114 
1115  if ((adcmask!=0) || !tdcs.empty() || (onlytdc!=0) || (onlynew!=0) || (onlyraw!=0)) { printsub = true; }
1116 
1117  printf("Try to open %s\n", argv[1]);
1118 
1119  bool ishld = false;
1120  std::string src = argv[1];
1121  if ((src.find(".hld") != std::string::npos) && (src.find("hld://") != 0)) {
1122  src = std::string("hld://") + src;
1123  ishld = true;
1124  }
1125 
1126  if ((src.find("hld://") == 0) || (src.find(".hld") != std::string::npos)) ishld = true;
1127 
1128  if (tmout < 0) tmout = ishld ? 0.5 : 5.;
1129 
1130  if (!ishld) {
1131 
1132  dabc::Url url(src);
1133 
1134  if (url.IsValid()) {
1135  if (url.GetProtocol().empty())
1136  src = std::string("mbss://") + src;
1137 
1138  if (reconnect && !url.HasOption("reconnect")) {
1139  if (url.GetOptions().empty())
1140  src+="?reconnect";
1141  else
1142  src+="&reconnect";
1143  }
1144  }
1145  }
1146 
1147 
1148  hadaq::RawEvent *evnt = nullptr;
1149 
1150  std::map<unsigned,SubevStat> idstat; // events id statistic
1151  std::map<unsigned,SubevStat> substat; // sub-events statistic
1152  std::map<unsigned,SubevStat> subsubstat; // sub-sub-events statistic
1153  long cnt(0), cnt0(0), lastcnt(0), printcnt(0);
1154  uint64_t lastsz{0}, currsz{0};
1155  dabc::TimeStamp last, first, lastevtm;
1156 
1158 
1160 
1161  while (nagain-- >= 0) {
1162 
1163  ref = hadaq::ReadoutHandle::Connect(src.c_str());
1164 
1165  if (ref.null()) return 1;
1166 
1167  idstat.clear();
1168  substat.clear();
1169  subsubstat.clear();
1170  cnt = cnt0 = lastcnt = printcnt = 0;
1171  lastsz = currsz = 0;
1172  last = first = lastevtm = dabc::Now();
1173 
1174  while (!dabc::CtrlCPressed()) {
1175 
1176  evnt = ref.NextEvent(maxage > 0 ? maxage/2. : 1., maxage);
1177 
1178  cnt0++;
1179 
1180  if (debug_delay>0) dabc::Sleep(debug_delay);
1181 
1182  dabc::TimeStamp curr = dabc::Now();
1183 
1184  if (evnt) {
1185 
1186  if (dostat)
1187  idstat[evnt->GetId()].accumulate(evnt->GetSize());
1188 
1189  // ignore events which are nor match with specified id
1190  if ((fullid!=0) && (evnt->GetId()!=fullid)) continue;
1191 
1192  cnt++;
1193  currsz+=evnt->GetSize();
1194  lastevtm = curr;
1195  } else if (curr - lastevtm > tmout) {
1196  /*printf("TIMEOUT %ld\n", cnt0);*/
1197  break;
1198  }
1199 
1200  if (showrate) {
1201 
1202  double tm = curr - last;
1203 
1204  if (tm>=0.3) {
1205  printf("\rTm:%6.1fs Ev:%8ld Rate:%8.2f Ev/s %6.2f MB/s", first.SpentTillNow(), cnt, (cnt-lastcnt)/tm, (currsz-lastsz)/tm/1024./1024.);
1206  fflush(stdout);
1207  last = curr;
1208  lastcnt = cnt;
1209  lastsz = currsz;
1210  }
1211 
1212  // when showing rate, only with statistic one need to analyze event
1213  if (!dostat) continue;
1214  }
1215 
1216  if (!evnt) continue;
1217 
1218  if (skip>0) { skip--; continue; }
1219 
1220  if (dofind) {
1221  if (find_eventid) {
1222  if (evnt->GetSeqNr() != find_eventid) continue;
1223  } else {
1224  auto *sub = evnt->NextSubevent(nullptr);
1225  if (!sub || (sub->GetTrigNr() != find_trigid)) continue;
1226  }
1227  dofind = false; // disable finding
1228  }
1229 
1230  printcnt++;
1231 
1232  bool print_header(false);
1233 
1234  if (!showrate && !dostat && !only_errors && (onlymonitor==0)) {
1235  print_header = true;
1236  evnt->Dump();
1237  }
1238 
1239  char errbuf[100];
1240 
1241  hadaq::RawSubevent* sub = nullptr;
1242  while ((sub = evnt->NextSubevent(sub)) != nullptr) {
1243 
1244  bool print_sub_header(false);
1245  if ((onlytdc==0) && (onlynew==0) && (onlyraw==0) && (onlymonitor==0) && !showrate && !dostat && !only_errors) {
1246  sub->Dump(printraw && !printsub);
1247  print_sub_header = true;
1248  }
1249 
1250  unsigned trbSubEvSize = sub->GetSize() / 4 - 4, ix = 0,
1251  maxhublen = 0, lasthubid = 0, lasthublen = 0,
1252  maxhhublen = 0, lasthhubid = 0, lasthhublen = 0,
1253  data, datalen, datakind;
1254 
1255  bool standalone_subevnt = sub->GetDecoding() & hadaq::EvtDecoding_AloneSubevt;
1256 
1257  if (dostat)
1258  substat[sub->GetId()].accumulate(sub->GetSize());
1259 
1260  if (onlymonitor != 0) {
1261  if (sub->GetId() == onlymonitor) {
1262  evnt->Dump();
1263  sub->Dump(printraw);
1264  if (!printraw)
1265  PrintMonitorData(sub);
1266  }
1267  break;
1268  }
1269 
1270  while ((ix < trbSubEvSize) && (printsub || dostat)) {
1271 
1272  if (standalone_subevnt && (ix == 0)) {
1273  data = 0; // unused
1274  datalen = trbSubEvSize - 2; // whole subevent beside last 2 words with 0x5555 id
1275  datakind = sub->GetId();
1276  } else {
1277  data = sub->Data(ix++);
1278  datalen = (data >> 16) & 0xFFFF;
1279  datakind = data & 0xFFFF;
1280  }
1281 
1282  errbuf[0] = 0;
1283  if (maxhhublen > 0) {
1284  if (datalen >= maxhhublen) datalen = maxhhublen-1;
1285  maxhhublen -= (datalen+1);
1286  } else {
1287  lasthhubid = 0;
1288  }
1289 
1290  bool as_raw = false, as_cts = false, as_tdc = false, as_new = false, as_adc = false,
1291  print_subsubhdr = (onlytdc==0) && (onlynew==0) && (onlyraw==0) && !only_errors;
1292 
1293  if (maxhublen > 0) {
1294 
1295  if (is_hub(datakind)) {
1296  maxhublen--; // just decrement
1297  if (dostat) {
1298  subsubstat[datakind].accumulate(datalen);
1299  } else if (!showrate && print_subsubhdr) {
1300  printf(" *** HHUB size %3u id 0x%04x full %08x\n", datalen, datakind, data);
1301  }
1302  maxhhublen = datalen;
1303  lasthhubid = datakind;
1304  lasthhublen = datalen;
1305  continue;
1306  }
1307 
1308  if (datalen >= maxhublen) {
1309  snprintf(errbuf, sizeof(errbuf), " wrong format, want size 0x%04x", datalen);
1310  datalen = maxhublen-1;
1311  }
1312  maxhublen -= (datalen+1);
1313  } else {
1314  lasthubid = 0;
1315  }
1316 
1317  if (is_tdc(datakind)) as_tdc = !onlytdc && !onlynew;
1318 
1319  if (is_newtdc(datakind)) as_new = !onlytdc && !onlynew;
1320 
1321  if (!as_tdc) {
1322  if ((onlytdc!=0) && (datakind == onlytdc)) {
1323  as_tdc = true;
1324  print_subsubhdr = true;
1325  } else if ((onlynew!=0) && (datakind == onlynew)) {
1326  as_new = true;
1327  print_subsubhdr = true;
1328  } else if (is_cts(datakind)) {
1329  as_cts = true;
1330  } else if (is_adc(datakind)) {
1331  as_adc = true;
1332  } else if ((maxhublen==0) && is_hub(datakind)) {
1333  // this is hack - skip hub header, inside is normal subsub events structure
1334  if (dostat) {
1335  subsubstat[datakind].accumulate(datalen);
1336  } else if (!showrate && print_subsubhdr) {
1337  printf(" *** HUB size %3u id 0x%04x full %08x\n", datalen, datakind, data);
1338  }
1339  maxhublen = datalen;
1340  lasthubid = datakind;
1341  lasthublen = datalen;
1342  continue;
1343  } else if ((onlyraw!=0) && (datakind==onlyraw)) {
1344  as_raw = true;
1345  print_subsubhdr = true;
1346  } else if (printraw) {
1347  as_raw = (onlytdc==0) && (onlynew==0) && (onlyraw==0);
1348  }
1349  }
1350 
1351  if (!dostat && !showrate) {
1352  // do raw printout when necessary
1353 
1354  unsigned errmask(0);
1355 
1356  if (only_errors) {
1357  // only check data without printing
1358  if (as_tdc) PrintTdcData(sub, ix, datalen, 0, errmask);
1359  // no errors - no print
1360  if (errmask==0) { ix+=datalen; continue; }
1361 
1362  print_subsubhdr = true;
1363  errmask = 0;
1364  }
1365 
1366  if (as_raw || as_tdc || as_new || as_adc) {
1367  if (!print_header) {
1368  print_header = true;
1369  evnt->Dump();
1370  }
1371 
1372  if (!print_sub_header) {
1373  sub->Dump(false);
1374  if (lasthubid!=0)
1375  printf(" *** HUB size %3u id 0x%04x\n", lasthublen, lasthubid);
1376  if (lasthhubid!=0)
1377  printf(" *** HHUB size %3u id 0x%04x\n", lasthhublen, lasthhubid);
1378  print_sub_header = true;
1379  }
1380  }
1381 
1382  unsigned prefix(9);
1383  if (lasthhubid!=0) prefix = 15; else if (lasthubid!=0) prefix = 12;
1384 
1385  // when print raw selected with autoid, really print raw
1386  if (printraw && autoid && as_tdc) { as_tdc = false; as_raw = true; }
1387 
1388  if (print_subsubhdr) {
1389  const char *kind = "Subsubevent";
1390  if (as_tdc) kind = "TDC "; else
1391  if (as_new) kind = "TDC "; else
1392  if (as_cts) kind = "CTS "; else
1393  if (as_adc) kind = "ADC ";
1394 
1395  printf("%*s*** %s size %3u id 0x%04x", prefix-3, "", kind, datalen, datakind);
1396  if(standalone_subevnt && (ix == 0))
1397  printf(" alone");
1398  else
1399  printf(" full %08x", data);
1400  printf("%s\n", errbuf);
1401  }
1402 
1403  if (as_tdc) PrintTdcData(sub, ix, datalen, prefix, errmask); else
1404  if (as_new) PrintTdc4Data(sub, ix, datalen, prefix); else
1405  if (as_adc) PrintAdcData(sub, ix, datalen, prefix); else
1406  if (as_cts) PrintCtsData(sub, ix, datalen, prefix); else
1407  if (as_raw) sub->PrintRawData(ix, datalen, prefix);
1408 
1409  if (errmask!=0) {
1410  printf(" %s!!!! TDC errors:%s", getCol(col_RED), getCol(col_RESET));
1411  unsigned mask = 1;
1412  for (int n=0;n<NumTdcErr;n++,mask*=2)
1413  if (errmask & mask) printf(" err_%s", TdcErrName(n));
1414  printf("\n");
1415  }
1416  } else
1417  if (dostat) {
1418  SubevStat &substat = subsubstat[datakind];
1419 
1420  substat.num++;
1421  substat.sizesum+=datalen;
1422  if (as_tdc) {
1423  substat.istdc = true;
1424  unsigned errmask(0);
1425  PrintTdcData(sub, ix, datalen, 0, errmask, &substat);
1426  unsigned mask = 1;
1427  for (int n=0;n<NumTdcErr;n++,mask*=2)
1428  if (errmask & mask) substat.IncTdcError(n);
1429  }
1430  }
1431 
1432  ix+=datalen;
1433  }
1434  }
1435 
1436  if ((number>0) && (printcnt>=number)) break;
1437  }
1438 
1439  if (showrate) {
1440  printf("\n");
1441  fflush(stdout);
1442  }
1443 
1444  ref.Disconnect();
1445 
1446  if (dostat) {
1447  printf("Statistic: %ld events analyzed\n", printcnt);
1448 
1449  int width = 3;
1450  if (printcnt > 1000) width = 6;
1451 
1452  printf(" Events ids:\n");
1453  for (auto &entry : idstat)
1454  printf(" 0x%04x : cnt %*lu averlen %6.1f\n", entry.first, width, entry.second.num, entry.second.aver_size());
1455 
1456  printf(" Subevents ids:\n");
1457  for (auto &entry : substat)
1458  printf(" 0x%04x : cnt %*lu averlen %6.1f\n", entry.first, width, entry.second.num, entry.second.aver_size());
1459 
1460  printf(" Subsubevents ids:\n");
1461  for (auto &entry : subsubstat) {
1462  SubevStat &substat = entry.second;
1463 
1464  printf(" 0x%04x : cnt %*lu averlen %6.1f", entry.first, width, substat.num, substat.aver_size());
1465 
1466  if (substat.istdc) {
1467  printf(" TDC ch:%2u", substat.maxch);
1468  for (unsigned n=0;n<substat.tdcerr.size();n++)
1469  if (substat.tdcerr[n] > 0) {
1470  printf(" %s=%lu (%3.1f%s)", TdcErrName(n), substat.tdcerr[n], substat.tdcerr_rel(n) * 100., "\%");
1471  }
1472  }
1473 
1474  printf("\n");
1475  }
1476  }
1477 
1478  if (dabc::CtrlCPressed()) break;
1479 
1480  } // ngain--
1481 
1482  return 0;
1483 }
Uniform Resource Locator interpreter.
Definition: Url.h:33
bool HasOption(const std::string &optname) const
Definition: Url.h:70
std::string GetProtocol() const
Definition: Url.h:57
std::string GetOptions() const
Definition: Url.h:63
bool IsValid() const
Definition: Url.h:55
hadaq::RawEvent * NextEvent(double tm=1.0, double maxage=-1.)
Retrieve next event from the server.
Definition: api.cxx:47
bool null() const
Return true if handle not initialized.
Definition: api.h:55
bool Disconnect()
Disconnect from MBS server.
Definition: api.h:58
static ReadoutHandle Connect(const std::string &url)
Connect with data source.
Definition: api.cxx:35
const char * TdcErrName(int cnt)
Definition: hldprint.cxx:130
bool autoid
Definition: hldprint.cxx:994
unsigned fine_max
Definition: hldprint.cxx:172
int main(int argc, char *argv[])
Definition: hldprint.cxx:1050
unsigned adcmask
Definition: hldprint.cxx:995
TrbDecodeKind
Definition: hldprint.cxx:92
@ decode_SingleSubev
Definition: hldprint.cxx:93
int usage(const char *errstr=nullptr)
Definition: hldprint.cxx:28
const char * getCol(const char *col_name)
Definition: hldprint.cxx:176
void PrintAdcData(hadaq::RawSubevent *sub, unsigned ix, unsigned len, unsigned prefix)
Definition: hldprint.cxx:959
unsigned hubmask
Definition: hldprint.cxx:995
TdcMessageKind
Definition: hldprint.cxx:96
@ tdckind_Mask
Definition: hldprint.cxx:101
@ tdckind_Reserved
Definition: hldprint.cxx:97
@ tdckind_Calibr
Definition: hldprint.cxx:105
@ tdckind_Debug
Definition: hldprint.cxx:99
@ tdckind_Hit1
Definition: hldprint.cxx:103
@ tdckind_Hit2
Definition: hldprint.cxx:104
@ tdckind_Epoch
Definition: hldprint.cxx:100
@ tdckind_Header
Definition: hldprint.cxx:98
@ tdckind_Hit
Definition: hldprint.cxx:102
std::vector< unsigned > newtdcs
Definition: hldprint.cxx:996
bool printsub
Definition: hldprint.cxx:994
const char * col_RED
Definition: hldprint.cxx:122
void PrintBubble(unsigned *bubble, unsigned len=0)
Definition: hldprint.cxx:305
bool only_errors
Definition: hldprint.cxx:173
void PrintTdcData(hadaq::RawSubevent *sub, unsigned ix, unsigned len, unsigned prefix, unsigned &errmask, SubevStat *substat=nullptr)
Definition: hldprint.cxx:608
bool epoch_per_channel
Definition: hldprint.cxx:173
void PrintCtsData(hadaq::RawSubevent *sub, unsigned ix, unsigned len, unsigned prefix)
Definition: hldprint.cxx:852
unsigned fine_min
Definition: hldprint.cxx:172
bool reconnect
Definition: hldprint.cxx:994
unsigned BUBBLE_SIZE
Definition: hldprint.cxx:216
bool is_newtdc(unsigned id)
Definition: hldprint.cxx:1032
unsigned onlynew
Definition: hldprint.cxx:995
unsigned fullid
Definition: hldprint.cxx:995
TdcErrorsKind
Definition: hldprint.cxx:110
@ tdcerr_Sequence
Definition: hldprint.cxx:115
@ tdcerr_ToT
Definition: hldprint.cxx:116
@ tdcerr_NoData
Definition: hldprint.cxx:114
@ tdcerr_MissEpoch
Definition: hldprint.cxx:113
@ tdcerr_MissHeader
Definition: hldprint.cxx:111
@ tdcerr_MissCh0
Definition: hldprint.cxx:112
const char * col_MAGENTA
Definition: hldprint.cxx:126
const char * debug_name[32]
Definition: hldprint.cxx:181
unsigned idrange
Definition: hldprint.cxx:995
const char * col_CYAN
Definition: hldprint.cxx:127
const char * col_RESET
Definition: hldprint.cxx:120
void PrintMonitorData(hadaq::RawSubevent *sub)
Definition: hldprint.cxx:977
unsigned fine_max4
Definition: hldprint.cxx:172
std::vector< unsigned > ctsids
Definition: hldprint.cxx:996
int onlych
Definition: hldprint.cxx:174
const char * col_YELLOW
Definition: hldprint.cxx:124
bool use_calibr
Definition: hldprint.cxx:173
bool bubble_mode
Definition: hldprint.cxx:173
void PrintTdc4Data(hadaq::RawSubevent *sub, unsigned ix, unsigned len, unsigned prefix)
Definition: hldprint.cxx:444
@ newkind_Mask7
Definition: hldprint.cxx:437
@ newkind_TMDR
Definition: hldprint.cxx:438
@ newkind_CTB
Definition: hldprint.cxx:427
@ newkind_HSDA
Definition: hldprint.cxx:424
@ newkind_TTRM
Definition: hldprint.cxx:432
@ newkind_TMDT
Definition: hldprint.cxx:408
@ newkind_TTRL
Definition: hldprint.cxx:433
@ newkind_HSTL
Definition: hldprint.cxx:423
@ newkind_EPOC
Definition: hldprint.cxx:413
@ newkind_HDR
Definition: hldprint.cxx:411
@ newkind_TMDS
Definition: hldprint.cxx:416
@ newkind_Mask3
Definition: hldprint.cxx:410
@ newkind_TTCM
Definition: hldprint.cxx:434
@ newkind_BAD
Definition: hldprint.cxx:429
@ newkind_TEMP
Definition: hldprint.cxx:428
@ newkind_TBD
Definition: hldprint.cxx:419
@ newkind_TTCL
Definition: hldprint.cxx:435
@ newkind_Mask9
Definition: hldprint.cxx:431
@ newkind_CTA
Definition: hldprint.cxx:426
@ newkind_Mask4
Definition: hldprint.cxx:415
@ newkind_HSTM
Definition: hldprint.cxx:422
@ newkind_Mask6
Definition: hldprint.cxx:418
@ newkind_HSDB
Definition: hldprint.cxx:425
@ newkind_TRL
Definition: hldprint.cxx:412
@ newkind_Mask8
Definition: hldprint.cxx:421
bool is_cts(unsigned id)
Definition: hldprint.cxx:998
unsigned fine_min4
Definition: hldprint.cxx:172
bool is_tdc(unsigned id)
Definition: hldprint.cxx:1014
std::vector< unsigned > tdcs
Definition: hldprint.cxx:996
@ NumTdcErr
Definition: hldprint.cxx:108
unsigned onlymonitor
Definition: hldprint.cxx:995
unsigned onlyraw
Definition: hldprint.cxx:995
bool is_adc(unsigned id)
Definition: hldprint.cxx:1045
const char * col_GREEN
Definition: hldprint.cxx:123
unsigned BubbleCheck(unsigned *bubble, int &p1, int &p2)
Definition: hldprint.cxx:218
double coarse_tmlen(5.)
void PrintBubbleBinary(unsigned *bubble, int p1=-1, int p2=-1)
Definition: hldprint.cxx:321
bool is_hub(unsigned id)
Definition: hldprint.cxx:1003
double tot_limit(20.)
unsigned onlytdc
Definition: hldprint.cxx:995
const char * col_WHITE
Definition: hldprint.cxx:128
bool use_colors
Definition: hldprint.cxx:173
bool printraw
Definition: hldprint.cxx:994
bool use_400mhz
Definition: hldprint.cxx:173
const char * col_BLACK
Definition: hldprint.cxx:121
bool dostat
Definition: hldprint.cxx:994
bool showrate
Definition: hldprint.cxx:994
const char * col_BLUE
Definition: hldprint.cxx:125
double tot_shift(20.)
unsigned skip_msgs_in_tdc
Definition: hldprint.cxx:172
std::vector< unsigned > hubs
Definition: hldprint.cxx:996
bool PrintBubbleData(hadaq::RawSubevent *sub, unsigned ix, unsigned len, unsigned prefix)
Definition: hldprint.cxx:344
void Sleep(double tm)
Definition: timing.cxx:129
bool InstallSignalHandlers()
Method is used to install DABC-specific Ctrl-C handler It allows to correctly stop program execution ...
Definition: api.cxx:83
bool CtrlCPressed()
Returns true when CtrlC was pressed in handler.
Definition: api.cxx:106
bool str_to_uint(const char *val, unsigned *res)
Convert string to unsigned integer value One could use hexadecimal (in form 0xabc100) or decimal form...
Definition: string.cxx:184
TimeStamp Now()
Definition: timing.h:260
bool str_to_double(const char *val, double *res)
Convert string to double value.
Definition: string.cxx:216
bool str_to_lint(const char *val, long *res)
Convert string to long integer value.
Definition: string.cxx:162
bool str_to_int(const char *val, int *res)
Convert string to integer value.
Definition: string.cxx:142
@ EvtDecoding_AloneSubevt
Definition: defines.h:127
long unsigned num
Definition: hldprint.cxx:143
double tdcerr_rel(unsigned n)
Definition: hldprint.cxx:150
SubevStat()=default
void IncTdcError(unsigned id)
Definition: hldprint.cxx:161
void accumulate(unsigned sz)
Definition: hldprint.cxx:155
unsigned maxch
Definition: hldprint.cxx:147
double aver_size()
Definition: hldprint.cxx:149
std::vector< long unsigned > tdcerr
Definition: hldprint.cxx:146
long unsigned sizesum
Definition: hldprint.cxx:144
bool istdc
Definition: hldprint.cxx:145
SubevStat(const SubevStat &src)
Definition: hldprint.cxx:153
Class for acquiring and holding timestamps.
Definition: timing.h:40
double SpentTillNow() const
Method return time in second, spent from the time kept in TimeStamp instance If time was not set befo...
Definition: timing.h:144
uint32_t GetId() const
Definition: defines.h:208
uint32_t GetSize() const
Definition: defines.h:182
uint32_t GetDecoding() const
Definition: defines.h:181
Hadaq event structure.
Definition: defines.h:443
RawSubevent * NextSubevent(RawSubevent *prev=0)
Definition: defines.cxx:66
uint32_t GetSeqNr() const
Definition: defines.h:460
Hadaq subevent structure.
Definition: defines.h:262
uint32_t Data(unsigned idx) const
swap-save access to any data.
Definition: defines.h:309
void Dump(bool print_raw_data=false)
Print subevent header and optionally raw data.
Definition: defines.cxx:97
unsigned Alignment() const
Definition: defines.h:272
void PrintRawData(unsigned ix=0, unsigned len=0xffffffff, unsigned prefix=6)
Print raw data, optionally one can position and portion to print.
Definition: defines.cxx:79