StRoot  1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
stgcPed.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 <TPC/rowlen.h>
12 #include <daqModes.h>
13 #include <TPX/tpx_altro_to_pad.h>
14 #include <SFS/sfs_index.h>
15 
16 //#include "tpxCore.h"
17 #include "stgcPed.h"
18 
19 
20 static const int MIN_EVENTS = 100 ;
21 
22 #define STGC_PED_FILENAME "/RTScache/pedestals"
23 
24 stgcPed::stgcPed()
25 {
26 
27  valid = 0 ;
28  rb_mask = 0x3F ; // assume all..
29 
30  memset(evts,0,sizeof(evts)) ;
31  memset(valid_evts,0,sizeof(valid_evts)) ;
32 
33  max_events = 1000 ;
34 
35 
36  sector = -1 ; // uniti...
37 
38 
39  return ;
40 }
41 
42 
43 stgcPed::~stgcPed()
44 {
45  stgcPed::clear() ;
46 
47  return ;
48 }
49 
50 
51 void stgcPed::clear()
52 {
53  memset(peds,0,sizeof(peds)) ;
54 }
55 
56 
57 // called at start of run...
58 void stgcPed::init(int sec, int active_rbs)
59 {
60 
61 
62  valid = 0 ;
63 
64  rb_mask = active_rbs ;
65  sector = sec ;
66 
67  memset(evts,0,sizeof(evts)) ;
68  memset(valid_evts,0,sizeof(valid_evts)) ;
69  memset(altro_found,0,sizeof(altro_found)) ;
70 
71  stgcPed::clear() ; // zap storage ;
72 
73 }
74 
75 void stgcPed::smooth()
76 {
77  LOG(TERR,"Running smooth...") ;
78 
79  LOG(TERR,"I have %f",peds[2][0].ped[0]) ;
80 
81  for(int a=0;a<256;a++) {
82  for(int c=0;c<16;c++) {
83  double sum = 0.0 ;
84  double cou = 0.0 ;
85  double rms = 0.0 ;
86 
87 
88 #if 0
89  for(int t=0;t<512;t++) {
90  double ped = peds[a][c].ped[t] ;
91  double p_rms = peds[a][c].rms[t] ;
92 
93  if(a==2 && c==0) LOG(TERR,"tb %d = %f %f",t,ped,p_rms) ;
94 
95  if(ped==0.0 && p_rms==0.0) break ;
96  if(ped>1022 && p_rms>9) break ;
97 
98  sum += ped ;
99  rms += ped*ped ;
100  cou++ ;
101  }
102 #endif
103  // use only the first 16ish timebins; before the ripple starts
104 
105  for(int t=0;t<16;t++) {
106  double ped = peds[a][c].ped[t] ;
107  double p_rms = peds[a][c].rms[t] ;
108 
109  //if(a==2 && c==0) LOG(TERR,"tb %d = %f %f",t,ped,p_rms) ;
110 
111  if(ped==0.0 && p_rms==0.0) break ;
112  if(ped>1022 && p_rms>9) break ;
113 
114  sum += ped ;
115  rms += ped*ped ;
116  cou++ ;
117  }
118 
119 
120  if(cou==0) continue ;
121 
122  sum /= cou ;
123  rms /= cou ;
124 
125  rms = sqrt(rms-sum*sum) ;
126 
127  for(int t=0;t<512;t++) {
128  peds[a][c].ped[t] = sum ;
129  peds[a][c].rms[t] = rms ;
130  }
131 
132  LOG(TERR,"A%d:%d - %d %d",a,c,(int)cou,(int)peds[a][c].ped[0]) ;
133  }
134  }
135 
136 }
137 
138 /*
139  Called per event, per RDO. evbbuff is the raw RDO contribuition
140 */
141 void stgcPed::accum(char *evbuff, int bytes)
142 {
143  int t ;
144  u_int *data_end ;
145  tpx_rdo_event rdo ;
146  tpx_altro_struct a ;
147 
148  t = tpx_get_start(evbuff, bytes/4, &rdo, 0) ;
149 
150  if(t <= 0) return ; // non data event...
151 
152  a.what = TPX_ALTRO_DO_ADC ;
153  a.rdo = rdo.rdo - 1 ; // a.rdo counts from 0
154  a.t = t ;
155  a.sector = rdo.sector ;
156  a.log_err = 0 ;
157 
158 
159  evts[a.rdo]++ ;
160 
161  // skip first few events!
162  if(evts[a.rdo] <= 3) {
163  LOG(NOTE,"RDO %d: skipping event %d < 3",rdo.rdo,evts[a.rdo]) ;
164  return ;
165  }
166 
167  valid_evts[a.rdo]++ ;
168 
169 
170  data_end = rdo.data_end ;
171 
172  do {
173  data_end = tpx_scan_to_next(data_end, rdo.data_start, &a) ;
174  accum(&a) ;
175  } while(data_end && (data_end > rdo.data_start)) ;
176 
177 
178  return ;
179 
180 }
181 
182 void stgcPed::accum(tpx_altro_struct *aa)
183 {
184  int a = aa->id ;
185  int ch = aa->ch ;
186 
187  altro_found[a]++ ;
188 
189  for(int i=0;i<aa->count;i++) {
190  int tb, adc ;
191 
192  adc = aa->adc[i] ;
193  tb = aa->tb[i] ;
194 
195  peds[a][ch].ped[tb] += (double) adc ;
196  peds[a][ch].rms[tb] += (double) (adc*adc) ;
197  peds[a][ch].cou[tb]++ ;
198  }
199 
200 
201  return ;
202 }
203 
204 void stgcPed::calc()
205 {
206  int bad ;
207 
208 
209  LOG(NOTE,"Calculating pedestals for sector %2d",sector) ;
210 
211  bad = 0 ;
212 
213  for(int a=0;a<256;a++) {
214  if(!altro_found[a]) continue ;
215 
216  for(int c=0;c<16;c++) {
217  for(int t=0;t<512;t++) {
218  if(peds[a][c].cou[t] == 0) {
219  peds[a][c].ped[t] = 1023.0 ;
220  peds[a][c].rms[t] = 9.999 ;
221  }
222  else {
223  double pp, rr ;
224 
225  pp = peds[a][c].ped[t] / (double) peds[a][c].cou[t] ;
226  rr = peds[a][c].rms[t] / (double) peds[a][c].cou[t] ;
227 
228  // due to roundoff I can have super small negative numbers
229  if(rr < (pp*pp)) rr = 0.0 ;
230  else rr = sqrt(rr - pp*pp) ;
231 
232  peds[a][c].ped[t] = pp ;
233  peds[a][c].rms[t] = rr ;
234  }
235  }
236  LOG(TERR,"AID %d:%d = %f +- %f",a,c,peds[a][c].ped[15],peds[a][c].rms[15]) ;
237  }
238  }
239 
240 
241  for(int r=0;r<6;r++) {
242  if(rb_mask & (1<<r)) {
243  if(valid_evts[r] < MIN_EVENTS) {
244  bad = 1 ;
245  LOG(ERR,"RDO %d: not enough valid events (%d < %d) [%d]",r+1,valid_evts[r],MIN_EVENTS,evts[r]) ;
246  }
247  }
248  }
249 
250 // 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]) ;
251 
252  valid = ! bad ; // if there's any problem I invalidate validity!
253 
254  if(valid) {
255  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]) ;
256  }
257  else {
258  LOG(ERR,"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]) ;
259  }
260 
261  return ;
262 }
263 
264 // returns bytes!
265 int stgcPed::to_altro(char *buff, int rb, int timebins)
266 {
267  int row, pad, t ;
268  int a, ch ;
269 
270  char *rbuff = buff ;
271 
272  if(!valid) {
273  LOG(ERR,"ped::to_altro peds are bad: RDO %d: valid %d",rb+1,valid) ;
274  }
275 
276 
277 
278 // LOG(TERR,"Preparing pedestals for Slo%02d:%d (Shw%02d:%d)...",sector,rb+1,s_real,r_real) ;
279 
280  for(a=0;a<256;a++) {
281 
282 
283 
284  if(!altro_found[a]) continue ;
285 
286  LOG(TERR,"ALTRO %d: found %d",a,altro_found[a]) ;
287 
288  for(ch=0;ch<16;ch++) {
289 
290 
291  u_int *addr = (u_int *) rbuff ; // remember where to store the address
292 
293  rbuff += 4 ; // skip 4 bytes
294 
295  u_short *ptr = (u_short *) rbuff ; // start
296 
297  int tcou = 0 ; // zero counter...
298 
299  // get the corresponding row & pad
300 
301  struct stgcPed::peds *ped = &(peds[a][ch]) ;
302 
303 
304  // pedestal memory for the altro is really odd
305 
306  // first should be the pedestals from the start
307  // of trigger...
308  for(t=15;t<timebins+15;t++) {
309  *ptr++ = (u_short) ped->ped[t] ;
310 
311  //if(ch==0 && t<40) LOG(TERR,"A%d:%d: %d: tb %d = %d",a,ch,tcou,t,(u_short)ped->ped[t]) ;
312 
313  if((row==42)&&(pad==140)) {
314  //LOG(TERR,"%d,%d = %d",t,tcou,(u_short)ped->ped[t]) ;
315  }
316  tcou++ ;
317  }
318 
319 
320 
321  // follow with a "wall" of 1023
322  for(;t<(TPX_MAX_TB+15);t++) {
323  u_short val = (u_short) 1023 ;
324 
325  *ptr++ = val ;
326  if((row==42)&&(pad==140)) {
327  //LOG(TERR,"%d,%d = %d",t,tcou,val) ;
328  }
329 
330  tcou++ ;
331  }
332 
333 
334 
335  // and this is the pedestal of the pre-trigger
336  // actually, I'm totally confused... this count of 15 must
337  // exist but the value seems irrelevant...
338  for(t=0;t<15;t++) {
339  u_short val = (u_short) ped->ped[t] ;
340  *ptr++ = val ;
341  if((row==42)&&(pad==140)) {
342  //LOG(TERR,"%d,%d = %d",t,tcou,val) ;
343  }
344 
345  tcou++ ;
346  }
347 
348  // this, last value is the one that gets used for the pre- pedestals
349  u_short val = (u_short) ped->ped[0] ;
350  *ptr++ = val ;
351  if((row==42)&&(pad==140)) {
352  //LOG(TERR,"%d,%d = %d",t,tcou,val) ;
353  }
354 
355  tcou++ ;
356 
357 
358 
359 
360  // need to be even
361  if(tcou & 1) {
362  LOG(WARN,"tcou %d is odd, adding ped of tb %d?",tcou,t) ;
363  *ptr++ = (u_short) ped->ped[0]; // was ped[t]; then ped[0]
364  tcou++ ;
365  }
366 
367  int aid = a ;
368 
369  *addr = (aid << 24) | (ch << 16) | tcou ;
370 
371  rbuff += 2 * tcou ; // skip stored...
372  }
373  }
374 
375 
376 
377  LOG(NOTE,"Pedestals prepared for RDO %d, bytes %d",rb+1,rbuff-buff) ;
378  return rbuff - buff ; // bytes!
379 }
380 
381 int stgcPed::to_evb(char *buff)
382 {
383  return 0 ;
384 }
385 
386 int stgcPed::from_cache(char *fname, u_int rb_msk)
387 {
388  FILE *f ;
389  char fn[64] ;
390  const char *pn ;
391 
392  // trivial load from disk...
393  if(fname) {
394  pn = fname ;
395  }
396  else {
397  pn = "/RTScache/pedestals" ;
398  }
399 
400 
401  int err = 0 ;
402 
403  memset(peds,0,sizeof(peds)) ;
404  memset(altro_found,0,sizeof(altro_found)) ;
405 
406  for(int rdo=1;rdo<=6;rdo++) {
407  if(rb_mask & (1<<(rdo-1))) ;
408  else continue ;
409 
410  sprintf(fn,"%s_s%02d_r%d.txt",pn,sector,rdo) ;
411  f = fopen(fn,"r") ;
412 
413  if(f==0) {
414  LOG(ERR,"ped::from_cache can't open output file \"%s\" [%s]",fn,strerror(errno)) ;
415  err++ ;
416  continue ;
417  }
418 
419 
420  LOG(NOTE,"Loading pedestals from cache \"%s\"...",fn) ;
421 
422 
423  while(!feof(f)) {
424  u_int r, p , t ;
425  float pp, rr ;
426  char buff[64] ;
427  int bad = 0 ;
428 
429  if(fgets(buff,sizeof(buff),f)==0) continue ;
430 
431  switch(buff[0]) {
432  case '#' :
433  case '/' :
434  continue ;
435  }
436 
437  int ret = sscanf(buff,"%d %d %d %f %f",&r,&p,&t,&pp,&rr) ;
438  if(ret != 5) continue ;
439 
440  if(r>=256) bad = 1 ;
441  if(p>=16) bad = 1 ;
442  if(t>=512) bad = 1 ;
443 
444  if(bad) {
445  LOG(ERR,"WHA %d %d",r,p) ;
446  continue ;
447  }
448 
449  altro_found[r]++ ;
450 
451 
452 
453  peds[r][p].ped[t] = pp ;
454  peds[r][p].rms[t] = rr ;
455 
456  if(p==0 && t==20) LOG(TERR,"S%d:%d: %f %f",r,p,pp,rr) ;
457  }
458 
459  fclose(f) ;
460  }
461 
462 
463  if(!err) {
464  LOG(TERR,"Pedestals loaded from cache (last was \"%s\"): sector %2d [0x%02X].",fn,sector,rb_mask) ;
465  valid = 1 ;
466  }
467  else {
468  LOG(ERR,"Pedestals failed from cache (last was \"%s\"): sector %2d [0x%02X].",fn,sector,rb_mask) ;
469  valid = 0 ;
470  }
471 
472 
473 
474 
475  return valid ;
476 }
477 
478 int stgcPed::to_cache(char *fname, u_int run)
479 {
480  FILE *f ;
481  char fn[64] ;
482  const char *pn ;
483  char *asc_date ;
484 
485 
486  if(!valid) {
487  LOG(ERR,"ped::to_cache peds are bad: valid %d -- not caching",valid) ;
488  return -1 ;
489  }
490 
491 
492  time_t tm = time(0) ;
493  asc_date = ctime(&tm) ;
494 
495  if(fname) {
496  pn = fname ;
497  }
498  else {
499  pn = "/RTScache/pedestals" ;
500  }
501 
502  // changed to per-RDO on Jan 13, 2010.
503 
504  for(int rdo=1;rdo<=6;rdo++) {
505 
506 
507  if(rb_mask & (1<<(rdo-1))) ;
508  else continue ;
509 
510 
511  // check if the RDO was present!
512  if(valid_evts[rdo-1] < MIN_EVENTS) {
513  LOG(ERR,"Sector %2d, RDO %d has %d events -- not caching!",sector,rdo,valid_evts[rdo-1]) ;
514  continue ;
515  }
516 
517  sprintf(fn,"%s_s%02d_r%d.txt",pn,sector,rdo) ;
518 
519  f = fopen(fn,"w") ;
520  if(f==0) {
521  LOG(ERR,"ped::to_cache can't open output file \"%s\" [%s]",fn,strerror(errno)) ;
522  continue ;
523  }
524 
525 
526  LOG(NOTE,"Writing pedestals to cache \"%s\"...",fn) ;
527 
528 
529  fprintf(f,"# Detector %s\n","STGC") ;
530  fprintf(f,"# Run %08u\n",run) ;
531  fprintf(f,"# Date %s",asc_date) ;
532  fprintf(f,"# Logical sector %d, logical RDO %d\n",sector,rdo) ;
533  fprintf(f,"\n") ;
534 
535  for(int a=0;a<256;a++) {
536  if(!altro_found[a]) continue ;
537 
538  for(int c=0;c<16;c++) {
539 
540  for(int t=0;t<512;t++) {
541  fprintf(f,"%d %d %d %.3f %.3f\n",a,c,t,peds[a][c].ped[t],peds[a][c].rms[t]) ;
542  }
543  }
544  }
545 
546  fclose(f) ;
547  }
548 
549  LOG(TERR,"Pedestals written to cache \"%s\", for sector %2d...",fn,sector) ;
550 
551  return 1 ;
552 }
553 
554 
555 
556 int stgcPed::kill_bad(int rdo0, int a, int ch)
557 {
558  for(int t=0;t<512;t++) {
559  peds[a][ch].ped[t] = 1023.0 ;
560  peds[a][ch].rms[t] = 9.999 ;
561  }
562 
563  return 1 ;
564 }
565 
566 
Definition: rb.hh:21