StRoot  1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
daq_stgc.cxx
1 #include <sys/types.h>
2 #include <errno.h>
3 #include <assert.h>
4 
5 #include <rtsLog.h>
6 #include <rtsSystems.h>
7 
8 
9 #include <SFS/sfs_index.h>
10 #include <DAQ_READER/daqReader.h>
11 #include <DAQ_READER/daq_dta.h>
12 
13 
14 
15 
16 //#include <DAQ_TPC/daq_tpc.h> // solely for the "legacy" use!
17 //#include <TPC/trans_table.hh> // same...
18 //#include <TPC/rowlen.h>
19 
20 #include <DAQ1000/ddl_struct.h> // for the misc DDL hardware constructs
21 
22 #include "daq_stgc.h"
23 #include "stgc_data_c.h"
24 
25 #include <DAQ_TPX/tpxCore.h>
26 
27 //#include "tpxGain.h"
28 //#include "tpxPed.h"
29 //#include "tpxFCF.h"
30 //#include "tpxFCF_2D.h"
31 //#include "tpxStat.h"
32 
33 
34 
35 
37 {
38 public:
40  daq_det_factory::det_factories[STGC_ID] = this ;
41  }
42 
43  daq_det *create() {
44  return new daq_stgc ;
45  }
46 } ;
47 
48 static daq_det_stgc_factory stgc_factory ;
49 
50 
51 
52 const char *daq_stgc::help_string = "\
53 \n\
54 ****** STGC Help ******* \n\
55 \n\
56 Sector is [1..24]\n\
57 Rdo is [1..6]\n\
58 \n\
59 Supported Banks: \n\
60  raw (sector,rdo); returns (char *) of start of DDL data\n\
61  log\n\
62 " ;
63 
64 
65 void daq_stgc::help() const
66 {
67  printf("%s\n%s\n",GetCVS(),help_string) ;
68 } ;
69 
70 daq_stgc::daq_stgc(daqReader *rts_caller)
71 {
72  // override mother...
73 
74  rts_id = STGC_ID ;
75  name = rts2name(rts_id) ;
76  sfs_name = "stgc" ;
77  caller = rts_caller ;
78 
79  if(caller) caller->insert(this, rts_id) ;
80 
81  raw = new daq_dta ; // in file, compressed
82  altro = new daq_dta ;
83  vmm = new daq_dta ;
84  vmmraw = new daq_dta ;
85 
86  event_mode = 0 ; // 0: TPX, 1:VMM
87 
88  LOG(DBG,"%s: constructor: caller %p",name, caller) ;
89 
90 // xing_min = -10 ;
91 // xing_max = 20 ;
92 
93  stgc_d = new stgc_data_c ;
94 
95  xing_min = -32000 ;
96  xing_max = 32000 ;
97 
98  return ;
99 }
100 
101 daq_stgc::~daq_stgc()
102 {
103  LOG(DBG,"%s: DEstructor",name) ;
104 
105  // daq data
106  delete raw ;
107  delete altro ;
108  delete vmm ;
109  delete vmmraw ;
110  delete stgc_d ;
111 
112  LOG(DBG,"%s: DEstructor done",name) ;
113  return ;
114 }
115 
116 
117 
118 
119 
120 
121 daq_dta *daq_stgc::get(const char *in_bank, int sec, int row, int pad, void *p1, void *p2)
122 {
123  const char *bank ;
124 
125  if(in_bank==0) { // just wants to know if I'm here so return some read-only non-NULL memory
126  bank = "altro" ; // default
127  }
128  else {
129  bank = in_bank ;
130  }
131 
132  Make() ;
133 
134  LOG(NOTE,"%s: looking for bank %s",name,bank) ;
135 
136  if(!present) return 0 ; // this det is not in this event...
137 
138 
139  if(strcasecmp(bank,"raw")==0) {
140  return handle_raw(sec,row) ; // actually sec, rdo; r
141  }
142  else if(strcasecmp(bank,"altro")==0) {
143  return handle_altro(sec,row) ; // actually sec, rdo:
144  }
145  else if(strcasecmp(bank,"vmm")==0) {
146  return handle_vmm(sec) ;
147  }
148  else if(strcasecmp(bank,"vmmraw")==0) {
149  return handle_vmmraw(sec) ;
150  }
151  else {
152  LOG(ERR,"%s: unknown bank type \"%s\"",name,bank) ;
153  }
154 
155 
156  return 0 ;
157 }
158 
159 daq_dta *daq_stgc::handle_altro(int sec, int rdo)
160 {
161 
162  int min_sec, max_sec ;
163  int min_rdo, max_rdo ;
164 
165 
166  // sanity
167  if(sec <= 0) {
168  min_sec = 1 ;
169  max_sec = MAX_SEC ;
170  }
171  else if((sec<1) || (sec>MAX_SEC)) return 0 ;
172  else {
173  min_sec = sec ;
174  max_sec = sec ;
175  }
176 
177  if(rdo <= 0) {
178  min_rdo = 1 ;
179  max_rdo = 6 ;
180  }
181  else if((rdo<0) || (rdo>6)) return 0 ;
182  else {
183  min_rdo = max_rdo = rdo ;
184  }
185 
186  // get a size estimate
187  int rdos = 0 ;
188 
189  for(int s=min_sec;s<=max_sec;s++) {
190  for(int r=min_rdo;r<=max_rdo;r++) {
191  rdos++ ;
192  }
193  }
194 
195  LOG(DBG,"handle_altro: secs %d to %d, rdos %d to %d",min_sec,max_sec,min_rdo,max_rdo) ;
196 
197  //IMPORTANT:
198  tpx_is_stgc = 1 ;
199 
200 
201  // guess the byte size...
202  int guess_bytes = rdos * 1152 * (sizeof(daq_store) + 10*sizeof(daq_adc_tb)) ;
203 
204  altro->create(guess_bytes,(char *)"adc",rts_id,DAQ_DTA_STRUCT(daq_adc_tb)) ;
205 
206 
207  for(int s=min_sec;s<=max_sec;s++) {
208  for(int r=min_rdo;r<=max_rdo;r++) {
209  daq_dta *rdo_dta ;
210 
211 
212  char *rdo_ptr ;
213  struct tpx_rdo_event rdo ;
214  struct tpx_altro_struct a ;
215  int rdo_words ;
216 
217  LOG(NOTE,"Calling handle_raw for %d:%d",s,r) ;
218  rdo_dta = handle_raw(s, r) ; // bring the raw data in, RDO-by_RDO!
219 
220 
221  if(rdo_dta == 0) {
222  LOG(WARN,"rdo_dta NULL?") ;
223  continue ; // sorry, not found...
224  }
225 
226  int ret = rdo_dta->iterate() ; // move from the header...
227  if(ret==0) { // no content
228  continue ;
229  }
230 
231  LOG(DBG,"Called handle_raw for %d:%d, iterate %d, returned %d objs",s,r,ret,rdo_dta->ncontent) ;
232  if(rdo_dta->ncontent == 0) continue ; // nothing found...
233 
234  rdo_ptr = (char *)rdo_dta->Byte ;
235  rdo_words = rdo_dta->ncontent / 4 ;
236 
237 
238  int token = tpx_get_start(rdo_ptr, rdo_words, &rdo, 0) ;
239 
240  if(token <= 0) {
241  LOG(ERR,"horrible error, token is %d?",token) ;
242  continue ;
243  }
244 
245  if(rdo.rdo != r) {
246  LOG(ERR,"RDO mismatch: in data %d, expect %d",rdo.rdo,r) ;
247  }
248 
249 
250  //LOG(TERR,"S%d:%d = RDO %d, token %d, words %d %d",s,r,rdo.rdo,token,rdo_words,rdo.data_end-rdo.data_start) ;
251 
252  u_int *data_end = rdo.data_end ;
253 
254  a.rdo = rdo.rdo -1 ;
255  a.t = token ;
256  a.what = TPX_ALTRO_DO_ADC ;
257  a.log_err = 0 ;
258  a.sector = s ;
259 
260  do {
261  data_end = tpx_scan_to_next(data_end, rdo.data_start, &a) ;
262 
263 
264  //LOG(TERR,"... A%d:%d count %d",a.id,a.ch,a.count) ;
265 
266  if(a.count == 0) continue ; // no data for this guy...
267 
268  // unallowed rows, pads...
269  //if((a.row>45) || (a.pad==0) || (a.pad>182)) {
270  // LOG(ERR,"STGC: S%02d:RDO%d: row %d, pad %d",a.sector,rdo.rdo,a.row,a.pad) ;
271  //}
272 
273  daq_adc_tb *at = (daq_adc_tb *) altro->request(a.count) ;
274 
275  //LOG(DBG,"%d: %d:%d %d",altro->obj_cou,a.row,a.pad,a.count) ;
276 
277  for(u_int i=0 ; i < a.count ; i++) {
278  at[i].adc = a.adc[i] ;
279  at[i].tb = a.tb[i] ;
280 
281  }
282 
283  altro->finalize(a.count, s, a.id, a.ch) ;
284 
285  } while(data_end && (data_end > rdo.data_start)) ;
286 
287 
288  }
289  }
290 
291  tpx_is_stgc = 0 ;
292 
293  altro->rewind() ; // wind data pointers to the beginning so that they can be used
294 
295  return altro ;
296 
297 }
298 
299 
300 
301 
302 daq_dta *daq_stgc::handle_raw(int sec, int rdo)
303 {
304  char str[128] ;
305  int tot_bytes ;
306  int min_sec, max_sec, min_rdo, max_rdo ;
307  struct {
308  int sec ;
309  int rb ;
310  u_int bytes ;
311  } obj[MAX_SEC*6] ;
312 
313  // sanity
314  if(sec <= 0) { // ALL sectors
315  min_sec = 1 ;
316  max_sec = MAX_SEC ;
317  }
318  else if((sec<1) || (sec>MAX_SEC)) return 0 ;
319  else {
320  min_sec = max_sec = sec ;
321  }
322 
323  if(rdo <= 0) { // ALL RDOs in this sector
324  min_rdo = 1 ;
325  max_rdo = 6 ;
326  }
327  else if((rdo<1) || (rdo>6)) return 0 ;
328  else {
329  min_rdo = max_rdo = rdo ;
330  }
331 
332  assert(caller) ;
333 
334 
335  // calc total bytes
336  tot_bytes = 0 ;
337  int o_cou = 0 ;
338 
339  for(int s=min_sec;s<=max_sec;s++) {
340  for(int r=min_rdo;r<=max_rdo;r++) {
341 
342  sprintf(str,"%s/sec%02d/rb%02d/adc",sfs_name, s, r) ;
343 
344  LOG(NOTE,"%s: trying sfs on \"%s\"",name,str) ;
345 
346  char *full_name = caller->get_sfs_name(str) ;
347  if(full_name == 0) continue ;
348 
349  int size = caller->sfs->fileSize(full_name) ; // this is bytes
350 
351  LOG(DBG,"%s: sector %d, rdo %d : raw size %d",name,s,r,size) ;
352 
353  if(size <= 0) {
354  if(size < 0) {
355  LOG(DBG,"%s: %s: not found in this event",name,str) ;
356  }
357  continue ;
358  }
359  else {
360  obj[o_cou].rb = r ;
361  obj[o_cou].sec = s ;
362  obj[o_cou].bytes = size ;
363 
364  o_cou++ ;
365 
366  tot_bytes += size ;
367 
368  LOG(DBG,"%s: %s: reading in \"%s\": bytes %d",name,str,"raw", size) ;
369  }
370  }
371  }
372 
373  raw->create(tot_bytes,(char *)"raw",rts_id,DAQ_DTA_STRUCT(u_char)) ;
374 
375  // bring in the bacon from the SFS file....
376  for(int i=0;i<o_cou;i++) {
377 
378  sprintf(str,"%s/sec%02d/rb%02d/adc",sfs_name,obj[i].sec, obj[i].rb) ;
379  char *full_name = caller->get_sfs_name(str) ;
380  if(!full_name) continue ;
381 
382  LOG(NOTE,"%s: request %d bytes",name,obj[i].bytes) ;
383 
384  char *mem = (char *) raw->request(obj[i].bytes) ;
385 
386  int ret = caller->sfs->read(full_name, mem, obj[i].bytes) ;
387 
388  if(ret != (int)obj[i].bytes) {
389  LOG(ERR,"%s: %s: read failed, expect %d, got %d [%s]",name,str,
390  obj[i].bytes,ret,strerror(errno)) ;
391  }
392  else {
393  LOG(NOTE,"%s: %s read %d bytes",name,str,ret) ;
394  }
395 
396  raw->finalize(obj[i].bytes, obj[i].sec, obj[i].rb, 0) ;
397  }
398 
399 
400  LOG(DBG,"Returning from raw_handler") ;
401  raw->rewind() ;
402  return raw ;
403 
404 }
405 
406 
407 daq_dta *daq_stgc::handle_vmmraw(int sec)
408 {
409  char str[128] ;
410  int tot_bytes ;
411  int min_sec, max_sec, min_rdo, max_rdo ;
412  struct {
413  int sec ;
414  int rb ;
415  u_int bytes ;
416  } obj[16] ;
417 
418  // sanity
419  if(sec <= 0) { // ALL sectors
420  min_sec = 1 ;
421  max_sec = 4 ;
422  }
423  else if((sec<1) || (sec>4)) return 0 ;
424  else {
425  min_sec = max_sec = sec ;
426  }
427 
428  min_rdo = 1 ;
429  max_rdo = 4 ;
430 
431  assert(caller) ;
432 
433 
434  // calc total bytes
435  tot_bytes = 0 ;
436  int o_cou = 0 ;
437 
438  for(int s=min_sec;s<=max_sec;s++) {
439  for(int r=min_rdo;r<=max_rdo;r++) {
440 
441  sprintf(str,"%s/sec%02d/rdo%d/vmm_raw",sfs_name, s, r) ;
442 
443  LOG(DBG,"%s: trying sfs on \"%s\"",name,str) ;
444 
445  char *full_name = caller->get_sfs_name(str) ;
446  if(full_name == 0) continue ;
447 
448  int size = caller->sfs->fileSize(full_name) ; // this is bytes
449 
450  LOG(NOTE,"%s: sector %d, rdo %d : raw size %d",name,s,r,size) ;
451 
452  if(size <= 0) {
453  if(size < 0) {
454  LOG(DBG,"%s: %s: not found in this event",name,str) ;
455  }
456  continue ;
457  }
458  else {
459  obj[o_cou].rb = r ;
460  obj[o_cou].sec = s ;
461  obj[o_cou].bytes = size ;
462 
463  o_cou++ ;
464 
465  tot_bytes += size ;
466 
467  LOG(DBG,"%s: %s: reading in \"%s\": bytes %d",name,str,"raw", size) ;
468  }
469  }
470  }
471 
472  vmmraw->create(tot_bytes,(char *)"vmmraw",rts_id,DAQ_DTA_STRUCT(u_char)) ;
473 
474  // bring in the bacon from the SFS file....
475  for(int i=0;i<o_cou;i++) {
476 
477  sprintf(str,"%s/sec%02d/rdo%d/vmm_raw",sfs_name,obj[i].sec, obj[i].rb) ;
478  char *full_name = caller->get_sfs_name(str) ;
479  if(!full_name) continue ;
480 
481  LOG(NOTE,"%s: request %d bytes",name,obj[i].bytes) ;
482 
483  char *mem = (char *) vmmraw->request(obj[i].bytes) ;
484 
485  int ret = caller->sfs->read(full_name, mem, obj[i].bytes) ;
486 
487  if(ret != (int)obj[i].bytes) {
488  LOG(ERR,"%s: %s: read failed, expect %d, got %d [%s]",name,str,
489  obj[i].bytes,ret,strerror(errno)) ;
490  }
491  else {
492  LOG(NOTE,"%s: %s read %d bytes",name,str,ret) ;
493  }
494 
495  vmmraw->finalize(obj[i].bytes, obj[i].sec, obj[i].rb, 0) ;
496  }
497 
498 
499  LOG(DBG,"Returning from raw_handler") ;
500  vmmraw->rewind() ;
501  return vmmraw ;
502 
503 }
504 
505 daq_dta *daq_stgc::handle_vmm(int sec)
506 {
507  char str[128] ;
508  int tot_bytes ;
509  int min_sec, max_sec, min_rdo, max_rdo ;
510  struct {
511  u_int bytes ;
512  u_char rb ;
513  u_char sec ;
514  } obj[8*4] ;
515 
516 
517  assert(caller) ;
518 
519  LOG(DBG,"sizeof stgc_vmm_t %d",sizeof(stgc_vmm_t)) ;
520 
521  // sanity
522  if(sec <= 0) { // ALL sectors
523  min_sec = 1 ;
524  max_sec = 4 ;
525  }
526  else {
527  min_sec = max_sec = sec ;
528  }
529 
530  min_rdo = 1 ;
531  max_rdo = 4 ;
532 
533 
534  stgc_d->xing_min = xing_min ;
535  stgc_d->xing_max = xing_max ;
536 
537  LOG(NOTE,"xing_min %d, xing_max %d",stgc_d->xing_min,stgc_d->xing_max) ;
538 
539  // calc total bytes
540  tot_bytes = 0 ;
541  int o_cou = 0 ;
542 
543  for(int s=min_sec;s<=max_sec;s++) {
544  for(int r=min_rdo;r<=max_rdo;r++) {
545 
546  sprintf(str,"%s/sec%02d/rdo%d/vmm_raw",sfs_name, s, r) ;
547 
548  LOG(NOTE,"%s: trying sfs on \"%s\"",name,str) ;
549 
550  char *full_name = caller->get_sfs_name(str) ;
551  if(full_name == 0) continue ;
552 
553  int size = caller->sfs->fileSize(full_name) ; // this is bytes
554 
555  LOG(DBG,"%s: sector %d, rdo %d : raw size %d",name,s,r,size) ;
556 
557  if(size <= 0) {
558  if(size < 0) {
559  LOG(DBG,"%s: %s: not found in this event",name,str) ;
560  }
561  continue ;
562  }
563  else {
564  tot_bytes += size ;
565 
566  obj[o_cou].bytes = size ;
567  obj[o_cou].rb = r ;
568  obj[o_cou].sec = s ;
569  o_cou++ ;
570 
571  }
572  }
573  }
574 
575  vmm->create(tot_bytes/sizeof(stgc_vmm_t),(char *)"vmm",rts_id,DAQ_DTA_STRUCT(stgc_vmm_t)) ;
576 
577  // bring in the bacon from the SFS file....
578  for(int i=0;i<o_cou;i++) {
579 // int vmm_max = obj[i].bytes/sizeof(stgc_vmm_t) * 3 / 2 ; // approx
580  int vmm_max = obj[i].bytes/8 ; // approx: 4 shorts per hit
581 
582  sprintf(str,"%s/sec%02d/rdo%d/vmm_raw",sfs_name,obj[i].sec, obj[i].rb) ;
583  char *full_name = caller->get_sfs_name(str) ;
584  if(!full_name) continue ;
585 
586  LOG(NOTE,"%s: request: %d bytes raw, vmm_hits %d",name,obj[i].bytes,vmm_max) ;
587 
588  stgc_vmm_t *vm = (stgc_vmm_t *) vmm->request(vmm_max) ;
589 
590  char *mem = (char *)malloc(obj[i].bytes) ;
591 
592  int ret = caller->sfs->read(full_name, mem, obj[i].bytes) ;
593 
594  if(ret != (int)obj[i].bytes) {
595  LOG(ERR,"%s: %s: read failed, expect %d, got %d [%s]",name,str,
596  obj[i].bytes,ret,strerror(errno)) ;
597  }
598  else {
599  LOG(NOTE,"%s: %s read %d bytes",name,str,ret) ;
600  }
601 
602  int hits = 0 ;
603  int all_hits = 0 ;
604  stgc_d->sector1 = obj[i].sec ;
605  stgc_d->rdo1 = obj[i].rb ;
606  stgc_d->start((u_short *)mem,obj[i].bytes/2) ;
607  while(stgc_d->event()) {
608  if(stgc_d->vmm.feb_vmm==0 && stgc_d->vmm.adc==0 && stgc_d->vmm.bcid==0 && stgc_d->vmm.ch==0) {
609  //printf("... ODD: S%d:%d\n",obj[i].sec,obj[i].rb) ;
610  continue ;
611  }
612 
613 
614  // fixed bug
615  if(hits >= vmm_max) {
616  LOG(NOTE,"ERROR: S%d:%d -- too many hits %d/%d",obj[i].sec,obj[i].rb,hits,vmm_max) ;
617  //break ;
618  }
619  else {
620  vm[hits] = stgc_d->vmm ;
621  hits++ ;
622  }
623  all_hits++ ;
624  }
625 
626  if(all_hits>=vmm_max) {
627  LOG(ERR,"S%d:%d -- too many hits %d/%d",obj[i].sec,obj[i].rb,all_hits,vmm_max) ;
628  }
629 
630 #if 0
631 
632  // d[16] event type
633  // d[17] data starts e.g. 0x1011
634 
635  for(int j=0;j<32;j++) {
636  LOG(TERR,"%d = 0x%04X",j,d[j]) ;
637  }
638 #endif
639 
640  vmm->finalize(hits, obj[i].sec, obj[i].rb, 0) ;
641  free(mem) ;
642  }
643 
644 
645  LOG(DBG,"Returning from vmm_handler") ;
646  vmm->rewind() ;
647  return vmm ;
648 
649 }
650 
651 // knows how to get the token out of an event while trying also find a l0 command
652 int daq_stgc::get_token(char *addr, int words)
653 {
654  daq_trg_word trgs[128] ;
655 
656  get_l2(addr, words, trgs, 1) ;
657 
658 
659 
660  if(trgs[0].t==0) {
661  LOG(ERR,"Token 0 not allowed but I will try to use the other triggers...") ;
662  trgs[0].t = 4097 ;
663  }
664 
665 
666  return trgs[0].t ;
667 
668 }
669 
670 int daq_stgc::get_l2_vmm(char *addr, int words, struct daq_trg_word *trgs, int do_log)
671 {
672  int t_hi, t_mid, t_lo ;
673 
674 
675  u_short *d = (u_short *)addr ;
676 
677  if(d[10]==0x0001) { // new version
678  int shorts = words*2 ;
679  shorts -= 8 ; // remove the TEF header
680  d += 8 ; // skip the TEF header
681 
682  u_short type = d[8] ;
683 
684  if(type==0x4544) { // triggered!
685  u_char trg_cmd ;
686  u_char daq_cmd ;
687  u_short t, t_lo, t_mid, t_hi ;
688 
689  trg_cmd = d[3]&0xF ;
690  daq_cmd = d[4]&0xF ;
691  t_hi = (d[4]>>4)&0xF ;
692  t_mid = (d[4]>>8)&0xF ;
693  t_lo = (d[4]>>12)&0xF ;
694 
695  t = (t_hi<<8)|(t_mid<<4)|t_lo ;
696 
697  if((trg_cmd>=4)&&(trg_cmd<=12)&&(t!=0)) {
698  trgs[0].t = t ;
699  trgs[0].trg = trg_cmd ;
700  trgs[0].daq = daq_cmd ;
701  }
702  else {
703  LOG(ERR,"get_l2_vmm: shorts %d: type 0x%04X: T %d, trg %d, daq %d [0x%04X]",shorts,type,
704  trgs[0].t,trgs[0].trg,trgs[0].daq,d[4]) ;
705 
706  trgs[0].t = 4096 ;
707  trgs[0].trg = 0 ;
708  trgs[0].daq = 0 ;
709  }
710 
711 // LOG(ERR,"get_l2_vmm: shorts %d: type 0x%04X: T %d, trg %d, daq %d [0x%04X]",shorts,type,
712 // trgs[0].t,trgs[0].trg,trgs[0].daq,d[4]) ;
713 
714  }
715  else {
716  trgs[0].t = 4096 ;
717  trgs[0].trg = 0 ;
718  trgs[0].daq = 0 ;
719 
720 
721 // LOG(WARN,"get_l2_vmm: shorts %d: type 0x%04X: T %d, trg %d, daq %d",shorts,type,
722 // trgs[0].t,trgs[0].trg,trgs[0].daq) ;
723 
724  }
725 
726 
727 #if 0
728  int cou = shorts>32?32:shorts ;
729  for(int i=0;i<cou;i++) {
730  LOG(TERR," %d/%d = 0x%04X",i,shorts,d[i]) ;
731  }
732 #endif
733  return 1 ;
734 
735 
736  }
737 
738  if(d[16] != 0x4544) { // non-data e.g. timer or echo
739  trgs[0].t = 4096 ;
740  trgs[0].trg = 0 ;
741  trgs[0].daq = 0 ;
742 
743  return 1 ;
744  }
745 
746  trgs[0].trg = d[11]&0xF ;
747  trgs[0].daq = d[12]&0xF ;
748 
749  t_hi = (d[12]>>4)&0xF ;
750  t_mid = (d[12]>>8)&0xF ;
751  t_lo = (d[12]>>12)&0xF ;
752 
753  trgs[0].t = (t_hi<<8)|(t_mid<<4)|t_lo ;
754 
755 // for(int i=0;i<20;i++) {
756 // LOG(TERR,"%d: 0x%04X",i,d[i]) ;
757 // }
758 
759  return 1 ;
760 }
761 
762 // dumps the known accept/abort trigger decisions from
763 // the FIFO part of the event.
764 // returns the count
765 int daq_stgc::get_l2(char *addr, int words, struct daq_trg_word *trgs, int do_log)
766 {
767  if(event_mode) {
768  int ret = get_l2_vmm(addr, words, trgs, do_log) ;
769  return ret ;
770  }
771 
772  struct tpx_rdo_event rdo ;
773  int cou = 0 ;
774  u_int collision = 0 ;
775  int err = 0 ;
776 
777  int ret = tpx_get_start(addr, words, &rdo, do_log) ;
778  if(ret < 0) {
779  LOG(ERR,"get_l2: broken data!") ;
780  return 0 ;
781  }
782 
783  LOG(DBG,"rdo %d, rdo token %d, trg cou %d",rdo.rdo,rdo.token,rdo.trg_cou) ;
784 
785  // grab only the prompt contribution...
786  for(u_int i=0;i<rdo.trg_cou;i++) {
787  u_int dta = rdo.trg[i].data ;
788  u_int marker = rdo.trg[i].csr >> 24 ;
789  u_int rhic = rdo.trg[i].rhic_counter ;
790 
791 
792 //#define WANT_LOGGING
793 #ifdef WANT_LOGGING
794  if(rdo.rdo==1 && rdo.sector==1) {
795  int delta = rhic - rdo.trg[0].rhic_counter ;
796  LOG(TERR,"RDO %d: trg %d/%d: dta 0x%08X, CSR 0x%08X, RHIC %u, delta %u",rdo.rdo,
797  i,rdo.trg_cou,
798  dta,rdo.trg[i].csr,rhic,
799  delta) ;
800 
801  }
802 #endif
803 
804  if((marker==0) || (marker==0xEE)) { // marks the prompt configuration
805 
806  trgs[cou].t = dta & 0xFFF ;
807  trgs[cou].daq = (dta >> 12) & 0xF ;
808  trgs[cou].trg = (dta >> 16) & 0xF ;
809  trgs[cou].rhic_delta = 0 ;
810  trgs[cou].rhic = rhic ;
811  trgs[cou].reserved[0] = 0xF0000000 | (0x0FFFFFFF & dta) ; // 0xF for "fired"
812 
813  switch(trgs[cou].trg) {
814  case 4 : // physics
815  case 8 : // interleaved laser
816  case 9 : // usual laser
817  case 10 : // pulser
818  break ;
819  default :
820  LOG(ERR,"RDO %d: T %d: prompt: bad trg: 0x%08X",rdo.rdo,trgs[cou].t,dta) ;
821  err = 1 ;
822  continue ;
823  }
824 
825  if(trgs[cou].t==0) {
826  LOG(ERR,"RDO %d: token 0 (prompt) -- ignoring: 0x%08X",rdo.rdo,dta) ;
827  err = 1 ;
828  continue ;
829  }
830 
831  // check for busy overrun
832  if((dta & 0x3000000) != 0x2000000) {
833  LOG(ERR,"RDO %d: T %d: prompt: BUSY overrun: 0x%08X",rdo.rdo,trgs[cou].t,dta) ;
834  err = 1 ;
835  continue ;
836  }
837 
838  if(cou) {
839  LOG(ERR,"RDO %d: duplicate prompt trigger",rdo.rdo) ;
840  err = 1 ;
841  continue ;
842  }
843 
844  cou++ ;
845 
846  collision = rhic ; // mark the collission time...
847  }
848 
849  }
850 
851  if(cou==0) { // no prompt trigger contrib; use the one from the RDO header.
852  // either for a logging event (4096) or the one from the trigger-only (4097)
853 
854  if(rdo.token != 4096) {
855  rdo.token = 4097 ;
856  LOG(NOTE,"No triggers in event, making it %d",rdo.token) ;
857  }
858 
859  trgs[cou].t = rdo.token ;
860  trgs[cou].daq = 0 ;
861  trgs[cou].trg = 4 ; // dummy
862  trgs[cou].rhic_delta = 0 ;
863  trgs[cou].rhic = 0 ;
864  trgs[cou].reserved[0] = 0 ;
865 
866  cou++ ;
867 
868  }
869  else if (cou > 1) {
870  LOG(ERR,"RDO %d: token %d? -- too many prompt contributions!",rdo.rdo,trgs[0].t) ;
871  err = 1 ;
872  }
873 
874  // at this point at least one contribution exists (i.e. cou>=1):
875  // real L0 t
876  // 4096 for log events
877  // 4097 for events without an L0
878 
879  if(trgs[0].t == 0) {
880  LOG(ERR,"Token 0 in RDO %d: making it 4097",rdo.rdo) ;
881  err = 1 ;
882  trgs[0].t = 4097 ;
883  }
884 
885  for(u_int i=0;i<rdo.trg_cou;i++) {
886  u_int dta = rdo.trg[i].data ;
887  u_int marker = rdo.trg[i].csr >> 24 ;
888  u_int rhic = rdo.trg[i].rhic_counter ;
889 
890  if(marker==0xFF) { // FIFO
891  int daq10k = 0 ;
892 
893  trgs[cou].t = dta & 0xFFF ;
894  trgs[cou].daq = (dta >> 12) & 0xF ;
895  trgs[cou].trg = (dta >> 16) & 0xF ;
896  trgs[cou].rhic = rhic ;
897  trgs[cou].reserved[0] = 0x20000000 | (0x0FFFFFFF & dta) ;
898 
899  switch(trgs[cou].trg) {
900  case 13 : // L2 ABORT
901  case 14 : // L1 ACCEPT
902  case 15 : // L2 ACCEPT
903  break ;
904 
905  case 2 : // RESET
906 
907  if((trgs[cou].t == 0x345) && (trgs[cou].daq == 2)) { // reset at run start from L0
908  continue ; // skip it
909  }
910  if((trgs[cou].t == 1001) && (trgs[cou].daq == 3)) { // reset at run start from TCD in local
911  continue ; // skip it
912  }
913 
914  // WARNING: no "break" here!!!
915 
916 
917  default : // readout command; BUT not necessarily for DAQ10k!
918 
919  // check for overrun UNLESS the actual command
920 
921  if((dta & 0x03A00000) == 0x00800000) {
922  //LOG(WARN,"DAQ10k trigger; no data") ;
923  daq10k = 1 ;
924  }
925  else {
926  if((dta & 0x3000000) != 0x2000000) {
927  if(trgs[0].trg == 9) { // laser!
928  LOG(NOTE,"RDO %d: T %d: FIFO: BUSY overrun: 0x%08X",rdo.rdo,trgs[cou].t,dta) ;
929  }
930  else {
931  LOG(ERR,"RDO %d: T %d: FIFO: BUSY overrun: 0x%08X",rdo.rdo,trgs[cou].t,dta) ;
932  err = 1 ;
933  }
934  }
935  }
936 
937  switch(trgs[cou].trg) {
938  case 4 : // physics
939  case 8 : // interspersed laser
940  case 9 : // laser
941  case 10 : // pulser
942  break ;
943  default:
944  if(trgs[0].trg == 9) { //laser!
945  LOG(NOTE,"RDO %d: T %d: FIFO: bad trg_cmd: 0x%08X",rdo.rdo,trgs[cou].t,dta) ;
946  }
947  else {
948  LOG(ERR,"RDO %d: T %d: FIFO: bad trg_cmd: 0x%08X",rdo.rdo,trgs[cou].t,dta) ;
949  err = 1 ;
950  }
951  break ;
952  }
953 
954  trgs[cou].reserved[0] = 0xA0000000 | (0x0FFFFFFF & dta) ; // maybe DAQ10k?
955 
956  // new in FY12, DAQ10k -- we leave all of them for receiver.C!
957 
958  if(daq10k) break ; // use it
959  else continue ; // skip it...
960 
961  }
962 
963  // we took out all the FIFO l0 contribs here!
964 
965  if(rhic >= collision) {
966  trgs[cou].rhic_delta = rhic - collision ;
967  }
968  else {
969  trgs[cou].rhic_delta = -(collision - rhic) ;
970  }
971 
972  if(trgs[cou].rhic_delta == 1) {
973  LOG(NOTE,"RDO %d: T %d: FIFO: delta == 1: 0x%08X",rdo.rdo,trgs[cou].t,dta) ;
974  if(trgs[0].trg == 9) { // a laser...
975  continue ;
976  }
977  }
978 
979  if((trgs[cou].t == 0)) {
980  LOG(ERR,"RDO %d: token 0 in L2 contribution 0x%08X -- skipping",rdo.rdo,dta) ;
981  err = 1 ;
982  continue ;
983  }
984 
985  cou++ ;
986  }
987 
988  }
989 
990  if(err) { // dump out everyhign
991  LOG(ERR," RDO %d: words %d",rdo.rdo,words) ;
992  for(u_int i=0;i<rdo.trg_cou;i++) {
993  LOG(ERR," RDO %d: T %4d: %d/%d: data 0x%08X, CSR 0x%08X, RHIC %u",rdo.rdo, rdo.token, i, rdo.trg_cou, rdo.trg[i].data, rdo.trg[i].csr, rdo.trg[i].rhic_counter) ;
994  }
995  }
996 
997 
998 
999  return cou ;
1000 }
Definition: rb.hh:21