StRoot  1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
tpxPed.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 "tpxPed.h"
18 #include "tpxGain.h"
19 
20 static const u_int MIN_EVENTS = 500 ;
21 #define TPX_PED_FILENAME "/RTScache/pedestals"
22 
23 tpxPed::tpxPed()
24 {
25  smoothed = 0 ;
26  valid = 0 ;
27  rb_mask = 0x3F ; // assume all..
28 
29  memset(evts,0,sizeof(evts)) ;
30  memset(valid_evts,0,sizeof(valid_evts)) ;
31 
32  max_events = 1000 ;
33 
34  clock_source = 9 ; // non-existant
35  sector = -1 ; // uniti...
36 
37  memset(ped_rdo_store,0,sizeof(ped_rdo_store)) ;
38 
39 
40 
41  return ;
42 }
43 
44 
45 tpxPed::~tpxPed()
46 {
47  tpxPed::clear() ;
48 
49  return ;
50 }
51 
52 
53 void tpxPed::clear()
54 {
55  for(int r=0;r<6;r++) {
56  if(ped_rdo_store[r].peds) {
57  free(ped_rdo_store[r].peds) ;
58  ped_rdo_store[r].peds = 0 ;
59  }
60  }
61 
62  return ;
63 }
64 
65 
66 // called at start of run...
67 void tpxPed::init(int sec, int active_rbs)
68 {
69 
70  smoothed = 0 ;
71  valid = 0 ;
72 
73  memset(evts,0,sizeof(evts)) ;
74  memset(valid_evts,0,sizeof(valid_evts)) ;
75 
76  rb_mask = active_rbs ;
77  sector = sec ;
78 
79  tpxPed::clear() ; // zap storage ;
80 
81  for(int r=0;r<6;r++) {
82  if(rb_mask & (1<<r)) ;
83  else continue ;
84 
85  int s_real, r_real ;
86 
87 
88  tpx36_to_real(sector,r+1,s_real,r_real) ;
89 
90  ped_rdo_store[r].r_real = r_real ;
91  ped_rdo_store[r].s_real = s_real ;
92 
93  ped_rdo_store[r].peds = (struct peds *) malloc(sizeof(struct peds)*1152) ;
94  memset(ped_rdo_store[r].peds,0,sizeof(struct peds)*1152) ;
95 
96  memset(ped_rdo_store[r].ix,0xFF,sizeof(ped_rdo_store[r].ix)) ;
97 
98  int cou = 0 ;
99  for(int a=0;a<256;a++) {
100  for(int c=0;c<16;c++) {
101  int row, pad ;
102 
103  tpx_from_altro(r_real-1,a,c,row,pad) ;
104  if(row==255) continue ;
105 
106  //LOG(TERR,"Real RDO %d: A%d:%d = RP %d:%d",r_real,a,c,row,pad) ;
107  ped_rdo_store[r].peds[cou].row = row ;
108  ped_rdo_store[r].peds[cou].pad = pad ;
109  ped_rdo_store[r].ix[row][pad] = cou ;
110  cou++ ;
111  }
112  }
113 
114  LOG(TERR,"peds_inited: sector %d, RDO real %d: %d",s_real,r_real,cou) ;
115 
116  }
117 
118 }
119 
120 /*
121  Called per event, per RDO. evbbuff is the raw RDO contribuition
122 */
123 void tpxPed::accum(char *evbuff, int bytes)
124 {
125  int t ;
126  u_int *data_end ;
127  tpx_rdo_event rdo ;
128  tpx_altro_struct a ;
129  int r0_logical ;
130 
131  t = tpx_get_start(evbuff, bytes/4, &rdo, 0) ;
132 
133  if(t <= 0) return ; // non data event...
134 
135 
136 
137  a.what = TPX_ALTRO_DO_ADC ;
138  a.rdo = rdo.rdo - 1 ; // a.rdo counts from 0
139  a.t = t ;
140  a.sector = rdo.sector ;
141  a.log_err = 0 ;
142 
143  r0_logical = tpx36_from_real(sector,rdo.sector,rdo.rdo) - 1 ;
144 
145  evts[r0_logical]++ ;
146 
147 
148  // skip first few events!
149  if(evts[r0_logical] <= 3) {
150  LOG(NOTE,"RDO %d: skipping event %d < 3",rdo.rdo,evts[r0_logical]) ;
151  return ;
152  }
153 
154  // what to do with this!!!???
155  if(tpx_rdo_dbg[a.sector-1][a.rdo].delta < 200000) {
156  LOG(WARN,"RDO %d: skipping event %d: delta %u too small",rdo.rdo,evts[r0_logical],tpx_rdo_dbg[a.sector-1][a.rdo].delta) ;
157  usleep(10000) ;
158  return ;
159  }
160 
161  valid_evts[r0_logical]++ ;
162 
163  LOG(NOTE,"RDO %d: event %d: delta %u OK",rdo.rdo,evts[r0_logical],tpx_rdo_dbg[a.sector-1][a.rdo].delta) ;
164 
165  data_end = rdo.data_end ;
166 
167  do {
168  data_end = tpx_scan_to_next(data_end, rdo.data_start, &a) ;
169  accum(&a) ;
170  } while(data_end && (data_end > rdo.data_start)) ;
171 
172 
173  return ;
174 
175 }
176 
177 void tpxPed::accum(tpx_altro_struct *a)
178 {
179  int i ;
180  int row, pad ;
181  struct peds *p ;
182  int r0_logical ;
183 
184  r0_logical = tpx36_from_real(sector, a->sector, a->rdo+1) ;
185  r0_logical-- ; // need from 0 later on...
186 
187  row = a->row ;
188  pad = a->pad ;
189 
190  if(tpx_is_stgc) {
191  LOG(TERR,"RDO0 %d, RP %d:%d, AID %d:%d",r0_logical,row,pad,a->id,a->ch) ;
192  }
193 
194  p = get(r0_logical,row, pad) ;
195 
196  if(p==0) {
197  LOG(ERR,"ped::accum for row %d, pad %d, A %d:%d bad (real RDO %d)?",row,pad,a->id,a->ch,a->rdo+1) ;
198  LOG(ERR,"Slog %d:%d, Shw %d:%d",sector,r0_logical+1,a->sector,a->rdo+1) ;
199  return ;
200  }
201 
202  // do not allow more than 1000 events; use tb[20]'s counter...
203  if(p->cou[20] > max_events) return ;
204 
205 
206  LOG(DBG,"count %d",a->count) ;
207  for(i=0;i<a->count;i++) {
208  int tb, adc ;
209 
210  adc = a->adc[i] ;
211  tb = a->tb[i] ;
212 
213  p->ped[tb] += (double) adc ;
214  p->rms[tb] += (double) (adc*adc) ;
215  p->cou[tb]++ ;
216  }
217 
218 
219  return ;
220 }
221 
222 void tpxPed::calc()
223 {
224  int r,p,t ;
225  int rl0 ;
226  int bad ;
227 
228 
229  LOG(NOTE,"Calculating pedestals for sector %2d",sector) ;
230 
231  bad = 0 ;
232 
233  for(rl0=0;rl0<6;rl0++) {
234  for(r=0;r<=45;r++) {
235  for(p=0;p<=182;p++) {
236  struct peds *ped = get(rl0,r,p) ;
237  if(ped==0) continue ;
238 
239  for(t=0;t<512;t++) {
240  if(ped->cou[t] == 0) {
241  ped->ped[t] = 1023.0 ;
242  ped->rms[t] = 9.999 ;
243  }
244  else {
245  double pp, rr ;
246 
247  pp = ped->ped[t] / (double) ped->cou[t] ;
248  rr = ped->rms[t] / (double) ped->cou[t] ;
249 
250  // due to roundoff I can have super small negative numbers
251  if(rr < (pp*pp)) rr = 0.0 ;
252  else rr = sqrt(rr - pp*pp) ;
253 
254  ped->ped[t] = pp ;
255  ped->rms[t] = rr ;
256  }
257  }
258  }
259  }
260  }
261 
262  for(r=0;r<6;r++) {
263  if(rb_mask & (1<<r)) {
264  if(valid_evts[r] < MIN_EVENTS) {
265  bad = 1 ;
266  LOG(ERR,"RDO %d: not enough valid events (%d < %d) [%d]",r+1,valid_evts[r],MIN_EVENTS,evts[r]) ;
267  }
268  }
269  }
270 
271 // 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]) ;
272 
273  valid = ! bad ; // if there's any problem I invalidate validity!
274 
275  if(valid) {
276  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]) ;
277  }
278  else {
279  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]) ;
280  }
281 
282  return ;
283 }
284 
285 // returns bytes!
286 int tpxPed::to_altro(char *buff, int rb, int timebins)
287 {
288  int row, pad, t ;
289  int a, ch ;
290  int s_real, r_real ;
291 
292  FILE *fff = 0 ;
293 
294 
295 #if 0
296  char fname[128] ;
297  sprintf(fname,"/RTScache/altro_ped_%d_%03d.txt",rb+1,timebins) ;
298 
299  fff = fopen(fname,"w") ;
300  if(fff==0) {
301  LOG(WARN,"Can't open \"%s\"",fname) ;
302  }
303 #endif
304 
305  char *rbuff = buff ;
306 
307  if(!valid || !smoothed) {
308  LOG(ERR,"ped::to_altro peds are bad: RDO %d: valid %d, smoothed %d",rb+1,valid,smoothed) ;
309  }
310 
311 
312 
313  tpx36_to_real(sector,rb+1,s_real,r_real) ;
314 
315  LOG(TERR,"Preparing pedestals for Slo%02d:%d (Shw%02d:%d)...",sector,rb+1,s_real,r_real) ;
316 
317  for(a=0;a<256;a++) {
318  for(ch=0;ch<16;ch++) {
319 
320  tpx_from_altro(r_real-1,a,ch,row,pad) ;
321 
322  if(row > 45) continue ; // not here...
323 
324 
325 
326  u_int *addr = (u_int *) rbuff ; // remember where to store the address
327 
328  rbuff += 4 ; // skip 4 bytes
329 
330  u_short *ptr = (u_short *) rbuff ; // start
331 
332  int tcou = 0 ; // zero counter...
333 
334  // get the corresponding row & pad
335 
336  struct peds *ped = get(rb,row,pad) ;
337  if(ped==0) {
338  LOG(ERR,"RDO %d (real %d): row %d, pad %d",rb+1,r_real,row,pad) ;
339  continue ;
340  }
341 
342  for(t=0;t<timebins+15;t++) {
343  if(fff) fprintf(fff,"%d %d %d %d %d %d\n",row,pad,a,ch,t,(u_short)ped->ped[t]) ;
344  }
345 #if 0
346  // copy as shorts BUT:
347  // needs to go from 15 _AND_ needs to be even!
348  for(t=15;t<509;t++) {
349  *ptr++ = (u_short) ped->ped[t] ;
350  tcou++ ;
351  }
352 
353  if(tcou & 1) {
354  *ptr++ = (u_short) ped->ped[t] ;
355  tcou++ ;
356  }
357 #endif
358 
359  // pedestal memory for the altro is really odd
360 
361  // first should be the pedestals from the start
362  // of trigger...
363  for(t=15;t<timebins+15;t++) {
364  *ptr++ = (u_short) ped->ped[t] ;
365  if((row==42)&&(pad==140)) {
366  //LOG(TERR,"%d,%d = %d",t,tcou,(u_short)ped->ped[t]) ;
367  }
368  tcou++ ;
369  }
370 
371 
372 
373  // follow with a "wall" of 1023
374  for(;t<(TPX_MAX_TB+15);t++) {
375  u_short val = (u_short) 1023 ;
376 
377  *ptr++ = val ;
378  if((row==42)&&(pad==140)) {
379  //LOG(TERR,"%d,%d = %d",t,tcou,val) ;
380  }
381 
382  tcou++ ;
383  }
384 
385 
386 
387  // and this is the pedestal of the pre-trigger
388  // actually, I'm totally confused... this count of 15 must
389  // exist but the value seems irrelevant...
390  for(t=0;t<15;t++) {
391  u_short val = (u_short) ped->ped[t] ;
392  *ptr++ = val ;
393  if((row==42)&&(pad==140)) {
394  //LOG(TERR,"%d,%d = %d",t,tcou,val) ;
395  }
396 
397  tcou++ ;
398  }
399 
400  // this, last value is the one that gets used for the pre- pedestals
401  u_short val = (u_short) ped->ped[0] ;
402  *ptr++ = val ;
403  if((row==42)&&(pad==140)) {
404  //LOG(TERR,"%d,%d = %d",t,tcou,val) ;
405  }
406 
407  tcou++ ;
408 
409 
410 
411 #if 0
412  // THIS is how it was done pre-FY11
413  // follow with pre-trigger pedestals
414  for(t=0;t<15;t++) {
415  *ptr++ = (u_short) ped->ped[t] ;
416  tcou++ ;
417  }
418 #endif
419 
420 #if 0
421  // testing....
422  // follow with 510
423 // for(t=0;t<20;t++) {
424 // *ptr++ = t ;
425 // tcou++ ;
426 // }
427 
428  *ptr++ = 5 ;
429  tcou++ ;
430  *ptr++ = 10 ;
431  tcou++ ;
432  *ptr++ = 15 ;
433  tcou++ ;
434  *ptr++ = 20 ;
435  tcou++ ;
436 #endif
437 
438  // need to be even
439  if(tcou & 1) {
440  LOG(WARN,"tcou %d is odd, adding ped of tb %d?",tcou,t) ;
441  *ptr++ = (u_short) ped->ped[0]; // was ped[t]; then ped[0]
442  tcou++ ;
443  }
444 
445  int aid = a ;
446  for(int i=0;i<tpx_fee_override_cou;i++) {
447  if(s_real == tpx_fee_override[i].sector) {
448  if(r_real == (tpx_fee_override[i].rdo)) {
449  int fee = a & 0xFE ;
450  if(fee == tpx_fee_override[i].orig_altro) {
451 
452  if(a & 1) {
453  aid = tpx_fee_override[i].curr_altro | 1 ;
454 
455  }
456  else {
457  aid = tpx_fee_override[i].curr_altro ;
458  }
459 
460  LOG(NOTE,"Sector %2d, RDO %d: overriding ALTRO from %3d to %3d",sector,rb+1,a,aid) ;
461  }
462  }
463  }
464  }
465 
466  *addr = (aid << 24) | (ch << 16) | tcou ;
467 
468 // LOG(TERR,"to_altro: sector %d, rb %d: ALTRO %3d:%02d tcou %d",sector,rb,aid,ch,tcou) ;
469 
470  rbuff += 2 * tcou ; // skip stored...
471  }
472  }
473 
474  if(fff) fclose(fff) ;
475 
476  LOG(NOTE,"Pedestals prepared for RDO %d, bytes %d",rb+1,rbuff-buff) ;
477  return rbuff - buff ; // bytes!
478 }
479 
480 int tpxPed::to_evb(char *buff)
481 {
482  int r, p, t ;
483  sfs_index sfs ;
484 
485  char *rbuff = buff ; // remember
486 
487  if(!valid || !smoothed) {
488  // log error but continue...
489  LOG(ERR,"ped::to_evb peds are bad: valid %d, smoothed %d",valid,smoothed) ;
490  }
491 
492  LOG(NOTE,"Preparing pedestals for later EVB...") ;
493 
494  for(int rl0=0;rl0<4;rl0++) {
495 
496  char sname[32] ;
497  int s_real, r_real ;
498  tpx36_to_real(sector,rl0+1,s_real,r_real) ;
499 
500  sprintf(sname,"sec%02d/rb%02d/pedrms",s_real,r_real) ;
501  char *save_rbuff = rbuff ;
502  int h_bytes = sfs.putfileheader(save_rbuff,sname,0) ;
503 
504  rbuff += h_bytes ;
505 
506  u_short *addr = (u_short *) rbuff ;
507 
508  for(r=0;r<=45;r++) {
509  for(p=1;p<=tpc_rowlen[r];p++) {
510  struct peds *ped = get(rl0,r, p) ;
511  if(ped==0) continue ;
512 
513  addr = (u_short *) rbuff ; // remember address
514  *(addr+1) = (r<<8) | p ; // row/pad
515 
516  u_short *ptr = addr + 2; // read to store
517 
518  for(t=0;t<512;t++) {
519  double rms = (ped->rms[t] * 16.0) ;
520  u_short val ;
521 
522  if((u_short)rms > 0x3F) val = 0x3F ;
523  else val = (u_short) rms ;
524 
525  // sanity check!
526  if(ped->ped[t] == 0) {
527  LOG(WARN,"WTF? ped 0 in rp %d:%d, tb %d",r,p,t) ;
528  }
529 
530  *ptr++ = (val << 10) | (u_short)ped->ped[t] ;
531  }
532 
533  *addr = t ; // unsert count at the first short
534  rbuff = (char *) ptr ;
535  }
536  }
537  sfs.putfileheader(save_rbuff,sname,rbuff-save_rbuff-h_bytes) ;
538 
539  }
540  // short cou
541  // short row|pad
542  // short: 6bit RMS, 10bit ped
543 
544  LOG(TERR,"Pedestals prepared for later EVB, sector %2d: %d bytes",sector,rbuff-buff) ;
545  return (rbuff-buff) ;
546 }
547 
548 int tpxPed::from_cache(char *fname, u_int rb_msk)
549 {
550  FILE *f ;
551  char fn[64] ;
552  const char *pn ;
553 
554  // trivial load from disk...
555  if(fname) {
556  pn = fname ;
557  }
558  else {
559  pn = "/RTScache/pedestals" ;
560  }
561 
562 
563  int err = 0 ;
564 
565  for(int rdo=1;rdo<=6;rdo++) {
566  if(rb_mask & (1<<(rdo-1))) ;
567  else continue ;
568 
569  int s_real, r_real ;
570 
571  tpx36_to_real(sector,rdo,s_real,r_real) ;
572 
573  sprintf(fn,"%s_s%02d_r%d.txt",pn,s_real,r_real) ;
574  f = fopen(fn,"r") ;
575 
576  if(f==0) {
577  LOG(ERR,"ped::from_cache can't open output file \"%s\" [%s]",fn,strerror(errno)) ;
578  err++ ;
579  continue ;
580  }
581 
582 
583  LOG(NOTE,"Loading pedestals from cache \"%s\"...",fn) ;
584 
585  while(!feof(f)) {
586  int r, p , t ;
587  float pp, rr ;
588  char buff[64] ;
589 
590  if(fgets(buff,sizeof(buff),f)==0) continue ;
591 
592  switch(buff[0]) {
593  case '#' :
594  case '/' :
595  continue ;
596  }
597 
598  int ret = sscanf(buff,"%d %d %d %f %f",&r,&p,&t,&pp,&rr) ;
599  if(ret != 5) continue ;
600 
601  struct peds *peds = get(rdo-1,r,p) ;
602 
603  //if((r==12) && (p==158) && (t==0)) LOG(TERR,"peds row %d, pad %d: %f %f",r,p,pp,rr) ;
604 
605  peds->ped[t] = pp ;
606  peds->rms[t] = rr ;
607  }
608 
609  fclose(f) ;
610  }
611 
612 
613  if(!err) {
614  LOG(TERR,"Pedestals loaded from cache (last was \"%s\"): sector %2d [0x%02X].",fn,sector,rb_mask) ;
615  valid = 1 ;
616  }
617  else {
618  LOG(ERR,"Pedestals failed from cache (last was \"%s\"): sector %2d [0x%02X].",fn,sector,rb_mask) ;
619  valid = 0 ;
620  }
621 
622  smoothed = 0 ;
623 
624 
625  return valid ;
626 }
627 
628 int tpxPed::to_cache(char *fname, u_int run)
629 {
630  FILE *f, *f_sum ;
631  int r, p, t ;
632  char fn[64] ;
633 // char f_sum_name[128] ;
634  const char *pn ;
635  char *asc_date ;
636 
637  static float old_sum[46][183] ;
638 
639 
640  if(!valid || smoothed) {
641  LOG(ERR,"ped::to_cache peds are bad: valid %d, smoothed %d -- not caching",valid,smoothed) ;
642  return -1 ;
643  }
644 
645 
646  time_t tm = time(0) ;
647  asc_date = ctime(&tm) ;
648 
649  if(fname) {
650  pn = fname ;
651  }
652  else {
653  pn = "/RTScache/pedestals" ;
654  }
655 
656  // changed to per-RDO on Jan 13, 2010.
657 
658  for(int rdo=1;rdo<=6;rdo++) {
659  int s_real, r_real ;
660 
661  if(rb_mask & (1<<(rdo-1))) ;
662  else continue ;
663 
664  // need real sector and real RDO here!!!
665  tpx36_to_real(sector,rdo,s_real,r_real) ;
666 
667  // check if the RDO was present!
668  if(valid_evts[rdo-1] < MIN_EVENTS) {
669  LOG(ERR,"Sector %2d, RDO %d has %d events -- not caching!",sector,rdo,valid_evts[rdo-1]) ;
670  continue ;
671  }
672 
673  sprintf(fn,"%s_s%02d_r%d.txt",pn,s_real,r_real) ;
674 
675  // first read old peds...
676 
677  memset(old_sum,0,sizeof(old_sum)) ;
678 
679  f = fopen(fn,"r") ;
680  if(f==0) {
681  LOG(ERR,"ped::to_cache can't open input file \"%s\" [%s]",fn,strerror(errno)) ;
682  }
683  else {
684 
685  while(!feof(f)) {
686  float fped, frms ;
687  char buff[64] ;
688 
689  if(fgets(buff,sizeof(buff),f)==0) continue ;
690 
691  switch(buff[0]) {
692  case '#' :
693  case '/' :
694  continue ;
695  }
696 
697  int ret = sscanf(buff,"%d %d %d %f %f",&r,&p,&t,&fped,&frms) ;
698  if(ret != 5) continue ;
699 
700  if(t < 22) {
701  old_sum[r][p] += fped ;
702  }
703  }
704 
705  for(r=0;r<=45;r++) {
706  for(p=1;p<=tpc_rowlen[r];p++) {
707  old_sum[r][p] /= 22.0 ;
708  }
709  }
710 
711  fclose(f) ;
712  }
713 
714 
715  f = fopen(fn,"w") ;
716  if(f==0) {
717  LOG(ERR,"ped::to_cache can't open output file \"%s\" [%s]",fn,strerror(errno)) ;
718  continue ;
719  }
720 
721  f_sum = 0 ;
722 #if 0
723  if(run==0) {
724  sprintf(f_sum_name,"/RTScache/ped_sum_s%02d_r%d_%u_%d.txt",s_real,r_real,(u_int)time(NULL),clock_source) ;
725  }
726  else {
727  sprintf(f_sum_name,"/RTScache/ped_sum_s%02d_r%d_%08u_%d.txt",s_real,r_real,run,clock_source) ;
728  }
729 
730  f_sum = fopen(f_sum_name,"w") ;
731  if(f_sum==0) {
732  LOG(ERR,"ped::to_cache can't open trace file \"%s\" [%s]",f_sum_name,strerror(errno)) ;
733  }
734 
735 #endif
736 
737  LOG(NOTE,"Writing pedestals to cache \"%s\"...",fn) ;
738 
739 
740  fprintf(f,"# Detector %s\n","TPX") ;
741  fprintf(f,"# Run %08u\n",run) ;
742  fprintf(f,"# Date %s",asc_date) ;
743  fprintf(f,"# Logical sector %d, logical RDO %d\n",sector,rdo) ;
744  fprintf(f,"# Hardware sector %d, hardware RDO %d\n",s_real, r_real) ;
745  fprintf(f,"\n") ;
746 
747 
748  for(r=0;r<=45;r++) {
749 
750  // ONLY from 1 to rowlen!
751  for(p=1;p<=tpc_rowlen[r];p++) {
752  int t_rdo, t_a, t_ch ;
753 
754  tpx_to_altro(r,p,t_rdo,t_a,t_ch) ;
755  if(t_rdo != r_real) {
756  //LOG(WARN,"RDO %d, real %d: RP %d:%d, AID %d:%d",t_rdo,r_real,r,p,t_a,t_ch) ;
757  continue ;
758  }
759 
760  struct peds *peds = get(rdo-1,r, p) ;
761  if(peds == 0) {
762  LOG(WARN,"Shouldnt %d %d %d %d",r_real,t_rdo,r,p) ;
763  continue ;
764  }
765 
766  double sum = 0.0 ;
767  int cou = 0 ;
768 
769  for(t=0;t<22;t++) {
770  sum += peds->ped[t] ;
771  cou++ ;
772  }
773 
774  sum /= (double)cou ;
775 
776  double p_diff = sum - old_sum[r][p] ;
777  if(fabs(p_diff)>1.0) {
778  LOG(WARN,"RDO %d (S%02d:%d): ped_compare r:p %d:%d = %.1f",rdo,s_real,r_real,r,p,p_diff) ;
779  }
780 
781 
782  if(f_sum) fprintf(f_sum,"%d %d %.5f\n",r,p,sum) ;
783 
784  for(t=0;t<512;t++) {
785 
786  //if((r==12) && (p==158) && (t==0)) LOG(TERR,"peds row %d, pad %d: %f %f",r,p,peds->ped[t],peds->rms[t]) ;
787  fprintf(f,"%d %d %d %.3f %.3f\n",r,p,t,peds->ped[t],peds->rms[t]) ;
788  }
789  }
790  }
791 
792  fclose(f) ;
793  if(f_sum) fclose(f_sum) ;
794  }
795 
796  LOG(TERR,"Pedestals written to cache \"%s\", for sector %2d...",fn,sector) ;
797 
798  return 1 ;
799 }
800 
801 int tpxPed::hlt_debug_setup(int param)
802 {
803  int delta_tb = param % 100 ;
804  int delta_pad = param / 100 ;
805  int hits ;
806 
807  if(delta_tb < 6) delta_tb = 6 ;
808  if(delta_pad < 3) delta_pad = 3 ;
809 
810  hits = 0 ;
811 
812  for(int rl0=0;rl0<4;rl0++) {
813 
814  for(int r=1;r<=45;r++) {
815 
816  for(int p=3;p<=(tpc_rowlen[r]-delta_pad-2);p+=delta_pad) {
817 
818  for(int pd=0;pd<2;pd++) {
819  struct peds *ped = get(rl0,r,p+pd) ;
820  if(ped==0) continue ;
821 
822  for(int t=15;t<400;t+=delta_tb) {
823 
824 
825  hits++ ;
826 
827  for(int td=0;td<5;td++) {
828  double val = ped->ped[t+td] ;
829  // lower the pedestal 5 ADC counts
830  if(val < 10.0) val = 0.0 ;
831  else val -= 10.0 ;
832 
833  ped->ped[t+td] = val ;
834  }
835  }
836  }
837  }
838  }
839  }
840 
841  LOG(TERR,"param %u: delta pad %d,time %d: %d hits",param,delta_pad,delta_tb,hits/2) ;
842 
843  valid = 1 ;
844  smoothed = 1 ;
845 
846  return 1 ;
847 }
848 
849 int tpxPed::special_setup(int run_type, int sub_type)
850 {
851  int r, p, t ;
852 // int m ;
853 
854  switch(run_type) {
855  case RUN_TYPE_PULSER_A :
856  case RUN_TYPE_PULSER :
857  case RUN_TYPE_PED_A :
858  case RUN_TYPE_PED_B :
859 
860  break ;
861  case RUN_TYPE_HLT_DEBUG :
862  LOG(WARN,"Special Pedestal setup: %d, %d",run_type, sub_type) ;
863  hlt_debug_setup(sub_type) ;
864  return 1 ;
865  case RUN_TYPE_LASER :
866  if(sub_type) {
867  break ;
868  }
869  return 1 ;
870  default :
871  if(sub_type) {
872  break ;
873 
874  }
875  return 1 ;
876  }
877 
878 
879  LOG(ERR,"Special Pedestal setup: %d, %d (just a warning)",run_type, sub_type) ;
880 
881  for(int rl0=0;rl0<4;rl0++) {
882  for(r=0;r<=45;r++) {
883  for(p=0;p<=182;p++) {
884  struct peds *ped = get(rl0,r,p) ;
885  if(ped==0) continue ;
886 
887  switch(run_type) {
888  case RUN_TYPE_PHYS : //occupancy increase; used e.g. in noise-calibration runs hot_channels
889  for(t=100;t<(100+sub_type);t++) {
890  ped->ped[t] -= 10 ;
891  }
892  break ;
893  case RUN_TYPE_PULSER_A :
894  // make it about 5% occupancy
895  for(t=100;t<110;t++) ped->ped[t] = 0.0 ;
896  //for(t=200;t<220;t++) ped->ped[t] = 0.0 ;
897  for(t=400;t<415;t++) ped->ped[t] = 0.0 ;
898  break ;
899  case RUN_TYPE_PULSER :
900  for(t=TPX_PULSER_PED_START;t<=TPX_PULSER_PED_STOP;t++) ped->ped[t] = 0.0 ;
901  break ;
902  case RUN_TYPE_HLT_DEBUG :
903 
904  break ;
905  case RUN_TYPE_PED_A : // starts with ped=0
906 /*
907  m = 0 ;
908  for(t=0;t<512;) {
909  for(int i=0;i<16;i++) {
910  ped->ped[t+i] = m * 1023.0 ;
911  }
912  if(m==0) m = 1 ;
913  else m = 0 ;
914  t += 16 ;
915  }
916 */
917 
918 
919  for(t=0;t<512;t++) {
920  ped->ped[t] = 0 ;
921  }
922 
923  //for(t=0;t<20;t++) ped->ped[t] = 10 ;
924  for(t=390;t<512;t++) ped->ped[t] = 20 ;
925 
926  break ;
927  case RUN_TYPE_PED_B : // starts with ped=1
928 
929 
930 /* don't know what this was...
931  m = 1 ;
932  for(t=0;t<512;) {
933  for(int i=0;i<16;i++) {
934  ped->ped[t+i] = m * 1023.0 ;
935  }
936  if(m==0) m = 1 ;
937  else m = 0 ;
938  t += 16 ;
939  }
940 */
941 
942  // use the first timebin for all...
943  for(t=1;t<512;t++) ped->ped[t] = ped->ped[0] ;
944 
945  break ;
946  case RUN_TYPE_LASER :
947  for(t=368;t<=383;t++) ped->ped[t] = 0.0 ;
948  break ;
949 
950  default : // some pattern
951  for(t=0;t<512;t++) ped->ped[t] = 1023.0 ; // kill all
952  for(t=p;t<(p+10);t++) ped->ped[t] = 0 ; // some pattern depending on row
953  break ;
954  }
955 
956  }
957  }
958  }
959 
960  valid = 1 ;
961  smoothed = 1 ;
962 
963  return 1 ;
964 }
965 
966 
967 void tpxPed::smooth(int mode)
968 {
969  int r, p, t ;
970 
971  double mean ;
972  int cou ;
973 
974  if(smoothed || !valid) {
975  LOG(ERR,"ped::smooth sector %2d invalid: smoothed %d, valid %d",sector,smoothed,valid) ;
976  return ;
977  }
978 
979  #define TPX_GG_START 20 // depends on TCD!
980  #define TPX_START_OF_RIPPLE 32 // doesn't depend on TCD
981  #define TPX_START_CORRECTION 34
982  #define TPX_USE_DATA 298
983  #define TPX_GG_DOWN 420
984 
985 
986  LOG(NOTE,"Smoothing pedestals...") ;
987 
988  for(int rl0=0;rl0<4;rl0++) {
989  for(r=0;r<=45;r++) {
990  for(p=0;p<=182;p++) {
991  struct peds *ped = get(rl0,r,p) ;
992  if(ped==0) continue ;
993 
994  double smoother[513] ;
995  double ripple[24] ;
996 
997 
998  // this gets funky...
999  for(t=0;t<512;t++) {
1000  smoother[t] = ped->ped[t] ;
1001  }
1002 
1003  /****** time before GG _and_ ripple -- flat! */
1004  mean = 0.0 ;
1005  cou = 0 ;
1006 
1007  for(t=0;t<TPX_GG_START;t++) { // before GG & ripple
1008  mean += smoother[t] ;
1009  cou++ ;
1010  }
1011  mean /= (double)cou ;
1012 
1013  for(t=0;t<TPX_GG_START;t++) {
1014  smoother[t] = mean ;
1015  }
1016 
1017 
1018  // now get the ripple at some nice point
1019  mean = 0.0 ;
1020  cou = 0 ;
1021 
1022  for(t=TPX_USE_DATA;t<(TPX_USE_DATA+8);t++) {
1023  mean += smoother[t] ;
1024  cou++ ;
1025  }
1026 
1027  mean /= (double) cou ;
1028 
1029  // calculate the ripple
1030  for(t=TPX_USE_DATA;t<(TPX_USE_DATA+8);t++) {
1031  ripple[t-TPX_USE_DATA] = smoother[t] - mean ;
1032  }
1033 
1034  // special tweak!
1035  smoother[TPX_START_OF_RIPPLE] -= ripple[2] * 0.6 ;
1036 
1037  //apply ripple correction
1038  for(t=TPX_START_CORRECTION;t<512;t+=8) {
1039  for(int i=0;i<8;i++) {
1040  if((t+i)>434) continue ; // skip
1041  smoother[t+i] -= ripple[i] ;
1042  }
1043  }
1044 
1045 
1046  // finally, we need to round off correctly!
1047  for(t=0;t<512;t++) {
1048  ped->ped[t] = (double) ((u_short) (smoother[t]+0.5)) ;
1049  if(mode==1) { // new in May2023, kills GG pickup
1050  if(t>=18 && t<=20) {
1051  ped->ped[t] = 1023.0 ;
1052  }
1053  }
1054  else if(mode==2) { // slight increase
1055  if(t>=18 && t<=20) {
1056  ped->ped[t] += 5.0 ;
1057  if(ped->ped[t]>1023.0) ped->ped[t] = 1023.0 ;
1058  }
1059 
1060  }
1061  }
1062 
1063 
1064 
1065 
1066  }
1067  }
1068  }
1069 
1070  LOG(TERR,"Pedestals smoothed: sector %2d, mode %d",sector,mode) ;
1071  smoothed = 1 ;
1072 
1073  return ;
1074 }
1075 
1076 
1077 int tpxPed::kill_bad(int r0_logical,int row, int pad)
1078 {
1079  struct peds *p ;
1080 
1081  p = get(r0_logical,row, pad) ;
1082  if(p==0) return 0 ;
1083 
1084  for(int t=0;t<512;t++) {
1085  p->ped[t] = 1023.0 ;
1086  p->rms[t] = 9.999 ;
1087  }
1088 
1089  return 1 ;
1090 }
1091 
1092 
Definition: rb.hh:21