StRoot  1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
itpcCore.cxx
1 #include <stdio.h>
2 #include <sys/types.h>
3 #include <string.h>
4 #include <stdlib.h>
5 #include <math.h>
6 #include <time.h>
7 
8 #include <rtsLog.h>
9 
10 #define IFEE_NO_LANE_HDRS 1
11 
12 #include "itpc_maps.h"
13 #include "itpc_rowlen.h"
14 #include "itpc_padplane.h"
15 
16 #include "itpcCore.h"
17 
18 // Copied over from tpx_altro_to_pad.h
19 static const u_char tpx_altro_to_j1[2][16] = {
20  {21,22,19,20,17,18,15,16, 8, 7,10, 9,12,11,14,13 },
21  {38,37,36,35,34,33,32,31, 23,24,25,26,27,28,29,30 }
22 } ;
23 
24 
25 static struct itpc_to_ifee_table_t {
26  u_char fee_id ;
27  u_char fee_ch ;
28 } itpc_to_ifee_table[72+1][182+1] ;
29 
30 static struct itpc_rowpad_to_id_t {
31  u_char id ;
32  u_char pin ;
33 } itpc_rowpad_to_id_s[41][121] ;
34 
35 
36 void itpc_ifee_to_rowpad(int fee_id, int ch, int &row, int &pad)
37 {
38  int pin ;
39 
40  row = pad = 0 ;
41 
42  if((fee_id<1)||(fee_id>55)) return ;
43  if((ch<0)||(ch>63)) return ;
44 
45  //first: get from the channel# to the pin of the padplane connector
46  if(ch > 31) pin = itpc_sampa_to_pin[1][ch-32] ;
47  else pin = itpc_sampa_to_pin[0][ch] ;
48 
49  row = itpc_padplane[fee_id][pin].row ;
50  pad = itpc_padplane[fee_id][pin].pad ;
51 
52  return ;
53 }
54 
55 // NOT FINISHED YET
56 #if 0
57 void itpc_rowpad_to_rdo(int row, int pad, int &rdo)
58 {
59  int fee_id, fee_ch ;
60 
61  itpc_rowpad_to_ifee(row,pad,fee_id,fee_ch) ;
62 
63  if(fee_id<1 || fee_id>55) {
64  rdo = 0 ; // what?
65  }
66  else return ifee_to_irdo_map[fee_id] ;
67 }
68 #endif
69 
70 void itpc_rowpad_to_ifee(int row, int pad, int &fee_id, int &fee_ch)
71 {
72  static int first ;
73 
74  if(first == 0) {
75  first = 1 ;
76 
77  for(int f=1;f<=55;f++) {
78  for(int c=0;c<64;c++) {
79  int row, pad ;
80 
81  itpc_ifee_to_rowpad(f,c,row,pad) ;
82 
83  itpc_to_ifee_table[row][pad].fee_id = f ;
84  itpc_to_ifee_table[row][pad].fee_ch = c ;
85  }
86  }
87 
88  }
89 
90  fee_id = 0 ;
91  fee_ch = 0 ;
92 
93  if(row < 1) return ;
94  if(pad < 1) return ;
95 
96  fee_id = itpc_to_ifee_table[row][pad].fee_id ;
97  fee_ch = itpc_to_ifee_table[row][pad].fee_ch ;
98 
99 }
100 
101 void itpc_sampa_to_rowpad(int id, int sampa, int ch, int &row, int &pad)
102 {
103  row = pad = 0 ;
104 
105  if((id<1)||(id>55)) return ;
106  if((ch<0)||(ch>31)) return ;
107 
108  sampa &= 1 ;
109 
110  int pin = itpc_sampa_to_pin[sampa][ch] ;
111 
112  row = itpc_padplane[id][pin].row ;
113  pad = itpc_padplane[id][pin].pad ;
114 
115  return ;
116 }
117 
118 void itpc_rowpad_to_id(int row, int pad, int &id, int &pin)
119 {
120  static int first ;
121 
122  id = pin = 0 ;
123 
124  if((row<0)||(row>40)) return ;
125  if((pad<1)||(pad>120)) return ;
126 
127 
128  if(first==0) {
129  for(int id=1;id<=55;id++) {
130  for(int pin=1;pin<=78;pin++) {
131  int r, p ;
132 
133  int sampa = -1 ;
134  int ch = -1 ;
135 
136  for(int s=0;s<2;s++) {
137  for(int c=0;c<32;c++) {
138  if(pin==itpc_sampa_to_pin[s][c]) {
139  sampa = s ;
140  ch = c ;
141  goto found ;
142  }
143  }
144  }
145 
146  found:;
147  if(sampa<0) {
148  continue ;
149  }
150 
151  itpc_sampa_to_rowpad(id,sampa,ch,r,p) ;
152 
153  itpc_rowpad_to_id_s[r][p].id = id ;
154  itpc_rowpad_to_id_s[r][p].pin = pin ;
155 
156 
157  }
158  }
159 
160 
161  first = 1 ;
162  }
163 
164  id = itpc_rowpad_to_id_s[row][pad].id ;
165  pin = itpc_rowpad_to_id_s[row][pad].pin ;
166 
167 }
168 
169 
170 int itpc_altro_to_ifee(int altro)
171 {
172  int fee = altro/2 ;
173 
174  int ifee = 0 ;
175 
176  if(fee&(1<<0)) ifee |= (1<<0) ;
177  if(fee&(1<<1)) ifee |= (1<<2) ;
178  if(fee&(1<<2)) ifee |= (1<<1) ;
179  if(fee&(1<<3)) ifee |= (1<<3) ;
180  if(fee&(1<<4)) ifee |= (1<<4) ;
181 
182  if(fee&(1<<6)) ifee |= (1<<5) ;
183 
184  return ifee ;
185 }
186 
187 void itpc_altro_to_rowpad(int altro, int ch, int odd, int &row, int &pad)
188 {
189 
190  int j1 ;
191 
192  int ifee = itpc_altro_to_ifee(altro) ;
193 
194  altro &= 1 ;
195 
196  j1 = tpx_altro_to_j1[altro][ch] ;
197 
198  int pin = itpc_adapter_jx_to_pin[odd][j1] ;
199 
200 
201  row = itpc_padplane[ifee][pin].row ;
202  pad = itpc_padplane[ifee][pin].pad ;
203 }
204 
205 
206 itpc_ped_t *itpc_data_c::ped_p = 0 ;
207 int itpc_data_c::ped_run = 0 ;
208 
209 void itpc_data_c::data_accum(fee_ch_t *fee_p, int tb, int adc)
210 {
211  int fee = fee_p->fee ;
212  int ch = fee_p->ch ;
213 
214  at[tb_cou].tb = tb ;
215  at[tb_cou].adc = adc ;
216  tb_cou++ ;
217 
218  if(!ped_p || !ped_run) return ;
219 
220  ped_p->g_mean[fee][ch] += adc ;
221  ped_p->g_rms[fee][ch] += adc*adc ;
222  ped_p->g_cou[fee][ch]++ ;
223 
224  ped_p->mean[fee][ch][tb] += adc ;
225  ped_p->rms[fee][ch][tb] += adc*adc ;
226  ped_p->cou[fee][ch][tb]++ ;
227 
228 }
229 
230 void itpc_data_c::ped_start()
231 {
232  if(ped_p==0) {
233  ped_p = (itpc_ped_t *)malloc(sizeof(itpc_ped_t)) ;
234  }
235 
236  memset(ped_p,0,sizeof(itpc_ped_t)) ;
237 }
238 
239 void itpc_data_c::ped_stop()
240 {
241  if(ped_p==0) return ;
242  if(!ped_run) return ;
243 
244  for(int f=0;f<64;f++) {
245  for(int c=0;c<64;c++) {
246  int any_cou = 0 ;
247  for(int t=0;t<512;t++) {
248  int cou = ped_p->cou[f][c][t] ;
249 
250  if(cou==0) continue ;
251  any_cou++ ;
252 
253  double mean = ped_p->mean[f][c][t] / cou ;
254  double rms = ped_p->rms[f][c][t] / cou ;
255 
256  rms = sqrt(rms-mean*mean) ;
257 
258  ped_p->mean[f][c][t] = mean ;
259  ped_p->rms[f][c][t] = rms ;
260  }
261  ped_p->cou[f][c][0] = any_cou ; //marker for this channel!
262 
263  int cou = ped_p->g_cou[f][c] ;
264  if(cou==0) continue ;
265 
266  double mean = ped_p->g_mean[f][c]/cou ;
267  double rms = ped_p->g_rms[f][c]/cou ;
268 
269  rms = sqrt(rms-mean*mean) ;
270 
271 
272  int row, pad ;
273 
274  itpc_ifee_to_rowpad(f,c,row,pad) ;
275 
276  printf("%2d %2d %2d %3d %f %f\n",f,c,row,pad,mean,rms) ;
277  }
278  }
279 
280 
281 
282 
283  time_t now = time(0) ;
284  struct tm *tm = localtime(&now) ;
285 
286  char fname[128] ;
287 
288  sprintf(fname,"/RTScache/itpc_pedestals_%d_%d_%d_%d_%d.txt",
289  tm->tm_year+1900,
290  tm->tm_mon+1,
291  tm->tm_mday,
292  tm->tm_hour,
293  tm->tm_min) ;
294 
295 
296  FILE *of = fopen(fname,"w") ;
297  LOG(TERR,"Writing pedestals to %s",fname) ;
298 
299 
300  for(int f=0;f<64;f++) {
301  for(int c=0;c<64;c++) {
302  if(ped_p->cou[f][c][0]) ;
303  else continue ;
304 
305  for(int t=0;t<512;t++) {
306  fprintf(of,"%d %d %d %.3f %.3f\n",f,c,t,ped_p->mean[f][c][t],ped_p->rms[f][c][t]) ;
307  }
308  }}
309  fclose(of) ;
310 
311 }
312 
313 //start of channel data!
314 int itpc_data_c::start(u_short *d16)
315 {
316  fee_ch_t *fee_p = rdo_p->fee_ch[rdo_p->fee_ch_cou] = (fee_ch_t *)malloc(sizeof(fee_ch_t)) ;
317  rdo_p->fee_ch_cou++ ;
318 
319  fee_p->port = port_id ;
320  fee_p->fee = fee_id ;
321  fee_p->ch = fee_ch ;
322  fee_p->err = 0 ;
323 
324  fee_p->words = words ;
325 
326 
327  u_short *d16_stop = d16 + words ;
328 
329  int tb_stop_last = -1 ;
330 
331 // for(int i=0;i<words;i++) {
332 // LOG(TERR,"%d: 0x%X [%d dec]",i,d16[i]&0x3FF,d16[i]&0x3FF) ;
333 // }
334 
335 
336  tb_cou = 0 ;
337 
338  while(d16<d16_stop) {
339 
340  int tb_cou = *d16++ & 0x3FF ;
341  int tb_start = *d16++ & 0x3FF ;
342 
343  int tb_stop = tb_start + tb_cou - 1 ;
344 
345 // LOG(TERR,"%d:%d - tb_start %d, tb_stop %d, tb_stop_last %d",fee_p->fee,fee_p->ch,
346 // tb_start,tb_stop,tb_stop_last) ;
347 
348  if(tb_start <= tb_stop_last) {
349  fee_p->err |= 1 ;
350  break ;
351  }
352  if(tb_stop > 512) { //NOTE: hardcoded max tb!
353  fee_p->err |= 2 ;
354  break ;
355  }
356 
357  //do something with the data at timebin "t"
358  for(int t=tb_start;t<=tb_stop;t++) {
359  data_accum(fee_p, t, *d16 & 0x3FF) ;
360  d16++ ;
361  }
362 
363  tb_stop_last = tb_stop ;
364 
365  }
366 
367  if(fee_p->err) {
368  LOG(ERR,"FEE %d:%d -- error 0x%X",fee_p->fee,fee_p->ch,fee_p->err) ;
369  return -1 ;
370  }
371 
372  return 0 ;
373 }
374 
375 
376 
377 
378 void itpc_data_c::rdo_zap(void *rdo_p)
379 {
380  if(rdo_p==0) {
381  LOG(ERR,"rdo_p NULL") ;
382  return ;
383  }
384 
385  rdo_t *rdo = (rdo_t *)rdo_p ;
386 
387  for(int i=0;i<rdo->fee_ch_cou;i++) {
388  if(rdo->fee_ch[i]) free(rdo->fee_ch[i]) ;
389  }
390 
391  free(rdo) ;
392 }
393 
394 
395 int itpc_data_c::fee_scan(u_short *d16, int shorts)
396 {
397 
398 // for(int i=0;i<10;i++) {
399 // LOG(TERR,"%d = 0x%04X",i,d16[i]) ;
400 // }
401 
402  if(next_word==0) { //start of FEE scan!
403  fee_err = 0 ;
404 
405  //event header check
406 // if(d16[0] != 0xFD04) fee_err |= 1 ; //start of FEE marker
407 // if(d16[1] != 0xFF8C || d16[1]!=0xFF16) fee_err |= 1 ;
408 // if(d16[2] != 0xFFFF) fee_err |= 1 ;
409 // if(d16[3] != 0xFD05) fee_err |= 1 ; //end of FEE marker
410 
411 
412 // for(int i=0;i<4;i++) LOG(TERR,"HDR %d: 0x%04X",i,d16[i]) ;
413 
414  sector = 1 ; //we assume we get it in the data...
415 
416 
417  sampa_type = -1 ;
418 
419  words = 0 ;
420 
421  sampa_id = -1 ;
422 
423  sampa_ch = -1 ;
424 
425  sampa_bx = -1 ;
426 
427 // fee_id = -1 ;
428 
429  port_id = d16[0] ;
430  fee_id = d16[1] ; // actually FEE port, from RDO!
431 
432  memset(hdr_cou,0,sizeof(hdr_cou)) ;
433 
434 // next_word = 4 ;
435  next_word = 2 ;
436  }
437 
438  sampa_ch++ ;
439 
440  int type = sampa_type ;
441  int id = -1 ;
442  int ch = -1 ;
443  int bx = -1 ;
444 
445  int lane_expect = 0 ;
446 
447  int fee = -1 ;
448 
449  //LOG(TERR,"next_word %d/%d",next_word,shorts) ;
450 
451  for(int i=next_word;i<shorts;i++) {
452  int l = d16[i] >> 13 ;
453  int h = (d16[i] >> 10) & 0x7 ;
454  int d = d16[i] & 0x3FF ;
455 
456  LOG(TERR,"Lane %d, hdr %d, d 0x%03X - 0x%04X [%d]",l,h,d,d16[i],i) ;
457 
458  hdr_cou[h]++ ; //MUST come last to avoid the spurious, last 0xFFFF datum
459 
460  switch(h) {
461  case 0 :
462  type = d>>7 ;
463 
464  if(sampa_type < 0) sampa_type = type ;
465  else if(sampa_type != type) {
466  fee_err |= 0x2 ;
467  LOG(ERR,"Different event type %d, expect %d",type,sampa_type) ;
468  }
469 
470  if(type==0) lane_expect = 2 ; //hearbeat!
471 
472  break ;
473  case 1 :
474  if(words != 0) {
475  fee_err |= 0x4000 ;
476  LOG(ERR,"Words are not 0") ;
477  }
478 
479  words = d ;
480 
481  break ;
482  case 2 :
483  id = d & 0xF ;
484  ch = (d>>4)&0x1F ;
485 
486  //LOG(TERR,"Id %d, expect %d; ch %d, expect %d",id,sampa_id,ch,sampa_ch) ;
487 
488 #ifdef IFEE_NO_LANE_HDRS
489 // if(sampa_id >= 0) {
490 // if(id != sampa_id) fee_err |= 0x4 ;
491 // }
492 
493 // fee_id = id & 0xFE ;
494 #else
495  if(id != sampa_id) fee_err |= 0x4 ;
496 #endif
497 
498  if(type == 0) {
499  if(ch != 21) {
500  fee_err |= 0x8 ;
501  LOG(ERR,"Wrong channel") ;
502  }
503  }
504  else {
505 #ifdef IFEE_NO_LANE_HDRS
506 #else
507  if(ch != sampa_ch) {
508  LOG(ERR,"SAMPA ch %d, expect %d",ch,sampa_ch) ;
509  fee_err |= 0x8 ;
510  }
511 #endif
512  }
513 
514  sampa_id = id ;
515  sampa_ch = ch ;
516 
517  if(id & 1) fee_ch = 32 + ch ;
518  else fee_ch = ch ;
519 
520  break ;
521  case 3 :
522  bx = d ;
523 
524  break ;
525  case 4 :
526  bx = (bx<<10)|(d&0x1FF) ;
527 
528  if(sampa_bx < 0) sampa_bx = bx ;
529  else if(bx != sampa_bx) {
530  fee_err |= 0x10 ;
531  LOG(ERR,"Different BX") ;
532  }
533 
534  switch(type) {
535  case 0: //heartbeat
536  if(words!=0 || ch!=21) {
537  fee_err |= 0x20 ;
538  LOG(ERR,"Wrong words in Hearbeat") ;
539  }
540  break ;
541  case 4 : //data
542  break ;
543  default :
544  LOG(ERR,"Bad event type %d",type) ;
545  fee_err |= 0x40 ;
546  break ;
547  }
548 
549 
550  start(d16+i+1) ; //THIS is where I fill the data!!!
551 
552  LOG(INFO,"Starting: FEE %d, SAMPA %d, ch %d, words %d",fee_id,sampa_id,sampa_ch,words) ;
553 
554  i += words ;
555  next_word = i + 1 ;
556  if(fee_err) LOG(ERR,"0x%X",fee_err) ;
557 
558  LOG(INFO,"Done: FEE %d, SAMPA %d, ch %d, words %d",fee_id,sampa_id,sampa_ch,words) ;
559 
560  //LOG(TERR,"Next word: %d/%d, words %d",next_word,shorts,words) ;
561  words = 0 ;
562  return 1 ;
563 
564  break ;
565  default :
566  case 5 : //data
567  LOG(ERR,"Can't have data 0x%04X!",d16[i]) ;
568  break ;
569 
570  case 7 : // end of lane data
571  //fee_id = d & 0x3F ;
572  {
573  LOG(TERR,"Lane %d: end of lane data 0x%04X, token %d",l,d16[i],d) ;
574 
575  }
576  break ;
577  case 6 :
578  {
579  int fee = d & 0x3F ;
580  int ev = (d >> 6)&3 ;
581  int tkn = (d>>8)&3 ;
582  LOG(TERR,"Lane %d: start of lane data 0x%X [0x%04X] - fee %d, ev %d, tkn %d",
583  l,d,d16[i],
584  fee,ev,tkn) ;
585  }
586  break ;
587  }
588  }
589 
590  stop:;
591 
592  if(words != 0) fee_err |= 0x4000 ;
593 
594  if(sampa_type == 4) { //normal
595 
596  //there is a bug in this version of the FEE firmware which
597  //eats header 0 for all cases apart from the start of lane
598  if(hdr_cou[0] != 64) fee_err |= 0x1000 ;
599 // if(hdr_cou[0] != 4) fee_err |= 0x1000 ;
600 
601  if(hdr_cou[1] != 64) fee_err |= 0x1000 ;
602  if(hdr_cou[2] != 64) fee_err |= 0x1000 ;
603  if(hdr_cou[3] != 64) fee_err |= 0x1000 ;
604  if(hdr_cou[4] != 64) fee_err |= 0x1000 ;
605  if(hdr_cou[5] != 0) fee_err |= 0x2000 ;
606 
607 #ifdef IFEE_NO_LANE_HDRS
608 #else
609  if(hdr_cou[6] != 8) fee_err |= 0x1000 ;
610  if(hdr_cou[7] != 4) fee_err |= 0x1000 ;
611 #endif
612 
613  }
614  else if(sampa_type == 0) {
615  if(hdr_cou[0] != 2) fee_err |= 0x2000 ;
616  if(hdr_cou[1] != 2) fee_err |= 0x2000 ;
617  if(hdr_cou[2] != 2) fee_err |= 0x2000 ;
618  if(hdr_cou[3] != 2) fee_err |= 0x2000 ;
619  if(hdr_cou[4] != 2) fee_err |= 0x2000 ;
620  if(hdr_cou[5] != 0) fee_err |= 0x2000 ;
621 #ifdef IFEE_NO_LANE_HDRS
622 #else
623  if(hdr_cou[6] != 4) fee_err |= 0x2000 ;
624  if(hdr_cou[7] != 2) fee_err |= 0x2000 ;
625 #endif
626  }
627 
628  if(fee_err) {
629  LOG(ERR,"Error 0x%08X",fee_err) ;
630  if(fee_err & 0x3000) {
631  for(int i=0;i<8;i++) {
632  LOG(TERR,"Hdr %d: %d",i,hdr_cou[i]) ;
633  }
634  }
635  }
636 
637  return 0 ;
638 // return err ;
639 
640 
641 }
642 
643 
644 
645 #ifdef MAIN
646 int main()
647 {
648  for(int id=1;id<=55;id++) {
649  for(int sampa=0;sampa<2;sampa++) {
650  for(int ch=0;ch<32;ch++) {
651  int row, pad ;
652  int iid,pin ;
653 
654  itpc_sampa_to_rowpad(id,sampa,ch,row,pad) ;
655 
656  itpc_rowpad_to_id(row,pad,iid,pin) ;
657 
658 
659  printf("Id %2d[==%2d], SAMPA %d, Ch %2d == row %2d, pad %3d, pin %2d\n",id,iid,sampa,ch,row,pad,pin) ;
660 
661  }}}
662 
663 
664 
665 
666  int altro = 160 ;
667  int adapter = 0 ;
668 
669  printf("ALTRO %d to iFEE %d %d\n",altro,itpc_altro_to_ifee(altro),itpc_altro_to_ifee(altro|1)) ;
670 
671  for(int i=0;i<16;i++) {
672  int row, pad ;
673 
674  itpc_altro_to_rowpad(altro,i,adapter,row,pad) ;
675 
676  printf("Altro %d, adapter %d: channel %d: row %d, pad %d\n",altro,adapter,i,row,pad) ;
677  }
678  for(int i=0;i<16;i++) {
679  int row, pad ;
680 
681  itpc_altro_to_rowpad(altro|1,i,adapter,row,pad) ;
682 
683  printf("Altro %d, adapter %d: channel %d: row %d, pad %d\n",altro|1,adapter,i,row,pad) ;
684 
685  }
686 
687  adapter = 1 ;
688 
689  for(int i=0;i<16;i++) {
690  int row, pad ;
691 
692  itpc_altro_to_rowpad(altro,i,adapter,row,pad) ;
693 
694  printf("Altro %d, adapter %d: channel %d: row %d, pad %d\n",altro,adapter,i,row,pad) ;
695  }
696  for(int i=0;i<16;i++) {
697  int row, pad ;
698 
699  itpc_altro_to_rowpad(altro|1,i,adapter,row,pad) ;
700 
701  printf("Altro %d, adapter %d: channel %d: row %d, pad %d\n",altro|1,adapter,i,row,pad) ;
702 
703  }
704 
705 
706  return 0 ;
707 }
708 
709 #endif