Class Reference for E1039 Core & Analysis Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
MainDaqParser.cc
Go to the documentation of this file.
1 #include <iomanip>
2 #include <sstream>
3 #include "CodaInputManager.h"
4 #include "MainDaqParser.h"
5 using namespace std;
6 
7 // In the current design, all event-word handlers (i.e. functions) should print out all error messages needed, so that their caller should print nothing but just check the returned value.
8 
10  : m_file_size_min(32768), m_sec_wait(15), m_n_wait(40)
11 {
12  coda = new CodaInputManager();
13  list_sd = new SpillDataMap();
14  list_ed = new EventDataMap();
15  sd_now = 0; // Will be just a pointer to one object in "list_sd"
16  list_ed_now = new EventDataMap();
17 }
18 
20 {
21  if (coda ) delete coda;
22  if (list_sd ) delete list_sd;
23  if (list_ed ) delete list_ed;
24  if (list_ed_now) delete list_ed_now;
25 }
26 
27 int MainDaqParser::OpenCodaFile(const std::string fname, const long file_size_min, const int sec_wait, const int n_wait)
28 {
29  m_file_size_min = file_size_min;
30  m_sec_wait = sec_wait;
31  m_n_wait = n_wait;
32  dec_par.timeStart = time(NULL);
33  dec_par.fn_in = fname;
34  return coda->OpenFile(fname, file_size_min, sec_wait, n_wait);
35 }
36 
38 {
39  static EventDataMap::iterator it = list_ed_now->begin();
40  if (it == list_ed_now->end()) { // No event in the event buffer
41  list_ed_now->clear();
42  while (list_ed_now->size() == 0 && ! coda->IsEnded()) {
43  ParseOneSpill();
44  }
45  it = list_ed_now->begin();
46  }
47  if (it != list_ed_now->end()) {
48  rd = &run_data;
49  sd = sd_now;
50  ed = &it->second;
51  it++;
52  return true;
53  } else {
54  rd = 0;
55  sd = 0;
56  ed = 0;
57  return false;
58  }
59 }
60 
61 int MainDaqParser::ParseOneSpill()
62 {
63  static bool call_1st = true;
64  if (call_1st) call_1st = false;
65  else if (dec_par.time_wait > 0) {
66  cout << "...sleep(" << dec_par.time_wait << ") to pretend waiting for next spill..." << endl;
67  for (int ii = dec_par.time_wait; ii > 0; ii--) sleep(1); // Looped to accept the online-monitor connection.
68  cout << "...done." << endl;
69  }
70 
71  dec_par.at_bos = false;
72  int* event_words = 0;
73  while (coda->NextCodaEvent(dec_par.codaID, event_words)) {
74  //cout << "NextCodaEvent(): " << dec_par.codaID << " 0x" << hex << event_words[1] << dec << endl;
75  int ret = 0;
76  int evt_type_id = event_words[1];
77 
78  // The last 4 hex digits will be 0x01cc for Prestart, Go Event,
79  // and End Event, and 0x10cc for Physics Events
80  switch (evt_type_id & 0xFFFF) {
81  case PHYSICS_EVENT:
82  ret = ProcessCodaPhysics(event_words);
83  break;
84  case CODA_EVENT:
85  switch (evt_type_id) {
86  case PRESTART_EVENT:
87  ret = ProcessCodaPrestart(event_words);
88  break;
89  case GO_EVENT: // do nothing
90  break;
91  case END_EVENT:
92  coda->ForceEnd(); //if (dec_par.verbose) printf ("End Event Processed\n");
93  break;
94  default:
95  cerr << "!!ERROR!! Uncovered Coda event type: " << evt_type_id << ". Exit." << endl;
96  return false;
97  }
98  break;
99  case FEE_PREFIX:
100  ret = ProcessCodaFee(event_words);
101  break;
102  case 0: // Special case which requires waiting and retrying. Purpose?? Still needed??
103  cout << "Case '0' @ coda " << dec_par.codaID << "." << endl;
104  ret = coda->OpenFile(dec_par.fn_in, m_file_size_min, m_sec_wait, m_n_wait);
105  if (ret == 0) {
106  ret = coda->JumpCodaEvent(dec_par.codaID, event_words, dec_par.codaID - 1) ? 0 : 2;
107  }
108  break;
109  default: // If no match to any given case, print it and exit.
110  cerr << "!!ERROR!! Uncovered Coda event type: " << evt_type_id << ". Exit." << endl;
111  return false;
112  }
113  if (ret != 0) {
114  cout << "WARNING: ParseOneSpill(): ret = " << ret << endl;
115  break;
116  }
117  if (dec_par.at_bos) break;
118  }
119  return 0;
120 }
121 
126 {
127  coda->CloseFile();
128  dec_par.timeEnd = time(NULL);
129  if (dec_par.verbose) {
130  cout << "\nStatistics in MainDaqParser:\n"
131  << " Phys events: all = " << run_data.n_phys_evt << "\n"
132  << " Flush events: all = " << run_data.n_flush_evt << "\n"
133  << " v1495 events: all = " << run_data.n_v1495 << ", 0xd1ad = " << run_data.n_v1495_d1ad << ", 0xd2ad = " << run_data.n_v1495_d2ad << ", 0xd3ad = " << run_data.n_v1495_d3ad << "\n"
134  << " Real events: all = " << run_data.n_evt_all << ", decoded = " << run_data.n_evt_dec << "\n"
135  << " TDC hits: total = " << run_data.n_hit << ", bad = " << run_data.n_hit_bad << "\n"
136  << " v1495 hits: total = " << run_data.n_t_hit << ", bad = " << run_data.n_t_hit_bad << "\n"
137  << " Real decoding time: " << (dec_par.timeEnd - dec_par.timeStart) << endl;
138  }
139  if (dec_par.is_online) {
140  dec_err.PrintData();
141  dec_err.InitData();
142  }
143  return 0;
144 }
145 
151 int MainDaqParser::ProcessCodaPrestart(int* words)
152 {
153  // int evLength = words[0];
154  // int prestartCode = words[1];
155  run_data.utime_b = words[2];
156  dec_par.runID = run_data.run_id = words[3];
157  // int runType = words[4];
158 
159  cout << " ProcessCodaPrestart " << dec_par.runID << " " << run_data.utime_b << " " << dec_par.sampling << endl;
160 
162  coda->SetRunNumber(dec_par.runID);
163 
164  return 0;
165 }
166 
167 int MainDaqParser::ProcessCodaFee(int* words)
168 {
169  if (words[1] != FEE_EVENT) {
170  cerr << "!!ERROR!! Not FEE_EVENT in case of FEE_PREFIX: " << words[1] << ". Exit." << endl;
171  return 1;
172  }
173  if (words[0] > 8) { // Process only if there is content
174  if (words[3] == (int)0xe906f011) {
175  return ProcessCodaFeeBoard(words);
176  } else if (words[3] == (int)0xe906f012) {
177  if (dec_par.verbose) cout << "feePrescale: codaEventID = " << dec_par.codaID << endl;
178  return ProcessCodaFeePrescale(words);
179  }
180  }
181  return 0;
182 }
183 
184 int MainDaqParser::ProcessCodaFeeBoard(int* words)
185 {
186  if (dec_par.verbose > 1) cout << "CodaFeeBoard: coda = " << dec_par.codaID << endl;
187 
188  FeeData data;
189  int size = words[0];
190  data.roc = words[2];
191  int i_wd = 3;
192  while (i_wd < size)
193  {
194  // words[i_wd] = 0xe906f011 // ignore this flag
195  i_wd++;
196  // This word contains only the boardID
197  data.board = get_hex_bits (words[i_wd], 7, 4);
198  data.hard = get_hex_bits (words[i_wd], 1, 2);
199  i_wd++;
200  // This is the TDC registry word
201  data.falling_enabled = get_hex_bit (words[i_wd], 2);
202  data.segmentation = get_hex_bit (words[i_wd], 1);
203  if ( data.segmentation == 0 ) data.segmentation = 512;
204  else if ( data.segmentation == 2 ) data.segmentation = 1024;
205  else if ( data.segmentation == 6 ) data.segmentation = 2048;
206 
207  i_wd++;
208  // Another TDC registry word
209  data.multihit_elim_enabled = get_bin_bit (words[i_wd], 23);
210  data.updating_enabled = get_bin_bit (words[i_wd], 22);
211 
212  data.elim_window = 0;
213  if (data.multihit_elim_enabled) {
214  data.elim_window = get_bin_bits (words[i_wd], 21, 6);
215  data.elim_window = 4 * (4 + data.elim_window);
216  }
217 
218  i_wd++;
219  data.lowLimit = get_hex_bits(words[i_wd], 2, 3);
220  data.highLimit = get_hex_bits(words[i_wd], 6, 3);
221  data.selectWindow = (get_hex_bit (words[i_wd], 7) == 8 ? 1 : 0);
222  i_wd++;
223 
224  run_data.fee.push_back(data);
225  if (dec_par.verbose > 1) {
226  cout << " feeE " << data.roc << " " << data.board << " " << data.hard
227  << " " << data.falling_enabled << " " << data.segmentation
228  << " " << data.multihit_elim_enabled << " " << data.updating_enabled
229  << " " << data.elim_window << " " << data.selectWindow << " "
230  << data.lowLimit << " " << data.highLimit << endl;
231  }
232  }
233 
234  run_data.n_fee_event++;
235  return 0;
236 }
237 
238 int MainDaqParser::ProcessCodaFeePrescale(int* words)
239 {
240  if (dec_par.verbose > 1) cout << "CodaFeePrescale: coda = " << dec_par.codaID << endl;
241  int feeTriggerBits = words[4];
243  for (int ii = 0; ii < 10; ii++) {
244  run_data.trig_bit[ii] = get_bin_bit (feeTriggerBits, ii);
245  }
246  for (int ii = 0; ii < 5; ii++) run_data.fpga_enabled[ii] = get_bin_bit (feeTriggerBits, ii );
247  for (int ii = 0; ii < 5; ii++) run_data. nim_enabled[ii] = get_bin_bit (feeTriggerBits, ii+5);
248 
250  for (int ii = 0; ii < 8; ii++) {
251  run_data.prescale[ii] = words[ii + 5];
252  }
253  for (int ii = 0; ii < 5; ii++) run_data.fpga_prescale[ii] = words[ii + 5];
254  for (int ii = 0; ii < 3; ii++) run_data. nim_prescale[ii] = words[ii + 10];
255 
256  run_data.n_fee_prescale++;
257  if (dec_par.verbose > 1) {
258  cout << " feeP ";
259  for (int ii = 0; ii < 10; ii++) cout << " " << run_data.trig_bit[ii];
260  cout << "\n feeP ";
261  for (int ii = 0; ii < 8; ii++) cout << " " << run_data.prescale[ii];
262  cout << endl;
263  }
264  return 0;
265 }
266 
277 int MainDaqParser::ProcessCodaPhysics(int* words)
278 {
279  run_data.n_phys_evt++;
280  int eventCode = words[1];
281  int ret = 0;
282  switch (get_hex_bits(eventCode, 7, 4) ) {
283  case FLUSH_EVENTS:
285  //PrintWords(words, 0, evLength);
286  //PrintCodaEventSummary(words);
287  if (! dec_par.has_1st_bos) break;
288  run_data.n_flush_evt++;
289  ret = ProcessPhysFlush(words);
290  if (dec_err.GetFlushError()) run_data.n_flush_evt_bad++;
291  break;
292  case SLOW_CONTROL:
293  ret = ProcessPhysSlow(words);
294  break;
295  case PRESTART_INFO:
296  ret = ProcessPhysPrestart(words);
297  break;
298  case STANDARD_PHYSICS:
300  //if (! dec_par.has_1st_bos) break;
301  //dec_par.eventIDstd++;
302  //SetEventInfo(&(*list_ed)[dec_par.eventIDstd].event, dec_par.eventIDstd);
303  //ret = ProcessPhysFlush(words); // This function handles STANDARD_PHYSICS as well.
304  break;
305  case SPILL_COUNTER:
306  ret = ProcessPhysSpillCounter(words);
307  break;
308  case RUN_DESCRIPTOR:
309  ret = ProcessPhysRunDesc(words);
310  break;
311  case BEGIN_SPILL:
312  ret = ProcessPhysBOSEOS(words, TYPE_BOS);
313  break;
314  case END_SPILL:
315  ret = ProcessPhysBOSEOS(words, TYPE_EOS);
316  break;
317  default: // Awaiting further event types
318  ret = -1;
319  cout << "Unknown event code: " << eventCode << ". Ignore." << endl;
320  break;
321  }
322  if (ret != 0) run_data.n_phys_evt_bad++;
323  return ret;
324 }
325 
326 int MainDaqParser::ProcessPhysRunDesc(int* words)
327 {
328  string desc = "";
329  int evLength = words[0];
330  // Assemble the descriptor from the hex
331  for (int i_wd = 4; i_wd < (evLength + 1); i_wd++) {
332  unsigned int number = words[i_wd];
333  for (int ii = 0; ii < 4; ii++) {
334  char word = (char)(number & 0xFF);
335  if (word == 0x22) word = 0x27; // replace " with '.
336  desc += word;
337  number = number >> 8;
338  }
339  }
340  run_data.run_desc = desc;
341  run_data.n_run_desc++;
342  cout << " run desc: " << desc.length() << " chars." << endl;
343  return 0;
344 }
345 
346 // Called in ProcessCodaPhysics() on PRESTART_INFO
347 // ProcessPhysEvent() is called in main() on PHYSICS_EVENT
348 // Never called as long as checking run 28700??
349 int MainDaqParser::ProcessPhysPrestart(int* words)
350 {
351  int evLength = words[0];
352  vector<string> list_line;
353  string line = "";
354  for (int i_wd = 4; i_wd < (evLength + 1); i_wd++) {
355  unsigned int number = words[i_wd];
356  for (int ii = 0; ii < 4; ii++) {
357  if ((number & 0xFF) == '\n') {
358  list_line.push_back(line);
359  line = "";
360  } else {
361  line += (char)(number & 0xFF);
362  }
363  number = number >> 8;
364  }
365  }
366  if (line.length() > 0) list_line.push_back(line);
367  else cerr << "Unexpectedly line.length() == 0." << endl;
368  for (unsigned int ii = 0; ii < list_line.size(); ii++) {
369  cout << " pre " << list_line[ii] << endl;
370  }
371  return 0;
372 }
373 
389 int MainDaqParser::ProcessPhysSlow(int* words)
390 {
391  if (dec_par.verbose) cout << "Slow Cont @ coda " << dec_par.codaID << ": ";
392  int evLength = words[0];
393  dec_par.targPos_slow = 0;
394 
395  vector<string> list_line;
396  string line = "";
397  for (int i_wd = 4; i_wd < (evLength + 1); i_wd++) {
398  unsigned int number = words[i_wd];
399  for (int ii = 0; ii < 4; ii++) {
400  if ((number & 0xFF) == '\n') {
401  list_line.push_back(line);
402  line = "";
403  } else {
404  line += (char)(number & 0xFF);
405  }
406  number = number >> 8;
407  }
408  }
409  if (line.length() > 0) list_line.push_back(line);
410  else cout << "WARNING: Unexpectedly line.length() == 0." << endl;
411 
412  std::vector<SlowControlData> list_data; //< temporary list
413  for (unsigned int ii = 0; ii < list_line.size(); ii++) {
414  istringstream iss(list_line[ii]);
415  string ts, name, value, type;
416  iss >> ts >> name >> value >> type;
417  if (name == "TARGPOS_CONTROL" ) dec_par.targPos_slow = atoi(value.c_str());
418  else if (name == "local_spillcount") dec_par.spillID_slow = atoi(value.c_str()) + 1;
419  //if (dec_par.verbose) cout << " slow [" << ts << "] [" << name << "] [" << value << "] [" << type <<"]\n";
420  SlowControlData data;
421  data.ts = ts;
422  data.name = name;
423  data.value = value;
424  data.type = type;
425  list_data.push_back(data);
426  // Kenichi found on 2018-08-30 that the past (and current) decoder always miss the entry with name=U:TODB25
427  // since it value includes ' '. He believe it has to be fixed at the slowcontrol side (i.e. removing ' ').
428  }
429  for (unsigned int ii = 0; ii < list_data.size(); ii++) {
430  unsigned int spill_id = dec_par.spillID_slow - 1; // default value
431  SlowControlData* data = &list_data[ii];
432  if ( data->type == "target" &&
433  (data->name == "TARGPOS_CONTROL" ||
434  data->name.substr(0, 4) == "FREQ" ||
435  data->name.substr(0, 4) == "PROX" ||
436  data->name.substr(0, 5) == "TARG_" ) ) {
437  spill_id = dec_par.spillID_slow; // No "- 1" according to the original decoder.
438  }
439  SpillData* spill_data = &(*list_sd)[spill_id];
440  spill_data->spill_id = spill_id;
441  spill_data->list_slow_cont.push_back(*data); // put into the global list
442  spill_data->n_slow++;
443  }
444  if (dec_par.verbose) cout << " spill " << dec_par.spillID_slow << ", target " << (short)dec_par.targPos_slow << endl;
445  // In the past decoder, almost all variables obtained here are inserted into
446  // the Beam, HV, Environment and Target tables according to "type".
447  return 0;
448 }
449 
456 int MainDaqParser::ProcessPhysSpillCounter(int* words)
457 {
458  int n_wd = words[0];
459  int i_wd_sc = 0;
460  char spillNum[12];
461  for (int i_wd = 4; i_wd < n_wd + 1; i_wd++) {
462  int number = words[i_wd];
463  for (int i_byte = 0; i_byte < 4; i_byte++) {
464  spillNum[i_wd_sc++] = (char)(number & 0xFF);
465  number = number >> 8;
466  }
467  }
468  spillNum[i_wd_sc] = '\0';
469 
473  dec_par.spillID_cntr = atoi(spillNum) + 1;
474  if (dec_par.verbose) {
475  cout << "Spill Counter @ coda = " << dec_par.codaID << ": spill = " << dec_par.spillID_cntr << endl;
476  }
477  run_data.n_spill++;
478  return 0;
479 }
480 
481 int MainDaqParser::ProcessPhysBOSEOS(int* words, const int type)
482 {
483  string type_str = (type == TYPE_BOS ? "BOS" : "EOS");
484  if (type == TYPE_BOS) {
485  dec_par.has_1st_bos = true;
486  dec_par.at_bos = true;
487  if (PackOneSpillData() != 0) { // if (SubmitEventData() != 0) {
488  cout << "Error submitting data. Exiting..." << endl;
489  return 1;
490  }
491 
495  static int spillID_local = 0;
496  dec_par.spillID_cntr = ++spillID_local;
497 
501  SpillData* data = &(*list_sd)[dec_par.spillID];
502  data->spill_id = dec_par.spillID;
504  data->run_id = dec_par.runID;
505  data->targ_pos = dec_par.targPos;
506 
509  dec_par.turn_id_max = 0;
510  }
511 
512  if (dec_par.verbose) {
513  cout << type_str << " @ coda " << dec_par.codaID << ": spill " << dec_par.spillID << "." << endl;
514  }
515  dec_par.spillType = type;
516 
517  int idx = 7;
518  int evLength = words[0];
519  while (idx < evLength && (words[idx] & 0xfffff000) != 0xe906f000) {
520  int rocEvLength = words[idx];
521  int idx_roc_end = idx + rocEvLength; // inclusive endpoint
522  if ( (rocEvLength + idx) > evLength) {
523  cout << "Word limit error: " << rocEvLength << " + " << idx << " > " << evLength << endl;
524  return 1;
525  }
526  idx++;
527  int rocID = get_hex_bits (words[idx], 7, 4);
528  dec_par.rocID = rocID;
529  idx += 3;
530  int codaEvVmeTime = words[idx];
531  idx++;
532  if (rocID == 2) {
533  SpillData* data = &(*list_sd)[dec_par.spillID];
534  if (type == TYPE_BOS) {
535  data->bos_coda_id = dec_par.codaID;
536  data->bos_vme_time = codaEvVmeTime;
537  data->n_bos_spill++;
538  } else {
539  data->eos_coda_id = dec_par.codaID;
540  data->eos_vme_time = codaEvVmeTime;
541  data->n_eos_spill++;
542  }
543  if (dec_par.verbose > 2) cout << " " << type_str << " spill: " << dec_par.spillID << " " << dec_par.runID << " " << dec_par.codaID << " " << (short)dec_par.targPos << " " << codaEvVmeTime << endl;
544  }
546  if (type != TYPE_BOS && rocID == 25) idx = idx_roc_end + 1;
547 
550  if (rocEvLength <= 6) idx = idx_roc_end + 1;
551 
552  while (idx <= idx_roc_end) {
553  int e906flag = words[idx];
554  //cout << " " << type_str << " " << idx << " 0x" << hex << e906flag << dec << endl;
555  idx++;
556  idx = ProcessBoardData (words, idx, idx_roc_end, e906flag);
557  if (idx == -1) return 0;
558  }
559  }
560  return 0;
561 }
562 
569 int MainDaqParser::ProcessPhysFlush(int* words)
570 {
571  const bool print_event = false;
572  int evLength = words[0];
573  //int codaEvVmeTime = 0;
574 
575  dec_err.SetFlushError(false);
576 
577  //PrintWords(words, 0, evLength+1);
578  if (print_event) cout << "\nEvent code = 0x" << hex << words[1] << dec << " (" << evLength << ")";
579 
580  int ret = 0;
581  int idx = 7; // the 1st word of ROC data.
582  while (idx < evLength) { // Loop over ROCs
583  int rocEvLength = words[idx];
584  //KN: In run 23751, ROC 2 often (always?) says "rocEvLength = 6" but
585  // the 1st board (0xe906f00f) says "boardEvLength = 512 or 1024".
586  // We should skip such a case. This problem is not seen in run 23930.
587  if (rocEvLength <= 6) { // Was "< 5" in the previous version.
588  idx += rocEvLength + 1;
589  continue; // Move to next ROC
590  } else if (get_hex_bits(rocEvLength, 7, 4) != 0) {
591  dec_err.SetFlushError(true);
592  cerr << "ERROR: rocEvLength != 0x0000****." << endl;
593  ret = -1;
594  break;
595  }
596 
597  // evLength is all the words summing all ROCs, and rocEvlLength is just for this ROC only.
598  // then, of course, evLength should be greater than rocEvLength
599  int idx_roc_end = idx + rocEvLength + 1; // this index itself is _not_ inside this ROC
600  if (idx_roc_end > evLength + 1) {
601  dec_err.SetFlushError(true);
602  cerr << "ERROR: ROC Event Length exceeds event length\n"
603  << " Event: " << dec_par.codaID << ", EventLength = " << evLength
604  << ", position = " << idx << ", rocEvLength = " << words[idx] << endl;
605  ret = -1;
606  break;
607  }
608 
609  idx++; // go to next position to get ROCID
610  int rocID = get_hex_bits (words[idx], 5, 2);
611  if (rocID > 32) {
612  dec_err.SetFlushError(true);
613  cerr << "ERROR: rocID > 32." << endl;
614  ret = -1;
615  break;
616  }
617  dec_par.rocID = rocID;
618  if (print_event) cout << "\n ROC " << setw(2) << rocID << " (" << setw(3) << rocEvLength << ") |";
619 
620  idx += 3; // move from "rocID" to "vmeTime"
621  //int vmeTime = words[idx];
622  //if (rocID == 2) codaEvVmeTime = vmeTime;
623 
624  idx++; // move to the 1st word of board data
625  while (idx < idx_roc_end) { // Loop over boards
626  int e906flag = words[idx];
627  //cout << " board " << idx << " " << e906flag << endl;
628  if (get_hex_bits(e906flag, 7, 4) != (int)0xe906) {
629  cerr << "Seems not e906flag (0x" << hex << e906flag << dec << ")" << endl;
630  if (dec_par.verbose > 1) {
631  cout << " At idx = " << idx << " / " << evLength << ".\n";
632  PrintWords(words, 0, idx + 20);
633  }
634  idx = idx_roc_end; // try to move to the next ROC
635  break;
636  }
637  if (e906flag == (int)0xe906c0da) { // i.e. end of this ROC
638  idx++;
639  break;
640  }
641  idx++; // Move to the 1st word of board data
642  int board_id = get_hex_bits(words[idx], 6, 1);
643  int n_wd_bd = get_hex_bits(words[idx], 3, 4);
644  if (print_event) cout << hex << " " << (e906flag&0xFFFF) << "@" << board_id << dec << "(" << n_wd_bd << ")";
645  idx = ProcessBoardData(words, idx, idx_roc_end, e906flag);
646  if (idx == -1) {
647  if (dec_par.verbose > 1) cout << " ProcessBoardData() returned -1: 0x" << hex << e906flag << dec << " " << board_id << " " << rocID << " " << dec_par.codaID << endl;
648  return 0;
649  }
650  }
651  if (idx != idx_roc_end) Abort("idx != idx_roc_end");
652  }
653  if (print_event) cout << endl;
654 
656 
657  return ret;
658 }
659 
673 int MainDaqParser::ProcessBoardData (int* words, int idx, int idx_roc_end, int e906flag)
674 {
675  if ( e906flag == (int)0xE906F003 ) idx = ProcessBoardScaler (words, idx);
676  else if ( e906flag == (int)0xE906F005 ) idx = ProcessBoardV1495TDC(words, idx);
677  else if ( e906flag == (int)0xE906F018 ) idx = ProcessBoardJyTDC2 (words, idx, idx_roc_end);
678  else if ( e906flag == (int)0xE906F019 ) return -1;
679  else if ( e906flag == (int)0xe906f01b ) idx = ProcessBoardFeeQIE (words, idx);
680  else if ( e906flag == (int)0xE906F014 ) idx = ProcessBoardTriggerCount(words, idx);
681  else if ( e906flag == (int)0xE906F00F ) idx = ProcessBoardTriggerBit (words, idx);
682 
683  // todo: "0xE906F999" below must be changed together with the hardware setting.
684  else if ( e906flag == (int)0xE906F999 ) idx = ProcessBoardStdV1495TDC(words, idx);
685  else if ( e906flag == (int)0xE906F010 ) idx = ProcessBoardStdJyTDC2 (words, idx, idx_roc_end);
686  else if ( e906flag == (int)0xe906f013 ) idx = ProcessBoardStdFeeQIE (words, idx);
687  else if ( e906flag == (int)0xE906F999 ) idx = ProcessBoardStdTriggerCount(words, idx);
688  else if ( e906flag == (int)0xE906F999 ) idx = ProcessBoardStdTriggerBit (words, idx);
689 
690  else {
691  cerr << "Unexpected board flag in CODA Event " << dec_par.codaID << " ROC " << (int)dec_par.rocID
692  << ": e906flag = " << e906flag << " @ " << idx-1 << "\n";
693  PrintWords(words, idx-10, idx+40);
694  return -1; // Temporary solution. Skip all boards and move to the next ROC.
695  Abort("Unexpected board type.");
696  }
697  return idx;
698 }
699 
700 int MainDaqParser::ProcessBoardScaler (int* words, int idx)
701 {
702  int boardID = (0xFFFF & words[idx]);
703  idx++;
704 
705  SpillData* spill_data = &(*list_sd)[dec_par.spillID];
706  spill_data->n_scaler++;
707  for (int ii = 0; ii < 32; ii++) {
708  unsigned int value = words[idx];
709  idx++;
710 
711  ScalerData data;
712  data.type = dec_par.spillType;
713  data.coda = dec_par.codaID;
714  data.roc = dec_par.rocID;
715  data.board = boardID;
716  data.chan = ii;
717  data.value = value;
718  //if (! dec_par.map_scaler.Find(data.roc, data.board, data.chan, data.name)) {
719  if (! dec_par.chan_map_scaler.Find(data.roc, data.board, data.chan, data.name)) {
720  if (dec_par.verbose > 2) cout << " Unmapped Scaler: " << data.roc << " " << data.board << " " << data.chan << "\n";
721  continue;
722  }
723  if (dec_par.verbose > 2) cout << " scaler " << dec_par.spillID << " " << data.type << " " << data.name << " " << data.value << "\n";
724  spill_data->list_scaler.push_back(data);
725  }
726 
727  return idx;
728 }
729 
730 int MainDaqParser::ProcessBoardTriggerBit (int* words, int j)
731 {
732  int n_words = words[j]; // N of words including this word itself (with an exception).
733  if (n_words == 0) return j+1; // Exception: n_words = 0 (not 1) in case of no event.
734  j++; // Move to the 1st event word.
735  n_words--; // Now it means N of trigger-bit & event-ID words.
736  //PrintWords(words, j-5, j+n_words+5);
737  if (n_words % 2 != 0) {
738  PrintWords(words, j-10, j+20);
739  Abort("N of trigger words % 2 != 0.");
740  }
741  int n_evt = n_words / 2; // because one event contains 1 trigger-bits & 1 event ID.
742  for (int i_evt = 0; i_evt < n_evt; i_evt++) {
743  int triggerBits = words[j + 2*i_evt ];
744  int evt_id = words[j + 2*i_evt + 1];
745  EventData* ed = &(*list_ed)[evt_id];
746  ed->n_trig_b++;
747  EventInfo* evt = &ed->event;
748  SetEventInfo(evt, evt_id);
749  evt->trigger_bits = triggerBits;
750 
751  int trigger[10];
752  for (int i = 0; i < 10; i++) trigger[i] = get_bin_bit (triggerBits, i);
753  for (int i = 0; i < 5; i++) {
754  // This function doesn't support the bit order for old runs (# < 4923).
755  evt->MATRIX[i] = trigger[i ];
756  evt->NIM [i] = trigger[i+5];
757  }
758  }
759 
760  return j + n_words;
761 }
762 
763 int MainDaqParser::ProcessBoardTriggerCount (int* words, int j)
764 {
765  // KN: Do we need to check this as done in the previous version??? 14 means STANDARD_PHYSICS
766  //if (get_hex_bits (words[1], 7, 4) == 14)
767 
768  int n_words = words[j]; // N of words including this word itself (with an exception).
769  if (n_words == 0) return j+1; // Exception: n_words = 0 (not 1) in case of no event.
770  j++; // Move to the 1st event word.
771  n_words--; // Now it means N of trigger-bit & event-ID words.
772 
773  if (n_words % 11 != 0) {
774  PrintWords(words, j-10, j+20);
775  Abort("N of trigger-count words % 11 != 0.");
776  }
777  int n_evt = n_words / 11; // because one event contains 10 counters & 1 event ID.
778  for (int i_evt = 0; i_evt < n_evt; i_evt++) {
779  int idx_evt = j + 11*i_evt; // The 1st index of this event
780  int evt_id = words[idx_evt + 10];
781  EventData* ed = &(*list_ed)[evt_id];
782  ed->n_trig_c++;
783  EventInfo* evt = &ed->event;
784  SetEventInfo(evt, evt_id);
785  for (int i_type = 0; i_type < 5; i_type++) {
786  evt->RawMATRIX [i_type] = words[idx_evt + i_type ];
787  evt->AfterInhMATRIX[i_type] = words[idx_evt + i_type + 5];
788  }
789  }
790 
791  return j + n_words;
792 }
793 
806 int MainDaqParser::ProcessBoardFeeQIE (int* words, int idx)
807 {
808  if (dec_par.runID < 22400) Abort("feeQIE does not support run < 22400.");
809 
810  while (words[idx] == (int)0xe906e906) idx++; // Still necessary??
811 
812  // int boardID = get_hex_bits (words[idx], 7, 4);
813  int n_wd = get_hex_bits (words[idx], 3, 4);
814  int idx_end = idx + n_wd + 1; // It points to the 1st word of the next board.
815  idx++;
816  if (n_wd == 0) return idx;
817 
818  while (words[idx] == (int)0xe906e906) { idx++; idx_end++; }
819 
820  idx++; // skip the number-of-words word for this TDC
821 
822  // One physics event contains 49 words:
823  // * 1 word for the number of filled words (44 or 39)
824  // * [5 words for spill header] ... appear only in 1st event in spill
825  // * 8 words for 4 presums,
826  // * 2 words for trigger counts
827  // * 2 words for turn ID
828  // * 1 words for rf ID
829  // * 25 words for rf intensities
830  // * 4 or 9 words for padding with "0"
831  // * 1 word for event ID
832  // The number of physics events per Coda event is 7 in most cases, but can be less
833  // in last Coda event per spill. Such case is caught by "idx < idx_end".
834  for (int i_evt = 0; i_evt < 7 && idx < idx_end; i_evt++) {
835  int idx_evt = idx; // Increment idx_evt (not idx) and update idx at loop end.
836  int eventID = words[idx_evt + 48];
837 
838  int n_wd_evt = get_hex_bits(words[idx_evt], 7, 4);
839  if (n_wd_evt == 44) idx_evt += 5; // skip the spill header
840  else if (n_wd_evt != 39) {
842  //cerr << "!! QIE: Unexpected N of words: " << dec_par.codaID << " " << i_evt << " " << n_wd_evt << " (" << n_wd << ")." << endl;
843  return idx_end;
844  }
845 
846  idx_evt++; // Move to the 1st word of data block
847 
848  unsigned int sums_vals[4]; // QIE records four intensity sums (called "presum")
849  for (int i_sum = 0; i_sum < 4 ; i_sum++) {
850  sums_vals[i_sum] = get_hex_bits(words[idx_evt],7,4)*65536 + get_hex_bits(words[idx_evt+1],7,4);
851  idx_evt += 2;
852  }
853  //while (words[idx_evt] == (int)0xe906e906) { idx_evt++; idx_end++; }
854 
855  unsigned int triggerCount = words[idx_evt] | ( get_hex_bits (words[idx_evt+1], 7, 4) );
856  idx_evt += 2;
857  //while (words[idx_evt] == (int)0xe906e906) { idx_evt++; idx_end++; }
858 
859  unsigned int turnOnset = words[idx_evt] | ( get_hex_bits (words[idx_evt+1], 7, 4) );
860  if (turnOnset > dec_par.turn_id_max) dec_par.turn_id_max = turnOnset;
861  idx_evt += 2;
862  //while (words[idx_evt] == (int)0xe906e906) { idx_evt++; idx_end++; }
863 
864  unsigned int rfOnset = get_hex_bits(words[idx_evt],7,4);
865  idx_evt++;
866 
867  unsigned int rf_vals[25];
868  for (int i_rf = 0; i_rf < 25; i_rf++) { // RF-12...RF+12
869  if (words[idx_evt] == (int)0xe906e906) Abort("Unexpected 0xe906e906 in QIE.");
870  rf_vals[i_rf] = ( get_hex_bits(words[idx_evt],7,4) );
871  idx_evt++;
872  }
873 
874  EventData* ed = &(*list_ed)[eventID];
875  ed->n_qie++;
876  EventInfo* evt = &ed->event;
877  //if (ed->n_qie == 2) {
878  // cout << "QIE#1 " << dec_par.codaID << " " << i_evt << " " << evt->eventID << " " << evt->spillID << " "
879  // << evt->triggerCount << " " << evt->turnOnset << " " << evt->rfOnset << endl;
880  //}
881  SetEventInfo(evt, eventID);
882 
883  for (int ii = 0; ii < 4; ii++) evt->sums[ii] = sums_vals[ii];
884  evt->triggerCount = triggerCount;
885  evt->turnOnset = turnOnset;
886  evt->rfOnset = rfOnset;
887  for (int ii = 0; ii < 25 ; ii++) evt->rf[ii+4] = rf_vals[ii]; // We are now missing first 4 bins and last 4 bins. YC, 2016/05/27
888 
889  idx += 49;
890  }
891 
892  if (idx != idx_end) {
893  cout << idx << " != " << idx_end;
894  Abort("idx != idx_end in feeQIE().");
895  }
896  return idx_end;
897 }
898 
905 int MainDaqParser::ProcessBoardV1495TDC (int* words, int idx)
906 {
907  int boardID = words[idx++]; // was get_hex_bits (words[idx], 3, 4);
908  int n_wd_fpga = words[idx++]; // N of words taken from FPGA buffer.
909  if (n_wd_fpga == 0) return idx; // No event data. Just finish.
910  int idx_end = idx + n_wd_fpga; // Exclusive endpoint. To be incremented in the while loop.
911  //PrintWords(words, idx-5, idx_end+20);
912 
913  int i_evt = 0;
914  vector<int> list_chan;
915  vector<int> list_time;
916  while (idx < idx_end) {
917  if (get_hex_bits(words[idx], 7, 1) == 1) { // event header
918  idx_end += 2; // one stop word and one event-ID word (which was added by CPU, not FPGA).
919  int word_stop = words[idx+1];
920  int evt_id = words[idx+2];
921  //int evt_id_fpga = (words[idx+3]<<15) + words[idx+4];
924  //if (evt_id != evt_id_fpga) {
925  // list_event[i_evt]->dataQuality |= EVT_ERR_V1495;
926  // cerr << "!! EventID mismatch @ v1495: " << evt_id << "@CPU vs " << evt_id_fpga << "@FPGA in " << dec_par.codaID << ":" << i_evt << endl;
927  //}
928 
929  EventData* ed = &(*list_ed)[evt_id];
930  ed->n_v1495++;
931  EventInfo* evt = &ed->event;
932  SetEventInfo(evt, evt_id);
933 
934  if (word_stop == (int)0xd2ad) {
935  evt->flag_v1495 |= 0x2;
936  run_data.n_v1495_d2ad++;
937  } else if (word_stop == (int)0xd3ad) {
938  evt->flag_v1495 |= 0x4;
939  run_data.n_v1495_d3ad++;
940  } else if (get_hex_bits(word_stop, 3, 1) != 1) {
941  evt->flag_v1495 |= 0x8;
942  cerr << " !! v1495: bad stop word: " << word_stop << endl;
943  } else { // OK. Insert hits.
944  int time_stop = get_hex_bits(word_stop, 2, 3);
945  for (unsigned int ii = 0; ii < list_chan.size(); ii++) {
946  HitData hit;
947  hit.event = evt_id;
948  hit.id = ++dec_par.hitID;
949  hit.roc = dec_par.rocID;
950  hit.board = boardID;
951  hit.chan = list_chan[ii];
952  hit.time = time_stop - list_time[ii];
953  ed->list_hit_trig.push_back(hit);
954  }
955  }
956  list_chan.clear();
957  list_time.clear();
958  run_data.n_v1495++;
959  idx += 5;
960  i_evt++;
961  } else { // start signal
963  list_chan.push_back( get_hex_bits (words[idx], 3, 2) );
964  list_time.push_back( get_hex_bits (words[idx], 1, 2) );
965  idx++;
966  }
967  }
968  if (idx != idx_end) Abort("idx != idx_end in ProcessBoardV1495TDC.");
969  return idx_end;
970 }
971 
993 int MainDaqParser::ProcessBoardJyTDC2 (int* words, int idx_begin, int idx_roc_end)
994 {
995  int hex7 = get_hex_bits (words[idx_begin], 7, 1);
996  int hex54 = get_hex_bits (words[idx_begin], 5, 2);
997  int boardID = get_hex_bits (words[idx_begin], 6, 3);
998  int nWordsBoard = get_hex_bits (words[idx_begin], 3, 4);
999  if (nWordsBoard == 0) return idx_begin + 1;
1000  int roc = (int)dec_par.rocID;
1001  //if (roc < 12 || roc > 30) Abort("rocID out of 12...30.");
1002 
1003  if (hex7 != 0 || hex54 != 0) {
1004  // According to Kun on 2017-Jan-01, the board sometimes gets to output only
1005  // "0x8*******" or "0x9*******". This "if" condition is strict enough to
1006  // catch this error. Shifter has to reset VME crate to clear this error.
1008  return idx_begin + 1;
1009  }
1010 
1012  int idx_events_begin = idx_begin + 2;
1013  int idx_events_end = idx_events_begin + nWordsBoard - 1; // "-1" to exclude the word "X".
1014  if (words[idx_begin + 1] == (int)0xe906e906) { // Dummy word *could* exist. Skip it
1015  idx_events_begin++;
1016  idx_events_end ++;
1017  }
1018  if (idx_events_end > idx_roc_end) {
1020  return -1;
1021  }
1022 
1023  int i_evt = 0;
1024  bool header_found = false;
1025  double time_header = 0;
1026  vector<int > list_chan;
1027  vector<double> list_time;
1028  for (int idx = idx_events_begin; idx < idx_events_end; idx++) {
1029  if (get_hex_bits(words[idx], 7, 1) == 8) { // header = stop hit
1030  if (header_found) { // Not seen in run 23930, but seen in run 23751.
1032  }
1033  int word = words[idx];
1034  if (get_bin_bit(word, 16) == 0) Abort("Stop signal is not rising. Not supported.");
1035  double fine = 4.0 - get_hex_bit (word, 0) * 4.0 / 9.0;
1036  double rough = 4.0 * get_hex_bits(word, 3, 3);
1037  time_header = fine + rough;
1038  header_found = true;
1039  } else if (get_hex_bits(words[idx], 7, 1) == 0 &&
1040  get_hex_bits(words[idx], 6, 7) != 0 ) { // event ID
1041  if (! header_found) { // Not seen in run 23930, but seen in run 23751.
1042  dec_err.AddTdcError(dec_par.codaID, roc, DecoError::EVT_ID_ONLY); // eventID without stop word
1043  run_data.n_hit_bad++;
1044  continue;
1045  }
1046  int evt_id = words[idx];
1047  EventData* ed = &(*list_ed)[evt_id];
1048  ed->n_tdc++;
1049  EventInfo* evt = &ed->event;
1050  SetEventInfo(evt, evt_id);
1051 
1053  for (unsigned int ii = 0; ii < list_chan.size(); ii++) {
1054  HitData hit;
1055  hit.event = evt_id;
1056  hit.id = ++dec_par.hitID;
1057  hit.roc = roc;
1058  hit.board = boardID;
1059  hit.chan = list_chan[ii];
1060  hit.time = list_time[ii];
1061  ed->list_hit.push_back(hit);
1062  //cout << " HIT " << dec_par.spillID << " " << evt_id << " " << (int)dec_par.rocID << " " << boardID << " " << list_chan[ii] << " " << list_time[ii] << endl;
1063  }
1064  i_evt++;
1065  header_found = false;
1066  list_chan.clear();
1067  list_time.clear();
1068  } else { // start hit
1069  if (! header_found) { // Not seen in run 23930, but seen in run 23751.
1070  dec_err.AddTdcError(dec_par.codaID, roc, DecoError::START_WO_STOP); // Start without stop word
1071  run_data.n_hit_bad++;
1072  continue;
1073  }
1074  int word = words[idx];
1075  if (get_bin_bit(word, 16) == 0) { // Not seen in run 23930, but seen in run 23751.
1076  dec_err.AddTdcError(dec_par.codaID, roc, DecoError::START_NOT_RISE); // Start signal is not rising
1077  run_data.n_hit_bad++;
1078  }
1079  double fine = 4.0 - get_hex_bit (word, 0) * 4.0 / 9.0;
1080  double rough = 4.0 * get_hex_bits(word, 3, 3);
1081  double time = time_header - (fine + rough);
1082  if (time < 0) time += 4096; // This constant 4096 is correct???
1083  list_time.push_back(time);
1084 
1085  int cable_chan = get_hex_bit (word, 6);
1086  int cable_id = get_bin_bits(word, 29, 2);
1087  int chan = cable_chan + 16*cable_id;
1088  list_chan.push_back(chan);
1089  }
1090  }
1091  if (header_found) { // Not seen in run 23930, but seen in run 23751.
1092  dec_err.AddTdcError(dec_par.codaID, roc, DecoError::DIRTY_FINISH); // Not finished cleanly
1093  }
1094 
1095  return idx_events_end;
1096 }
1097 
1098 int MainDaqParser::ProcessBoardStdTriggerBit (int* words, int idx)
1099 {
1100  EventData* ed = &(*list_ed)[dec_par.eventIDstd];
1101  ed->n_trig_b++;
1102  EventInfo* evt = &ed->event;
1103 
1104  int triggerBits = words[idx];
1105  evt->trigger_bits = triggerBits;
1106  for (int i = 0; i < 5; i++) {
1107  // This function doesn't support the bit order for old runs (# < 4923).
1108  evt->MATRIX[i] = get_bin_bit (triggerBits, i );
1109  evt->NIM [i] = get_bin_bit (triggerBits, i+5);
1110  }
1111 
1112  return idx + 1;
1113 }
1114 
1115 int MainDaqParser::ProcessBoardStdTriggerCount (int* words, int idx)
1116 {
1117  // KN: Do we need to check this as done in the previous version??? 14 means STANDARD_PHYSICS
1118  //if (get_hex_bits (words[1], 7, 4) == 14)
1119 
1120  EventData* ed = &(*list_ed)[dec_par.eventIDstd];
1121  ed->n_trig_c++;
1122  EventInfo* evt = &ed->event;
1123 
1124  for (int ii = 0; ii < 5; ii++) {
1125  evt->RawMATRIX [ii] = words[idx + ii ];
1126  evt->AfterInhMATRIX[ii] = words[idx + ii + 5];
1127  }
1128 
1129  return idx + 10;
1130 }
1131 
1137 int MainDaqParser::ProcessBoardStdFeeQIE (int* words, int idx)
1138 {
1139  if (dec_par.runID < 22400) Abort("StdFeeQIE does not support run < 22400.");
1140 
1141  while (words[idx] == (int)0xe906e906) idx++; // Still necessary??
1142 
1143  // int boardID = get_hex_bits (words[idx], 7, 4);
1144  int n_wd = get_hex_bits (words[idx], 3, 4);
1145  int idx_end = idx + n_wd + 1; // It points to the 1st word of the next board.
1146  idx++;
1147  if (n_wd == 0) return idx;
1148 
1149  while (words[idx] == (int)0xe906e906) { idx++; idx_end++; }
1150 
1151  int n_wd2 = get_hex_bits(words[idx], 7, 4);
1152  if (n_wd2 == 0x2C) idx += 5;
1153  idx++; // skip the number-of-words word for this TDC
1154 
1155  EventData* ed = &(*list_ed)[dec_par.eventIDstd];
1156  ed->n_qie++;
1157  EventInfo* evt = &ed->event;
1158 
1159  // QIE records four intensity sums (called "presum")
1160  for (int i_sum = 0; i_sum < 4 ; i_sum++) {
1161  evt->sums[i_sum] = get_hex_bits(words[idx],7,4)*65536 + get_hex_bits(words[idx+1],7,4);
1162  idx += 2;
1163  }
1164  //while (words[idx_evt] == (int)0xe906e906) { idx_evt++; idx_end++; }
1165 
1166  evt->triggerCount = words[idx] | ( get_hex_bits (words[idx+1], 7, 4) );
1167  idx += 2;
1168  //while (words[idx_evt] == (int)0xe906e906) { idx_evt++; idx_end++; }
1169 
1170  evt->turnOnset = words[idx] | ( get_hex_bits (words[idx+1], 7, 4) );
1172  idx += 2;
1173  //while (words[idx_evt] == (int)0xe906e906) { idx_evt++; idx_end++; }
1174 
1175  evt->rfOnset = get_hex_bits(words[idx],7,4);
1176  idx++;
1177 
1178  for (int i_rf = 0; i_rf < 25; i_rf++) { // RF-12...RF+12
1179  if (words[idx] == (int)0xe906e906) Abort("Unexpected 0xe906e906 in QIE.");
1180  evt->rf[i_rf+4] = get_hex_bits(words[idx],7,4);
1181  idx++;
1182  }
1183 
1184  if (idx != idx_end) {
1185  cout << idx << " != " << idx_end;
1186  Abort("idx != idx_end in StdFeeQIE().");
1187  }
1188  return idx_end;
1189 }
1190 
1194 int MainDaqParser::ProcessBoardStdV1495TDC (int* words, int idx)
1195 {
1196  EventData* ed = &(*list_ed)[dec_par.eventIDstd];
1197  ed->n_v1495++;
1198  EventInfo* evt = &ed->event;
1199 
1200  int boardID = words[idx++]; // was get_hex_bits (words[idx], 3, 4);
1201 
1202  // Check to see if there is an error in next word
1203  // If so, don't submit the information from this board for this event
1204  bool ignore = (get_bin_bit(words[idx + 1], 12) != 1);
1205 
1206  if ((words[idx] & 0xFFFF) == (int)0xd1ad) {
1207  evt->flag_v1495 |= 0x1;
1208  run_data.n_v1495_d1ad++;
1209  }
1210  if ((words[idx + 1] & 0xFFFF) == (int)0xd2ad) {
1211  evt->flag_v1495 |= 0x2;
1212  run_data.n_v1495_d2ad++;
1213  } else if ((words[idx + 1] & 0xFFFF) == (int)0xd3ad) {
1214  evt->flag_v1495 |= 0x4;
1215  run_data.n_v1495_d3ad++;
1216  }
1217  run_data.n_v1495++;
1218 
1219  // Contains 0x000000xx where xx is number of channel entries
1220  int numChannels = (words[idx] & 0x0000FFFF);
1221  if (numChannels > 255) {
1222  //printf("number of Channels stated in v1495 readout exceeds 255. Skipping...\n");
1223  return idx + 2;
1224  }
1225  idx++;
1226 
1227  // Next contains 0x00001xxx where xxx is the stop time
1228  unsigned int stopTime = (words[idx] & 0x00000FFF);
1229  idx++;
1230 
1231  if (! ignore) {
1232  HitData hit;
1233  hit.event = dec_par.eventIDstd;
1234  hit.roc = dec_par.rocID;
1235  hit.board = boardID;
1236 
1237  for (int kk = 0; kk < numChannels; kk++) {
1238  unsigned int channel = get_hex_bits(words[idx+kk], 3, 2);
1239  unsigned int channelTime = get_hex_bits(words[idx+kk], 1, 2);
1240  double tdcTime = stopTime - channelTime;
1241  hit.id = ++dec_par.hitID;
1242  hit.chan = channel;
1243  hit.time = tdcTime;
1244  ed->list_hit_trig.push_back(hit);
1245  }
1246  }
1247 
1248  return idx + numChannels;
1249 }
1250 
1257 int MainDaqParser::ProcessBoardStdJyTDC2 (int* words, int idx_begin, int idx_roc_end)
1258 {
1259  int boardID = get_hex_bits (words[idx_begin], 6, 3);
1260  int nWordsBoard = get_hex_bits (words[idx_begin], 3, 4);
1261  if (nWordsBoard == 0) return idx_begin + 1;
1262  int idx_end = idx_begin + nWordsBoard;
1263  if (idx_end > idx_roc_end) {
1264  cerr << "WARNING: Word overflow. Skip ROC (" << dec_par.rocID << ")" << endl;
1265  return -1;
1266  }
1267 
1268  int idx = idx_begin + 1;
1269  if (words[idx] == (int)0xe906e906) idx++; // Dummy word *could* exist. Skip it
1270 
1271  int trigger_clock_cycle = get_hex_bit(words[idx], 0);
1272  double trigger_rough = 4.0 * get_hex_bits(words[idx], 3, 3);
1273  double trigger_fine;
1274  if (get_bin_bit(words[idx], 16)) { // rising-edge mode
1275  trigger_fine = 4.0 - trigger_clock_cycle * 4.0 / 9.0;
1276  } else {
1277  trigger_fine = 0.5 * trigger_clock_cycle;
1278  }
1279  double trigger_time = trigger_rough + trigger_fine;
1280  idx++;
1281 
1282  EventData* ed = &(*list_ed)[dec_par.eventIDstd];
1283  ed->n_tdc++;
1284  HitData hit;
1285  hit.event = dec_par.eventIDstd;
1286  hit.roc = (int)dec_par.rocID;
1287  hit.board = boardID;
1288 
1289  while (idx < idx_end) {
1290  bool rising = get_bin_bit(words[idx], 16);
1291  if (rising && (words[idx] & 0x80000000) == 0) {
1292  double fine = 4.0 - get_hex_bit (words[idx], 0) * 4.0 / 9.0;
1293  double rough = 4.0 * get_hex_bits(words[idx], 3, 3);
1294  double time = trigger_time - (fine + rough);
1295  if (time < 0) time += 4096;
1296 
1297  int cable_chan = get_hex_bit (words[idx], 6);
1298  int cable_id = get_bin_bits(words[idx], 29, 2);
1299  int chan = cable_chan + 16*cable_id;
1300 
1301  hit.id = ++dec_par.hitID;
1302  hit.chan = chan;
1303  hit.time = time;
1304  ed->list_hit.push_back(hit);
1305  }
1306  idx++;
1307  }
1308 
1309  return idx_end;
1310 }
1311 
1312 int MainDaqParser::PackOneSpillData()
1313 {
1314  if (dec_par.verbose > 2) cout << "PackOneSpillData(): n=" << list_ed->size() << endl;
1315 
1316  if (dec_par.is_online) {
1319  }
1320 
1321  sd_now = &(*list_sd)[dec_par.spillID];
1322  run_data.n_evt_all += list_ed->size();
1323 
1326  for (EventDataMap::iterator it = list_ed->begin(); it != list_ed->end(); ) {
1327  unsigned int evt_id = it->first;
1328  EventData* ed = &it->second;
1329  EventInfo* event = &ed->event;
1330  if (evt_id == 0 || // 1st event? bad anyway
1331  (dec_par.sampling > 0 && evt_id % dec_par.sampling != 0) || // sampled out
1332  (dec_par.turn_id_max > 360000 && event->turnOnset == 0 && event->NIM[2])) { // NIM3 after spill end
1333  it = list_ed->erase(it);
1334  continue;
1335  }
1336  it++;
1337  run_data.n_evt_dec++;
1338 
1339  unsigned int n_taiwan = ed->list_hit .size();
1340  unsigned int n_v1495 = ed->list_hit_trig.size();
1341  run_data.n_hit += n_taiwan;
1342  run_data.n_t_hit += n_v1495;
1343 
1346  for (unsigned int ih = 0; ih < n_taiwan; ih++) {
1347  HitData* hd = &ed->list_hit[ih];
1348  if (! dec_par.chan_map_taiwan.Find(hd->roc, hd->board, hd->chan, hd->det, hd->ele)) {
1349  if (dec_par.verbose > 2) cout << " Unmapped Taiwan: " << hd->roc << " " << hd->board << " " << hd->chan << "\n";
1350  }
1351  }
1352  for (unsigned int ih = 0; ih < n_v1495; ih++) {
1353  HitData* hd = &ed->list_hit_trig[ih];
1354  if (! dec_par.chan_map_v1495.Find(hd->roc, hd->board, hd->chan, hd->det, hd->ele, hd->lvl)) {
1355  if (dec_par.verbose > 2) cout << " Unmapped v1495: " << hd->roc << " " << hd->board << " " << hd->chan << "\n";
1356  }
1357  }
1358  }
1359 
1360  EventDataMap* ptr = list_ed_now;
1361  list_ed_now = list_ed;
1362  list_ed = ptr;
1363 
1364  return 0;
1365 }
1366 
1367 void MainDaqParser::SetEventInfo(EventInfo* evt, const int eventID)
1368 {
1369  evt->runID = dec_par.runID;
1370  evt->eventID = eventID;
1371  evt->spillID = dec_par.spillID;
1372 }
unsigned short int runID
Definition: DecoParam.h:32
unsigned int selectWindow
Definition: DecoData.h:65
int spillID_slow
Definition: DecoParam.h:36
int n_phys_evt
Definition: DecoData.h:93
int n_v1495_d3ad
Definition: DecoData.h:104
SlowControlDataList list_slow_cont
Definition: DecoData.h:155
int spillID_cntr
Definition: DecoParam.h:35
FeeDataList fee
Definition: DecoData.h:84
bool GetFlushError()
Definition: DecoError.h:44
std::map< unsigned int, SpillData > SpillDataMap
Definition: DecoData.h:161
std::string fn_in
Definition: DecoParam.h:18
ChanMapV1495 chan_map_v1495
Definition: DecoParam.h:26
int n_v1495
Definition: DecoData.h:101
unsigned int roc
Definition: DecoData.h:55
bool NextCodaEvent(unsigned int &coda_id, int *&event_words)
int eventIDstd
Definition: DecoParam.h:43
int utime_b
Definition: DecoData.h:74
unsigned int board
Definition: DecoData.h:56
short chan
Definition: DecoData.h:131
int n_v1495_d1ad
Definition: DecoData.h:102
bool NextPhysicsEvent(EventData *&ed, SpillData *&sd, RunData *&rd)
short targPos
Definition: DecoParam.h:37
int get_bin_bits(unsigned int binNum, int numBitFromRight, int numBits)
int spillID
Definition: DecoData.h:186
int OpenCodaFile(const std::string fname, const long file_size_min=32768, const int sec_wait=15, const int n_wait=40)
void AggregateData()
Definition: DecoError.cc:48
unsigned int hard
Definition: DecoData.h:57
ChanMapTaiwan chan_map_taiwan
Definition: DecoParam.h:25
unsigned int bos_coda_id
Definition: DecoData.h:145
int fpga_prescale[5]
Definition: DecoData.h:79
int n_hit
Definition: DecoData.h:97
int n_spill
Definition: DecoData.h:90
int n_evt_dec
Definition: DecoData.h:92
int n_hit_bad
Definition: DecoData.h:99
int get_bin_bit(unsigned int binNum, int numBitFromRight)
void Abort(const char *message)
int sampling
Definition: DecoParam.h:21
short targPos_slow
Definition: DecoParam.h:38
unsigned int multihit_elim_enabled
Definition: DecoData.h:60
short ele
Definition: DecoData.h:174
std::map< unsigned int, EventData > EventDataMap
Definition: DecoData.h:219
unsigned int targ_pos
Definition: DecoData.h:144
time_t timeStart
Definition: DecoParam.h:53
int n_evt_all
Definition: DecoData.h:91
unsigned int n_eos_spill
Definition: DecoData.h:151
#define NULL
Definition: Pdb.h:9
bool is_online
Definition: DecoParam.h:20
DecoParam dec_par
Definition: MainDaqParser.h:70
int n_t_hit
Definition: DecoData.h:98
unsigned int n_trig_c
Definition: DecoData.h:210
unsigned int segmentation
Definition: DecoData.h:59
int eventID
Definition: DecoData.h:183
int prescale[8]
Definition: DecoData.h:83
int runID
Definition: DecoData.h:185
std::string name
Definition: DecoData.h:133
int AfterInhMATRIX[5]
Definition: DecoData.h:190
int value
Definition: DecoData.h:132
unsigned int spill_id_slow
Definition: DecoData.h:142
int event
Definition: DecoData.h:168
int n_phys_evt_bad
Definition: DecoData.h:94
int RawMATRIX[5]
Definition: DecoData.h:189
short board
Definition: DecoData.h:171
std::string type
Definition: DecoData.h:119
int trigger_bits
Definition: DecoData.h:193
short flag_v1495
Definition: DecoData.h:199
unsigned int n_qie
Definition: DecoData.h:206
void PrintData(std::ostream &os=std::cout)
Definition: DecoError.cc:56
unsigned int falling_enabled
Definition: DecoData.h:58
unsigned int eos_vme_time
Definition: DecoData.h:148
time_t timeEnd
Definition: DecoParam.h:53
unsigned int n_bos_spill
Definition: DecoData.h:150
int n_fee_event
Definition: DecoData.h:87
unsigned int rf[33]
Definition: DecoData.h:198
bool has_1st_bos
Definition: DecoParam.h:46
void CountFlush()
Definition: DecoError.cc:35
double time
Definition: DecoData.h:176
short roc
Definition: DecoData.h:170
ChanMapScaler chan_map_scaler
Definition: DecoParam.h:27
ScalerDataList list_scaler
Definition: DecoData.h:156
int get_hex_bits(unsigned int hexNum, int numBitFromRight, int numBits)
void PrintWords(int *words, int idx_begin, int idx_end, int idx_atte)
int time_wait
Definition: DecoParam.h:23
EventInfo event
Definition: DecoData.h:212
short spillType
Definition: DecoParam.h:41
int coda
Definition: DecoData.h:128
long int hitID
Definition: DecoParam.h:44
short type
Definition: DecoData.h:127
unsigned int turn_id_max
Max turnOnset in a spill. Used to drop NIM3 events that came after the beam stops. See elog 15010.
Definition: DecoParam.h:50
unsigned int n_v1495
Definition: DecoData.h:207
unsigned int n_slow
Definition: DecoData.h:152
int n_fee_prescale
Definition: DecoData.h:88
unsigned int highLimit
Definition: DecoData.h:64
int fpga_enabled[5]
Definition: DecoData.h:77
bool at_bos
Definition: DecoParam.h:47
unsigned int updating_enabled
Definition: DecoData.h:61
bool JumpCodaEvent(unsigned int &coda_id, int *&event_words, const int n_evt)
short lvl
Definition: DecoData.h:175
int n_flush_evt_bad
Definition: DecoData.h:96
short chan
Definition: DecoData.h:172
short det
Definition: DecoData.h:173
DecoError dec_err
Definition: MainDaqParser.h:71
unsigned int lowLimit
Definition: DecoData.h:63
int n_flush_evt
Definition: DecoData.h:95
unsigned int rfOnset
Definition: DecoData.h:197
void SetID(const int run_id, const int spill_id)
Definition: DecoError.cc:18
unsigned int codaID
Definition: DecoParam.h:40
std::string name
Definition: DecoData.h:117
HitDataList list_hit_trig
Definition: DecoData.h:214
int spillID
Definition: DecoParam.h:34
void InitData()
Definition: DecoError.cc:24
int InitMapper()
Definition: DecoParam.cc:16
int n_t_hit_bad
Definition: DecoData.h:100
int NIM[5]
Definition: DecoData.h:191
void SetRunNumber(const int run)
short rocID
Definition: DecoParam.h:42
int id
Definition: DecoData.h:169
int trig_bit[10]
Definition: DecoData.h:82
bool Find(const short roc, const short board, const short chan, std::string &name)
unsigned int elim_window
Definition: DecoData.h:62
short board
Definition: DecoData.h:130
unsigned int n_tdc
Definition: DecoData.h:208
unsigned int spill_id
Definition: DecoData.h:141
bool Find(const short roc, const short board, const short chan, short &det, short &ele, short &lvl)
void AddTdcError(const int event, const int roc, const TdcError_t type)
Definition: DecoError.cc:41
short roc
Definition: DecoData.h:129
unsigned int run_id
Definition: DecoData.h:143
std::string run_desc
Definition: DecoData.h:85
bool Find(const short roc, const short board, const short chan, short &det, short &ele)
int run_id
Definition: DecoData.h:73
int n_v1495_d2ad
Definition: DecoData.h:103
int MATRIX[5]
Definition: DecoData.h:192
unsigned int n_trig_b
Definition: DecoData.h:209
int n_run_desc
Definition: DecoData.h:89
HitDataList list_hit
Definition: DecoData.h:213
unsigned int triggerCount
Definition: DecoData.h:195
int get_hex_bit(unsigned int hexNum, int numBitFromRight)
unsigned int bos_vme_time
Definition: DecoData.h:146
void SetFlushError(const bool val)
Definition: DecoError.h:43
unsigned int sums[4]
Definition: DecoData.h:194
unsigned int n_scaler
Definition: DecoData.h:153
unsigned int turnOnset
Definition: DecoData.h:196
int verbose
Definition: DecoParam.h:22
unsigned int eos_coda_id
Definition: DecoData.h:147
int OpenFile(const std::string fname, const long file_size_min=0, const int sec_wait=10, const int n_wait=0)