StRoot  1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
bsmdPed.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 
13 #include "bsmdPed.h"
14 
15 
16 bsmdPed::bsmdPed()
17 {
18  valid = 0 ;
19  rb_mask = 0x3F ; // assume all..
20 
21  memset(evts,0,sizeof(evts)) ;
22  memset(valid_evts,0,sizeof(valid_evts)) ;
23 
24  sizeof_ped = sizeof(struct peds) * 6 ; // for 6 RDOs
25 
26  ped_store = 0 ; // unassigned!
27 
28  sector = -1 ; // uniti...
29 
30 
31  return ;
32 }
33 
34 
35 bsmdPed::~bsmdPed()
36 {
37  if(ped_store) free(ped_store) ;
38 
39  return ;
40 }
41 
42 
43 void bsmdPed::init(int active_rbs)
44 {
45  valid = 0 ;
46 
47  memset(evts,0,sizeof(evts)) ;
48  memset(valid_evts,0,sizeof(valid_evts)) ;
49 
50  rb_mask = active_rbs ;
51 
52  if(ped_store == 0) {
53  ped_store = (struct peds *) malloc(sizeof_ped) ;
54  }
55 
56  memset(ped_store,0,sizeof_ped) ;
57 
58  LOG(TERR,"Pedestals zapped: sector %2d, rb_mask 0x%02X.", sector, rb_mask) ;
59 }
60 
61 
62 int bsmdPed::do_zs(char *src, int in_bytes, char *dst, int rdo1, u_int *adc_sum)
63 {
64  u_short *d_out = (u_short *) dst ;
65  int fiber ;
66  u_short cap ;
67  u_short *d ;
68  u_int *d32 = (u_int *) src ;
69  double sum_adc = 0.0 ; // for phase scanning
70 
71  LOG(NOTE,"BSMD ZS: rdo %d: in bytes %d",rdo1,in_bytes) ;
72 
73  d = (u_short *)(src + 10*4) ; // data start at 10th word
74 
75  cap = (u_short) (d32[8] & 0x7F) ; // cap is now 16 bits!
76 
77  fiber = (sector-1)*2 + (rdo1 - 1) ;
78 
79  *d_out++ = 0x0002 ; // version 2!
80  u_short *count = d_out++ ; // save counter spot
81  *d_out++ = d32[8] & 0xFFFF ; // save 16 bits of the cap!
82  *d_out++ = fiber ;
83 
84  u_short *tmp = d_out ;
85 
86  double *ped = (ped_store + rdo1 - 1)->ped[cap] ;
87  u_short *thr = (ped_store + rdo1 - 1)->thr[cap] ;
88 
89  for(int ii=0;ii<4800;ii++) {
90  u_short dta = *d ;
91  if(dta > *thr) {
92 
93  sum_adc += (double)dta - (*ped) ;
94 
95  *d_out++ = ii ;
96  *d_out++ = dta - (int)(*ped + 0.5) ;
97  }
98  d++ ;
99  thr++ ;
100  ped++ ;
101  }
102  *count = (d_out - tmp)/2 ;
103 
104  int out_bytes = (char *)d_out - dst ;
105 
106  if(out_bytes > in_bytes) {
107  valid_evts[rdo1-1]++ ; // not really!
108  LOG(NOTE,"BSMD ZS: rdo %d: in bytes %d, out bytes %d",rdo1,in_bytes,out_bytes) ;
109  }
110  else {
111  LOG(NOTE,"BSMD ZS: rdo %d: in bytes %d, out bytes %d",rdo1,in_bytes,out_bytes) ;
112  }
113 
114  evts[rdo1-1]++ ;
115 
116  if(adc_sum) {
117  *adc_sum = (u_int) (sum_adc + 0.5) ;
118  }
119 
120  return out_bytes ;
121 }
122 
123 
124 /*
125  Called per event, per RDO. evbbuff is the raw RDO contribuition.
126  rdo counts from 1.
127 */
128 void bsmdPed::accum(char *evbuff, int bytes, int rdo1)
129 {
130  int cap ;
131  u_short *d_in ;
132  u_int *d32 ;
133  int rdo = rdo1 - 1 ; // since rdo1 is from 1
134 
135  d_in = (u_short *) evbuff ;
136  d32 = (u_int *) evbuff ;
137 
138  // this is where the cap should be...
139  cap = d32[8] & 0x7F ; // mask off, in case of problems...
140 
141 
142  evts[rdo]++ ;
143 
144 
145  // skip first few events!
146  if(evts[rdo] <= 3) {
147  LOG(NOTE,"RDO %d: skipping event %d < 3",rdo,evts[rdo]) ;
148  return ;
149  }
150 
151 
152 
153  valid_evts[rdo]++ ;
154 
155  LOG(NOTE,"RDO %d: event %d",rdo,evts[rdo]) ;
156 
157  struct peds *p = ped_store + rdo ;
158 
159  if(p->cou[cap] > 0xFFF0) return ;
160  p->cou[cap]++ ;
161 
162  // move to start of data
163  d_in = (u_short *)(evbuff + 10*4) ; // start at the 10th
164 
165  for(int j=0;j<4800;j++) {
166 
167  int adc = d_in[j] ; // hack!
168 
169  p->ped[cap][j] += (double) adc ;
170  p->rms[cap][j] += (double) (adc*adc) ;
171 
172  }
173 
174 
175 
176  return ;
177 
178 }
179 
180 void bsmdPed::do_thresh(double thr_sm, double thr_pre)
181 {
182  double n_sigma ;
183 
184  if(!ped_store || !valid) {
185  LOG(ERR,"bsmd:do_thresh invalid") ;
186  return ;
187  }
188 
189 
190  for(int r=0;r<6;r++) {
191  if((sector==2) && (r>2)) n_sigma = thr_pre ; // preshower...
192  else n_sigma = thr_sm ;
193 
194  struct peds *p = ped_store + r ;
195  for(int c=0;c<128;c++) {
196  for(int t=0;t<4800;t++) {
197  p->thr[c][t] = (u_short) (p->ped[c][t] + p->rms[c][t] * n_sigma + 0.5) ;
198  }
199  }
200  }
201 
202  return ;
203 
204 }
205 
206 void bsmdPed::calc()
207 {
208  int r, cap, ch ;
209  int bad ;
210  const u_int MIN_EVENTS = 20 ;
211 
212 
213  LOG(NOTE,"Calculating pedestals for sector %2d",sector) ;
214 
215 
216  for(r=0;r<6;r++) {
217  if(rb_mask & (1<<r)) ;
218  else continue ;
219 
220  struct peds *ped = ped_store + r ;
221 
222  for(cap=0;cap<128;cap++) {
223  for(ch=0;ch<4800;ch++) {
224 
225  if(ped->cou[cap] == 0) {
226  ped->ped[cap][ch] = 0xFFFF ;
227  ped->rms[cap][ch] = 9.999 ;
228  }
229  else {
230  double pp, rr ;
231 
232  pp = ped->ped[cap][ch] / (double) ped->cou[cap] ;
233  rr = ped->rms[cap][ch] / (double) ped->cou[cap] ;
234 
235  // due to roundoff I can have super small negative numbers
236  if(rr < (pp*pp)) rr = 0.0 ;
237  else rr = sqrt(rr - pp*pp) ;
238 
239  ped->ped[cap][ch] = pp ;
240  ped->rms[cap][ch] = rr ;
241  }
242  }
243  }
244  }
245 
246 
247  bad = 0 ;
248  int real_bad = 0 ;
249 
250  for(r=0;r<6;r++) {
251  if(rb_mask & (1<<r)) ;
252  else continue ;
253 
254  struct peds *ped = ped_store + r ;
255 
256  for(cap=0;cap<128;cap++) {
257  if(ped->cou[cap] < MIN_EVENTS) {
258  bad++ ;
259 
260  if(bad<50) {
261  LOG(WARN,"RDO %d: cap %3d: only %d events!",r+1,cap,ped->cou[cap]) ;
262  }
263  else if(bad==50) {
264  LOG(WARN,"Stopping detailed bad cap logging...") ;
265  }
266 
267  if(ped->cou[cap] == 0) real_bad++ ;
268  }
269 
270  }
271  }
272 
273  LOG(TERR,"Pedestals calculated. RDO counts: %u %u %u %u %u %u",valid_evts[0],valid_evts[1],valid_evts[2],valid_evts[3],valid_evts[4],valid_evts[5]) ;
274 
275  valid = ! bad ; // if there's any problem I invalidate validity!
276 
277  if(valid) {
278  //LOG(TERR,"Pedestals calculated. RDO counts: %u %u %u %u %u %u",valid_evts[0],valid_evts[1],valid_evts[2],valid_evts[3],valid_evts[4],valid_evts[5]) ;
279  }
280  else {
281  LOG(ERR,"BSMD pedestals not good (%d caps not good, %d missing)",bad,real_bad) ;
282  if(!real_bad) {
283  LOG(WARN,"But since no real bad I will allow it!") ;
284  valid = 1 ;
285  }
286  }
287 
288  return ;
289 }
290 
291 
292 int bsmdPed::to_evb(char *buff)
293 {
294  int r, p, t ;
295  int fiber ;
296 
297  u_short *dta = (u_short *) buff ;
298 
299 
300 
301  if(!valid) {
302  // log error but continue...
303  LOG(WARN,"ped::to_evb peds are bad: valid %d",valid) ;
304  }
305 
306  LOG(NOTE,"Preparing pedestals for later EVB...") ;
307 
308  for(r=0;r<6;r++) {
309  struct peds *ped = ped_store + r ;
310 
311  fiber = (sector-1)*6 + r ; // fiber counts from 0
312 
313  *dta++ = 0x0002 ; // version
314  *dta++ = 4800 ; // count per cap
315  *dta++ = 128 ; // caps
316  *dta++ = fiber ; // fiber... // match current sector+rdo to old fiber [0..11]
317 
318  for(p=0;p<128;p++) {
319  for(t=0;t<4800;t++) {
320 
321  u_int rr, pp ;
322 
323  rr = (u_int)(ped->rms[p][t] * 8.0 + 0.5) ;
324  if(rr > 0x3F) rr = 0x3F ; // maximum I can have!
325 
326 
327  pp = (u_int)(ped->ped[p][t] + 0.5) ;
328  if(pp > 0x3FF) pp = 0x3FF ; // maximum I can have!
329 
330  *dta++ = (rr<<10)|pp ;
331 
332  }
333 
334  }
335 
336  }
337 
338  LOG(TERR,"Pedestals prepared for later EVB, sector %2d: %d bytes",sector,(char *)dta-buff) ;
339  return ((char *)dta-buff) ;
340 }
341 
342 int bsmdPed::from_cache(const char *fname)
343 {
344  FILE *f ;
345  const char *fn ;
346 
347  init(0x3F) ; // to clear ped storage for all 6 RDOs
348 
349  // trivial load from disk...
350  if(fname) {
351  fn = fname ;
352  f = fopen(fname,"r") ;
353  }
354  else {
355  fn = "/RTScache/pedestals.txt" ;
356  f = fopen(fn,"r") ;
357  }
358 
359  if(f==0) {
360  LOG(ERR,"ped::from_cache can't open input file \"%s\" [%s]",fn,strerror(errno)) ;
361  return -1 ;
362  }
363 
364 
365  LOG(NOTE,"Loading pedestals from cache \"%s\"...",fn) ;
366 
367  while(!feof(f)) {
368  int r, p , t ;
369  float pp, rr ;
370  char buff[128] ;
371 
372  if(fgets(buff,sizeof(buff),f)==0) continue ;
373 
374  if(buff[0]=='#' || buff[0]=='/') continue ;
375 
376  int ret = sscanf(buff,"%d %d %d %f %f",&r,&p,&t,&pp,&rr) ;
377  if(ret != 5) continue ;
378 
379  struct peds *peds = ped_store + (r-1) ;
380 
381  peds->ped[p][t] = pp ;
382  peds->rms[p][t] = rr ;
383  }
384 
385  fclose(f) ;
386  LOG(TERR,"Pedestals loaded from cache \"%s\": sector %2d.",fn,sector) ;
387 
388 
389  valid = 1 ;
390 
391  return valid ;
392 }
393 
394 int bsmdPed::to_cache(const char *fname, u_int run)
395 {
396  FILE *f ;
397  int r, p, t ;
398  const char *fn ;
399 
400 
401  if(!valid) {
402  LOG(ERR,"ped::to_cache peds are bad: valid %d -- not caching",valid) ;
403  return -1 ;
404  }
405 
406  if(fname) {
407  fn = fname ;
408  }
409  else {
410  fn = "/RTScache/pedestals.txt" ;
411  }
412 
413 
414  f = fopen(fn,"w") ;
415  if(f==0) {
416  LOG(ERR,"ped::to_cache can't open output file \"%s\" [%s]",fn,strerror(errno)) ;
417  return -1 ;
418  }
419 
420 
421  LOG(NOTE,"Writing pedestals to cache \"%s\"...",fn) ;
422  time_t tim = time(0) ;
423  fprintf(f,"# Detector %s\n","BSMD") ;
424  fprintf(f,"# Sector %2d\n",sector) ;
425  fprintf(f,"# Run %08u\n",run) ;
426  fprintf(f,"# Date %s",ctime(&tim)) ;
427  fprintf(f,"\n") ;
428 
429  for(r=0;r<6;r++) {
430  struct peds *peds = ped_store + r ;
431 
432  for(p=0;p<128;p++) {
433  for(t=0;t<4800;t++) {
434  fprintf(f,"%d %d %d %8.3f %.3f\n",r+1,p,t,peds->ped[p][t],peds->rms[p][t]) ;
435  }
436  }
437  }
438 
439  fclose(f) ;
440 
441  LOG(TERR,"Pedestals written to cache \"%s\", for sector %2d...",fn,sector) ;
442 
443  return 1 ;
444 }
445 
446 int bsmdPed::special_setup(int run_type, int sub_type)
447 {
448  int r, p, t ;
449  int m ;
450 
451  switch(run_type) {
452  case RUN_TYPE_PULSER_A :
453  case RUN_TYPE_PED_A :
454  case RUN_TYPE_PED_B :
455  LOG(WARN,"Special Pedestal setup: %d, %d",run_type, sub_type) ;
456  break ;
457  default :
458  return 1 ;
459  }
460 
461  for(r=0;r<6;r++) {
462  struct peds *ped = ped_store + r ;
463  for(p=0;p<128;p++) {
464 
465  switch(run_type) {
466  case RUN_TYPE_PULSER_A :
467  for(t=100;t<110;t++) ped->ped[p][t] = 0.0 ;
468  for(t=400;t<415;t++) ped->ped[p][t] = 0.0 ;
469  break ;
470  case RUN_TYPE_PED_A : // starts with ped=0
471  m = 0 ;
472  for(t=0;t<512;) {
473  for(int i=0;i<16;i++) {
474  ped->ped[p][t+i] = m * 1023.0 ;
475  }
476  if(m==0) m = 1 ;
477  else m = 0 ;
478  t += 16 ;
479  }
480  break ;
481  case RUN_TYPE_PED_B : // starts with ped=1
482  m = 1 ;
483  for(t=0;t<512;) {
484  for(int i=0;i<16;i++) {
485  ped->ped[p][t+i] = m * 1023.0 ;
486  }
487  if(m==0) m = 1 ;
488  else m = 0 ;
489  t += 16 ;
490  }
491  break ;
492  default : // some pattern
493  for(t=0;t<512;t++) ped->ped[p][t] = 1023.0 ; // kill all
494  for(t=p;t<(p+10);t++) ped->ped[p][t] = 0 ; // some pattern depending on row
495  break ;
496  }
497  }
498 
499  }
500 
501 
502  valid = 1 ;
503 
504  return 1 ;
505 }
506 
507 
508