StRoot  1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
tpc23_base.cxx
1 #include <sys/types.h>
2 #include <stdio.h>
3 #include <stdlib.h>
4 #include <errno.h>
5 #include <string.h>
6 #include <math.h>
7 
8 #include <rtsLog.h>
9 
10 #include <rtsSystems.h>
11 #include <DAQ_READER/daqReader.h>
12 #include <DAQ_READER/daq_dta.h>
13 #include <DAQ_READER/daq_det.h>
14 
15 #include <DAQ_TPX/daq_tpx.h>
16 #include <DAQ_TPX/tpxFCF_flags.h>
17 #include <DAQ_TPX/tpxPed.h>
18 
19 #include <DAQ_ITPC/daq_itpc.h>
20 #include <DAQ_ITPC/itpcFCF.h>
21 #include <DAQ_ITPC/itpcPed.h>
22 
23 
24 //#define DBG_PRINT 1
25 
26 #include "tpc23_base.h"
27 
28 
29 //tpc23_base::row_pad_t (*tpc23_base::rp_gain)[ROW_MAX+1][PAD_MAX+1] ;
30 
31 //tpc23_base::row_pad_t (*tpc23_base::rp_gain_tpx)[ROW_MAX+1][PAD_MAX+1] ;
32 //tpc23_base::row_pad_t (*tpc23_base::rp_gain_itpc)[ROW_MAX+1][PAD_MAX+1] ;
33 
34 short tpc23_base::bad_fee_cou[24][46] ;
35 short tpc23_base::bad_fee[24][46][36] ;
36 
37 //int tpc23_base::rowlen[ROW_MAX+1] ;
38 //int tpc23_base::row_min ;
39 //int tpc23_base::row_max ;
40 
41 itpcData *tpc23_base::data_c ;
42 
43 //tpxPed *tpc23_base::peds ;
44 //pthread_mutex_t tpc23_base::peds_mutex ;
45 
46 int tpc23_base::fcf_decode(u_int *p_buff, daq_sim_cld_x *dc, u_int version)
47 {
48  daq_cld cld ;
49  int words_used ;
50  itpc_fcf_c *old_fcf ;
51 
52  words_used = old_fcf->fcf_decode(p_buff,&cld,version) ;
53 
54  memcpy(&dc->cld,&cld,sizeof(cld)) ;
55 
56  p_buff += words_used ;
57 
58  dc->track_id = 0 ;
59  dc->quality = (*p_buff)>>16;
60 
61  p_buff++ ;
62 
63  dc->max_adc = *p_buff & 0xFFFF ;
64  dc->pixels = (*p_buff)>>16 ;
65 
66  p_buff++ ;
67 
68  dc->reserved[0] = *p_buff ; // NOTE: this is where the extended 32 bit track ID is
69  dc->track_id = dc->reserved[0]&0xFFFF ; // but use the lower 16 bits...
70 
71  p_buff++ ;
72 
73  return words_used + 3 ;
74 }
75 
76 void tpc23_base::sim_evt_start(int sec1)
77 {
78  sector1 = sec1 ;
79 
80  if(s1_dta==0) {
81  s1_dta = (u_short *) malloc((ROW_MAX+1)*(PAD_MAX+1)*512*sizeof(*s1)) ;
82  }
83  if(s1_track_id==0) {
84  s1_track_id = (int *) malloc((ROW_MAX+1)*(PAD_MAX+1)*512*sizeof(*s1_track_id)) ;
85  }
86  if(store_track_id==0) {
87  store_track_id = (int *) malloc((PAD_MAX+1)*512*sizeof(*store_track_id)) ;
88  }
89 
90  sequence_cou = 0 ;
91  err = 0 ;
92  last_ix = 0 ;
93 
94  evt++ ;
95  evt_trgd++ ;
96 }
97 
98 
99 int tpc23_base::do_ch_sim(int row, int pad, u_short *adc, int *track_id)
100 {
101  int t_start = -1 ;
102 
103  struct seq_t *seq = s1[row][pad].seq ;
104 
105  int s_cou = 0 ;
106  int dta_p_ix = 0 ;
107 
108  s1[row][pad].ix = last_ix ;
109 
110  u_short *dta = s1_dta + last_ix ; // where I store the data
111  int *track = s1_track_id + last_ix ; // and corresponding track_id
112 
113 #if 1
114  // SAMPA allows up to 2 zeros in a row so let's emulate it
115  for(int t=1;t<510;t++) {
116  if(adc[t-1]!=0 && adc[t]==0 && adc[t+1]!=0) {
117  adc[t] = 0xFFFF ;
118  }
119  else if(adc[t-1]!=0 && adc[t]==0 && adc[t+1]==0 && adc[t+2]!=0) {
120  adc[t] = 0xFFFF ;
121  adc[t+1] = 0xFFFF ;
122  t += 1 ;
123  }
124 
125  }
126 #endif
127 
128  int t_err = 0 ;
129 
130  for(int t=0;t<512;t++) {
131  if(adc[t]) {
132  if(t_start<0) {
133  // starting
134  seq[s_cou].t_lo = t ;
135  seq[s_cou].dta_p = dta_p_ix ;
136  seq[s_cou].blob_id = 0 ; // clear it here
137 
138  t_start = t ;
139  }
140 
141  if(adc[t]==0xFFFF) {
142  //adc[t] = 0 ;
143  dta[dta_p_ix] = 0 ;
144  }
145  else {
146  dta[dta_p_ix] = adc[t] ;
147  }
148  track[dta_p_ix] = track_id[t] ;
149 
150  dta_p_ix++ ;
151  }
152  else { // data is now 0
153  if(t_start>=0) { // started!
154  // so stop it
155  seq[s_cou].t_hi = t-1 ;
156 
157  if(t<=0) {
158  LOG(ERR,"rp %d:%d t is %d, t_start is %d",row,pad,t,t_start) ;
159  t_err = 1 ;
160  }
161 
162  s_cou++ ;
163 
164  t_start = -1 ;
165 
166  if(s_cou>=SEQ_MAX) {
167  LOG(WARN,"too many sequences %d: sec %d, row %d, pad %d, tb %d",s_cou,sector1,row,pad,t-1) ;
168  goto done ;
169  }
170  }
171  }
172  }
173 
174  if(t_err) {
175  for(int t=0;t<511;t++) {
176  LOG(TERR," tb %3d %d",t,adc[t]) ;
177  }
178  }
179 
180  if(t_start>=0) { // a sequence started but was never finished before the timebins ran out
181  // stop it
182  seq[s_cou].t_hi = 511 ;
183  s_cou++ ;
184  }
185 
186  if(s_cou>=SEQ_MAX) {
187  LOG(ERR,"still too many sequences %d: sec %d, row %d, pad %d",s_cou,sector1,row,pad) ;
188  }
189 
190  done:;
191 
192  sequence_cou += s_cou ;
193 
194  seq[s_cou].t_hi = -1 ; // sentinel
195 
196  last_ix += dta_p_ix ;
197 
198  return 0 ;
199 }
200 
201 #if 0
202 void tpc23_base::sim_do_pad(int row, int pad, short *adc, int *track_id)
203 {
204  int t_start = -1 ;
205 
206  struct seq_t *seq = s1[row][pad].seq ;
207 
208  int s_cou = 0 ;
209  int dta_p_ix = 0 ;
210 
211  s1[row][pad].ix = last_ix ;
212 
213  u_short *dta = s1_dta + last_ix ; // where I store the data
214  int *track = s1_track_id + last_ix ; // and corresponding track_id
215 
216  for(int t=0;t<512;t++) {
217  if(adc[t]) {
218  if(t_start<0) {
219  // starting
220  seq[s_cou].t_lo = t ;
221  seq[s_cou].dta_p = dta_p_ix ;
222  seq[s_cou].blob_id = 0 ; // clear it here
223 
224  t_start = t ;
225  }
226  dta[dta_p_ix] = adc[t] ;
227  track[dta_p_ix] = track_id[t] ;
228  dta_p_ix++ ;
229  }
230  else { // data is now 0
231  if(t_start>=0) { // started!
232  // so stop it
233  seq[s_cou].t_hi = t-1 ;
234 
235  if(t<=1) {
236  LOG(ERR,"t is %d, t_start is %d",t,t_start) ;
237  }
238 
239  s_cou++ ;
240 
241  t_start = -1 ;
242 
243  if(s_cou>=SEQ_MAX) {
244  LOG(WARN,"too many sequences %d: sec %d, row %d, pad %d, tb %d",s_cou,sector1,row,pad,t-1) ;
245  goto done ;
246  }
247  }
248  }
249  }
250 
251  if(t_start>=0) { // a sequence started but was never finished before the timebins ran out
252  // stop it
253  seq[s_cou].t_hi = 511 ;
254  s_cou++ ;
255  }
256 
257  if(s_cou>=SEQ_MAX) {
258  LOG(ERR,"still too many sequences %d: sec %d, row %d, pad %d",s_cou,sector1,row,pad) ;
259  }
260 
261  done:;
262 
263  sequence_cou += s_cou ;
264 
265  seq[s_cou].t_hi = -1 ; // sentinel
266 
267  last_ix += dta_p_ix ;
268 
269 }
270 #endif
271 
272 
273 int tpc23_base::row_stage2(int row)
274 {
275  int blob_good = 0 ;
276 #ifdef DBG_PRINT
277  printf("ROW %2d: STAGE2: BLOBS: blob_cou %d\n",row,blob_cou-1) ; fflush(stdout) ;
278 #endif
279  u_int *s2_marker = s2_dta ;
280 
281 
282  // I can preapply some cuts here already
283 
284  for(int i=1;i<blob_cou;i++) {
285 
286  // apply morphological cuts too
287  int t_len = blob[i].t2-blob[i].t1+1 ;
288 
289  if(t_len<=1) blob[i].flags |= FCF_BROKEN_EDGE ; // lenght in time is 2 or less
290 
291  // to match older itpcFCF
292  if(t_len<=3) blob[i].flags |= FCF_BROKEN_EDGE ; // lenght in time is 2 or less
293 
294 
295  if(blob[i].area<=4) blob[i].flags |= FCF_BROKEN_EDGE ; // pixel count is 4 or less
296 
297 
298 #ifdef DBG_PRINT
299  printf("blob %2d(%2d): pad %d:%d, tb %d:%d, flags 0x%X, area %d\n",i,blob_ix[i],
300  blob[i].p1,blob[i].p2,
301  blob[i].t1,blob[i].t2,
302  blob[i].flags,
303  blob[i].area) ;
304 #endif
305  if(log_level>=2) {
306  LOG(TERR,"blob %2d: pad %d:%d, tb %d:%d, flags 0x%X, area %d",i,
307  blob[i].p1,blob[i].p2,
308  blob[i].t1,blob[i].t2,
309  blob[i].flags,
310  blob[i].area) ;
311 
312 
313  }
314 
315 // if(blob[i].flags) continue ;
316  if(blob[i].flags&FCF_BROKEN_EDGE) continue ;
317 
318  blob_good++ ;
319  }
320 
321  if(log_level>=1) LOG(TERR,"ROW %2d: STAGE2: BLOBS: blob_cou %d/%d",row,blob_good,blob_cou) ;
322 
323  // and now loop over blobs, extract data
324  for(int i=1;i<blob_cou;i++) {
325  if(blob[i].flags & FCF_BROKEN_EDGE) continue ; // skip SMALL clusters!
326  if(blob[i].flags & 0x80) continue ;
327 
328 
329 
330 #ifdef DBG_PRINT
331  printf("BLOB %d(%d)/%d: row %2d:\n",i,i,blob_cou,row) ;
332  printf(" pad %d:%d, tb %d:%d\n",blob[i].p1,blob[i].p2,blob[i].t1,blob[i].t2) ;
333 #endif
334 
335  int td = blob[i].t2 - blob[i].t1 + 1 ;
336  int pd = blob[i].p2 - blob[i].p1 + 1 ;
337 
338  for(int pad=blob[i].p1;pad<=blob[i].p2;pad++) {
339  struct seq_t *seq = s1[row][pad].seq ;
340 
341  if(log_level>=2) {
342  LOG(TERR,"blob %d: pad %d, t_hi %d; ix %d",i,pad,seq->t_hi,s1[row][pad].ix) ;
343  }
344 
345  if(seq->t_hi==-1) continue ;
346 
347  u_short *d = s1_dta + s1[row][pad].ix ;
348 
349 
350 
351  int px = pad - blob[i].p1 ;
352 
353  memset(store[px],0,td*sizeof(store[px][0])) ;
354 
355  while(seq->t_hi>=0) {
356  int j ;
357 
358  {
359  int bid = blob_ix[seq->blob_id] ;
360 
361 
362  if(log_level>=2) {
363  LOG(TERR," i %d, bid %d, blob_id %d",i,bid,seq->blob_id) ;
364  }
365 
366  if(bid!=i) { // we want only data which comes from the blob I am looking for!
367  seq++ ;
368  continue ;
369  }
370  }
371 
372 
373 
374  j=0 ;
375  for(int t=seq->t_lo;t<=seq->t_hi;t++) {
376  u_short dta = *(d+seq->dta_p+j) ;
377 #ifdef DBG_PRINT
378  printf(" pad %3d, tb %3d, adc %3d %5u\n",pad,t,dta,dta) ;
379 #endif
380  int tx = t - blob[i].t1 ;
381 
382  store[px][tx] = dta ;
383 
384  j++ ;
385  }
386 
387 #ifdef DBG_PRINT
388 // LOG(TERR,"here: online %d, RP%d:%d, %d:%d",online,row,pad,seq->t_lo,seq->t_hi) ;
389 #endif
390  if(online==0) { // also store track_ids in parallel
391  int *d_track_id = s1_track_id + s1[row][pad].ix ;
392 
393  j=0 ;
394  for(int t=seq->t_lo;t<=seq->t_hi;t++) {
395  int (*tr)[512] ;
396 
397  tr = (int (*)[512]) store_track_id ;
398 
399  int dta = *(d_track_id+seq->dta_p+j) ;
400 
401  int tx = t - blob[i].t1 ;
402 
403  tr[px][tx] = dta ;
404  j++ ;
405  }
406  }
407 
408 
409 #ifdef DBG_PRINT
410 // LOG(TERR,"here") ;
411 #endif
412 
413  seq++ ;
414  }
415  }
416 
417 
418 #ifdef DBG_PRINT
419  printf("Here: %d %d\n",pd,td) ; fflush(stdout) ;
420 #endif
421 
422  if(log_level>=2) LOG(TERR," pd %d, td %d",pd,td) ;
423 
424  for(int p=0;p<pd;p++) {
425  for(int t=0;t<td;t++) {
426 
427  int sum ;
428 
429  sum = store[p][t] ;
430 
431  if(sum <= 10) { // a peak can't have less than that ADC counts
432  // so skip the 3x3 sum to save time
433  sum = 0 ;
434  goto store ;
435  }
436 
437  //sum = 0 ; // if I leave this out I will have an additional count of the middle ADC...
438 
439  for(int ip=-1;ip<=1;ip++) {
440  for(int it=-1;it<=1;it++) {
441  int d1 = 0 ;
442  int adc ;
443 
444  int iii = ip * it ;
445  if(iii==1 || iii==-1) continue ; // skip corners ala itpcFCF
446 
447  // check for blob bounds
448  if((p+ip)<0) d1 = 1 ;
449  if((p+ip)>=pd) d1 = 1 ;
450  if((t+it)<0) d1 = 1 ;
451  if((t+it)>=td) d1 = 1 ;
452 
453  if(d1) adc = 0 ;
454  else adc = store[p+ip][t+it] ;
455 
456  sum += adc ;
457 
458  }
459  }
460 
461  store: ;
462 
463  smooth[p][t] = sum ;
464 
465  }
466  }
467 
468 #ifdef DBG_PRINT
469  printf("Here 1: %d %d\n",pd,td) ; fflush(stdout) ;
470 #endif
471 
472  // and now find peaks using smoothed data
473  peaks_cou = 0 ;
474 
475  if(log_level>=2) LOG(TERR," here %d %d",pd,td) ;
476 
477  for(int p=0;p<pd;p++) {
478  for(int t=0;t<td;t++) {
479  // a peak has to be at least this much above any of the surrounding 8 pixels
480  int adc = smooth[p][t] - 5 ; // I should put this constant out
481 
482  if(adc < 1) continue ;
483 
484  for(int ip=-1;ip<=1;ip++) {
485  if((p+ip)<0) continue ;
486  if((p+ip)>=pd) continue ;
487 
488  for(int it=-1;it<=1;it++) {
489  if((t+it)<0) continue ;
490  if((t+it)>=td) continue ;
491 
492  if(ip==0 && it==0) continue ;
493 
494 
495 
496 
497  int s_adc = smooth[p+ip][t+it] ;
498 
499  //printf("peak %d,%d: %d,%d --> mid %d < %d -- skips\n",p,t,ip,it,adc,s_adc) ;
500 
501  if(adc < s_adc) goto skip_calc ;
502  if(s_adc < 0) goto skip_calc ;
503 
504  }
505  }
506 
507  // we have a peak here!!!
508  peaks[peaks_cou].t = t ;
509  peaks[peaks_cou].p = p ;
510  peaks_cou++ ;
511 
512  smooth[p][t] = -adc ; // mark as used
513 
514  t += 5 ; // skip some timebins so I don't have close peaks
515  // should put this as a parameter too!
516 
517  skip_calc: ;
518  }
519 
520 
521  }
522 
523 #ifdef DBG_PRINT
524  printf("Here 2: %d %d\n",pd,td) ; fflush(stdout) ;
525 #endif
526 
527 #ifdef DBG_PRINT
528  printf("PEAKS %d\n",peaks_cou) ;
529 
530  printf("PAD : ") ;
531  for(int p=0;p<pd;p++) {
532  printf("%3d ",blob[i].p1+p) ;
533  }
534  printf("\n") ;
535  for(int t=0;t<td;t++) {
536  printf("TB %3d: ",blob[i].t1+t) ;
537  for(int p=0;p<pd;p++) {
538  int pk = 0 ;
539  for(int j=0;j<peaks_cou;j++) {
540  if(peaks[j].p == p && peaks[j].t==t) pk = 1 ;
541  }
542 
543  printf("%3d[%4d]%c ",store[p][t],smooth[p][t],pk?'*':' ') ;
544  }
545  printf("\n") ;
546  }
547  fflush(stdout) ;
548 #endif
549  // and now rip am out
550  int one_peak = 0 ;
551  if(peaks_cou<=1) one_peak = 1 ;
552 
553 
554  if(log_level>=2) LOG(TERR,"row %d: blob %d: flags 0x%X: peaks_cou %d, one_peak %d",row,i,blob[i].flags,peaks_cou,one_peak) ;
555 
556  //if(blob[i].flags & 1) one_peak = 0 ;
557 
558 #ifdef DBG_PRINT
559  printf("Here: %d %d: onepeak %d\n",pd,td,one_peak) ; fflush(stdout) ;
560 #endif
561 
562 // if(peaks_cou<=1) { // not that it could have been 0 in some patho cases
563  if(one_peak) { // not that it could have been 0 in some patho cases
564  double f_charge = 0.0 ;
565  double f_t_ave = 0.0 ;
566  double f_p_ave = 0.0 ;
567  u_short flags = blob[i].flags ;
568 
569  if(log_level>=2) LOG(TERR," flags again %d: %d %d",flags,pd,td) ;
570 
571  if(flags) goto done_peaks ; // under all circumstances
572 
573  for(int p=0;p<pd;p++) {
574  int pad = blob[i].p1+p ;
575  double gain = rp_gain[sector1-1][row][pad].gain ;
576  double t0 = rp_gain[sector1-1][row][pad].t0 ;
577  int i_charge = 0 ;
578  int i_t_ave = 0 ;
579 
580  if(log_level>=2) LOG(TERR," gain %d %d %d %f",sector1,row,pad,gain) ;
581 #ifdef DBG_PRINT
582  printf("... gain %d %d %d = %f\n",sector1,row,pad,gain) ;
583  fflush(stdout) ;
584 #endif
585  for(int t=0;t<td;t++) {
586  int adc = store[p][t] ;
587 
588  i_charge += adc ;
589  i_t_ave += t * adc ;
590  }
591 
592  if(i_charge==0) continue ;
593 
594  double corr_charge = (double)i_charge * gain ;
595 
596  f_charge += corr_charge ;
597  f_t_ave += i_t_ave * gain + t0 * corr_charge ;
598  f_p_ave += p * corr_charge ;
599 
600  }
601 
602  if(log_level>=2) LOG(TERR," here %f",f_charge) ;
603 
604  if(f_charge<0.1) goto done_peaks ;
605 
606 
607  if(online==0) { // craft stuff for the simulation
608  int (*tr)[512] ;
609  tr = (int (*)[512]) store_track_id ;
610 
611  sim_max_adc = 0 ;
612  int max_p = 0 ;
613  int max_t = 0 ;
614 
615  for(int p=0;p<pd;p++) {
616  for(int t=0;t<td;t++) {
617  if(store[p][t] > sim_max_adc) {
618  sim_max_adc = store[p][t] ;
619  max_p = p ;
620  max_t = t ;
621  }
622  }
623  }
624 
625  sim_track_id = tr[max_p][max_t] ;
626 
627  int sim_all = 0 ;
628  sim_quality = 0 ;
629  for(int p=0;p<pd;p++) {
630  for(int t=0;t<td;t++) {
631  if(tr[p][t]==sim_track_id) {
632  sim_quality++ ;
633  }
634  if(store[p][t]) sim_all++ ;
635  }
636  }
637 
638  if(sim_all != 0) {
639  float yada = (float)sim_quality/(float)sim_all ;
640  yada = (100.0 * yada) + 0.5 ;
641  sim_quality = (int) yada ;
642  }
643 
644  }
645 
646 
647  f_t_ave /= f_charge ;
648  f_p_ave /= f_charge ;
649 
650  f_p_ave += blob[i].p1 ;
651  f_t_ave += blob[i].t1 ;
652 
653 #ifdef DBG_PRINT
654 // printf("CLD2 row %2d, p_ave %.3f %d %d, t_ave %.3f %d %d, charge %.1f, flags 0x%02X\n",
655 // row, f_p_ave,blob[i].p1,blob[i].p2,
656 // f_t_ave,blob[i].t1,blob[i].t2,
657 // f_charge,blob[i].flags) ;
658 #endif
659  // and now packing for output
660  u_int time_c = (u_int)(f_t_ave*64.0+0.5) ;
661  u_int pad_c = (u_int)(f_p_ave*64.0+0.5) ;
662  u_int cha = (u_int)(f_charge+0.5) ;
663 
664  if(cha > 0x7FFF) cha = 0x8000 | (cha/1024) ;
665 
666 
667  u_int tmp_fl ;
668 
669  int p_lo = (pad_c/64) - blob[i].p1 ;
670  int p_hi = blob[i].p2 - (pad_c/64) ;
671 
672  if(p_lo<0) p_lo = 0 ;
673  if(p_hi<0) p_hi = 0 ;
674  if(p_lo>7) p_lo = 7 ;
675  if(p_hi>7) p_hi = 7 ;
676 
677  tmp_fl = (p_lo<<8)|(p_hi<<11) ;
678 
679  int t_lo = (time_c/64) - blob[i].t1 ;
680  int t_hi = blob[i].t2 - (time_c/64) ;
681 
682 
683  if(t_lo<0) t_lo = 0 ;
684  if(t_hi<0) t_hi = 0 ;
685  if(t_lo>7) t_lo = 15 ;
686  if(t_hi>7) t_hi = 15 ;
687 
688  tmp_fl |= (t_hi<<4)|t_lo ;
689 
690  if(flags & FCF_MERGED) pad_c |= 0x8000 ;
691  if(flags & FCF_DEAD_EDGE) pad_c |= 0x4000 ;
692 
693  if(flags & FCF_ONEPAD) time_c |= 0x8000 ;
694 
695  if(flags & FCF_ROW_EDGE) tmp_fl |= 0x8000 ;
696  if(flags & FCF_BROKEN_EDGE) tmp_fl |= 0x4000 ;
697 
698 
699  *s2_dta++ = (time_c<<16)|pad_c ;
700  *s2_dta++ = (cha<<16)|tmp_fl ;
701 
702  if(online==0) { //simulation!
703  *s2_dta++ = sim_quality<<16 ; // quality
704  *s2_dta++ = (blob[i].area<<16)|sim_max_adc ; // pixels|max_adc
705  *s2_dta++ = sim_track_id ; // track id
706  }
707 
708 
709 #ifdef DBG_PRINT
710 
711  // and decode...
712 
713  double ppp = (double)(pad_c & 0x3FFF)/64.0 ;
714  double ttt = (double)(time_c & 0x7FFF)/64.0 ;
715 
716  printf("CLD3 row %2d, p_ave %f %d %d, t_ave %f %d %d, charge %d, flags 0x%02X\n",
717  row, ppp,blob[i].p1,blob[i].p2,
718  ttt,blob[i].t1,blob[i].t2,
719  cha,blob[i].flags) ;
720  fflush(stdout) ;
721 #endif
722 
723  if(log_level>=2) {
724  double ppp = (double)(pad_c & 0x3FFF)/64.0 ;
725  double ttt = (double)(time_c & 0x7FFF)/64.0 ;
726 
727  LOG(TERR,"CLD3 row %2d, p_ave %f %d %d, t_ave %f %d %d, charge %d, flags 0x%02X",
728  row, ppp,blob[i].p1,blob[i].p2,
729  ttt,blob[i].t1,blob[i].t2,
730  cha,flags) ;
731 
732  }
733 
734  }
735  else {
736  for(int pk=0;pk<peaks_cou;pk++) {
737  double f_charge = 0.0 ;
738  double f_t_ave = 0.0 ;
739  double f_p_ave = 0.0 ;
740  u_short flags = blob[i].flags ;
741 
742  flags |= FCF_MERGED ;
743 
744  int ip1, ip2 ;
745  int it1, it2 ;
746 
747  ip1 = peaks[pk].p - 1 ;
748  if(ip1<0) ip1 = 0 ;
749  ip2 = peaks[pk].p + 1;
750  if(ip2>=pd) ip2 = pd-1 ;
751 
752  it1 = peaks[pk].t - 2 ;
753  if(it1<0) it1 = 0 ;
754  it2 = peaks[pk].t + 2;
755  if(it2>=td) it2 = td-1 ;
756 
757  for(int p=ip1;p<=ip2;p++) {
758  int pad = blob[i].p1 + p ;
759 
760  double gain = rp_gain[sector1-1][row][pad].gain ;
761  double t0 = rp_gain[sector1-1][row][pad].t0 ;
762 
763 
764  u_int i_charge = 0 ;
765  u_int i_t_ave = 0 ;
766 
767  for(int t=it1;t<=it2;t++) {
768  int adc = store[p][t] ;
769 
770  i_charge += adc ;
771  i_t_ave += t*adc ;
772  }
773 
774  if(i_charge==0) continue ;
775 
776  double corr_charge = (double)i_charge * gain ;
777 
778  f_charge += corr_charge ;
779  f_t_ave += i_t_ave * gain + t0 * corr_charge ;
780  f_p_ave += p * corr_charge ;
781  }
782 
783  if(f_charge<0.1) continue ;
784 
785 
786 
787 
788  f_t_ave /= f_charge ;
789  f_p_ave /= f_charge ;
790 
791  f_p_ave += blob[i].p1 ;
792  f_t_ave += blob[i].t1 ;
793 
794  int p_lo = blob[i].p1 + peaks[pk].p-1 ;
795  int p_hi = blob[i].p1 + peaks[pk].p+1 ;
796 
797  int t_lo = blob[i].t1 + peaks[pk].t-2 ;
798  int t_hi = blob[i].t1 + peaks[pk].t+2 ;
799 
800 
801 #ifdef DBG_PRINT
802 // printf("CLD2 row %2d, p_ave %.3f %d %d, t_ave %.3f %d %d, charge %.1f, flags 0x%02X\n",
803 // row, f_p_ave,p_lo,p_hi,
804 // f_t_ave,t_lo,t_hi,
805 // f_charge,flags) ;
806 #endif
807 
808  // and now packing for output
809  u_int time_c = (u_int)(f_t_ave*64.0+0.5) ;
810  u_int pad_c = (u_int)(f_p_ave*64.0+0.5) ;
811  u_int cha = (u_int)(f_charge+0.5) ;
812 
813  if(cha > 0x7FFF) cha = 0x8000 | (cha/1024) ;
814 
815  u_int tmp_fl ;
816 
817  p_lo = 1 ;
818  p_hi = 1 ;
819 
820  if(p_lo<0) p_lo = 0 ;
821  if(p_hi<0) p_hi = 0 ;
822  if(p_lo>7) p_lo = 7 ;
823  if(p_hi>7) p_hi = 7 ;
824 
825  tmp_fl = (p_lo<<8)|(p_hi<<11) ;
826 
827  t_lo = 2 ;
828  t_hi = 2 ;
829 
830 
831  if(t_lo<0) t_lo = 0 ;
832  if(t_hi<0) t_hi = 0 ;
833  if(t_lo>7) t_lo = 15 ;
834  if(t_hi>7) t_hi = 15 ;
835 
836  tmp_fl |= (t_hi<<4)|t_lo ;
837 
838 
839 
840  if(flags & FCF_MERGED) pad_c |= 0x8000 ;
841  if(flags & FCF_DEAD_EDGE) pad_c |= 0x4000 ;
842 
843  if(flags & FCF_ONEPAD) time_c |= 0x8000 ;
844 
845  if(flags & FCF_ROW_EDGE) tmp_fl |= 0x8000 ;
846  if(flags & FCF_BROKEN_EDGE) tmp_fl |= 0x4000 ;
847 
848 
849  *s2_dta++ = (time_c<<16)|pad_c ;
850  *s2_dta++ = (cha<<16)|tmp_fl ;
851 
852  if(online==0) { //simulation!
853  int (*tr)[512] ;
854 
855  tr = (int (*)[512]) store_track_id ;
856 
857  sim_max_adc = 0 ;
858 
859  for(int p=ip1;p<=ip2;p++) {
860  for(int t=it1;t<=it2;t++) {
861  int adc = store[p][t] ;
862 
863  if(adc > sim_max_adc) {
864  sim_max_adc = adc ;
865  sim_track_id = tr[p][t] ;
866  }
867  }
868  }
869 
870  int sim_all = 0 ;
871  sim_quality = 0 ;
872  for(int p=ip1;p<=ip2;p++) {
873  for(int t=it1;t<=it2;t++) {
874  if(tr[p][t]==sim_track_id) {
875  sim_quality++ ;
876  }
877  if(store[p][t]) sim_all++ ;
878  }
879  }
880 
881  if(sim_all != 0) {
882  float yada = (float)sim_quality/(float)sim_all ;
883  yada = (100.0 * yada) + 0.5 ;
884  sim_quality = (int) yada ;
885  }
886 
887 
888  *s2_dta++ = sim_quality<<16 ; // quality
889  *s2_dta++ = (15<<16)|sim_max_adc ; // pixels(always 15)|max_adc
890  *s2_dta++ = sim_track_id ; // track id
891  }
892 
893 #ifdef DBG_PRINT
894  double ppp = (double)(pad_c & 0x3FFF)/64.0 ;
895  double ttt = (double)(time_c & 0x7FFF)/64.0 ;
896 
897 
898 
899  printf("CLD3 row %2d, p_ave %f %d %d, t_ave %f %d %d, charge %d, flags 0x%02X\n",
900  row, ppp,p_lo,p_hi,
901  ttt,t_lo,t_hi,
902  cha,flags) ;
903 #endif
904  if(log_level>=2) {
905  double ppp = (double)(pad_c & 0x3FFF)/64.0 ;
906  double ttt = (double)(time_c & 0x7FFF)/64.0 ;
907 
908 
909 
910  LOG(TERR,"CLD3 row %2d, p_ave %f %d %d, t_ave %f %d %d, charge %d, flags 0x%02X",
911  row, ppp,peaks[pk].p,peaks[pk].p,
912  ttt,peaks[pk].t,peaks[pk].t,
913  cha,flags) ;
914 
915 
916  }
917 
918 
919  }
920 
921 
922  }
923 
924  done_peaks:;
925 #ifdef DBG_PRINT
926  printf("ROW %2d: done_peaks: good clusters %d\n",row,blob_good) ; fflush(stdout) ;
927 #endif
928 
929 
930  }
931 
932 #ifdef DBG_PRINT
933  printf("ROW %2d: STAGE2: good clusters %d\n",row,blob_good) ;
934  fflush(stdout) ;
935 #endif
936  return s2_dta-s2_marker ;
937 
938 }
939 
940 
941 // Where I create blobs with known extents...
942 int tpc23_base::row_stage1(int row)
943 {
944  int got_one = 0 ;
945  int p_max ;
946  int odd_errs = 0 ;
947 
948  blob_cou = 1 ;
949  int blob_merges = 0 ;
950 
951  p_max = rowlen[row] ; //r=1 --> r==14
952 #ifdef DBG_PRINT
953  printf("ROW %2d: STAGE1, rowlen %2d\n",row,p_max) ;
954 #endif
955 
956  for(int pad=1;pad<p_max;pad++) { // < is on purpose!!!
957  struct seq_t *seq_l ;
958 
959  //error_retry:;
960 
961  seq_l = s1[row][pad].seq ;
962 
963 #ifdef DBG_PRINT
964  printf(" pad %d: t_hi %d\n",pad,seq_l->t_hi) ;
965 #endif
966  if(seq_l->t_hi==-1) continue ; // no data ;
967 
968  while(seq_l->t_hi!=-1) {
969  u_int tl_hi = seq_l->t_hi ;
970  u_int tl_lo = seq_l->t_lo ;
971  int bl = seq_l->blob_id ;
972 
973  got_one++ ; // count sequences
974 #ifdef DBG_PRINT
975  printf(" left: pad %d: seq %d: t_lo %d, t_hi %d (bl %d)\n",pad,got_one,tl_lo,tl_hi,bl) ;
976 #endif
977  struct seq_t *seq_r = s1[row][pad+1].seq ;
978 
979  char flags = rp_gain[sector1-1][row][pad].flags ;
980  char flags_r = rp_gain[sector1-1][row][pad+1].flags ;
981 
982  flags |= flags_r ;
983 
984  while(seq_r->t_hi!=-1) {
985  u_int tr_hi = seq_r->t_hi ;
986  u_int tr_lo = seq_r->t_lo ;
987  int br = seq_r->blob_id ;
988 
989  if(tr_hi>=512 || tr_lo>=512) {
990  odd_errs++ ;
991  if(odd_errs<5) {
992  LOG(ERR,"S%d: tr_hi %d, tr_lo %d: row %d, pad %d",sector1,
993  tr_hi,tr_lo,row,pad+1) ;
994  }
995  seq_r->t_hi = -1 ;
996  continue ;
997  }
998 
999  //printf("tr_hi %d, tr_lo %d: row %d, pad %d\n", tr_hi,tr_lo,row,pad) ;
1000 
1001  int merge = 0 ;
1002 
1003  if(tl_lo > tr_hi) merge = 0 ;
1004  else if(tr_lo > tl_hi) merge = 0 ;
1005  else merge = 1 ;
1006 #ifdef DBG_PRINT
1007  printf(" right: pad %d: seq %d: t_lo %d, t_hi %d\n",pad+1,got_one,tr_lo,tr_hi) ;
1008 #endif
1009  if(merge) {
1010  //printf("merging: pad %d: %d[%d:%d] with %d[%d:%d]\n",pad,
1011  // bl,tl_lo,tl_hi,
1012  // br,tr_lo,tr_hi) ;
1013 
1014  if(bl==0 && br==0) { // USUAL: both sequences don't belong to a blob yet
1015  seq_l->blob_id = blob_cou ;
1016  seq_r->blob_id = blob_cou ;
1017  bl = blob_cou ;
1018 
1019  blob[blob_cou].p1 = pad ;
1020  blob[blob_cou].p2 = pad+1 ;
1021  blob[blob_cou].flags = flags ;
1022  blob[blob_cou].area = (tl_hi-tl_lo+1)+(tr_hi-tr_lo+1) ;
1023 
1024  blob_ix[blob_cou] = blob_cou ;
1025 
1026  if(tl_hi>tr_hi) blob[blob_cou].t2 = tl_hi ;
1027  else blob[blob_cou].t2 = tr_hi ;
1028 
1029  if(tl_lo<tr_lo) blob[blob_cou].t1 = tl_lo ;
1030  else blob[blob_cou].t1 = tr_lo ;
1031 #ifdef DBG_PRINT
1032  printf(" new blob %d: left %d:%d, right %d:%d \n",blob_cou,
1033  tl_lo,tl_hi,tr_lo,tr_hi) ;
1034 #endif
1035 
1036  blob_cou++ ; // and a new blob is created...
1037  }
1038  else if(bl==0 && br!=0) {
1039  // UNUSUAL: left sequence is not assigned to a blob but right is
1040  // move into right
1041  seq_l->blob_id = br ;
1042  bl = br ;
1043 
1044  if(blob[br].p1>pad) {
1045  //printf(" ERROR pad %d, p1 %d\n",pad,blob[br].p1) ;
1046  }
1047  // NOT!
1048  //blob[br].p1 = pad ;
1049 
1050  blob[br].flags |= flags ;
1051  blob[br].area += (tl_hi-tl_lo+1) ;
1052 
1053 #ifdef DBG_PRINT
1054  printf(" WARN: %d: left into right %d: pad in blob %d, pad %d\n",row,br,blob[br].p1,pad) ;
1055 
1056  printf(" left %d:%d, right %d:%d, blob %d:%d\n",tl_lo,tl_hi,
1057  tr_lo,tr_hi,
1058  blob[br].t1,blob[br].t2) ;
1059 #endif
1060 
1061  if(tl_hi>blob[br].t2) blob[br].t2 = tl_hi ;
1062  if(tl_lo<blob[br].t1) blob[br].t1 = tl_lo ;
1063 
1064  }
1065  else if(bl!=0 && br==0) {
1066  // USUAL: right sequence is not asigned -- move into left
1067  seq_r->blob_id = bl ;
1068 
1069  blob[bl].p2 = pad+1 ;
1070  blob[bl].flags |= flags ;
1071  blob[bl].area += (tr_hi-tr_lo+1) ;
1072 
1073  //printf(" right into left %d\n",bl) ;
1074 #ifdef DBG_PRINT
1075  printf(" merge left %d: left %d:%d, right %d:%d \n",blob_cou,
1076  tl_lo,tl_hi,tr_lo,tr_hi) ;
1077 #endif
1078 
1079  if(tr_hi>blob[bl].t2) blob[bl].t2 = tr_hi ;
1080  if(tr_lo<blob[bl].t1) blob[bl].t1 = tr_lo ;
1081 
1082  }
1083  else {
1084  if(bl==br) {
1085  blob[bl].area += (tr_hi-tr_lo+1) ;
1086 #ifdef DBG_PRINT
1087  printf(" WARN: %d: already %d: p2 %d, r_pad %d\n",row,bl,blob[br].p2,pad+1) ;
1088  //printf(" WARN: t1 %d vs %d, t2 %d vs %d\n",blob[bl].t1,tr_lo,blob[bl].t2,tr_hi) ;
1089 
1090 
1091  printf(" WARN: pad %d: left: %d:%d, right %d:%d\n",pad,
1092  blob[bl].p1,blob[bl].p2,
1093  blob[br].p1,blob[br].p2) ;
1094 
1095  printf(" WARN: tb %d:%d, left: %d:%d, right %d:%d\n",tr_lo,tr_hi,
1096  blob[bl].t1,blob[bl].t2,
1097  blob[br].t1,blob[br].t2) ;
1098 #endif
1099 
1100 
1101  blob[bl].p2 = pad+1 ;
1102  blob[bl].flags |= flags ;
1103 
1104 
1105  if(tr_hi>blob[bl].t2) blob[bl].t2 = tr_hi ;
1106  if(tr_lo<blob[bl].t1) blob[bl].t1 = tr_lo ;
1107 
1108 
1109 
1110  }
1111  else {
1112 #ifdef DBG_PRINT
1113  printf(" WARN: %d: blob left %d, blob right %d???\n",row,bl,br) ;
1114  printf(" WARN: pad %d: left: %d:%d, right %d:%d\n",pad,
1115  blob[bl].p1,blob[bl].p2,
1116  blob[br].p1,blob[br].p2) ;
1117 
1118  printf(" WARN: tb %d:%d, left: %d:%d, right %d:%d\n",tr_lo,tr_hi,
1119  blob[bl].t1,blob[bl].t2,
1120  blob[br].t1,blob[br].t2) ;
1121 #endif
1122 
1123  blob_merges++ ;
1124 
1125  //blob[bl].flags |= 1 ;
1126  //blob[br].flags |= 1 ;
1127 
1128  // merge into smaller index
1129 
1130  if(bl < br) {
1131 #ifdef DBG_PRINT
1132  printf("BLOB %d right -- killed, merged into left %d\n",br,bl) ;
1133 #endif
1134 
1135 
1136  // killing BR
1137  blob[br].flags |= 0x80 ;
1138 
1139  blob_ix[br] = blob_ix[bl] ;
1140  }
1141  else {
1142 #ifdef DBG_PRINT
1143  printf("BLOB %d left -- killed, merged into right %d\n",bl,br) ;
1144 #endif
1145  blob[bl].flags |= 0x80 ;
1146 
1147  blob_ix[bl] = blob_ix[br] ;
1148  }
1149 
1150 
1151  merge = 0 ; // chaos... don't merge or do anything...
1152  }
1153 
1154  }
1155 
1156 
1157  }
1158  else {
1159  //printf("merging-NOT: pad %d: [%d:%d] with [%d:%d]\n",pad,tl_lo,tl_hi,tr_lo,tr_hi) ;
1160  }
1161 
1162  seq_r++ ;
1163  if(merge==0) continue ;
1164 
1165  }
1166  // I need to sweep unasigned here
1167  seq_l++ ; // move to next sequence
1168  }
1169 
1170  }
1171 
1172 // error_retry:;
1173 
1174 #ifdef DBG_PRINT
1175  printf("ROW %2d: STAGE1: %d blobs, blob_merges %d\n",row,blob_cou-1,blob_merges) ;
1176 #endif
1177 
1178  if(blob_merges) {
1179  for(int i=0;i<blob_cou;i++) {
1180  int ix = blob_ix[i] ;
1181 
1182  if(ix==i) continue ;
1183 
1184  //merge i into ix
1185  if(blob[i].p1 < blob[ix].p1) blob[ix].p1 = blob[i].p1 ;
1186  if(blob[i].p2 > blob[ix].p2) blob[ix].p2 = blob[i].p2 ;
1187  if(blob[i].t1 < blob[ix].t1) blob[ix].t1 = blob[i].t1 ;
1188  if(blob[i].t2 > blob[ix].t2) blob[ix].t2 = blob[i].t2 ;
1189 
1190 
1191  }
1192  }
1193 
1194  return blob_cou ;
1195 }
1196 
1197 
1198 int tpc23_base::evt_stop()
1199 {
1200  int words = 0 ;
1201 
1202  s2_dta = s2_start ;
1203 
1204  // here I run stage2!
1205  if(log_level>=1) {
1206  LOG(TERR,"evt_stop: S%02d: had %d last_ix, %d sequences",sector1,last_ix,sequence_cou) ;
1207  LOG(TERR," token %d, run_type %d, rows %d:%d",token,run_type,row_min,row_max) ;
1208  }
1209 
1210  if((token<=0)||(token>=4096)) { // non-triggered events, at least for now...
1211  goto cleanup ;
1212  }
1213 
1214 
1215  if(run_type==1 || run_type==5 || no_cld) { // ped, pulser
1216  //peds_accum() ;
1217  goto cleanup ; // for now...
1218  }
1219 
1220 
1221 
1222  for(int row=row_min;row<=row_max;row++) {
1223  u_int *row_store = s2_dta ;
1224  int wds ;
1225 
1226  if((s2_dta-s2_start)>(s2_max_words-1000)) {
1227  LOG(ERR,"T %d: row %d: lots of CLD words %d vs %d, sequences %d -- skipping the rest",token,row,
1228  s2_dta-s2_start, s2_max_words-1000,
1229  sequence_cou) ;
1230 
1231  break ;
1232  }
1233 
1234  // slighly different formats: let's keep the compatibility with associated reader
1235  if(rts_id==ITPC_ID) {
1236  s2_dta += 3 ; // skip 3 words of row header
1237  }
1238  else {
1239  s2_dta += 2 ;
1240  }
1241 
1242  // where I form blobs
1243  row_stage1(row) ;
1244 
1245  // where I loop over blobs, extract data, smooth
1246  // and dump_out
1247  wds = row_stage2(row) ;
1248 
1249 
1250  if(log_level>=2) LOG(TERR,"row %d: words %d",row,wds) ;
1251 
1252  if(wds) {
1253  int words_per_cluster ;
1254 
1255  if(online) words_per_cluster = 2 ;
1256  else words_per_cluster = 5 ;
1257 
1258  if(rts_id==ITPC_ID) { // compatibility with the Reader
1259  row_store[0] = (words_per_cluster<<16)|row ; // words_per_cluster<<16 | row
1260  row_store[1] = 0x20220508 ; // version: yyyy,mm,dd
1261  row_store[2] = wds ; // words
1262  }
1263  else { // TPX is a little different
1264  row_store[0] = 0x20230000 | row ;
1265  row_store[1] = wds ; // hits
1266  }
1267  }
1268  else {
1269  if(rts_id==ITPC_ID) {
1270  s2_dta -= 3 ; // roll back
1271  }
1272  else {
1273  s2_dta -= 2 ;
1274  }
1275  }
1276 
1277  } // loop over rows
1278 
1279 
1280  // CLEANUP after the event!
1281  cleanup: ;
1282 
1283 // LOG(TERR,"Cleanup") ;
1284 
1285  if(s2_start) {
1286  words = s2_dta - s2_start ;
1287  if(log_level>=1) LOG(TERR,"T %d: %d CLD words",token,words) ;
1288  s2_dta = s2_start ; // return back
1289  s2_words = words ;
1290  }
1291  else {
1292  if(s2_dta) {
1293  LOG(ERR,"WTF: T %d: s2_dta???",token) ;
1294  }
1295  s2_words = 0 ;
1296  }
1297 
1298  for(int row=row_min;row<=row_max;row++) {
1299  int p_max = rowlen[row] ;
1300  for(int pad=1;pad<=p_max;pad++) {
1301  s1[row][pad].seq->t_hi = -1 ; ;
1302  }
1303  }
1304 
1305  return words ; // will return words of
1306 }
1307 
1308 
1309 
1310 int tpc23_base::evt_start()
1311 {
1312  if(online==0) {
1313  sim_evt_start(1) ;
1314  return 0 ;
1315  }
1316 
1317  err = 0 ;
1318  sequence_cou = 0 ;
1319  last_ix = 0 ; // important!
1320 
1321  evt++ ;
1322  evt_trgd++ ;
1323 
1324 // memset(&s1,0xFF,sizeof(s1)) ;
1325 
1326  return 0 ;
1327 }
1328 
1329 // Called at run-start
1330 int tpc23_base::run_start()
1331 {
1332  LOG(NOTE,"%d: run_start: detector %d",id,rts_id) ;
1333 
1334  if(s1_dta==0) {
1335  if(rts_id==ITPC_ID) { // ITPC
1336  s1_bytes = (ROW_MAX*PAD_MAX)*512*2 ;
1337 
1338  }
1339  else { // TPX
1340  s1_bytes = (ROW_MAX*PAD_MAX)*512*2 ;
1341  }
1342 
1343  if(online) LOG(INFO,"%d: allocing %d s1_bytes, s1_t %d, blobs %d",id,s1_bytes,sizeof(s1),sizeof(blob)) ;
1344 
1345  s1_dta = (u_short *) malloc(s1_bytes) ;
1346  }
1347 
1348  // must make sure I am clearing the various counters, pointers, etc
1349 // memset(&s1,0,sizeof(s1)) ;
1350  memset(&s1,0xFF,sizeof(s1)) ;
1351 
1352  evt = 0 ;
1353  evt_trgd = 0 ;
1354 
1355  run_errors = 0 ;
1356 // fee_errs = 0 ;
1357 
1358  memset(&f_stat,0,sizeof(f_stat)) ;
1359 
1360  return 0 ;
1361 
1362 }
1363 
1364 
1365 // Called at run-stop: generally dumps statistics
1366 int tpc23_base::run_stop()
1367 {
1368 // LOG(TERR,"%d: run_stop: %d/%d events, run_errors %d",id,evt_trgd,evt,run_errors) ;
1369 
1370  if(online || mode) {
1371  for(int i=0;i<10;i++) {
1372  f_stat.tm[i] /= f_stat.evt_cou ;
1373  }
1374 
1375  LOG(NOTE,"id %d: evts %d, means %f %f %f %f %f %f",id,f_stat.evt_cou,
1376  f_stat.tm[0],f_stat.tm[1],f_stat.tm[2],f_stat.tm[3],f_stat.tm[4],
1377  f_stat.tm[5]) ;
1378  }
1379 
1380  return 0 ;
1381 }
1382 
1383 
1384 tpc23_base::tpc23_base()
1385 {
1386  LOG(NOTE,"%s",__PRETTY_FUNCTION__) ;
1387 
1388  online = 0 ; // assume offline!
1389 
1390  s1_dta = 0 ;
1391  s1_track_id = 0 ;
1392  s1_bytes = 0 ;
1393 
1394  s2_start = 0 ;
1395  s2_dta = 0 ;
1396  s2_words = 0 ;
1397 
1398  no_cld = 0 ;
1399  mode = 0 ;
1400 
1401 // rp_gain_tpx = 0 ;
1402 // rp_gain_itpc = 0 ;
1403 
1404  rp_gain = 0 ;
1405 
1406 
1407 
1408  for(int f=0;f<SIM_FIFOS;f++) {
1409  for(int r=0;r<6;r++) {
1410  sim_dta[f].rb[r].mem = 0 ;
1411  }
1412  }
1413 
1414  log_level = 0 ;
1415 
1416  id = 0 ;
1417 
1418  run_type = 3 ; // physics default
1419 
1420  // for sanity
1421  fmt = 23 ; // new data
1422  rts_id = ITPC_ID ; // TPX
1423  sector1 = 1 ;
1424  rdo1 = 1 ;
1425  subdet_id = 1;
1426 
1427  data_c = 0 ;
1428 
1429  store_track_id = 0 ;
1430 
1431  token = 1 ; // for ease of simulation
1432 }
1433 
1434 tpc23_base::~tpc23_base()
1435 {
1436 // LOG(TERR,"%s",__PRETTY_FUNCTION__) ;
1437 
1438  if(s1_dta) free(s1_dta) ;
1439  if(s1_track_id) free(s1_track_id) ;
1440  if(s2_start) free(s2_start) ;
1441  if(store_track_id) free(store_track_id) ;
1442 
1443 // LOG(TERR,"des: %p %p",s1_dta,s2_start) ;
1444 
1445  for(int f=0;f<SIM_FIFOS;f++) {
1446  for(int r=0;r<6;r++) {
1447  if(sim_dta[f].rb[r].mem) {
1448  //LOG(TERR,"des: %d %d",f,r) ;
1449  free(sim_dta[f].rb[r].mem) ;
1450  }
1451  }
1452  }
1453 
1454  //LOG(TERR,"des: done") ;
1455 }
1456 
1457 
1458 int tpc23_base::rdo_scan(char *mem, int words)
1459 {
1460  LOG(ERR,"%s: can't be",__PRETTY_FUNCTION__) ;
1461 
1462  return -1 ;
1463 }
1464 
1465 int tpc23_base::from22to23(char *dta, int words) // rewrite the old FY22 raw data foramt to FY23
1466 {
1467  LOG(ERR,"%s: can't be",__PRETTY_FUNCTION__) ;
1468 
1469  return words ;
1470 
1471 }
1472 
1473 // statics
1474 
1475 //tpc23_base::row_pad_t tpc23_base::rp_gain[24][ROW_MAX+1][PAD_MAX+1] ; // max for both dets
1476 
1477 int tpc23_base::gains_from_cache(const char *fname)
1478 {
1479  int ret = 0 ;
1480 
1481 // LOG(TERR,"%s [%s;%p]",__PRETTY_FUNCTION__,fname,rp_gain) ;
1482 
1483  // set defaults, again
1484  for(int s=0;s<24;s++) {
1485  for(int r=0;r<=ROW_MAX;r++) {
1486  for(int p=0;p<=PAD_MAX;p++) {
1487  rp_gain[s][r][p].gain = 1.0 ;
1488  rp_gain[s][r][p].t0 = 0.0 ;
1489  rp_gain[s][r][p].flags = 0 ;
1490 
1491  }}}
1492 
1493  for(int s=0;s<24;s++) {
1494  for(int r=0;r<46;r++) {
1495  bad_fee_cou[s][r] = 0 ;
1496  }}
1497 
1498 
1499 
1500  if(strcasecmp(fname,"none")==0) {
1501  LOG(WARN,"Requesting no gain correction") ;
1502  return 0 ;
1503  }
1504 
1505  // load gains from cache
1506  if(fname==0) {
1507  if(rts_id==ITPC_ID) fname = "/RTS/conf/itpc/itpc_gains.txt" ;
1508  else fname = "/RTS/conf/tpx/tpx_gains.txt" ;
1509  }
1510 
1511  FILE *f = fopen(fname,"r") ;
1512  if(f) {
1513  // load stuff here....
1514  LOG(INFO,"gains_from_cache: opened %s",fname) ;
1515 
1516 
1517  while(!feof(f)) {
1518  int sec,rdo,port,ch,row,pad ;
1519  float g, t ;
1520  char buff[256] ;
1521  int ret ;
1522 
1523  if(fgets(buff,sizeof(buff),f)==0) continue ;
1524 
1525  if(buff[0]=='#') continue ;
1526 
1527  if(strlen(buff)<1) continue ;
1528 
1529 
1530  if(rts_id==ITPC_ID) {
1531  ret = sscanf(buff,"%d %d %d %d %d %d %f %f",&sec,&rdo,&port,&ch,&row,&pad,&g,&t) ;
1532  if(ret != 8) continue ;
1533 
1534  if(ch<0) { //kill FEE == NOT DONE YET!!!
1535  LOG(WARN,"S%02d:%d FEE #%d -- killed",sec,rdo,port) ;
1536 
1537  bad_fee[sec-1][rdo-1][bad_fee_cou[sec-1][rdo-1]] = port ;
1538  bad_fee_cou[sec-1][rdo-1]++ ;
1539  continue ;
1540  }
1541 
1542  }
1543  else {
1544  ret = sscanf(buff,"%d %d %d %f %f",&sec,&row,&pad,&g,&t) ;
1545  if(ret != 5) continue ;
1546 
1547  if(sec<0) { // kill FEE
1548  sec *= -1 ;
1549 
1550 
1551  LOG(WARN,"S%02d:%d FEE #%d -- killed",sec,row,pad) ;
1552 
1553  bad_fee[sec-1][row-1][bad_fee_cou[sec-1][row-1]] = pad ;
1554  bad_fee_cou[sec-1][row-1]++ ;
1555 
1556  continue ;
1557  }
1558 
1559  }
1560 
1561 #ifdef DBG_PRINT
1562  //printf("gain %d: row %d, row_max %d\n",rts_id,row,row_max) ;
1563 #endif
1564 
1565  if(row>row_max) continue ;
1566 
1567 #ifdef DBG_PRINT
1568  //printf("gain %d %d %d = %f %f\n",sec,row,pad,g,t) ;
1569 #endif
1570  int flags = rp_gain[sec-1][row][pad].flags ;
1571 
1572  if(log_level>0) {
1573  printf("gain %d %d %d = %f %f; %d\n",sec,row,pad,g,t,flags) ;
1574  }
1575 
1576  rp_gain[sec-1][row][pad].gain = g ;
1577  rp_gain[sec-1][row][pad].t0 = t ;
1578 
1579  if(g<0.01) {
1580  int p1 = pad - 1 ;
1581  int p2 = pad + 1 ;
1582 
1583  if(p1<1) p1 = 1 ;
1584  if(p2>rowlen[row]) p2 = rowlen[row] ;
1585 
1586 
1587  if(log_level>0) printf("dead edge row %d, pad %d %d %d: %d %d %d\n",row,pad,p1,p2,
1588  rp_gain[sec-1][row][pad].flags,
1589  rp_gain[sec-1][row][p1].flags,
1590  rp_gain[sec-1][row][p2].flags) ;
1591 
1592  rp_gain[sec-1][row][pad].flags |= FCF_DEAD_EDGE ;
1593  rp_gain[sec-1][row][p1].flags |= FCF_DEAD_EDGE ;
1594  rp_gain[sec-1][row][p2].flags |= FCF_DEAD_EDGE ;
1595 
1596  }
1597 
1598  }
1599 
1600  fclose(f) ;
1601  }
1602  else {
1603  ret = -1 ;
1604  LOG(ERR,"gains_from_cache: %s [%s]",fname,strerror(errno)) ;
1605  }
1606 
1607 
1608 
1609  // I need to put RDO edges in case of masked RDOs: iTPC
1610 
1611  // I need to put pad edges into flags: depends on detector
1612  for(int s=0;s<24;s++) {
1613  for(int r=1;r<=row_max;r++) {
1614 
1615 
1616 
1617 // SHOULD BE ENABLED
1618 #if 1
1619 
1620  int p_max ;
1621 
1622  rp_gain[s][r][1].flags |= FCF_ROW_EDGE ; // row edge
1623 
1624  if(rts_id==TPX_ID) {
1625  p_max = rowlen[r] ; // tpc_rowlen[r] ; //1-->14
1626  }
1627  else {
1628  p_max = rowlen[r] ; // itpc_rowlen[r] ;
1629  }
1630 
1631 
1632  rp_gain[s][r][p_max].flags |= FCF_ROW_EDGE ;
1633 
1634 // if(s==0) {
1635 // printf(".... gains: row %d, p_max %d\n",r,p_max) ;
1636 // }
1637 #endif
1638  }
1639  }
1640 
1641 
1642 
1643  return ret ;
1644 }
1645 
1646 
1647 tpc23_base::sim_dta_t tpc23_base::sim_dta[SIM_FIFOS] ;
1648 
1649 int tpc23_base::load_replay(const char *fname, int sec_soft)
1650 {
1651  daqReader *rdr = 0 ;
1652  int good = 0 ;
1653  int s_start ;
1654  int s_stop ;
1655  const char *det ;
1656  int fix = 0 ;
1657  int offset = 0 ;
1658  daq_tpx *daq_tpx = 0 ;
1659  daq_itpc *daq_itpc = 0 ;
1660 
1661  if(rts_id==ITPC_ID) {
1662  s_start = sec_soft ;
1663  s_stop = sec_soft ;
1664  det = "itpc" ;
1665 
1666  daq_itpc = new class daq_itpc ;
1667 
1668  }
1669  else {
1670  det = "tpx" ;
1671 
1672  if(sec_soft<=24) {
1673  s_start = sec_soft ;
1674  s_stop = sec_soft ;
1675  }
1676  else {
1677  s_start = (sec_soft-25)*2+1 ;
1678  s_stop = s_start + 1 ;
1679  }
1680 
1681  daq_tpx = new class daq_tpx ;
1682  }
1683 
1684 
1685  LOG(INFO,"Loading replay data from %s for sector %d[%d:%d], offset %d",fname,sec_soft,s_start,s_stop,offset) ;
1686 
1687 
1688  rdr = new daqReader((char *)fname) ;
1689 
1690 
1691  for(;;) {
1692 
1693  if(rdr->get(0,EVP_TYPE_ANY)) ;
1694  else break ;
1695 
1696  int got_one = 0 ;
1697 
1698  for(int s=s_start;s<=s_stop;s++) {
1699  daq_dta *dd = rdr->det(det)->get("raw",s) ;
1700 
1701  while(dd && dd->iterate()) {
1702  got_one = 1 ;
1703  rdo1 = dd->rdo ;
1704  sector1 = dd->sec ;
1705 
1706  int rix ;
1707 
1708  if(rts_id==ITPC_ID) {
1709  rix = rdo1 - 1 ;
1710  }
1711  else {
1712 
1713  if(sec_soft<=24) {
1714  rix = rdo1 - 3 ; // 3 goes to 0
1715  }
1716  else {
1717  if(rdo1<5) continue ;
1718 
1719  if(s==s_start) rix = rdo1 - 5 ;
1720  else rix = rdo1 - 5 + 2 ;
1721  }
1722  }
1723 
1724  int bytes = dd->ncontent ;
1725  char *c_addr = (char *) dd->Void ;
1726 
1727 
1728  LOG(TERR,"FIFO %d, RB %d, SR %d:%d: bytes %d",fix,rix,dd->sec,dd->rdo,bytes) ;
1729 
1730  int words = from22to23(c_addr,bytes/4) ; // format change
1731  int n_bytes = words * 4 ;
1732 
1733  //LOG(TERR," alloced %d bytes",n_bytes) ;
1734 
1735  sim_dta[fix].rb[rix].bytes = n_bytes ;
1736  sim_dta[fix].rb[rix].mem = (char *) malloc(n_bytes) ;
1737  memcpy(sim_dta[fix].rb[rix].mem,c_addr,n_bytes) ;
1738 
1739  }
1740 
1741 
1742 
1743  }
1744 
1745  if(got_one) {
1746  fix++ ;
1747  if(fix==SIM_FIFOS) break ;
1748  }
1749  good++ ;
1750 
1751 
1752 
1753  }
1754 
1755  LOG(INFO,"Loaded %d FIFOs",fix) ;
1756 
1757  if(rdr) delete rdr ;
1758  if(daq_tpx) delete daq_tpx ;
1759  if(daq_itpc) delete daq_itpc ;
1760 
1761  return fix ;
1762 }
Definition: rb.hh:21