StRoot  1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
fcs_data_c.cxx
1 #include <assert.h>
2 #include <sys/types.h>
3 #include <sys/stat.h>
4 #include <errno.h>
5 #include <math.h>
6 #include <time.h>
7 #include <string.h>
8 #include <stdio.h>
9 #include <stdlib.h>
10 
11 #include <rtsLog.h>
12 
13 #include "fcs_data_c.h"
14 
15 static inline u_int sw16(u_int d)
16 {
17  u_int tmp = d ;
18 
19  d >>= 16 ;
20 
21  d |= (tmp & 0xFFFF)<<16 ;
22 
23  return d ;
24 }
25 
26 // this shouldn't really be static when running offline!
27 //unsigned long long fcs_data_c::ch_mask[8] ; // channel masks for the 8 RDOs; where are they? map file!
28 struct fcs_data_c::fcs_ped_t fcs_data_c::ped[FCS_SECTOR_COU][8] ; // 8 RDO
29 
30 struct fcs_data_c::rdo_map_t fcs_data_c::rdo_map[FCS_SECTOR_COU][8] ; // FCS_SECTOR_COU sectors, 8 RDOs each --> det,ns,dep
31 struct fcs_data_c::det_map_t fcs_data_c::det_map[4][2][24] ; // det,ns,dep --> sector RDO
32 u_char fcs_data_c::rdo_map_loaded ;
33 
34 u_char fcs_data_c::fcs_bad_ch[8][34] ;
35 u_char fcs_data_c::fcs_bad_ch_all[FCS_SECTOR_COU][8][34] ;
36 
37 u_int fcs_data_c::run_number ;
38 u_int fcs_data_c::run_type ;
39 
40 // for ZS
41 float fcs_data_c::n_sigma ;
42 float fcs_data_c::n_sigma_hcal ;
43 float fcs_data_c::n_sigma_epd ;
44 short fcs_data_c::n_pre ;
45 short fcs_data_c::n_post ;
46 short fcs_data_c::n_cou ;
47 char fcs_data_c::n_mode ;
48 
49 // set in send_config, for shared access during data-checking
50 u_short fcs_data_c::ht_threshold ;
51 u_short fcs_data_c::tb_pre ;
52 u_short fcs_data_c::tb_all ;
53 
54 u_char fcs_data_c::ascii_no ;
55 
56 pthread_mutex_t fcs_data_c::ped_mutex ;
57 
58 fcs_data_c::statistics_t fcs_data_c::statistics[8] ;
59 
60 int fcs_data_c::stage_params_txt[32] ;
61 
62 
63 long fcs_data_c::dep_to_char(int det, int ns, int dep)
64 {
65  long ret ;
66  char *ctmp = (char *)&ret ;
67 
68  switch(det) {
69  case 0 :
70  ctmp[0] = 'E' ;
71  break ;
72  case 1 :
73  ctmp[0] = 'H' ;
74  break ;
75  case 2 :
76  ctmp[0] = 'P' ;
77  break ;
78  case 3 :
79  ctmp[0] = 'M' ;
80  break ;
81  default :
82  ctmp[0] = 'X' ;
83  break ;
84  }
85 
86 
87  if(ns==0) ctmp[1] = 'N' ;
88  else ctmp[1] = 'S' ;
89 
90  sprintf(ctmp+2,"%02d",dep) ;
91 
92  return ret ;
93 
94 
95 }
96 
97 #if 0
98 // this was for stage2 and stage1 _before_ 23-Nov-2021
99 const char *fcs_data_c::stage_labels[] = {
100  "FCS_HAD-HERATIO-THR", //
101  "FCS_EM-HERATIO-THR", //
102  "FCS_HADTHR1", //
103  "FCS_HADTHR2", //
104  "FCS_HADTHR3",
105  "FCS_EMTHR1", //
106  "FCS_EMTHR2", //
107  "FCS_EMTHR3",
108  "FCS_JETTHR1",
109  "FCS_JETTHR2",
110  "FCS_ETOTTHR", //
111  "FCS_HTOTTHR", // 11 //
112 
113  "FCS_EHTTHR", // 12 //
114  "FCS_HHTTHR", // 13 //
115  "FCS_PHTTHR" // 14 //
116 } ;
117 #endif
118 
119 // FY22
120 #if 0
121 // From Christian
122 Word Type Value
123 0 2x uint8 (had_ratio_thr << 8) || em_ratio_thr
124 1 uint11 had_thr_0
125 2 uint11 had_thr_1
126 3 uint11 had_thr_2
127 4 uint11 em_thr_0
128 5 uint11 em_thr_1
129 6 uint11 em_thr_2
130 7 uint11 ele_thr_0
131 8 uint11 ele_thr_1
132 9 uint11 ele_thr_2
133 10 2x uint8 (jp_a_thr_1 << 8) || jp_a_thr_0
134 11 2x uint8 (0x00 << 8) || jp_a_thr_2
135 12 2x uint8 (jp_bc_thr_1 << 8) || jp_bc_thr_0
136 13 2x uint8 (jp_bc_thr_d << 8) || jp_bc_thr_2
137 14 2x uint8 (jp_de_thr_1 << 8) || jp_de_thr_0
138 15 2x uint8 (jp_de_thr_d << 8) || jp_de_thr_2
139 16 uint11 etot_thr
140 17 uint11 htot_thr
141 18 2x uint8 (hcal_ht_thr << 8) || ecal_ht_thr
142 19 bit16 signature
143 20 N/A
144 
145 
146 #endif
147 
148 const char *fcs_data_c::stage_labels[32] = {
149  "FCS_HAD-HERATIO-THR", //0
150  "FCS_EM-HERATIO-THR", //1
151 
152  "FCS_HADTHR0", //2
153  "FCS_HADTHR1", //3
154  "FCS_HADTHR2", //4
155 
156  "FCS_EMTHR0", //5
157  "FCS_EMTHR1", //6
158  "FCS_EMTHR2", //7
159 
160  "FCS_ELETHR0", //8
161  "FCS_ELETHR1", //9
162  "FCS_ELETHR2", //10
163 
164  "FCS_JPATHR0", //11
165  "FCS_JPATHR1", //12
166  "FCS_JPATHR2", //13
167 
168  "FCS_JPBCTHR0", //14
169  "FCS_JPBCTHR1", //15
170  "FCS_JPBCTHR2", //16
171  "FCS_JPBCTHRD", //17
172 
173  "FCS_JPDETHR0", //18
174  "FCS_JPDETHR1", //19
175  "FCS_JPDETHR2", //20
176  "FCS_JPDETHRD", //21
177 
178  "FCS_ETOTTHR", //22
179  "FCS_HTOTTHR", //23
180 
181  "FCS_EHTTHR", //24
182  "FCS_HHTTHR", //25
183  "FCS_PHTTHR" //26
184 } ;
185 
186 
187 
188 
189 
190 int fcs_data_c::load_stage_params(int sec1, const char *fname)
191 {
192  if(fname==0) {
193  fname="/RTS/conf/fcs/stage_params.txt" ;
194  }
195 
196  FILE *f = fopen(fname,"r") ;
197  if(f==0) {
198  LOG(ERR,"sector %2d: %s: [%s]",sec1,fname,strerror(errno)) ;
199  return -1 ;
200  }
201 
202  LOG(INFO,"sector %2d: stage_params %s opened",sec1,fname) ;
203 
204  u_int max_i = 0 ;
205 
206  while(!feof(f)) {
207  char buff[128] ;
208  char name[64] ;
209  int val ;
210  int ix ;
211  int dummy ;
212 
213  if(fgets(buff,sizeof(buff),f)==0) continue ;
214 
215  if(buff[0]=='#') continue ;
216  if(buff[0]=='\n') continue ;
217 
218  name[0] = '?' ;
219  name[1] = 0 ;
220  val = -1 ;
221 
222  int ret = sscanf(buff,"%d %d %d %s %d",&dummy,&dummy,&ix,name,&val) ;
223  if(ret != 5) continue ;
224 
225 // LOG(TERR,"ret %d: [%s]=%d",ret,name,val) ;
226 
227  char got_it = -1 ;
228  for(u_int i=0;i<sizeof(stage_labels)/sizeof(stage_labels[0]);i++) {
229  if(stage_labels[i]==0) continue ;
230 
231  if(strcasecmp(stage_labels[i],name)==0) {
232  stage_params_txt[i] = val ;
233  got_it = i ;
234  if(i>max_i) max_i = i ;
235  break ;
236  }
237  }
238 
239  if(sec1==11) { // LOG only from this one
240  if(got_it<0) {
241  LOG(ERR,"stage_param_txt [%s]=%d NOT coded locally",name,val) ;
242  }
243  else {
244  LOG(INFO,"stage_param_txt [%s]=%d, index %d, ix %d",name,val,got_it,ix) ;
245  }
246  }
247  }
248 
249  if(sec1==11) { // LOG from this one only
250  for(u_int i=0;i<max_i;i++) {
251  LOG(TERR,"stage_params_txt: %d/%d = %d",i,max_i,stage_params_txt[i]) ;
252  }
253  }
254 
255  fclose(f) ;
256  return 0 ;
257 }
258 
259 
260 
261 int fcs_data_c::zs_start(u_short *buff)
262 {
263  int thr ;
264  int l_cou ;
265  int l_pre, l_post ;
266  int is_trg = 0 ;
267  int i_ped ;
268  float sigma ;
269 
270  if(hdr_det==2) sigma = n_sigma_epd ;
271  else if(hdr_det==1) sigma = n_sigma_hcal ;
272  else sigma = n_sigma ;
273 
274  // trigger channels are special so figure this out
275  if(ch >= 32) is_trg = 1 ;
276  if(hdr_det >= 3) is_trg = 1;
277 
278  if(is_trg) { // this is the trigger data channel, no need to go pre/post
279  thr = 0 ;
280  l_cou = 1 ;
281  l_pre = 0 ;
282  l_post = 0 ;
283  i_ped = 0 ;
284  }
285  else {
286  i_ped = (int)(ped[sector-1][rdo-1].mean[ch]+0.5) ;
287 
288  LOG(DBG,"S%d:%d:%d mean %f, n_sigma %f, rms %f",
289  sector,rdo,ch,
290  (float)ped[sector-1][rdo-1].mean[ch],
291  (float)sigma,
292  (float)ped[sector-1][rdo-1].rms[ch]) ;
293 
294  // I don't think that a threshold as a function of RMS is a good idea.
295  // I should do what the ASICs do and have a fixed digital threshold
296  if(n_mode==0) {
297  thr = (int)(ped[sector-1][rdo-1].mean[ch] + sigma * ped[sector-1][rdo-1].rms[ch] + 0.5) ;
298  }
299  else {
300  thr = (int)(ped[sector-1][rdo-1].mean[ch] + sigma) ;
301  }
302 
303  l_cou = n_cou ;
304  l_pre = n_pre ;
305  l_post = n_post ;
306  }
307 
308  int t_cou = 0 ;
309  int t_start = 0 ;
310  int t_stop ;
311  int got_one = 0 ;
312 
313 // int q_ped = 0 ;
314 
315  // form sequences including the l_pre and l_post bits
316  for(int i=0;i<tb_cou;i++) {
317  short i_adc = adc[i] & 0xFFF ;
318 
319 // if(i<4) {
320 // q_ped += d ;
321 // }
322 
323 // printf("CH %d: %d = %d < thr %d: t_start %d, t_cou %d\n",ch,i,d,thr,t_start,t_cou) ;
324 
325  if(i_adc <= thr) { // datum needs to be greater than the threshold
326  if(t_cou >= l_cou) {
327  t_stop = t_start + t_cou ;
328 
329  t_start -= l_pre ;
330  if(t_start < 0) t_start = 0 ;
331 
332  t_stop += l_post ;
333  if(t_stop > tb_cou) t_stop = tb_cou ;
334 
335  if(got_one==0) { // first one
336  memset(mark,0,tb_cou) ;
337  }
338 
339  got_one = 1;
340  for(;t_start<t_stop;t_start++) {
341  mark[t_start] = 1 ;
342  }
343  }
344  t_cou = 0 ;
345  }
346  else {
347  if(t_cou==0) {
348  t_start = i ;
349  }
350  t_cou++ ;
351  }
352 
353  }
354 
355 
356 #if 0
357  if(!is_trg) {
358  q_ped /= 4 ; // quick ped
359  LOG(DBG,"RDO %d, ch %d, q_ped %d, i_ped %d",rdo,ch,q_ped,i_ped) ;
360 
361  q_ped -= i_ped ;
362  if(abs(q_ped)>3) {
363  statistics[rdo-1].odd_ped[ch]++ ;
364  }
365  }
366 #endif
367 
368  //finalize the last sequence
369  if(t_cou >= l_cou) {
370  t_stop = t_start + t_cou ;
371 
372  t_start -= l_pre ;
373  if(t_start < 0) t_start = 0 ;
374 
375  t_stop += l_post ;
376  if(t_stop > tb_cou) t_stop = tb_cou ;
377 
378  if(got_one==0) {
379  memset(mark,0,tb_cou) ;
380  }
381 
382  got_one = 1 ;
383 
384  for(;t_start<t_stop;t_start++) {
385  mark[t_start] = 1 ;
386  }
387 
388  }
389 
390 
391  LOG(DBG,"RDO %d, ch %d: thr %d: got %d",rdo,ch,thr,got_one) ;
392 
393  if(got_one==0) return 0 ; // nothing found
394 
395  u_short *dp ;
396 
397  dp = (u_short *)buff ;
398 
399 
400  int seq_cou = 0 ;
401 
402  // and now go through the "mark"
403  u_short *dstart = dp ;
404 
405  dstart[0] = ch ;
406  dstart[1] = 0 ; // count of sequences
407 
408  dp += 2 ; // skip the header
409 
410  u_short *t_cou_p = dp + 1 ;
411  t_cou = 0 ;
412 
413  for(int i=0;i<tb_cou;i++) {
414  if(mark[i]) {
415 // printf("Mark at %d\n",i) ;
416 
417  if(t_cou==0) {
418 // printf("t_start %d\n",i) ;
419  *dp++ = i ;
420  t_cou_p = dp++ ;
421  t_start = i ;
422  }
423 
424  short i_adc = adc[i] & 0xFFF ;
425  short fla = adc[i] >> 12 ;
426 
427  // Akio's request to see if the ADC pegged
428  if(i_adc==4095) ; // leave it!
429  else {
430  i_adc -= i_ped ;
431  if(i_adc < 0) i_adc = 0 ; // no stinkin' negative numbers
432  }
433 
434  i_adc |= (fla<<12) ; // put the flags back
435 
436 // printf("adc[%d] = %d\n",i,i_adc&0xFFF) ;
437  *dp++ = i_adc ;
438 
439  t_cou++ ;
440  }
441  else {
442  if(t_cou) {
443  *t_cou_p = t_cou ;
444  seq_cou++ ;
445 // printf("ZS: Ch %d:%d: seq %d: t_start %d, t_cou %d\n",rdo,ch,seq_cou,t_start,t_cou) ;
446  }
447  t_cou = 0 ;
448  }
449  }
450 
451  if(t_cou) {
452  *t_cou_p = t_cou ;
453  seq_cou++ ;
454 // printf("ZS: Ch %d:%d: seq %d(last): t_start %d, t_cou %d\n",rdo,ch,seq_cou,t_start,t_cou) ;
455  }
456 
457  dstart[1] = seq_cou ;
458 
459 // printf("... ZS is now %d shorts (seq_cou %d)\n",(int)(dp-dstart),seq_cou) ;
460 
461  // I probably want to return 0 if nothing is founf
462  if(seq_cou == 0) return 0 ;
463 
464  return dp-dstart ; // shorts
465 
466 
467 }
468 
469 
470 /*******************************/
471 int fcs_data_c::start(u_short *d16, int shorts)
472 {
473  u_int *d ;
474 
475  //class members
476  events++ ;
477 
478  bad_error = 0 ;
479 
480  dta_start = dta_p = d16 ;
481  dta_stop = d16 + shorts ;
482  dta_shorts = shorts ;
483 
484  d = (u_int *)d16 ;
485 
486  rhic_start = 0;
487  ch_count = 0 ;
488  ch_mask_seen = 0 ;
489  want_saved = 0 ;
490 
491 
492 // for(int i=0;i<16;i++) {
493 // LOG(TERR,"...start: %d = 0x%04X",i,d16[i]) ;
494 // }
495 
496 
497  //version = 0 ; // unknown...
498 // LOG(TERR,"VERSION 0x%X",d[0]) ;
499 
500  //check version
501  if(d[0]==0xDDDDDDDD) { // new FY18 data!
502  d += 4 ; // skip GTP header
503  d16 += 8 ;
504 
505  // d16[0] is start comma
506  // d16[1] is cccc ;
507  // d16[2] is 0x9801
508  // ... and then trigger data
509 
510  version = sw16(d[2]) ;
511 
512  switch(version) {
513  case 0x12340000 : // pre-May-15-2018
514  version = 0x18040000 ; //Apr 2018
515  d += 12 ; // skip event header to go to ADC data
516  break ;
517  default : // nre
518  switch(d16[2]) {
519  case 0x9801 :
520  version = 0x18050000 ; // 15-May-2018
521 
522  dta_p = ((u_short *)d)+6 ; // this is for May18-Dec18
523 
524 
525  for(int i=0;i<16;i++) {
526  LOG(TERR,"...data9801: %d = 0x%04X",i,dta_p[i]) ;
527  }
528 
529 
530  return 1 ;
531  case 0x9802 :
532  case 0x9803 :
533  version = 0x18110000 ;
534 
535  dta_p = d16 ;
536 
537  return hdr_event() ;
538 
539  case 0x9810 : // experimental streaming, May 2020
540  version = 0x30050000 ;
541 
542  dta_p = d16 ;
543 
544  return hdr_event() ;
545 
546  }
547 
548  LOG(ERR,"uknown version 0x%04X",d16[2]) ;
549  bad_error |= 1 ;
550  return 0 ;
551 
552  break ;
553  }
554 
555  // pre-May-15-2018
556  dta_p = (u_short *) d ;
557 
558 
559  for(int i=0;i<8;i++) {
560  LOG(TERR,"...data: %d = 0x%04X",i,dta_p[i]) ;
561  }
562 
563  return 1 ;
564  }
565 
566  // old 2017 format here
567  //LOG(TERR,"start: 0x%08X 0x%08X",d[0],d[1]) ;
568 
569  //move to start-of-ADC marker
570  while(dta_p < dta_stop) {
571  if(*dta_p++ == 0xFD06) {
572  //for(int i=0;i<16;i++) {
573  // LOG(TERR,"...%d = 0x%04X",i,dta_p[i]) ;
574  //}
575 
576 
577  return 1 ;
578  }
579  }
580 
581 
582  return -1 ;
583 }
584 
585 // at entry dta_p points to the start-comma of the event
586 // at exit, dta_p must point to start of ADC data
587 // returns
588 // >0 if all OK and triggered event
589 // 0 is all OK and not a triggered event
590 // <0 is not all OK
591 int fcs_data_c::hdr_event()
592 {
593  u_short *start_p = dta_p ;
594 
595 
596 // for(int i=0;i<32;i++) {
597 // LOG(TERR,"... %d 0x%04X",i,dta_p[i]) ;
598 // }
599 
600 // has_ascii = 0 ;
601  first_tb_cou = 0 ;
602 
603  //I will need the board id as a sector/id combo
604  hdr_board_id = dta_p[3] ;
605 
606 
607  hdr_sector = ((hdr_board_id >> 11) & 0x1F)+1 ;
608  hdr_rdo = ((hdr_board_id >> 8) & 0x7)+1 ;
609 
610  hdr_det = (hdr_board_id >> 6) & 0x3 ;
611  hdr_ns = (hdr_board_id >> 5) & 1 ;
612  hdr_dep = hdr_board_id & 0x1F ;
613 
614 
615 // LOG(TERR,"... 0x%X S%d:%d %d %d %d",hdr_board_id,hdr_sector,hdr_rdo,hdr_det,hdr_ns,hdr_dep) ;
616 
617 
618  if((sector != hdr_sector) || (rdo != hdr_rdo)) {
619  bad_error |= 2 ;
620  LOG(ERR,"%d: sector %d:%d expected, received %d:%d [0x%X]",id,sector,rdo,hdr_sector,hdr_rdo,hdr_board_id) ;
621  }
622 
623  // this won't work Offline because I don't have the real board id...
624  if(realtime && (hdr_board_id != board_id)) {
625  bad_error |= 2 ;
626  LOG(ERR,"%d: evt %d: board_id: expected 0x%04X, received 0x%04X",id,events,board_id,hdr_board_id) ;
627  }
628 
629  //extract trigger_word and rhic_counter
630  hdr_trg_word = ((dta_p[5]&0xF)<<16) | dta_p[4] ;
631  hdr_rhic_counter = (dta_p[7]<<16)|dta_p[6] ;
632 
633 
634  LOG(NOTE,"HDR S%d:%d: trg_word 0x%05X, RHIC %u, upper 0x%03X",hdr_sector,hdr_rdo, hdr_trg_word,hdr_rhic_counter,dta_p[5]>>4) ;
635 
636  trg_cmd = hdr_trg_word & 0xF ;
637  daq_cmd = (hdr_trg_word>>4) & 0xF ;
638  token = ((hdr_trg_word>>8)&0xF)<<8 ;
639  token |= ((hdr_trg_word>>12)&0xF)<<4 ;
640  token |= ((hdr_trg_word>>16)&0xF) ;
641 
642  LOG(NOTE,"HDR: token %d, trg_cmd %d, daq_cmd %d",token,trg_cmd,daq_cmd) ;
643 
644  if(version == 0x30050000) {
645  // leave dta_p
646 
647  trgd_event = 0 ; // need to check what this really means?
648  return 0 ;
649  }
650 
651 
652  // skip to first datum
653  dta_p += 8 ;
654 
655 // has_ascii = 0 ;
656  ascii_p = 0 ;
657  ascii_words = 0 ;
658 
659 
660  if(dta_p[0]==0xEEEE && dta_p[1]==0xEEEE) { // start of ASCII
661  char ctmp[1024] ;
662 
663  dta_p += 2 ; // adjust
664  u_int *d32 = (u_int *)dta_p ;
665 
666  int words = (dta_shorts - 8 - 2)/2 ; // adjust
667 
668 // has_ascii = 1 ;
669  ascii_p = (char *)dta_p ;
670  ascii_words = words ;
671 
672  if(ascii_no==0) LOG(TERR,"ASCII contribution - words %d[%d]: sector %d, rdo %d, hdr_trg_word 0x%X, hdr_board 0x%X",words,dta_shorts,sector,rdo,hdr_trg_word,hdr_board_id) ;
673 
674  int end_marker = 0 ;
675  u_int cou = 0 ;
676  for(int i=0;i<words;i++) {
677  u_int asc = d32[i] ;
678 
679  if((asc&0xFF00FFFF)==0xF5009800) {
680  char c = (asc>>16)&0xFF ;
681 
682  if(cou>sizeof(ctmp)) ;
683  else {
684  if(c=='\n') {
685  float f_val = 0.0 ;
686  u_int i_val = 0 ;
687  char *c ;
688  //int ret ;
689 
690  ctmp[cou] = 0 ;
691  if(ascii_no==0) LOG(TERR,"S%d:%d:%d: \"%s\"",sector,rdo,events,ctmp) ;
692  cou = 0 ;
693 
694 
695  if((c=strstr(ctmp,"r0 7"))) {
696  sscanf(c,"r0 7 %f",&f_val) ;
697 
698  ped_lock() ;
699  statistics[rdo-1].ht_rate = (int) f_val ;
700  ped_unlock() ;
701 
702 
703  }
704  else if((c=strstr(ctmp,"t W "))) {
705  sscanf(c,"t W %f",&f_val) ;
706 
707  ped_lock() ;
708  statistics[rdo-1].temperature = f_val ;
709  ped_unlock() ;
710  }
711  else if((c=strstr(ctmp,"tb "))) {
712  sscanf(c,"tb 0x%X",&i_val) ;
713 
714  f_val = 100.0*(double)(i_val & 0x3FF)/1023.0 ;
715 
716  ped_lock() ;
717  statistics[rdo-1].deadtime = f_val ;
718  ped_unlock() ;
719 
720  //if(f_val > 50.0) {
721  // LOG(WARN,"S%d:%d: deadtime %.1f",sector,rdo,f_val) ;
722  //}
723  //else {
724  // LOG(TERR,"S%d:%d: deadtime %.1f",sector,rdo,f_val) ;
725  //}
726  }
727  else if((c=strstr(ctmp,"b "))) {
728  sscanf(c,"b %f",&f_val) ;
729 
730  ped_lock() ;
731  statistics[rdo-1].deadtime = f_val ;
732  ped_unlock() ;
733  }
734  else if((c=strstr(ctmp,"rg 7 "))) {
735  sscanf(c,"rg 7 0x%X",&i_val) ;
736 
737  f_val = 100.0*(double)(i_val & 0x3ff)/1023.0 ;
738 
739 
740  ped_lock() ;
741  statistics[rdo-1].rx_throttle = f_val ;
742  ped_unlock() ;
743 
744  //if(f_val > 50.0) {
745  // LOG(WARN,"S%d:%d: RX-throttle %.1f",sector,rdo,f_val) ;
746  //}
747  //else {
748  // LOG(TERR,"S%d:%d: RX-throttle %.1f",sector,rdo,f_val) ;
749  //}
750  }
751 
752 
753  }
754  else {
755  ctmp[cou] = c ;
756  cou++ ;
757  }
758  }
759  }
760  else if(asc != 0xFFFFFFFF) {
761  bad_error |= 4 ;
762  LOG(ERR,"ASCII wha %d: 0x%08X",i,asc) ;
763  }
764 
765  dta_p += 2 ;
766 
767  if(asc==0xFFFFFFFF) {
768  end_marker = 1 ;
769  break ;
770  }
771 
772  }
773 
774  ctmp[cou] = 0 ;
775  if(!end_marker) {
776  bad_error |= 8 ;
777  LOG(ERR,"S%d:%d:%d: ASCII[%d] but no end-marker \"%s\"",sector,rdo,events,cou,ctmp) ;
778  }
779  else if(cou) {
780  bad_error |= 8 ;
781  LOG(ERR,"S%d:%d:%d: ASCII[%d] \"%s\"",sector,rdo,events,cou,ctmp) ;
782  }
783 
784  }
785  else if(dta_p[0]==0xFFFF && dta_p[1]==0xFFFF) { // bug: end-of-ascii without ascii
786  bad_error |= 8 ;
787  LOG(ERR,"S%d:%d:%d: ASCII bug: 0x%X, 0x%X",sector,rdo,events,hdr_trg_word,dta_p[2]) ;
788  for(int i=0;i<32;i++) {
789  LOG(TERR,"... %d = 0x%04X",i,start_p[i]) ;
790  }
791  dta_p += 2 ;
792  }
793 #if 1
794  else if(dta_p[0]==0xFFFF) {
795  bad_error |= 8 ;
796 
797  LOG(ERR,"BAD 0xFFFF bug -- 0x%08X",*((u_int *)dta_p)) ;
798 
799  u_int *d32 = (u_int *)start_p ;
800 
801  for(int i=0;i<32;i++) {
802  LOG(ERR,"... %d = 0x%04X",i,d32[i]) ;
803  }
804 
805 
806  dta_p++ ; // this is super bad for streaming!@@
807  }
808 #endif
809 
810 // LOG(TERR,"... 0x%X 0x%X",dta_p[0],dta_p[1]) ;
811 
812  if(dta_p[0]==0xE800) {
813  trgd_event = 0 ;
814  return 0 ; // no triggered
815  }
816  else {
817  trgd_event = 1 ;
818  return 1 ;
819  }
820 
821 
822 }
823 
824 
825 // how==0 : OK
826 // else: some error
827 int fcs_data_c::event_end(int how)
828 {
829  if(!trgd_event) return 0 ;
830 
831  if(rdo_map_loaded && (ch_mask_seen != rdo_map[sector-1][rdo-1].ch_mask)) {
832  bad_error |= 0x10 ;
833  LOG(ERR,"%d: event_end: %d: S%02d:%d: mask not-complete 0x%llX (T %d)",id,events,sector,rdo,ch_mask_seen,token) ;
834  }
835 
836 
837  return 0 ;
838 }
839 
840 int fcs_data_c::event_stream()
841 {
842  u_int *d = (u_int *)dta_p ;
843  u_int *d_stop = (u_int *)dta_stop ;
844  u_int xings = 0 ;
845  u_int deadtime = 0 ;
846  u_int trgs = 0 ;
847  u_char want_log = 0 ;
848  u_char end_seen = 0 ;
849 
850  ch = -1 ;
851  tb_cou = 0 ;
852  d += 1 ; // d[0] is now at version
853 
854 // LOG(TERR,"start packet 0x%08X, end 0x%08X",d[0],d_stop[0]) ;
855 
856 
857  if(d_stop[0]==0x5C || d_stop[0]==0xAAAABBBB) ;
858  else {
859  want_log |= 1 ;
860 
861  for(int i=-8;i<=8;i++) {
862  LOG(ERR,"%d: d_stop 0x%08X",i,d_stop[i]) ;
863  }
864  }
865 
866 
867  u_int slice = d[1] ;
868  u_int old_slice = d[2] ;
869  u_int pkt_counter = d[5] ;
870 
871  u_int end_slice = 0xdeadbeef ;
872  u_int pkt_status = 0xdeadbeef ;
873 
874 
875  double mean[32] ;
876  double rms[32] ;
877  u_int cou[32] ;
878 
879  memset(mean,0,sizeof(mean)) ;
880  memset(rms,0,sizeof(rms)) ;
881  memset(cou,0,sizeof(cou)) ;
882 
883 
884  u_int ch_dead[32] ;
885  memset(ch_dead,0,sizeof(ch_dead)) ;
886 
887  // skip header
888  d += 7 ;
889 
890 
891 // for(int i=0;i<16;i++) {
892 // LOG(TERR,"%d: 0x%08X",i,d[i]) ;
893 // }
894 
895 
896  u_int *adc32 = (u_int *)adc ; // re-use instance storage
897  int adc_cou = 0 ;
898  int adc_ch = 0 ;
899 
900 
901  u_char sync = 0xFF ;
902 
903  u_int got_adc_end = 0 ;
904 
905  u_int bad_sync = 0 ;
906 
907  while(d < d_stop) {
908  u_int dta = *d ;
909  u_int t = dta>>28 ; // type
910 
911 
912  switch(t) {
913  case 0xE : // trg last
914  //LOG(WARN,"TRG last 0x%08X at RHIC %u(%u), sync %d",dta,d[1],d[1]&0xFFFF,(dta>>20)&3) ;
915  d++ ;
916  break ;
917  case 0xA : // trg
918  //LOG(WARN,"TRG norm 0x%08X at RHIC %u(%u), sync %d",dta,d[1],d[1]&0xFFFF,(dta>>20)&3) ;
919  if((dta & 0xF)==0xC) {
920  sync = (dta>>20) & 3 ;
921  }
922  trgs++ ;
923  d++ ;
924  break ;
925  case 0xC : // ADC slice-end
926  adc_ch = dta & 0x1F ;
927 
928  if(got_adc_end & (1<<adc_ch)) {
929  LOG(ERR,"Ch %d -- adc-slice_end already received",adc_ch) ;
930  }
931  got_adc_end |= (1<<adc_ch) ;
932 
933  LOG(WARN,"ADC slice-end 0x%08X at RHIC %u, sync %d, ch %d",dta,(dta>>8)&0xFFFF,(dta>>24)&3,
934  dta&0x1F) ;
935  break ;
936  case 0x8 : // ADC ch end
937  adc_ch = dta & 0x1F ;
938 
939  if(((dta>>24)&0x3)!= sync) {
940  bad_sync++ ;
941  //LOG(ERR,"Bad sync 0x%08X: ch %d: expect %d, have %d",dta,adc_ch,sync,(dta>>24)&3) ;
942  }
943 
944  //LOG(TERR,"CH %d: adc_cou %d",adc_ch,adc_cou) ;
945 
946  // check for error: can happen if there's deadtime...
947  if(adc_cou%4 || adc_cou==0) {
948  LOG(ERR,"ADC ch %d, adc_cou %d??",adc_ch,adc_cou) ;
949  for(int i=2;i>=-20;i--) {
950  LOG(ERR," prev %d 0x%08X",i,d[i]) ;
951  }
952  adc_cou = 0 ;
953  break ;
954  }
955 
956  xings += adc_cou / 4 ; // 2adcs per entry,
957 
958  for(int i=0;i<adc_cou;i++) {
959  u_int d_lo = adc32[i] & 0xFFF ;
960  u_int d_hi = (adc32[i]>>16) & 0xFFF ;
961 
962  mean[adc_ch] += d_lo ;
963  rms[adc_ch] += d_lo * d_lo ;
964  cou[adc_ch]++ ;
965 
966  mean[adc_ch] += d_hi ;
967  rms[adc_ch] += d_hi * d_hi ;
968  cou[adc_ch]++ ;
969 
970 #if 0
971  if(((adc32[i]>>13)&3)!=sync) {
972  LOG(ERR,"ADC ch %d: 0x%08X: bad sync: expect %d",adc_ch,adc32[i],sync) ;
973  }
974  if(((adc32[i]>>(13+16))&3)!=sync) {
975  LOG(ERR,"ADC ch %d: 0x%08X: bad sync: expect %d",adc_ch,adc32[i],sync) ;
976  }
977 #endif
978  }
979 
980  adc_cou = 0 ;
981 
982  break ;
983  case 0x9 : // deadtime
984  // can happen that the high value is already on the next slice!
985  //
986  if(adc_cou != 1) { // must be 1 because I counted the 0x7....
987  LOG(WARN,"DEAD but unfinished ADCs %d on ch %d",adc_cou,adc_ch) ;
988  }
989 
990  adc_cou = 0 ;
991 
992  //for(int i=2;i>-8;i--) {
993  // LOG(ERR," dead %d 0x%08X",i,d[i]) ;
994  //}
995 
996  {
997  want_log |= 2 ;
998  //u_int d_start = (d[-1]>>8)&0xFFFF ;
999  u_int d_end = (dta>>8) & 0xFFFF ;
1000  u_int ch = dta & 0x1F ;
1001 
1002  //LOG(ERR,"DEAD 0x%08X 0x%08X - %u %u",dta,d[-1],d_end,d_start) ;
1003 
1004  deadtime += d_end ;
1005  ch_dead[ch] += d_end ;
1006 
1007  }
1008  break ;
1009  case 0xF : // end
1010  end_slice = d[1] ;
1011  pkt_status = d[5] ;
1012  end_seen = 1 ;
1013  goto event_end ;
1014  break ;
1015  default :
1016  if(t&8) {
1017  LOG(ERR,"Unknown packet 0x%X",t) ;
1018  }
1019  else {
1020  if(adc_cou>=128) {
1021  LOG(ERR,"Too many ADCs %d after ch %d",adc_cou,adc_ch) ;
1022  }
1023  else {
1024  adc32[adc_cou] = dta ;
1025  adc_cou++ ;
1026  }
1027  }
1028  break ;
1029  }
1030 
1031  d++ ;
1032  }
1033 
1034  event_end: ;
1035 
1036  if(got_adc_end != 0xFFFFFFFF) {
1037  LOG(ERR,"ADCs got end 0x%08X",got_adc_end) ;
1038  want_log |= 4 ;
1039  }
1040 
1041  if(bad_sync) {
1042  LOG(ERR,"ADCs with bad sync %d",bad_sync) ;
1043  want_log |= 4 ;
1044  }
1045 
1046  if(want_log || !end_seen || deadtime || pkt_status || (slice==old_slice) || (slice != end_slice)) {
1047 
1048  LOG(ERR,"Packet 0x%08X:0x%08X:0x%08X:%d, shorts %d - status 0x%08X: xings %d, trgs %d, deadtime %d",
1049  slice,old_slice,end_slice,pkt_counter,dta_shorts,
1050  pkt_status,
1051  xings,trgs,deadtime) ;
1052 
1053  if(deadtime) {
1054  for(int i=0;i<32;i++) {
1055  if(ch_dead[i]) {
1056  LOG(ERR,"\t deadtime %d=%d",i,ch_dead[i]) ;
1057  }
1058  }
1059  }
1060  }
1061 
1062 
1063  for(int i=0;i<32;i++) {
1064  if(cou[i]==0) continue ;
1065 
1066  mean[i] /= cou[i] ;
1067  rms[i] /= cou[i] ;
1068 
1069  rms[i] = sqrt(rms[i]-mean[i]*mean[i]) ;
1070 
1071  if(cou[i]>10000) LOG(TERR,"Ch %d: %f +- %f, cou %d -- %d",i,mean[i],rms[i],cou[i],(int)(mean[i]*8.0+0.5)) ;
1072 
1073  if(run_type==1) printf("PED %d %f %f %d %d\n",i,mean[i],rms[i],cou[i],(int)(mean[i]*8.0+0.5)) ;
1074  }
1075 
1076 
1077 
1078  return 0 ;
1079 }
1080 
1081 // this gets called over and over again for each channel!
1082 int fcs_data_c::event()
1083 {
1084 
1085  if(version != 0x18110000) {
1086  if(version == 0x30050000) {
1087  return event_stream() ;
1088  }
1089  return event_pre_fy19() ;
1090  }
1091 
1092  if(!trgd_event) {
1093  event_end(0) ;
1094  return 0 ;
1095  }
1096 
1097  if(dta_p[0]==0xE800) {
1098  event_end(0) ;
1099  return 0 ; // end of event
1100  }
1101 
1102  // this is pretty critical...
1103 // if(*dta_p == 0xFFFF) {
1104  while(*dta_p == 0xFFFF) {
1105  want_saved = 1 ;
1106 
1107  bad_error |= 0x20 ;
1108 
1109  LOG(ERR,"S%d:%d: events %d: BUG 0xFFFF: ch %d, bytes left %d",sector,rdo,events,ch_count,dta_stop-dta_p) ;
1110  LOG(ERR," 0x%X 0x%X 0x%X",dta_p[1],dta_p[2],dta_p[3]) ;
1111 
1112 // u_short *dta_use = dta_p - 1000 ;
1113 // while(dta_use<dta_stop) {
1114 // printf("%d = 0x%04X\n",dta_stop-dta_use,*dta_use++) ;
1115 // }
1116 
1117  event_end(1) ;
1118  return 0 ;
1119 
1120  dta_p++ ;
1121  }
1122 
1123  // from class
1124  tb_cou = 0 ;
1125  ch = -1 ;
1126 
1127  ch_count++ ;
1128 
1129  u_int rhic_cou_xpect = hdr_rhic_counter & 0x7F ;
1130  u_int board_id_xpect = board_id & 0xFF ;
1131 
1132 // for(int i=-16;i<16;i++) {
1133 // LOG(TERR,"in event %d = 0x%04X",i,dta_p[i]) ;
1134 // }
1135 
1136 
1137 
1138 
1139  while(dta_p<dta_stop) {
1140  u_short h[0] ;
1141  u_int trg_word ;
1142  u_int rhic_cou ;
1143  u_int board ;
1144  u_char complain = 0 ;
1145  u_short *dbg_h = dta_p ;
1146 
1147  h[0] = *dta_p++ ; // board,channel
1148  h[1] = *dta_p++ ; // trigger cmd
1149  h[2] = *dta_p++ ; // rhic_cou, token lo
1150 
1151  ch = h[0]&0x3F ;
1152  board = (h[0] >> 6) ;
1153 
1154  trg_word = ((h[2]&0xFF)<<12)|(h[1]) ;
1155  rhic_cou = h[2]>>8 ;
1156 
1157 // LOG(TERR,"ch %d: trg_word 0x%X, rhic_cou %d",ch,trg_word,rhic_cou) ;
1158 // LOG(TERR,"ch %d: 0x%X 0x%X 0x%X",ch,h[0],h[1],h[2]) ;
1159 
1160  //complain = 1 ;
1161  if(board_id_xpect != board) complain = 1 ;
1162 
1163  if(ch>36) complain = 1 ; // Sep21: stage2 can have 37 chs
1164  else {
1165  if(ch_mask_seen & (1LL<<ch)) {
1166  if(realtime) LOG(ERR,"event %d: ch duplicate %d",events,ch) ;
1167  complain = 1 ;
1168  }
1169  ch_mask_seen |= (1LL<<ch) ;
1170  }
1171 
1172  if((hdr_trg_word!=trg_word)|(rhic_cou_xpect!=rhic_cou)) {
1173  complain = 1 ;
1174  }
1175 
1176  if(complain) {
1177  bad_error |= 0x40 ;
1178 
1179  if(realtime && err_count<10) {
1180  LOG(ERR,"%d: S%d:%d: Evt %d, ch %d[%d]: 0x%X 0x%05X %d expected: 0x%X 0x%05X %d seen",id,sector,rdo,
1181  events,ch,ch_count,
1182  board_id_xpect,hdr_trg_word,rhic_cou_xpect,
1183  board,trg_word,rhic_cou) ;
1184 
1185  LOG(ERR,"%d: 0x%04X 0x%04X 0x%04X 0x%04X",id,dbg_h[-1],dbg_h[0],dbg_h[1],dbg_h[2]) ;
1186  }
1187 
1188  err_count++ ;
1189  }
1190 
1191 
1192  while(dta_p<dta_stop) {
1193  u_short d = *dta_p++ ;
1194 
1195  //if(ch==32 && tb_cou==2) LOG(TERR,".... ch %d = %d = 0x%X",ch,tb_cou,d) ;
1196 
1197  if(d==0xFFFF) { // last item of adc_single
1198  //LOG(TERR,"... tb_cou %d: 0x%04X",tb_cou,d) ;
1199  break ;
1200  }
1201  else if(d & 0x8000) {
1202  bad_error |= 0x80 ;
1203  if(realtime) LOG(ERR,"... ch %d: tb_cou %d: 0x%04X",ch,tb_cou,d) ;
1204  }
1205 
1206  //protect structures
1207  if((u_int)tb_cou>=(sizeof(adc)/sizeof(adc[0]))) {
1208  bad_error |= 0x80 ;
1209  LOG(ERR,"Event too big, ch %d, tb %d",ch,tb_cou) ;
1210  event_end(1) ;
1211  return 0 ;
1212  }
1213 
1214  //if(tb_cou < 5) {
1215  // LOG(TERR,"%d: %d = 0x%04X",ch,tb_cou,d) ;
1216  //}
1217 
1218  adc[tb_cou] = d ; //but store the full data, with flags
1219 
1220 
1221  tb_cou++ ;
1222  }
1223 
1224  if(first_tb_cou==0) {
1225  first_tb_cou = tb_cou ;
1226  }
1227  else if(tb_cou != first_tb_cou) {
1228  bad_error |= 0x80 ;
1229  if(complain) LOG(ERR,"%d: ch length mismatch: expect %d, is %d: ch %d(%d)",rdo,first_tb_cou,tb_cou,ch,ch_count) ;
1230  }
1231 
1232  ana_ch() ;
1233 
1234  //LOG(TERR,"0x%08X 0x%08X 0x%08X",dta_p[0],dta_p[1],dta_p[2]) ;
1235 
1236  //LOG(TERR,"Ch %d, %d ADCs, trg 0x%05X",ch,tb_cou,trg_word) ;
1237  return 1 ;
1238  }
1239 
1240 // u_int rhic_end = (dta_p[1]<<16)|dta_p[2] ;
1241 // LOG(TERR,"RHIC ticks %u",rhic_end-rhic_start) ;
1242 
1243  //LOG(TERR,"0x%08X 0x%08X 0x%08X: 0x%08X",dta_p[0],dta_p[1],dta_p[2],rhic_end) ;
1244 
1245  event_end(0) ;
1246  return 0 ;
1247 }
1248 
1249 
1250 int fcs_data_c::ana_ch()
1251 {
1252 
1253 
1254  switch(run_type) {
1255  case 1 :
1256  case 2 :
1257 // case 5 :
1258  break ;
1259  default:
1260  return 0 ;
1261  }
1262 
1263  if(run_type==2 && sector==11 && trg_cmd==4) {
1264  static int first ;
1265 
1266 
1267  static u_char expect[3][37] ;
1268 
1269  if(first==0) {
1270  expect[0][0]=0xC1 ;
1271  expect[0][1]=0xC1 ;
1272  expect[0][2]=0xE1 ;
1273  expect[0][3]=0xE1 ;
1274 
1275  expect[1][34]=0xC1 ;
1276  expect[1][35]=0xC1 ;
1277  expect[1][36]=0x66 ;
1278 
1279  expect[2][34]=0xE1 ;
1280  expect[2][35]=0xE1 ;
1281  expect[2][36]=0x77 ;
1282 
1283  for(int i=0;i<20;i++) {
1284  expect[1][i]= i ;
1285  expect[2][i]=(1<<5)|i ;
1286  }
1287 
1288  for(int i=20;i<28;i++) {
1289  expect[1][i] = (1<<6)|(i-20) ;
1290  expect[2][i] = (1<<6)|(1<<5)|(i-20) ;
1291  }
1292 
1293  for(int i=28;i<34;i++) {
1294  expect[1][i] = (2<<6)|(i-28) ;
1295  expect[2][i] = (2<<6)|(1<<5)|(i-28) ;
1296  }
1297 
1298  first = 1 ;
1299  }
1300 
1301  int errs = 0 ;
1302  for(int tb=0;tb<tb_cou;tb++) {
1303  int r=rdo-5 ;
1304  int d = adc[tb] & 0xFF ;
1305 
1306  if(ch==36) {
1307  if(d && (expect[r][ch] != d)) {
1308  errs++ ;
1309  }
1310  }
1311  else if(expect[r][ch] != d) {
1312  errs++ ;
1313  }
1314  }
1315 
1316 
1317 // if(errs) {
1318  ped_lock() ;
1319  ped[sector-1][rdo-1].cou[ch]++ ;
1320  ped[sector-1][rdo-1].bad_4[ch] += errs ;
1321  ped_unlock() ;
1322 // }
1323 
1324  return 0 ;
1325 
1326  }
1327 
1328  if(ch>=32 || sector==11) return 0 ;
1329 
1330  ped_lock() ;
1331 
1332  u_int aaa[2] ;
1333 
1334  aaa[0] = 0xAAA ;
1335  aaa[1] = 0x555 ;
1336 
1337  if((adc[0] & 0xFFF)==0x555) {
1338  aaa[0] = 0x555 ;
1339  aaa[1] = 0xAAA ;
1340  }
1341 
1342  for(int tb=0;tb<tb_cou;tb++) {
1343  u_int iadc = adc[tb] & 0xFFF ;
1344 
1345  if(run_type==2) {
1346  if(aaa[tb%2] != iadc) {
1347  ped[sector-1][rdo-1].bad_4[ch]++ ;
1348  }
1349  }
1350 
1351  double sadc = (double)iadc ;
1352 
1353  ped[sector-1][rdo-1].mean[ch] += sadc ;
1354  ped[sector-1][rdo-1].rms[ch] += sadc * sadc ;
1355  ped[sector-1][rdo-1].cou[ch]++ ;
1356 
1357 
1358  ped[sector-1][rdo-1].tmp_val_8[ch] += sadc ;
1359  ped[sector-1][rdo-1].tmp_cou_8[ch]++ ;
1360 
1361 
1362  if(ped[sector-1][rdo-1].tmp_cou_8[ch]==8) {
1363  double d = ped[sector-1][rdo-1].tmp_val_8[ch] ;
1364 
1365  ped[sector-1][rdo-1].mean_8[ch] += d ;
1366  ped[sector-1][rdo-1].rms_8[ch] += d*d ;
1367  ped[sector-1][rdo-1].cou_8[ch]++ ;
1368 
1369  ped[sector-1][rdo-1].tmp_val_8[ch] = 0.0 ;
1370  ped[sector-1][rdo-1].tmp_cou_8[ch] = 0 ;
1371  }
1372  }
1373 
1374  ped_unlock() ;
1375 
1376  return 0 ;
1377 }
1378 
1379 
1380 
1381 int fcs_data_c::accum_pre_fy19(u_int ch, u_int tb, u_short sadc)
1382 {
1383 // int fla ;
1384 
1385  //protect structures
1386  if(tb>=(sizeof(adc)/sizeof(adc[0]))) {
1387  return -1 ;
1388  }
1389 
1390  adc[tb] = sadc ; //but store the full data, with flags
1391 
1392 
1393  if(ch>=32) return 0 ; // skip non-ADC channels
1394 
1395 
1396 // fla = sadc >> 12 ; // flags
1397  sadc &= 0xFFF ; //zap the flags to get to raw ADC
1398 
1399 
1400  switch(run_type) {
1401  case 1 :
1402  case 2 :
1403 // case 5 :
1404  ped[sector-1][rdo-1].mean[ch] += (double)sadc ;
1405  ped[sector-1][rdo-1].rms[ch] += (double)sadc * (double)sadc ;
1406  ped[sector-1][rdo-1].cou[ch]++ ;
1407 
1408 
1409  ped[sector-1][rdo-1].tmp_val_8[ch] += (double)sadc ;
1410  ped[sector-1][rdo-1].tmp_cou_8[ch]++ ;
1411 
1412  if(ped[sector-1][rdo-1].tmp_cou_8[ch]==8) {
1413  double d = ped[sector-1][rdo-1].tmp_val_8[ch] ;
1414 
1415  ped[sector-1][rdo-1].mean_8[ch] += d ;
1416  ped[sector-1][rdo-1].rms_8[ch] += d*d ;
1417  ped[sector-1][rdo-1].cou_8[ch]++ ;
1418 
1419  ped[sector-1][rdo-1].tmp_val_8[ch] = 0.0 ;
1420  ped[sector-1][rdo-1].tmp_cou_8[ch] = 0 ;
1421  }
1422 
1423 
1424 
1425  break ;
1426  }
1427 
1428  return 0 ;
1429 
1430 }
1431 
1432 
1433 
1434 void fcs_data_c::run_start(u_int run, int type)
1435 {
1436 
1437  events = 0 ;
1438  err_count = 0 ;
1439 
1440  switch(run_type) {
1441  case 1 :
1442  case 2 :
1443 // case 5 :
1444  ped_start() ;
1445  break ;
1446  }
1447 
1448  if(id==0) {
1449  memset(&statistics,0,sizeof(statistics)) ;
1450 
1451  run_number = run ;
1452  run_type = type ;
1453 
1454  ped_mutex_init() ;
1455  }
1456 
1457 }
1458 
1459 void fcs_data_c::run_stop(int bad_ped)
1460 {
1461  switch(run_type) {
1462  case 1 :
1463  case 2 :
1464 // case 5 :
1465  ped_stop(bad_ped) ;
1466  break ;
1467  }
1468 
1469 }
1470 
1471 // RDO-per-RDO
1472 void fcs_data_c::ped_start()
1473 {
1474  int r = rdo - 1 ;
1475  int s = sector -1 ;
1476 
1477  memset(ped[s][r].mean,0,sizeof(ped[s][r].mean)) ;
1478  memset(ped[s][r].rms,0,sizeof(ped[s][r].rms)) ;
1479  memset(ped[s][r].cou,0,sizeof(ped[s][r].cou)) ;
1480 
1481  memset(ped[s][r].bad_4,0,sizeof(ped[s][r].bad_4)) ;
1482 
1483  memset(ped[s][r].mean_8,0,sizeof(ped[s][r].mean_8)) ;
1484  memset(ped[s][r].rms_8,0,sizeof(ped[s][r].rms_8)) ;
1485  memset(ped[s][r].cou_8,0,sizeof(ped[s][r].cou_8)) ;
1486 
1487  memset(ped[s][r].tmp_val_8,0,sizeof(ped[s][r].tmp_val_8)) ;
1488  memset(ped[s][r].tmp_cou_8,0,sizeof(ped[s][r].tmp_cou_8)) ;
1489 
1490 }
1491 
1492 // RDO per RDO
1493 void fcs_data_c::ped_stop(int bad_ped)
1494 {
1495  char status[64] ;
1496 
1497  int s = sector - 1 ;
1498  int r = rdo - 1 ;
1499  u_int max_c = 0 ;
1500 
1501 
1502  if(sector==11 && run_type==1) return ;
1503 
1504 // if(rdo_map[s][r].det >= 3) { // trigger DEPs
1505 // LOG(WARN,"S%d:%d is a DEP/IO -- skipping ped_stop",sector,rdo) ;
1506 // return ;
1507 // }
1508 
1509 
1510  // check for bad pedestals... since we can have masked channels just find the max
1511  for(int c=0;c<32;c++) {
1512  if(ped[s][r].cou[c] > max_c) {
1513  max_c = ped[s][r].cou[c] ;
1514  }
1515  }
1516 
1517  if(max_c < 500) bad_ped |= 4 ;
1518 
1519  for(int c=0;c<32;c++) {
1520 
1521  if(ped[s][r].cou[c]) {
1522  ped[s][r].mean[c] /= ped[s][r].cou[c] ;
1523  ped[s][r].rms[c] /= ped[s][r].cou[c] ;
1524 
1525  ped[s][r].rms[c] -= ped[s][r].mean[c] * ped[s][r].mean[c] ;
1526 
1527  if(ped[s][r].rms[c] < 0.0) ped[s][r].rms[c] = 0.0 ;
1528 
1529  ped[s][r].rms[c] = sqrt(ped[s][r].rms[c]) ;
1530  }
1531  else {
1532  ped[s][r].mean[c] = -1.0 ;
1533  ped[s][r].rms[c] = 0.0 ;
1534 
1535  }
1536 
1537  if(ped[s][r].cou_8[c]) {
1538  ped[s][r].mean_8[c] /= ped[s][r].cou_8[c] ;
1539  ped[s][r].rms_8[c] /= ped[s][r].cou_8[c] ;
1540 
1541  ped[s][r].rms_8[c] -= ped[s][r].mean_8[c] * ped[s][r].mean_8[c] ;
1542 
1543  if(ped[s][r].rms_8[c] < 0.0) ped[s][r].rms_8[c] = 0.0 ;
1544 
1545  ped[s][r].rms_8[c] = sqrt(ped[s][r].rms_8[c]) ;
1546 
1547 
1548  }
1549  else {
1550  ped[s][r].mean_8[c] = -1.0 ;
1551  ped[s][r].rms_8[c] = 0.0 ;
1552  }
1553 
1554 
1555  }
1556 
1557  if(bad_ped) {
1558  strcpy(status," -- Bad: ") ;
1559  if(bad_ped & 1) strcat(status,"wrong_run_type,") ;
1560  if(bad_ped & 2) strcat(status,"beam_in_rhic,") ;
1561  if(bad_ped & 4) strcat(status,"not_enough_events") ;
1562 
1563  LOG(ERR,"S%d:%d pedestals %s",sector,rdo,status) ;
1564  }
1565  else {
1566  strcpy(status," -- Status OK") ;
1567  }
1568 
1569  //pedestal dump...
1570  FILE *pedf ;
1571 
1572  time_t now = time(0) ;
1573  struct tm *tm = localtime(&now) ;
1574 
1575  char fname[128] ;
1576 
1577  if(run_number) {
1578  sprintf(fname,"/RTScache/fcs_pedestals_s%02d_r%d_t%d_%08u_f%u.txt",sector,rdo,run_type,run_number,rhic_freq) ;
1579  }
1580  else {
1581  sprintf(fname,"/RTScache/fcs_pedestals_%d_%d_%d_%d_%d.txt",
1582  tm->tm_year+1900,
1583  tm->tm_mon+1,
1584  tm->tm_mday,
1585  tm->tm_hour,
1586  tm->tm_min) ;
1587  }
1588 
1589  pedf = fopen(fname,"w") ;
1590  if(pedf==0) {
1591  LOG(ERR,"Can't open %s [%s]",fname,strerror(errno)) ;
1592  return ;
1593  }
1594 
1595  int d = rdo_map[s][r].det ;
1596  int n = rdo_map[s][r].ns ;
1597  int p = rdo_map[s][r].dep ;
1598 
1599  fprintf(pedf,"# Sector %2d, RDO %d\n",sector,rdo) ;
1600  fprintf(pedf,"# Det %d, NS %d, DEP %d\n",d,n,p) ;
1601  fprintf(pedf,"# RUN %08u, type %d %s\n",run_number,run_type,status) ;
1602  fprintf(pedf,"# TIME %u\n",(unsigned int)now) ;
1603  char *ctm = ctime(&now) ;
1604  fprintf(pedf,"# DATE %s",ctm) ;
1605  fprintf(pedf,"# RHIC %u, FEE state %d\n",rhic_freq,fee_state) ;
1606 
1607  fprintf(pedf,"\n") ;
1608 
1609  int c_max ;
1610 
1611  if((s+1)==11) {
1612  if((r+1)==5) c_max = 4 ;
1613  else c_max = 37 ;
1614  }
1615  else c_max = 32 ;
1616 
1617  for(int c=0;c<c_max;c++) {
1618  int err = 0 ;
1619  double m = ped[s][r].mean[c] ;
1620  double rms = ped[s][r].rms[c] ;
1621 
1622  switch(run_type) {
1623  case 1 :
1624  if((m<3.0)||(m>200.0)||(rms<0.3)||(rms>2.2)) err = 1 ;
1625  break ;
1626  case 2 :
1627  if(ped[s][r].bad_4[c]) {
1628 // if((m != 2047.5)||(rms != 682.5)) {
1629  err = 1 ;
1630  }
1631  break ;
1632  }
1633 
1634  if(err) {
1635  const char *masked ;
1636 
1637  if(ped[s][r].i_gain[c]==0) masked = " -- MASKED" ;
1638  else masked = "" ;
1639 
1640  LOG(ERR,"S%02d:%d ch %02d: ped %.1f, rms %.1f: bad cou %u%s",sector,rdo,c,m,rms,ped[s][r].bad_4[c],masked) ;
1641  }
1642 
1643  //LOG(TERR,"PEDs: S%02d:%d: %d: %.1f [0x%03X] %.2f - %.1f %.1f [cou %d]",sector,rdo,c,
1644  // ped[s][r].mean[c],(int)ped[s][r].mean[c],
1645  // ped[s][r].rms[c],
1646  // ped[s][r].mean_8[c],ped[s][r].rms_8[c],ped[s][r].cou[c]) ;
1647 
1648  double rms8 = ped[s][r].rms_8[c] ;
1649 
1650  if(run_type==2) rms8 = ped[s][r].bad_4[c] ;
1651 
1652  fprintf(pedf,"%d %d %d %d %d %d %f %f %f %f\n",sector,rdo,d,n,p,c,
1653  ped[s][r].mean[c],ped[s][r].rms[c],
1654  ped[s][r].mean_8[c],rms8) ;
1655 
1656  }
1657 
1658  fclose(pedf) ;
1659 
1660 
1661  if(!bad_ped && run_type==1) {
1662 
1663  sprintf(fname,"/RTScache/fcs_pedestals_s%02d_r%d_f%u.txt",sector,rdo,rhic_freq) ;
1664 
1665  LOG(WARN,"also making pedestals formal to [%s]",fname) ;
1666 
1667  pedf = fopen(fname,"w") ;
1668  if(pedf==0) {
1669  LOG(ERR,"Can't open %s [%s]",fname,strerror(errno)) ;
1670  return ;
1671  }
1672 
1673 
1674  int d = rdo_map[s][r].det ;
1675  int n = rdo_map[s][r].ns ;
1676  int p = rdo_map[s][r].dep ;
1677 
1678  fprintf(pedf,"# Sector %2d, RDO %d\n",sector,rdo) ;
1679  fprintf(pedf,"# Det %d, NS %d, DEP %d\n",d,n,p) ;
1680  fprintf(pedf,"# RUN %08u, type %d %s\n",run_number,run_type,status) ;
1681  fprintf(pedf,"# TIME %u\n",(unsigned int)now) ;
1682  char *ctm = ctime(&now) ;
1683  fprintf(pedf,"# DATE %s",ctm) ;
1684  fprintf(pedf,"# RHIC %u, FEE state %d\n",rhic_freq,fee_state) ;
1685 
1686  fprintf(pedf,"\n") ;
1687 
1688  int c_max ;
1689 
1690  if((s+1)==11) {
1691  if((r+1)==5) c_max = 4 ;
1692  else c_max = 37 ;
1693  }
1694  else c_max = 32 ;
1695 
1696  for(int c=0;c<c_max;c++) {
1697  //double m = ped[s][r].mean[c] ;
1698  //double rms = ped[s][r].rms[c] ;
1699 
1700  double rms8 = ped[s][r].rms_8[c] ;
1701 
1702  if(run_type==2) rms8 = ped[s][r].bad_4[c] ;
1703 
1704  fprintf(pedf,"%d %d %d %d %d %d %f %f %f %f\n",sector,rdo,d,n,p,c,
1705  ped[s][r].mean[c],ped[s][r].rms[c],
1706  ped[s][r].mean_8[c],rms8) ;
1707 
1708  }
1709 
1710  fclose(pedf) ;
1711  }
1712  else {
1713  LOG(ERR,"S%d:%d: not caching pedestals 0x%X",sector,rdo,bad_ped) ;
1714  }
1715 
1716 }
1717 
1718 // load_map MUST be called before!
1719 int fcs_data_c::gain_from_cache(const char *fname)
1720 {
1721  int ret ;
1722  const char *file_name ;
1723  struct stat sstat ;
1724  int is_dir ;
1725 
1726  if(!rdo_map_loaded) {
1727  LOG(ERR,"You must load the rdo map before!") ;
1728  }
1729 
1730  // set defaults!
1731  for(int s=0;s<FCS_SECTOR_COU;s++) {
1732  for(int i=0;i<8;i++) {
1733  for(int c=0;c<32;c++) {
1734  ped[s][i].el_gain[c] = 1.0 ;
1735  ped[s][i].et_gain[c] = 1.0 ;
1736  }
1737  }
1738  }
1739 
1740  if(fname==0) {
1741  file_name = "/RTS/conf/fcs" ;
1742  }
1743  else {
1744  file_name = fname ;
1745  }
1746 
1747  ret = stat(file_name,&sstat) ;
1748  if(ret<0) {
1749  LOG(ERR,"gain_from_cache: %s: [%s]",file_name,strerror(errno)) ;
1750  return -1 ;
1751  }
1752 
1753  if(sstat.st_mode & S_IFDIR) {
1754  is_dir = 1 ;
1755  }
1756  else if(sstat.st_mode & S_IFREG) {
1757  is_dir = 0 ;
1758  }
1759  else {
1760  LOG(ERR,"gain_from_cache: %s: incorrect file type",file_name) ;
1761  return -1 ;
1762  }
1763 
1764  for(int det_ix=0;det_ix<3;det_ix++) { // ECAL, HCAL, FPRE
1765  for(int v=0;v<2;v++) { // 0=electronics, 1=et
1766  char ff[128] ;
1767 
1768  if(!is_dir) {
1769  strncpy(ff,file_name,sizeof(ff)-1) ;
1770  }
1771  else {
1772  const char *c_det, *c_typ ;
1773 
1774  switch(det_ix) {
1775  case 0 :
1776  c_det = "ecal" ;
1777  break ;
1778  case 1 :
1779  c_det = "hcal" ;
1780  break ;
1781  default :
1782  c_det = "fpre" ;
1783  break ;
1784  }
1785 
1786  if(v==0) c_typ = "electronics" ; // was "electronics"
1787  else c_typ = "et" ; // was "et"
1788 
1789  sprintf(ff,"%s/fcs_%s_%s_gains.txt",file_name,c_det,c_typ) ;
1790  }
1791 
1792  FILE *f = fopen(ff,"r") ;
1793  if(f==0) {
1794  LOG(ERR,"gain_from_cache: %s [%s] (perhaps not an error)",ff,strerror(errno)) ;
1795  if(!is_dir) goto read_done ;
1796  continue ;
1797  }
1798 
1799  LOG(INFO,"gain_from_cache: Opened gains[%s] %s",v==0?"electronics":"Et",ff) ;
1800 
1801 
1802  while(!feof(f)) {
1803  char buff[128] ;
1804 
1805  if(fgets(buff,sizeof(buff),f)==0) continue ;
1806 
1807  if(buff[0]=='#') continue ;
1808  if(buff[0]==0) continue ;
1809 
1810  int ch ;
1811  int det, ns, dep ;
1812  float gain ;
1813 
1814  int ret = sscanf(buff,"%d %d %d %d %f",&det,&ns,&dep,&ch,&gain) ;
1815 
1816  if(ret!=5) continue ;
1817 
1818  if(is_dir && (det_ix != det)) {
1819  LOG(WARN,"det expect %d, det in file %d",det_ix,det) ;
1820  continue ;
1821  }
1822 
1823 
1824 
1825  int s = det_map[det][ns][dep].sector - 1 ;
1826  int r = det_map[det][ns][dep].rdo - 1 ;
1827 
1828  if(s<0 || r<0) continue ; // bad map?
1829  if(ch < 0) continue ; // really bad!
1830 
1831  if(v==0) {
1832  ped[s][r].el_gain[ch] = gain ;
1833  }
1834  else {
1835  ped[s][r].et_gain[ch] = gain ;
1836  }
1837  }
1838 
1839  fclose(f) ;
1840  if(!is_dir) goto read_done ;
1841  }}
1842 
1843  read_done: ;
1844 
1845  for(int s=0;s<FCS_SECTOR_COU;s++) {
1846  for(int i=0;i<8;i++) {
1847  for(int c=0;c<32;c++) {
1848 
1849  double d = ped[s][i].el_gain[c] * ped[s][i].et_gain[c] ;
1850 
1851 
1852  // pre FY20:
1853  //ped[s][i].i_gain[c] = (u_int)(d*64.0+0.5) ;
1854  ped[s][i].i_gain[c] = (u_int)(d*256.0+0.5) ; // Akio changing to 4.8 fixed
1855 
1856  if(ped[s][i].i_gain[c]>4095) { // 12 bit max!
1857  LOG(NOTE,"S%d:%d: ch %d -- gain correction too big",s+1,i+1,c,ped[s][i].i_gain[c]) ;
1858  }
1859  else {
1860 
1861  }
1862  }
1863  }
1864  }
1865 
1866  return 0 ;
1867 
1868 }
1869 
1870 
1871 // static; expect to have it called for each and every file so
1872 // don't clear stuff etc.
1873 
1874 int fcs_data_c::ped_from_cache(const char *ff)
1875 {
1876  FILE *f = fopen(ff,"r") ;
1877  if(f==0) {
1878  LOG(ERR,"ped_from_cache: can't open %s [%s]",ff,strerror(errno)) ;
1879  return -1 ;
1880  }
1881 
1882  LOG(INFO,"ped_from_cache: opened %s",ff) ;
1883 
1884  while(!feof(f)) {
1885  char buff[256] ;
1886 
1887  if(fgets(buff,sizeof(buff),f)==0) continue ;
1888 
1889  if(buff[0]=='#') continue ;
1890  if(buff[0]==0) continue ;
1891 
1892  int c ;
1893  float p,r,pp,rr ;
1894  int ss,rrd,dd,nn,ppp ;
1895 
1896  int ret = sscanf(buff,"%d %d %d %d %d %d %f %f %f %f",&ss,&rrd,&dd,&nn,&ppp,&c,&p,&r,&pp,&rr) ;
1897 
1898  if(ret!=10) continue ;
1899 
1900 
1901  // single timebin: for ZS
1902  ped[ss-1][rrd-1].mean[c] = p ;
1903  ped[ss-1][rrd-1].rms[c] = r ;
1904  ped[ss-1][rrd-1].cou[c] = 0 ; // irrelevant when loading from file
1905 
1906  // 8xtimebin: for trigger
1907  ped[ss-1][rrd-1].mean_8[c] = pp ;
1908  ped[ss-1][rrd-1].rms_8[c] = rr ;
1909  ped[ss-1][rrd-1].cou_8[c] = 0 ; // irrelevant when loading from file
1910 
1911  u_short pppp = (u_short)(pp+0.5) ;
1912 
1913  //if(pppp) {
1914  // LOG(TERR,"S%d:%d: %d",ss,rrd,pppp) ;
1915  //}
1916 
1917  ped[ss-1][rrd-1].i_ped[c] = pppp ; // also for trigger
1918 
1919  }
1920 
1921  fclose(f) ;
1922 
1923  return 0 ;
1924 }
1925 
1926 
1927 int fcs_data_c::event_pre_fy19()
1928 {
1929  tb_cou = 0 ;
1930  ch = -1 ;
1931 
1932 // trigger_tick = -1 ;
1933 // first_rhic_strobe_tick = -1 ;
1934 
1935  LOG(TERR,"event() version 0x%08X",version) ;
1936  return 0 ;
1937 
1938  while(dta_p<dta_stop) {
1939 
1940 #if 0
1941  u_short h[3] ;
1942 
1943 
1944  for(int i=0;i<128;i++) printf("%d 0x%04X\n",i,dta_p[i]) ;
1945 
1946 
1947 
1948  h[0] = *dta_p++ ; // adc_single ID
1949 
1950  if(h[0]==0xFD07 || h[0]==0x5800) { //end of adc_single stream at 0x580000007
1951  break ;
1952  }
1953 
1954  if(version==0x28010518) dta_p++ ; // the ID is doubled always...
1955 
1956  h[1] = *dta_p++ ; // adc_single token
1957  h[2] = *dta_p++ ; // adc_single rhic
1958 
1959  ch = h[0] & 0xF ;
1960 #else
1961  //printf("+++ 0x%04X 0x%04X\n",dta_p[0],dta_p[1]) ;
1962  if((dta_p[0]==0xFD07) || (dta_p[0]==0x5800)) break ;
1963  if((dta_p[0]==0x0066) && (dta_p[1]==0x7788)) break ;
1964 
1965 
1966  ch = *dta_p & 0xF ;
1967  dta_p += 1 ;
1968 
1969  // and also skip the token for now
1970  dta_p += 2 ;
1971 #endif
1972  //LOG(TERR,"H 0x%X 0x%X 0x%X (ch %2d)",h[0],h[1],h[2],ch) ;
1973 
1974  while(dta_p<dta_stop) {
1975  u_short d = *dta_p++ ;
1976 
1977  //printf("... %d = 0x%04X [%u]\n",tb_cou,d,d) ;
1978 
1979  //LOG(TERR,".... %d = 0x%X",tb_cou,d) ;
1980 
1981  if(d==0xFFFF) { // last item of adc_single
1982  //LOG(TERR,"... tb_cou %d",tb_cou) ;
1983  break ;
1984  }
1985 
1986 #if 0
1987  if(d & 0x2000) {
1988  if(first_rhic_strobe_tick < 0) {
1989  first_rhic_strobe_tick = tb_cou ;
1990  //LOG(TERR,"... first rhic strobe at %d",tb_cou) ;
1991  }
1992  }
1993  if(d & 0x8000) {
1994  if(trigger_tick < 0) {
1995  trigger_tick = tb_cou ;
1996  //LOG(TERR,"... trigger tick at %d",tb_cou) ;
1997  }
1998  }
1999 #endif
2000 
2001 // accum(ch,tb_cou,d&0xFFF) ;
2002  if(accum_pre_fy19(ch,tb_cou,d)<0) {
2003  LOG(ERR,"Event too big, ch %d, tb %d",ch,tb_cou) ;
2004  return 0 ;
2005  }
2006  tb_cou++ ;
2007  }
2008 
2009  //LOG(TERR,"0x%08X 0x%08X 0x%08X",dta_p[0],dta_p[1],dta_p[2]) ;
2010 
2011  //LOG(TERR,"Ch %d, %d ADCs",ch,tb_cou) ;
2012  return 1 ;
2013  }
2014 
2015 // u_int rhic_end = (dta_p[1]<<16)|dta_p[2] ;
2016 // LOG(TERR,"RHIC ticks %u",rhic_end-rhic_start) ;
2017 
2018  //LOG(TERR,"0x%08X 0x%08X 0x%08X: 0x%08X",dta_p[0],dta_p[1],dta_p[2],rhic_end) ;
2019 
2020  return 0 ;
2021 }
2022 
2023 int fcs_data_c::load_readout_map(const char *fname)
2024 {
2025  char buff[256] ;
2026  const char *fn ;
2027 
2028  if(rdo_map_loaded==0) {
2029  LOG(ERR,"rdo_map not loaded!") ;
2030  return -1 ;
2031  }
2032 
2033  for(u_int dd=0;dd<4;dd++) {
2034 
2035 
2036  switch(dd) {
2037  case 0 :
2038  fn = "/RTS/conf/fcs/fcs_ecal_readout_map.csv" ;
2039  break ;
2040  case 1 :
2041  fn = "/RTS/conf/fcs/fcs_hcal_readout_map.csv" ;
2042  break ;
2043  case 2 :
2044  fn = "/RTS/conf/fcs/fcs_fpre_readout_map.csv" ;
2045  break ;
2046  case 3 :
2047  fn = "/RTS/conf/fcs/fcs_main_readout_map.csv" ;
2048  break ;
2049  }
2050 
2051 
2052 
2053 
2054  FILE *f = fopen(fn,"r") ;
2055 
2056  if(f) LOG(INFO,"load_readout_map: opened %s",fn) ;
2057  else {
2058  LOG(ERR,"load_readout_map: %s [%s]",fn,strerror(errno)) ;
2059  return -1 ;
2060  }
2061 
2062  while(!feof(f)) {
2063  u_int adet, id ;
2064  u_int row, col ;
2065  u_int det, ns, dep, ch ;
2066  u_int crt, slt ;
2067 
2068  if(fgets(buff,sizeof(buff),f)==0) continue ;
2069 
2070  if(buff[0]=='#') continue ;
2071  if(buff[0]=='\n') continue ;
2072  if(buff[0]==0) continue ;
2073 
2074  int ret = sscanf(buff,"%d %d %d %d %d %d %d %d %d %d",
2075  &adet,&id,&row,&col,
2076  &det,&ns,&crt,&slt,&dep,&ch) ;
2077 
2078  if(ret!=10) continue ;
2079 
2080 
2081  if(det != dd) {
2082  LOG(ERR,"expect det %d, not %d",dd,det) ;
2083  continue ;
2084  }
2085 
2086  if(ns>=2) {
2087  LOG(ERR,"bad ns %d",ns) ;
2088  continue ;
2089  }
2090 
2091  if(dep>=24) {
2092  LOG(ERR,"bad dep %d",dep) ;
2093  continue ;
2094  }
2095 
2096  if(ch>=32) {
2097  LOG(ERR,"bad ch %d",ch) ;
2098  continue ;
2099  }
2100 
2101  int sec = det_map[det][ns][dep].sector ;
2102  int rdo = det_map[det][ns][dep].rdo ;
2103 
2104  rdo_map[sec-1][rdo-1].ch[ch].id = id ;
2105  rdo_map[sec-1][rdo-1].ch[ch].row = row ;
2106  rdo_map[sec-1][rdo-1].ch[ch].col = col ;
2107  rdo_map[sec-1][rdo-1].crt = crt ;
2108  rdo_map[sec-1][rdo-1].slt = slt ;
2109  }
2110 
2111  fclose(f) ;
2112 
2113  }
2114 
2115  return 0 ;
2116 }
2117 
2118 
2119 int fcs_data_c::load_sc_map(const char *fname)
2120 {
2121  char buff[256] ;
2122  const char *fn ;
2123 
2124  if(rdo_map_loaded==0) {
2125  LOG(ERR,"rdo_map not loaded!") ;
2126  return -1 ;
2127  }
2128 
2129  for(int s=0;s<10;s++) {
2130  for(int r=0;r<8;r++) {
2131  for(int c=0;c<32;c++) {
2132  rdo_map[s][r].ch[c].sc_sipm = 0xFF ;
2133  }}}
2134 
2135  for(u_int dd=0;dd<3;dd++) {
2136 
2137 
2138  switch(dd) {
2139  case 0 :
2140  fn = "/RTS/conf/fcs/fcs_ecal_sc_map.csv" ;
2141  break ;
2142  case 1 :
2143  fn = "/RTS/conf/fcs/fcs_hcal_sc_map.csv" ;
2144  break ;
2145  case 2 :
2146  fn = "/RTS/conf/fcs/fcs_pres_sc_map.csv" ;
2147  break ;
2148  case 3 :
2149  fn = "/RTS/conf/fcs/fcs_main_sc_map.csv" ;
2150  break ;
2151  }
2152 
2153 #if 0
2154  if(dd==2) { // SPECIAL HACKS FOR EPD Splitter!
2155  LOG(INFO,"load_sc_map: constructing FPRE map") ;
2156 
2157  for(int s=0;s<10;s++) {
2158  for(int r=0;r<8;r++) {
2159  if(rdo_map[s][r].det != 2) continue ; // skip non preshower
2160 
2161  int dep = rdo_map[s][r].dep ;
2162 
2163  for(int c=0;c<32;c++) {
2164  rdo_map[s][r].ch[c].sc_sipm = 0 ; // make them ALL active
2165  rdo_map[s][r].ch[c].sc_dep = dep ;
2166  rdo_map[s][r].ch[c].sc_add = 0 ;
2167  rdo_map[s][r].ch[c].sc_bra = 0 ;
2168  }
2169 
2170  int ns = rdo_map[s][r].ns ;
2171 
2172 
2173  // and now kill some of them according to Akio's Aug-2021 recipe
2174 
2175  if(ns==0) { // North
2176  rdo_map[s][r].ch[16].sc_sipm= 0xFF ;
2177  }
2178  else {
2179  rdo_map[s][r].ch[0].sc_sipm = 0xFF ;
2180  }
2181 
2182  if(dep==0) {
2183  for(int c=0;c<16;c++) {
2184  rdo_map[s][r].ch[c].sc_sipm = 0xFF ;
2185  }
2186  }
2187  else if(dep==5) {
2188  for(int c=16;c<32;c++) {
2189  rdo_map[s][r].ch[c].sc_sipm = 0xFF ;
2190  }
2191 
2192  }
2193 
2194  }}
2195 
2196  return 0 ;
2197  }
2198 
2199 #endif
2200 
2201  FILE *f = fopen(fn,"r") ;
2202 
2203  if(f) LOG(INFO,"load_sc_map: opened %s",fn) ;
2204  else {
2205  LOG(ERR,"load_sc_map: %s [%s]",fn,strerror(errno)) ;
2206  return -1 ;
2207  }
2208 
2209  while(!feof(f)) {
2210  u_int adet, id ;
2211  u_int row, col ;
2212  u_int det, ns, dep ; //NOTE: this is the DEP where the FEE is connected!
2213  u_int bra, add, sipm ;
2214 
2215 
2216  if(fgets(buff,sizeof(buff),f)==0) continue ;
2217 
2218  if(buff[0]=='#') continue ;
2219  if(buff[0]=='\n') continue ;
2220  if(buff[0]==0) continue ;
2221 
2222  int ret = sscanf(buff,"%d %d %d %d %d %d %d %d %d %d",
2223  &adet,&id,&row,&col,
2224  &det,&ns,&dep,&bra,&add,&sipm) ;
2225 
2226  if(ret!=10) continue ;
2227 
2228 
2229  if(det != dd) {
2230  LOG(ERR,"expect det %d, not %d",dd,det) ;
2231  continue ;
2232  }
2233 
2234  if(ns>=2) {
2235  LOG(ERR,"bad ns %d",ns) ;
2236  continue ;
2237  }
2238 
2239  if(dep>=24) {
2240  LOG(ERR,"bad dep %d",dep) ;
2241  continue ;
2242  }
2243 
2244  if(bra>=2) {
2245  LOG(ERR,"bad bra %d",bra) ;
2246  continue ;
2247  }
2248 
2249  int found_it = 0 ;
2250 
2251  for(int s=0;s<10;s++) {
2252  for(int r=0;r<8;r++) {
2253  if(rdo_map[s][r].det != dd) continue ;
2254  if(rdo_map[s][r].ns != ns) continue ;
2255 
2256  for(int c=0;c<32;c++) {
2257  if(rdo_map[s][r].ch[c].id != id) continue ;
2258 
2259  rdo_map[s][r].ch[c].sc_dep = dep ;
2260  rdo_map[s][r].ch[c].sc_bra = bra ;
2261  rdo_map[s][r].ch[c].sc_add = add ;
2262 
2263 
2264  // FPRE is special: Akio marked unused channels with non-0
2265  if(dd==2) {
2266  //if(sipm!=0) {
2267  if(sipm>=2) { // new for FY23 EPD use
2268  //LOG(TERR,"%d %d %d = %d",s,r,c,sipm) ;
2269  sipm = 0xFF ;
2270  }
2271  }
2272 
2273  rdo_map[s][r].ch[c].sc_sipm = sipm ;
2274 
2275  found_it = 1 ;
2276  goto done ;
2277  }
2278  }}
2279 
2280  done: ;
2281 
2282  if(!found_it) {
2283  LOG(ERR,"DET %d: can't find id %d",dd,id) ;
2284  }
2285  }
2286 
2287  fclose(f) ;
2288 
2289  }
2290 
2291  return 0 ;
2292 }
2293 
2294 int fcs_data_c::load_rdo_map(const char *fname)
2295 {
2296 // if(id != 0) return 0 ;
2297 
2298 
2299 
2300  rdo_map_loaded = 0 ;
2301  memset(rdo_map,0,sizeof(rdo_map)) ;
2302  memset(det_map,0,sizeof(det_map)) ;
2303 
2304 
2305  // set up defaults so that non-existing entries in
2306  // the map file map to non-existing nodes
2307  for(int s=0;s<12;s++) {
2308  for(int r=0;r<8;r++) {
2309  rdo_map[s][r].det = 3 ; //pseudo-main
2310  rdo_map[s][r].ns = 0 ; //pseudo-side
2311  rdo_map[s][r].dep = 10 ; // dummy!!!
2312  }}
2313 
2314  // physical crate map: done by hand
2315  for(int r=0;r<8;r++) {
2316  // Crate 0
2317 
2318  rdo_map[0][r].crate = 0 ;
2319  rdo_map[0][r].slot = r ;
2320 
2321  rdo_map[1][r].crate = 0 ;
2322  rdo_map[1][r].slot = r+8 ;
2323 
2324  if(r < 4) {
2325  rdo_map[2][r].crate = 0 ;
2326  rdo_map[2][r].slot = r+16 ;
2327  }
2328  else {
2329  rdo_map[2][r].crate = 1 ;
2330  rdo_map[2][r].slot = r+16-4 ;
2331  }
2332 
2333 
2334  // Crate 1
2335  rdo_map[3][r].crate = 1 ;
2336  rdo_map[3][r].slot = r ;
2337 
2338  rdo_map[4][r].crate = 1 ;
2339  rdo_map[4][r].slot = r+8 ;
2340 
2341 
2342  // crate 2 aka Main
2343 #if 0
2344 
2345  if(r < 3) {
2346  rdo_map[10][r].crate = 2 ;
2347  rdo_map[10][r].slot = r ;
2348  }
2349 #else
2350  // moved fibers from 1,2,3 to 5,6,7
2351 
2352  if(r>=4 && r<=7) {
2353  rdo_map[10][r].crate = 2 ;
2354  rdo_map[10][r].slot = r - 4 ;
2355  }
2356 #endif
2357  rdo_map[5][r].crate = 4 ;
2358  rdo_map[5][r].slot = r ;
2359 
2360  rdo_map[6][r].crate = 4 ;
2361  rdo_map[6][r].slot = r+8 ;
2362 
2363  if(r < 4) {
2364  rdo_map[7][r].crate = 4 ;
2365  rdo_map[7][r].slot = r+16 ;
2366  }
2367  else {
2368  rdo_map[7][r].crate = 3 ;
2369  rdo_map[7][r].slot = r+16-4 ;
2370  }
2371 
2372 
2373  // Crate 3
2374  rdo_map[8][r].crate = 3 ;
2375  rdo_map[8][r].slot = r ;
2376 
2377  rdo_map[9][r].crate = 3 ;
2378  rdo_map[9][r].slot = r+8 ;
2379 
2380 
2381  }
2382 
2383  //special cases and remaps
2384  rdo_map[5-1][2-1] = rdo_map[7-1][8-1] ; // moved 7-8 to 5-2
2385  rdo_map[10-1][2-1] = rdo_map[10-1][8-1] ; // moved 10-8 to 10-2
2386 
2387 
2388  if(fname==0) {
2389  fname = "/RTS/conf/fcs/fcs_daq_map.txt" ;
2390  }
2391 
2392  FILE *f = fopen(fname,"r") ;
2393  if(f == 0) {
2394  LOG(ERR,"Can't open map file %s [%s]",fname,strerror(errno)) ;
2395  return -1 ;
2396  }
2397 
2398  LOG(INFO,"load_rdo_map: opened %s",fname) ;
2399 
2400 
2401  while(!feof(f)) {
2402  char buff[128] ;
2403 
2404  int s,r,d,n,b ;
2405  unsigned long long mask ;
2406 
2407  buff[0] =0 ;
2408 
2409  if(fgets(buff,sizeof(buff),f)==0) continue ;
2410 
2411  if(buff[0]=='#') continue ;
2412  if(buff[0]=='\n') continue ;
2413  if(buff[0]==0) continue ;
2414 
2415  int ret = sscanf(buff,"%d %d %d %d %d 0x%llX",&s,&r,&d,&n,&b,&mask) ;
2416 
2417  if(ret != 6) continue ;
2418 
2419 // if(sector != s) continue ;
2420 
2421  r-- ;
2422  s-- ;
2423 
2424 
2425  if((s<0) || (r<0)) {
2426 
2427  LOG(ERR,"Mapping S%d:%d --> %d,%d,%d, mask 0x%llX",s+1,r+1,d,n,b,mask) ;
2428  continue ;
2429  }
2430 
2431  // forward and reverse
2432  rdo_map[s][r].det = d ;
2433  rdo_map[s][r].ns = n ;
2434  rdo_map[s][r].dep = b ;
2435  rdo_map[s][r].ch_mask = mask ;
2436 
2437  det_map[d][n][b].sector = s+1 ;
2438  det_map[d][n][b].rdo = r+1 ;
2439  }
2440 
2441  rdo_map_loaded = 1 ;
2442 
2443  fclose(f) ;
2444 
2445  return 0 ;
2446 }
2447 
2448 u_short fcs_data_c::set_rdo(int rdo1)
2449 {
2450  rdo = rdo1 ;
2451 
2452  return set_board_id() ;
2453 } ;
2454 
2455 
2456 u_short fcs_data_c::set_board_id()
2457 {
2458  int sec = sector - 1 ;
2459  int r = rdo - 1 ;
2460 
2461 
2462  if((sec<0)||(r<0)) {
2463  LOG(ERR,"bad %d %d",sec,r) ;
2464  }
2465 
2466  int det = rdo_map[sec][r].det ;
2467  int ns = rdo_map[sec][r].ns ;
2468  int dep = rdo_map[sec][r].dep ;
2469 
2470 
2471  board_id = (sec<<11)|(r<<8)|(det<<6)|(ns<<5)|dep ;
2472 
2473 // LOG(TERR,"set_board_id: %d %d --> %d %d %d --> 0x%X",sector,rdo,det,ns,dep,board_id) ;
2474 
2475  return board_id ;
2476 }
2477 
2478 int fcs_data_c::load_bad_ch(const char *fname, int sector)
2479 {
2480  memset(fcs_bad_ch,0,sizeof(fcs_bad_ch)) ;
2481  memset(fcs_bad_ch_all,0,sizeof(fcs_bad_ch_all)) ;
2482 
2483  if(fname==0) {
2484  fname = "/RTS/conf/fcs/bad_channels.txt" ;
2485  }
2486 
2487  FILE *f = fopen(fname,"r") ;
2488  if(f==0) {
2489  LOG(ERR,"fcs_load_bad_ch: %s [%s]",fname,strerror(errno)) ;
2490  return -1 ;
2491  }
2492 
2493  LOG(INFO,"fcs_load_bad_ch: %s",fname) ;
2494 
2495  while(!feof(f)) {
2496  char buff[1024] ;
2497 
2498 // LOG(ERR,"asd") ;
2499 
2500  if(fgets(buff,sizeof(buff),f)==0) continue ;
2501 
2502 // LOG(ERR,"--- %s",buff) ;
2503 
2504  if(buff[0]=='#') continue ;
2505  if(buff[0]=='\n') continue ;
2506 
2507  int s,r,det,ns,dep,ch,flag ;
2508  float ped, rms ;
2509 
2510  int ret = sscanf(buff,"%d %d %d %d %d %d %f %f 0x%X",&s,&r,&det,&ns,&dep,&ch,&ped,&rms,&flag) ;
2511 
2512 // LOG(WARN,"ret [%s]",buff) ;
2513 
2514  if(ret != 9) continue ;
2515 
2516  if(sector==0) LOG(WARN,"Bad ch: S%02d:%d:%02d",s,r,ch) ;
2517 
2518  if((r<1)||(r>8)) continue ;
2519  if((ch<0)||(ch>33)) continue ;
2520  if((s<1)||(s>10)) continue ;
2521 
2522  fcs_bad_ch_all[s-1][r-1][ch] = 1 ;
2523 
2524  if(s != sector) continue ;
2525 
2526  LOG(WARN,"Bad ch: S%02d:%d:%02d",s,r,ch) ;
2527 
2528  fcs_bad_ch[r-1][ch] = 1 ;
2529  }
2530 
2531  fclose(f) ;
2532 
2533  return 0 ;
2534 
2535 }