StRoot  1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
fgtPed.cxx
1 #include <stdio.h>
2 #include <sys/types.h>
3 #include <math.h>
4 #include <stdlib.h>
5 #include <string.h>
6 #include <errno.h>
7 #include <time.h>
8 #include <unistd.h>
9 
10 #include <rtsLog.h>
11 #include <daqModes.h>
12 #include <rtsSystems.h>
13 
14 #include <DAQ_READER/daq_dta.h>
15 
16 #include "fgtPed.h"
17 
18 
19 
20 fgtPed::fgtPed(int rts)
21 {
22  valid = 0 ;
23  rb_mask = 0 ;
24 
25  memset(fgt_stat,0,sizeof(fgt_stat)) ;
26 
27 
28  k_seq = 0 ;
29  n_sigma = 0.0 ;
30 
31  rts_id = rts ;
32 
33  tb_cou_xpect = -1 ;
34  tb_cou_ped = -1 ;
35 
36  memset(ch_status,0,sizeof(ch_status)) ;
37 
38 
39  switch(rts_id) {
40  case IST_ID :
41  case FST_ID :
42  for(int r=0;r<6;r++) {
43  for(int ar=0;ar<6;ar++) {
44  for(int ap=0;ap<24;ap++) {
45  for(int c=0;c<128;c++) {
46  ch_status[r][ar][ap][c] = FGT_CH_STAT_SHOULD ;
47  }}}
48  fgt_rdr[r] = new daq_fgt(0) ;
49  }
50  rb_mask = 0x3F ;
51 
52 
53  break ;
54  case GMT_ID :
55  for(int ar=0;ar<2;ar++) {
56  u_int ap_mask = 0x00F00F ;
57  for(int ap=0;ap<24;ap++) {
58  if(ap_mask & (1<<ap)) ;
59  else continue ;
60 
61  for(int c=0;c<128;c++) {
62  ch_status[0][ar][ap][c] = FGT_CH_STAT_SHOULD ;
63  }
64  }
65  }
66  fgt_rdr[0] = new daq_fgt(0) ;
67 
68  rb_mask = 1 ;
69  break ;
70  case FGT_ID :
71  for(int r=0;r<2;r++) {
72  for(int ar=0;ar<6;ar++) {
73 
74  u_int ap_mask = 0x3FF3FF ;
75  for(int ap=0;ap<24;ap++) {
76  if(ap_mask & (1<ap)) ;
77  else continue ;
78 
79  for(int c=0;c<128;c++) {
80  ch_status[r][ar][ap][c] = FGT_CH_STAT_SHOULD ;
81  }
82  }}
83  fgt_rdr[r] = new daq_fgt(0) ;
84  }
85  rb_mask = 0x3 ;
86  break ;
87 
88  }
89 
90 
91  return ;
92 }
93 
94 
95 
96 #if 0
97 static int fgt_bad_heuristics(int rts_id, double ped, double rms)
98 {
99  switch(rts_id) {
100  case IST_ID :
101  case FST_ID :
102  if((rms < 5.0)||(rms>50.0)||(ped>2000.0)||(ped<5.0)) return -1 ;
103  break ;
104  default :
105  if((rms<=0.0) || (ped<0.0)) return -1 ;
106  break ;
107  }
108 
109  return 0 ; // take it!
110 }
111 #endif
112 
113 int fgtPed::run_stop()
114 {
115  for(int r=0;r<FGT_RDO_COU;r++) {
116  if(rb_mask & (1<<r)) ;
117  else continue ;
118 
119  int evts = fgt_stat[r].evts ;
120 
121  if(fgt_stat[r].err) {
122  LOG(ERR,"RDO %d: %d errors in %d events",r+1,fgt_stat[r].err,evts) ;
123  }
124 
125  for(int arm=0;arm<FGT_ARM_COU;arm++) {
126  if(fgt_stat[r].arm_mask & (1<<arm)) ;
127  else continue ;
128 
129  for(int apv=0;apv<FGT_APV_COU;apv++) {
130  int errs = fgt_stat[r].err_apv[arm][apv] ;
131  int cou = fgt_stat[r].cou_apv[arm][apv] ;
132 
133  if(errs || (cou && (cou!=evts))) {
134  LOG(ERR,"RDO %d: ARM %d, APV %2d: %d errors, in %d/%d events",
135  r+1,arm,apv,errs,cou,evts) ;
136  }
137  }
138  }
139  }
140 
141  return 0 ;
142 }
143 
144 
145 void fgtPed::init(int active_rbs)
146 {
147  memset(fgt_stat,0,sizeof(fgt_stat)) ;
148 
149  rb_mask = active_rbs ;
150 
151 }
152 
153 
154 int fgtPed::do_zs(char *src, int in_bytes, char *dst, int rdo1)
155 {
156  int ks = k_seq ;
157  int dumped_cou = 0 ;
158  int all_cou = 0 ;
159 
160  short *d16 = (short *) dst ;
161  u_int *d32 = (u_int *)dst ;
162 
163  fgt_stat[rdo1-1].evts++ ;
164 
165  daq_dta *dd = fgt_rdr[rdo1-1]->handle_adc(0, rdo1, src) ;
166 
167 
168  // create meta
169  apv_meta_zs_t meta_zs ;
170  apv_meta_t *meta = (apv_meta_t *) dd->meta ;
171 
172  memset(&meta_zs,0,sizeof(meta_zs)) ;
173 
174  int t_xpect = tb_cou_ped ;
175 
176  int max_tb = -1 ;
177 
178  total_charge = 0 ;
179 
180  for(int arm=0;arm<FGT_ARM_COU;arm++) {
181  for(int apv=0;apv<FGT_APV_COU;apv++) {
182 #if 0
183  printf("ARC %d, ARM %d, APV %d: %d %d %d %d\n",rdo1,arm,apv,
184  meta->arc[rdo1].arm[arm].apv[apv].present,
185  meta->arc[rdo1].arm[arm].apv[apv].ntim,
186  meta->arc[rdo1].arm[arm].apv[apv].error,
187  meta->arc[rdo1].arm[arm].error) ;
188 #endif
189  if(meta->arc[rdo1].arm[arm].apv[apv].present) {
190  int err = 0 ;
191 
192  meta_zs.status[arm][apv] |= 1 ;
193 
194  int t_cou = meta->arc[rdo1].arm[arm].apv[apv].ntim ;
195 
196  if(t_cou != t_xpect) {
197  if(fgt_stat[rdo1-1].err < 12) {
198  LOG(WARN,"wrong tb_cou %d(expect %d): ARC %d, ARM %d, APV %d",t_cou,t_xpect,rdo1,arm,apv) ;
199  }
200  fgt_stat[rdo1-1].err++ ;
201  err |= 2 ;
202  }
203 
204  if(t_cou > max_tb) max_tb = t_cou ;
205 
206 
207  if(err) {
208  meta_zs.status[arm][apv] |= err ;
209  }
210  }
211 
212  if(meta->arc[rdo1].arm[arm].apv[apv].error || meta->arc[rdo1].arm[arm].error) {
213  meta_zs.status[arm][apv] |= 4 ; // error ;
214  }
215 
216  if(meta_zs.status[arm][apv] & 1) {
217  fgt_stat[rdo1-1].cou_apv[arm][apv]++ ;
218  }
219 
220  if(meta_zs.status[arm][apv] & 0xFE) {
221  fgt_stat[rdo1-1].err_apv[arm][apv]++ ;
222  }
223 
224  switch(meta_zs.status[arm][apv]) {
225  case 0 : // not present
226  case 1 : // present
227  case 3 : // present but wrong tb
228  break ;
229  default :
230  if(fgt_stat[rdo1-1].err < 100) {
231  LOG(ERR,"ARC %d, ARM %d, APV %d: meta_zs 0x%X",rdo1,arm,apv,meta_zs.status[arm][apv]) ;
232  }
233  fgt_stat[rdo1-1].err++ ;
234  break ;
235  }
236 
237  }}
238 
239  // cut data!
240  if(max_tb > tb_cou_ped) max_tb = tb_cou_ped ; // FORCED!
241 
242  meta_zs.tb_cou = max_tb ;
243 
244  // roundoff to a 16 bit word...
245  int meta_bytes = sizeof(meta_zs) ;
246  while(meta_bytes % 2) meta_bytes++ ;
247 
248  *d32++ = 0xFEEDBEEF ; // signature
249 
250  int do_ped_sub = 0 ; // non ped-sub
251  switch(rts_id) {
252  default :
253  case FGT_ID :
254  *d32++ = META_ZS_VERSION ; // version
255  break ;
256  case IST_ID :
257  case FST_ID :
258  do_ped_sub = 1 ;
259  *d32++ = META_PED_ZS_VERSION ; // zs _AND_ ped subtracted
260  break ;
261  case GMT_ID :
262  do_ped_sub = 1 ; // subtract peds
263  *d32++ = META_PED_ZS_VERSION ; // zs _AND_ ped subtracted
264  break ;
265  }
266 
267  u_int *dta_bytes = d32++ ; // reserve space
268  *d32++ = meta_bytes ;
269 
270  memcpy(d32,&meta_zs,meta_bytes) ;
271  d16 = (short *)d32 + meta_bytes/2 ;
272 
273  while(dd && dd->iterate()) {
274  int arc, arm, apv ;
275 
276  arc = dd->rdo ;
277  arm = dd->sec ;
278  apv = dd->pad ;
279 
280 // printf("**** ARC %d, ARM %d, APV %d: entries %d\n",
281 // arc,arm,apv,dd->ncontent) ;
282 
283  fgt_adc_t *f = (fgt_adc_t *) dd->Void ;
284 
285  struct peds_t *p_thr = &(peds[arc-1]) ;
286 
287  int i_save = -1 ;
288  int cou = 0 ;
289  int dump = 0 ;
290  int thr = 0 ;
291  int ch = -1 ;
292  int cou_tb = 0 ;
293 
294  *d16++ = 0xAB00 | arc ;
295  *d16++ = (arm << 8) | apv ;
296 
297 
298  for(u_int i=0;i<dd->ncontent;i++) {
299  int tb = f[i].tb ;
300  int adc = f[i].adc ;
301 
302  // if the timebin of the data is larger than the timebin of
303  // the available pedestals/thresholds -- silently drop!!!
304 
305  if(tb >= max_tb) continue ;
306 
307  if(tb==0) {
308  if(dump) {
309 // printf("*** dump ARC %d, ARM %d, APV %d, CH %d in %d tb\n",arc,arm,apv,ch,cou_tb) ;
310 
311  *d16++ = (cou_tb << 8) | ch ;
312  dumped_cou++ ;
313 
314  for(int i=0;i<cou_tb;i++) {
315 
316  if(do_ped_sub) {
317  short adc = (short) ((float)f[i_save+i].adc - p_thr->ped[arm][apv][ch][i] + 0.5); // had bug, was "+ 0.2"!
318  *d16++ = adc ;
319 
320  if(adc > 0) total_charge++ ;
321 
322  }
323  else {
324  *d16++ = f[i_save+i].adc ;
325  }
326 
327 
328 
329  }
330  }
331 
332  ch = f[i].ch ;
333 
334  i_save = i ;
335  cou = 0 ;
336  dump = 0 ;
337  thr = p_thr->thr[arm][apv][ch] ;
338  cou_tb = 0 ;
339 
340 
341  all_cou++ ;
342 
343  }
344 
345 
346  if(adc > thr) {
347  cou++ ;
348  if(cou >= ks) {
349  dump = 1 ;
350  }
351  }
352  else cou = 0 ;
353 
354  cou_tb++ ;
355 
356 // printf(" %4d: CH %3d, TB %d == %d, thr %d\n",
357 // i,f[i].ch,f[i].tb, f[i].adc,thr) ;
358 
359  }
360 
361  // last guy
362  if(dump) {
363 // printf("*** LAST dump ARC %d, ARM %d, APV %d, CH %d in %d tb\n",arc,arm,apv,ch,cou_tb) ;
364 
365  *d16++ = (cou_tb <<8) | ch ;
366  dumped_cou++ ;
367 
368  for(int i=0;i<cou_tb;i++) {
369 
370 
371  if(do_ped_sub) {
372  short adc = (short) ((float)f[i_save+i].adc - p_thr->ped[arm][apv][ch][i] + 0.5); // had bug, was "+ 0.2"!
373  *d16++ = adc ;
374  }
375  else {
376  *d16++ = f[i_save+i].adc ;
377  }
378 
379  }
380  }
381 
382  }
383 
384  *d16++ = dumped_cou ;
385 
386 
387  int out_bytes = (char *)d16 - (char *)dst ;
388 
389  *dta_bytes = out_bytes ;
390 
391  // make sure we are on a 32bit boundary!
392  while(out_bytes % 4) {
393  *d16++ = 0xBABA ;
394  out_bytes += 2 ;
395  }
396 
397  //LOG(TERR,"ARC %d: dumped %d/%d, %d bytes",rdo1,dumped_cou,all_cou,out_bytes) ;
398 
399  return out_bytes ;
400 }
401 
402 
403 /*
404  Called per event, per RDO. evbbuff is the raw RDO contribuition.
405  rdo counts from 1.
406 */
407 void fgtPed::accum(char *evbuff, int bytes, int rdo1)
408 {
409 
410  int rdo = rdo1 - 1 ; // since rdo1 is from 1
411 
412 
413 
414  fgt_stat[rdo].evts++ ;
415 
416  // skip first few events!
417 // if(fgt_stat[rdo].evts <= 3) {
418 // return ;
419 // }
420 
421  if(fgt_stat[rdo].evts > 0xFF00) return ; // don't allow more than 16bits worth...
422 
423  struct peds_t *p = peds + rdo ;
424 
425  daq_dta *dd = 0 ;
426  dd = fgt_rdr[rdo1-1]->handle_adc(0,rdo1, evbuff) ;
427 
428 
429  int t_xpect = tb_cou_xpect ;
430 
431  char need[FGT_ARM_COU][FGT_APV_COU] ;
432  memset(need,0,sizeof(need)) ;
433 
434  if(dd && dd->meta) {
435  apv_meta_t *meta = (apv_meta_t *)dd->meta ;
436 
437  for(int arm=0;arm<FGT_ARM_COU;arm++) {
438  for(int apv=0;apv<FGT_APV_COU;apv++) {
439  if(meta->arc[rdo1].arm[arm].apv[apv].present == 0) continue ;
440 
441 
442  if(meta->arc[rdo1].arm[arm].apv[apv].ntim != t_xpect) {
443  if(fgt_stat[rdo1-1].err < 10) {
444  LOG(WARN,"evt %d: RDO %d, ARM %d, APV %d: ntim %d, expect %d??",fgt_stat[rdo].evts,rdo1,arm,apv,meta->arc[rdo1].arm[arm].apv[apv].ntim,t_xpect) ;
445  }
446  fgt_stat[rdo1-1].err++ ;
447  }
448 
449  need[arm][apv] |= 1 ;
450 
451  if(meta->arc[rdo1].arm[arm].apv[apv].apv_id != apv) {
452  LOG(ERR,"RDO %d, ARM %d, APV %d: %d",rdo1,arm,apv,meta->arc[rdo1].arm[arm].apv[apv].apv_id) ;
453  need[arm][apv] |= 2 ; // error
454  }
455 
456 
457  }
458  }
459  }
460 
461  while(dd && dd->iterate()) {
462  if(dd->rdo != rdo1) continue ;
463 
464  int arm = dd->sec ;
465  int apv = dd->pad ;
466 
467  fgt_adc_t *f = (fgt_adc_t *) dd->Void ;
468 
469  need[arm][apv] |= 4 ;
470 
471  for(u_int i=0;i<dd->ncontent;i++) {
472  int adc ;
473  int ch ;
474  int tb ;
475 
476  ch = f[i].ch ;
477  adc = f[i].adc ;
478  tb = f[i].tb ;
479 
480  p->ped[arm][apv][ch][tb] += (float) adc ;
481  p->rms[arm][apv][ch][tb] += (float) (adc * adc) ;
482  if(tb==0) p->cou[arm][apv][ch]++ ;
483  }
484  }
485 
486 
487  // the following is just an error dump...
488  for(int arm=0;arm<FGT_ARM_COU;arm++) {
489  for(int apv=0;apv<FGT_APV_COU;apv++) {
490  if(need[arm][apv] == 0) continue ;
491 
492  switch(need[arm][apv]) {
493  case 1 : // missing in data; will capture the error later
494  case 5 : // all OK
495  break ;
496  default :
497  LOG(ERR,"ARC %d, ARM %d, APV %d: need is 0x%X",rdo1,arm,apv,need[arm][apv]) ;
498  }
499 
500  }
501  }
502 
503 
504  return ;
505 
506 }
507 
508 
509 
510 double fgtPed::do_thresh(double ns, int k, int do_log)
511 {
512  // suspect
513  // tb_cou set in from_cache
514 
515 
516 
517  n_sigma = ns ;
518  k_seq = k ;
519 
520 
521  LOG(INFO,"do_thresh: n-sigma %f, k-seq %d",n_sigma, k_seq) ;
522 
523 
524  for(int r=0;r<FGT_RDO_COU;r++) {
525  struct peds_t *p = peds + r ;
526 
527  for(int arm=0;arm<FGT_ARM_COU;arm++) {
528  for(int apv=0;apv<FGT_APV_COU;apv++) {
529  for(int c=0;c<FGT_CH_COU;c++) {
530 
531  if(ch_status[r][arm][apv][c] & FGT_CH_STAT_SHOULD) ;
532  else continue ;
533 
534 
535  double ped = 0.0 ;
536  double rms = 0.0 ;
537  int cou = 0 ;
538 
539  for(int t=0;t<tb_cou_ped;t++) {
540  double pp = p->ped[arm][apv][c][t] ;
541  double rm = p->rms[arm][apv][c][t] ;
542 
543  if(rm < 0.0) continue ; // should be here but not found in data, damn...
544 
545  ped += pp ;
546  rms += rm ;
547  cou++ ;
548  }
549 
550  if(cou == 0) { // channel should have been present but it wasn't in the pedestal file...
551  p->thr[arm][apv][c] = 0xFFFD ;
552  continue ;
553  }
554 
555  ped /= cou ;
556  rms /= cou ;
557 
558  p->thr[arm][apv][c] = (u_short) (ped + rms * n_sigma + 0.5) ;
559 
560  }
561  }
562  }
563  }
564 
565  // kill bad
566  int b_all_all = 0 ;
567  int b_bad_all = 0 ;
568 
569  for(int r=0;r<FGT_RDO_COU;r++) {
570  struct peds_t *p = peds + r ;
571 
572  int b_ped_0 = 0 ;
573  int b_bad = 0 ;
574  int b_masked = 0 ;
575  int b_misconfigured = 0 ;
576  int b_all = 0 ;
577  int b_unknown = 0 ;
578 
579  for(int arm=0;arm<FGT_ARM_COU;arm++) {
580  for(int apv=0;apv<FGT_APV_COU;apv++) {
581  for(int c=0;c<FGT_CH_COU;c++) {
582  if(ch_status[r][arm][apv][c] & FGT_CH_STAT_SHOULD) ;
583  else {
584  p->thr[arm][apv][c] = 0xFFFE ; // not physically present...
585  continue ;
586  }
587 
588  b_all++ ;
589 
590  // kill any channel marked odd!
591  if(ch_status[r][arm][apv][c] & 0xFE) {
592  p->thr[arm][apv][c] = 0xFFFF ;
593  b_bad_all++ ;
594  }
595  else if(p->thr[arm][apv][c] >= 0xFFFD) {
596  //LOG(WARN,"Killed but not marked: %d %d %d %d",r,arm,apv,c) ;
597  b_unknown++ ;
598  b_bad_all++ ;
599  }
600 
601  if(ch_status[r][arm][apv][c] & FGT_CH_STAT_NO_CONFIG) {
602  b_masked++ ;
603  }
604  if(ch_status[r][arm][apv][c] & FGT_CH_STAT_NO_RESPONSE) {
605  b_misconfigured++ ;
606  }
607  if(ch_status[r][arm][apv][c] & FGT_CH_STAT_BAD) {
608  b_bad++ ;
609  }
610  if(ch_status[r][arm][apv][c] & FGT_CH_STAT_PED_UNKNOWN) {
611  b_ped_0++ ;
612  }
613 
614 
615 
616  }}}
617 
618  b_all_all += b_all ;
619 
620  LOG(WARN,"ARC %d: masked %d, misconfigd %d, bad %d, bad ped %d, unknown %d of %d all",
621  r+1,b_masked,b_misconfigured,b_bad,b_ped_0,b_unknown,b_all) ;
622 
623  }
624 
625  double perc = (double)b_bad_all/(double)b_all_all ;
626  perc *= 100.0 ;
627 
628  return perc ;
629 
630 }
631 
632 void fgtPed::calc()
633 {
634 
635  const int MIN_EVENTS = 1000 ;
636 
637 
638  LOG(NOTE,"Calculating pedestals") ;
639 
640  tb_cou_ped = -1 ;
641 
642  int bad = 0 ;
643 
644 
645 
646  for(int r=0;r<FGT_RDO_COU;r++) {
647  if(rb_mask & (1<<r)) ;
648  else continue ;
649 
650 
651 
652  struct peds_t *ped = peds + r ;
653 
654  for(int arm=0;arm<FGT_ARM_COU;arm++) {
655  for(int apv=0;apv<FGT_APV_COU;apv++) {
656  for(int ch=0;ch<FGT_CH_COU;ch++) {
657 
658  int cou = ped->cou[arm][apv][ch] ;
659 
660  for(int t=0;t<tb_cou_xpect;t++) {
661 
662  if(cou == 0) { // never seen in the data!
663  ped->ped[arm][apv][ch][t] = 0 ;
664  ped->rms[arm][apv][ch][t] = -1.0 ;
665  }
666  else {
667  double pp, rr ;
668 
669 
670  pp = ped->ped[arm][apv][ch][t] / (double) cou ;
671  rr = ped->rms[arm][apv][ch][t] / (double) cou ;
672 
673  // due to roundoff I can have super small negative numbers
674  if(rr < (pp*pp)) rr = 0.0 ;
675  else rr = sqrt(rr - pp*pp) ;
676 
677  ped->ped[arm][apv][ch][t] = pp ;
678  ped->rms[arm][apv][ch][t] = rr ;
679 
680  if(t > tb_cou_ped) tb_cou_ped = t ;
681 
682 // LOG(TERR,"RDO %d, ARM %d, APV %d, CH %d, TB %d: %f +- %f, cou %d",
683 // r,arm,apv,ch,t,pp,rr,ped->cou[arm][apv][ch][t]) ;
684  }
685  }
686  }
687 
688  }
689  }
690  }
691 
692  tb_cou_ped++ ; // need to increment...
693 
694 
695  int not_enough = 0 ;
696  for(int r=0;r<FGT_RDO_COU;r++) {
697  if(rb_mask & (1<<r)) ;
698  else continue ;
699 
700  if(fgt_stat[r].evts < MIN_EVENTS) {
701  not_enough = 1 ;
702  }
703  }
704 
705 
706 
707  LOG(TERR,"Pedestals calculated. tb_count %d, RDO counts: %u",tb_cou_ped,fgt_stat[0].evts) ;
708  valid = 1 ; // assume all OK...
709 
710  if(not_enough) valid = 0 ;
711 
712 
713  if(!valid) {
714  LOG(ERR,"FGT pedestals not good: APVs bad %d, events %d",bad,fgt_stat[0].evts) ;
715  }
716 
717  return ;
718 }
719 
720 
721 int fgtPed::to_evb(char *buff)
722 {
723  int r, arm, apv, c, t ;
724  u_short *dta = (u_short *) buff ;
725 
726 
727  if(!valid) {
728  // log error but continue...
729  LOG(ERR,"ped::to_evb peds are bad: valid %d",valid) ;
730  }
731 
732  LOG(NOTE,"Preparing pedestals for later EVB...") ;
733 
734  *dta++ = 0xBEEF ; // signature
735  *dta++ = 0x0001 ; // version
736  *dta++ = FGT_ARM_COU ; // ARM
737  *dta++ = FGT_APV_COU ;
738  *dta++ = FGT_CH_COU ; // channel count
739  *dta++ = tb_cou_ped ; // timebin count
740 
741 
742  for(r=0;r<FGT_RDO_COU;r++) {
743  if(rb_mask && (1<<r)) ;
744  else continue ;
745 
746  struct peds_t *ped = peds + r ;
747 
748  *dta++ = r+1 ; // ARC, from 1
749  u_short *apv_cou = dta++ ;
750  *apv_cou = 0 ;
751 
752  // need to dump the apv_meta_zs_t bank!!!
753 
754  for(arm=0;arm<FGT_ARM_COU;arm++) {
755  for(apv=0;apv<FGT_APV_COU;apv++) {
756 
757 
758 
759  *dta++ = arm ;
760  *dta++ = apv ;
761  (*apv_cou)++ ;
762 
763  for(c=0;c<FGT_CH_COU;c++) {
764  for(t=0;t<tb_cou_ped;t++) {
765 
766  u_short pp ;
767 
768  pp = (u_short)(ped->ped[arm][apv][c][t]*16.0 + 0.5) ;
769  *dta++ = pp;
770 
771  pp = (u_short)(ped->rms[arm][apv][c][t]*16.0 + 0.5) ;
772 
773  *dta++ = pp ;
774  }
775  }
776  }
777  }
778 
779  }
780 
781  LOG(TERR,"Pedestals prepared for later EVB, %d bytes",(char *)dta-buff) ;
782 
783  return ((char *)dta-buff) ;
784 }
785 
786 void fgtPed::clear()
787 {
788  memset(peds,0,sizeof(peds)) ;
789 }
790 
791 void fgtPed::clear_from_cache()
792 {
793  for(int r=0;r<FGT_RDO_COU;r++) {
794  struct peds_t *p = peds_from_cache + r ;
795 
796  for(int arm=0;arm<FGT_ARM_COU;arm++) {
797  for(int apv=0;apv<FGT_APV_COU;apv++) {
798  for(int c=0;c<FGT_CH_COU;c++) {
799  for(int t=0;t<FGT_TB_COU;t++) {
800  p->ped[arm][apv][c][t] = 0.0 ;
801  p->rms[arm][apv][c][t] = -2.0 ;
802  }
803  p->cou[arm][apv][c] = 0 ;
804  p->thr[arm][apv][c] = 0xFFFF ;
805  }
806  }
807  }
808  }
809 
810 
811 }
812 
813 int fgtPed::from_cache(char *fname)
814 {
815  FILE *f ;
816  const char *fn ;
817 
818 
819  tb_cou_ped = - 1;
820 
821  clear() ;
822  clear_from_cache() ;
823 
824 
825  // trivial load from disk...
826  if(fname) {
827  fn = fname ;
828  f = fopen(fname,"r") ;
829  }
830  else {
831  fn = "/RTScache/pedestals.txt" ;
832  f = fopen(fn,"r") ;
833  }
834 
835  if(f==0) {
836  LOG(U_TONKO,"ped::from_cache can't open input file \"%s\" [%s]",fn,strerror(errno)) ;
837  return -1 ;
838  }
839 
840 
841  LOG(NOTE,"Loading pedestals from cache \"%s\"...",fn) ;
842 
843 
844 
845  while(!feof(f)) {
846  int r, arm, apv, ch, tb ;
847  float pp, rr ;
848  char buff[256] ;
849 
850  if(fgets(buff,sizeof(buff),f) == 0) continue ;
851 
852  switch(buff[0]) {
853  case '#' :
854  case '!' :
855  case '*' :
856  case '/' :
857  case '.' :
858  continue ;
859  }
860 
861 
862  int ret = sscanf(buff,"%d %d %d %d %d %f %f",&r,&arm,&apv,&ch,&tb,&pp,&rr) ;
863  if(ret != 7) continue ;
864 
865 
866  struct peds_t *ped = peds + (r-1) ;
867 
868  ped->ped[arm][apv][ch][tb] = pp ;
869  ped->rms[arm][apv][ch][tb] = rr ;
870 
871  struct peds_t *ped_fc = peds_from_cache + (r-1) ;
872 
873  ped_fc->ped[arm][apv][ch][tb] = pp ;
874  ped_fc->rms[arm][apv][ch][tb] = rr ;
875 
876  if(tb > tb_cou_ped) {
877  tb_cou_ped = tb ;
878  }
879 
880 
881  if(tb==0) {
882  if(pp<=0.0 || rr<=0.0) {
883  ch_status[r-1][arm][apv][ch] |= FGT_CH_STAT_PED_UNKNOWN ;
884  }
885  }
886  }
887 
888  fclose(f) ;
889 
890  tb_cou_ped++ ; // to get to the ntimbins
891 
892  if(tb_cou_ped != tb_cou_xpect) {
893  LOG(ERR,"Pedestals loaded from cache \"%s\" but have %d timebins != expect %d!",fn,
894  tb_cou_ped,tb_cou_xpect) ;
895  }
896  else {
897  LOG(INFO,"Pedestals loaded from cache \"%s\", %d timebins OK",fn,tb_cou_ped) ;
898  }
899 
900  valid = 1 ;
901 
902  return valid ;
903 }
904 
905 int fgtPed::to_cache(char *fname, u_int run, int dont_cache)
906 {
907  FILE *f ;
908  char f_fname[128] ;
909  int do_ln = 1 ;
910 
911  if(!valid) {
912  LOG(ERR,"ped::to_cache peds are bad: valid %d -- caching anyway...",valid) ;
913  do_ln = 0 ;
914  //LOG(CAUTION,"Pedestals are not valid -- not caching!") ;
915  }
916 
917  if(fname) {
918  strcpy(f_fname,fname) ;
919  do_ln = 0 ;
920  }
921  else {
922  sprintf(f_fname,"/RTScache/%s_pedestals_%08u.txt",rts2name(rts_id),run) ;
923  }
924 
925 
926  f = fopen(f_fname,"w") ;
927  if(f==0) {
928  LOG(ERR,"ped::to_cache can't open output file \"%s\" [%s]",f_fname,strerror(errno)) ;
929  return -1 ;
930  }
931 
932 
933  if(tb_cou_ped != tb_cou_xpect) {
934  LOG(CAUTION,"Writing pedestals to cache \"%s\" [valid %d] but data has %d timebins != expect %d!",f_fname,valid,
935  tb_cou_ped,tb_cou_xpect) ;
936  }
937  else {
938  LOG(TERR,"Writing pedestals to cache \"%s\" [valid %d], ntimebins %d",f_fname,valid,tb_cou_ped) ;
939  }
940 
941  time_t tim = time(0) ;
942  fprintf(f,"# Detector %s\n",rts2name(rts_id)) ;
943  fprintf(f,"# Run %08u\n",run) ;
944  fprintf(f,"# Date %s",ctime(&tim)) ;
945  fprintf(f,"# Timebins %d\n",tb_cou_ped) ;
946  fprintf(f,"\n") ;
947 
948  for(int r=0;r<FGT_RDO_COU;r++) {
949  if(rb_mask & (1<<r)) ;
950  else continue ;
951 
952 
953  struct peds_t *ped = peds + r ;
954 
955  for(int arm=0;arm<FGT_ARM_COU;arm++) {
956  for(int apv=0;apv<FGT_APV_COU;apv++) {
957 
958 
959  for(int c=0;c<FGT_CH_COU;c++) {
960 
961  // dump only the ones which need to exist!
962  if(ch_status[r][arm][apv][c] & FGT_CH_STAT_SHOULD) ;
963  else continue ;
964 
965  for(int t=0;t<tb_cou_ped;t++) {
966 
967  fprintf(f,"%d %d %2d %3d %2d %7.3f %.3f\n",r+1,arm,apv,c,t,
968  ped->ped[arm][apv][c][t],
969  ped->rms[arm][apv][c][t]) ;
970  }
971  }
972  }
973  }
974  }
975 
976  fclose(f) ;
977 
978 
979  if(dont_cache) {
980  LOG(CAUTION,"Pedestals NOT cached for run %08u: bad run conditions 0x%X!",run,dont_cache) ;
981  return 0 ;
982  }
983 
984 
985  f = fopen("/RTScache/pedestals.txt","w") ;
986  if(f==0) {
987  LOG(ERR,"ped::to_cache can't open output file \"%s\" [%s]","/RTScache/pedestals.txt",strerror(errno)) ;
988  return -1 ;
989  }
990 
991  fprintf(f,"# Detector %s\n",rts2name(rts_id)) ;
992  fprintf(f,"# Run %08u\n",run) ;
993  fprintf(f,"# Date %s",ctime(&tim)) ;
994  fprintf(f,"# Timebins %d\n",tb_cou_ped) ;
995  fprintf(f,"\n") ;
996 
997  int all_cou = 0 ;
998  int non_cached_cou = 0 ;
999 
1000  for(int r=0;r<FGT_RDO_COU;r++) {
1001  if(rb_mask & (1<<r)) ;
1002  else continue ;
1003 
1004 
1005  struct peds_t *ped = peds + r ;
1006 
1007  for(int arm=0;arm<FGT_ARM_COU;arm++) {
1008  for(int apv=0;apv<FGT_APV_COU;apv++) {
1009 
1010 
1011  for(int c=0;c<FGT_CH_COU;c++) {
1012 
1013  // dump only the ones which need to exist!
1014  if(ch_status[r][arm][apv][c] & FGT_CH_STAT_SHOULD) ;
1015  else continue ;
1016 
1017  struct peds_t *use_ped ;
1018 
1019  all_cou++ ;
1020  // use just he lower bits of status!!!
1021  if((ch_status[r][arm][apv][c] & 0x0E) || (ped->cou[arm][apv][c]==0)) {
1022  //use_ped = peds_from_cache ; Major bug before Aug 2014!!! All peds_from_cache were taken from RDO1
1023  //FIXED in Aug 2014:
1024  use_ped = peds_from_cache + r ;
1025  non_cached_cou++ ;
1026  }
1027  else {
1028  use_ped = ped ;
1029  }
1030 
1031  for(int t=0;t<tb_cou_ped;t++) {
1032 
1033  fprintf(f,"%d %d %2d %3d %2d %7.3f %.3f\n",r+1,arm,apv,c,t,
1034  use_ped->ped[arm][apv][c][t],
1035  use_ped->rms[arm][apv][c][t]) ;
1036  }
1037  }
1038  }
1039  }
1040  }
1041 
1042  fclose(f) ;
1043 
1044  {
1045  char cmd[128] ;
1046 
1047  sprintf(cmd,"/bin/cp /RTScache/pedestals.txt /RTScache/%s_pedestals_%08u_loaded.txt",rts2name(rts_id),run) ;
1048  system(cmd) ;
1049  }
1050 
1051 
1052 
1053 // if(do_ln) {
1054 // char cmd[128] ;
1055 // sprintf(cmd,"/bin/ln -f -s %s_pedestals_%08u.txt /RTScache/pedestals.txt",rts2name(rts_id),run) ;
1056 // system(cmd) ;
1057 // }
1058 
1059  double perc = 100.0 * (double)non_cached_cou / (double)all_cou ;
1060  if(perc > 10.0) {
1061  LOG(U_TONKO,"Pedestals cached for run %08u: skipped %d/%d (%d%%) channels.",run,non_cached_cou,all_cou,(int)perc) ;
1062  }
1063  else {
1064  LOG(TERR,"Pedestals cached for run %08u: skipped %d/%d channels.",run,non_cached_cou,all_cou) ;
1065  }
1066 
1067  return 1 ;
1068 }
1069 
1070 
1071 
1072 int fgtPed::bad_from_cache(char *fname)
1073 {
1074  FILE *f ;
1075  const char *fn ;
1076 
1077  int b_cou = 0 ;
1078 
1079 
1080  // trivial load from disk...
1081  if(fname) {
1082  fn = fname ;
1083  f = fopen(fname,"r") ;
1084  }
1085  else {
1086  switch(rts_id) {
1087  case GMT_ID :
1088  fn = "/RTS/conf/gmt/gmt_bad_channels.txt" ;
1089  break ;
1090  case IST_ID :
1091  fn = "/RTS/conf/ist/ist_bad_channels.txt" ;
1092  break ;
1093  case FST_ID :
1094  fn = "/RTS/conf/fst/fst_bad_channels.txt" ;
1095  break ;
1096  case FGT_ID :
1097  default:
1098  fn = "/RTS/conf/fgt/fgt_bad_channels.txt" ;
1099  break ;
1100  }
1101 
1102  f = fopen(fn,"r") ;
1103  }
1104 
1105  if(f==0) {
1106  LOG(ERR,"ped::bad_from_cache can't open input file \"%s\" [%s]",fn,strerror(errno)) ;
1107  return -1 ;
1108  }
1109 
1110 
1111  LOG(NOTE,"Loading bad from cache \"%s\"...",fn) ;
1112 
1113 
1114 
1115  while(!feof(f)) {
1116  int r, arm, apv, ch ;
1117  char buff[256] ;
1118 
1119  if(fgets(buff,sizeof(buff),f) == 0) continue ;
1120 
1121  switch(buff[0]) {
1122  case '#' :
1123  case '!' :
1124  case '*' :
1125  case '/' :
1126  case '.' :
1127  continue ;
1128  }
1129 
1130 
1131  int ret = sscanf(buff,"%d %d %d %d",&r,&arm,&apv,&ch) ;
1132  if(ret != 4) continue ;
1133  //check for negative 0!
1134 
1135  char ca[4][16] ;
1136  char n[4] ;
1137  memset(n,0,sizeof(n)) ;
1138  sscanf(buff,"%s %s %s %s",ca[0],ca[1],ca[2],ca[3]) ;
1139  for(int i=0;i<4;i++) {
1140  int dummy ;
1141  if(sscanf(ca[i],"%d",&dummy)!=1) continue ;
1142  if(dummy==0) {
1143  if(index(ca[i],'-')) n[i] = '-' ;
1144  else n[i] = '+' ;
1145  }
1146  else {
1147  if(dummy<0) n[i] = '-' ;
1148  else n[i] = '+' ;
1149  }
1150  }
1151 
1152  if(r<0) r *= -1 ;
1153  if(arm < 0) arm *= -1 ;
1154  if(apv < 0) apv *= -1 ;
1155  if(ch < 0) ch *= -1 ;
1156 
1157 
1158 
1159  if(n[1]=='-') { //nix ARM
1160  for(int a=0;a<FGT_APV_COU;a++) {
1161  for(int c=0;c<FGT_CH_COU;c++) {
1162  ch_status[r-1][arm][a][c] |= FGT_CH_STAT_BAD ;
1163  }
1164  }
1165  }
1166  else if(n[2]=='-') { //nix APV
1167  for(int c=0;c<FGT_CH_COU;c++) {
1168  ch_status[r-1][arm][apv][c] |= FGT_CH_STAT_BAD ;
1169  }
1170  }
1171  else {
1172  ch_status[r-1][arm][apv][ch] |= FGT_CH_STAT_BAD ;
1173  }
1174 
1175 
1176  }
1177 
1178  fclose(f) ;
1179 
1180  for(int r=0;r<FGT_RDO_COU;r++) {
1181  for(int m=0;m<FGT_ARM_COU;m++) {
1182  for(int a=0;a<FGT_APV_COU;a++) {
1183  for(int c=0;c<FGT_CH_COU;c++) {
1184  if(ch_status[r][m][a][c] & FGT_CH_STAT_BAD) b_cou++ ;
1185  }
1186  }
1187  }
1188  }
1189 
1190  LOG(INFO,"Loaded %d bad channels from \"%s\"",b_cou,fn) ;
1191 
1192  return b_cou ;
1193 }