StRoot  1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
stage_2_202203.cxx
1 #include <stdio.h>
2 #include <sys/types.h>
3 #include <string.h>
4 
5 #include "fcs_trg_base.h"
6 #include "fcs_ecal_epd_mask.h"
7 
8 // Processing on the North or South DEP/IO flavoured board.
9 // Inputs are up to 32 links but I already organized them according to strawman.
10 // output is 1 link over the external OUT connector.
11 // There are 20 inputs from ECAL, 8 from HCAL and 6 from PRE.
12 // This version combines HT trigger and physics triggers as Christian did in VHDL.
13 
14 namespace{
15 
16  //version2 with top2 & bottom2 rows in trigger, missing far side column
17  static const int EtoHmap[15][9][2] = {
18  { { 0, 0},{ 0, 1},{ 0, 1},{ 0, 2},{ 0, 2},{ 0, 3},{ 0, 4},{ 0, 4},{ 0, 4}},
19  { { 0, 0},{ 0, 1},{ 0, 1},{ 0, 2},{ 0, 2},{ 0, 3},{ 0, 4},{ 0, 4},{ 0, 4}},
20  { { 1, 0},{ 1, 1},{ 1, 1},{ 1, 2},{ 1, 2},{ 1, 3},{ 1, 4},{ 1, 4},{ 1, 4}},
21  { { 2, 0},{ 2, 1},{ 2, 1},{ 2, 2},{ 2, 2},{ 2, 3},{ 2, 4},{ 2, 4},{ 2, 4}},
22  { { 2, 0},{ 2, 1},{ 2, 1},{ 2, 2},{ 2, 2},{ 2, 3},{ 2, 4},{ 2, 4},{ 2, 4}},
23  { { 3, 0},{ 3, 1},{ 3, 1},{ 3, 2},{ 3, 2},{ 3, 3},{ 3, 4},{ 3, 4},{ 3, 4}},
24  { { 3, 0},{ 3, 1},{ 3, 1},{ 3, 2},{ 3, 2},{ 3, 3},{ 3, 4},{ 3, 4},{ 3, 4}},
25  { { 4, 0},{ 4, 1},{ 4, 1},{ 4, 2},{ 4, 2},{ 4, 3},{ 4, 4},{ 4, 4},{ 4, 4}},
26  { { 5, 0},{ 5, 1},{ 5, 1},{ 5, 2},{ 5, 2},{ 5, 3},{ 5, 4},{ 5, 4},{ 5, 4}},
27  { { 5, 0},{ 5, 1},{ 5, 1},{ 5, 2},{ 5, 2},{ 5, 3},{ 5, 4},{ 5, 4},{ 5, 4}},
28  { { 6, 0},{ 6, 1},{ 6, 1},{ 6, 2},{ 6, 2},{ 6, 3},{ 6, 4},{ 6, 4},{ 6, 4}},
29  { { 6, 0},{ 6, 1},{ 6, 1},{ 6, 2},{ 6, 2},{ 6, 3},{ 6, 4},{ 6, 4},{ 6, 4}},
30  { { 7, 0},{ 7, 1},{ 7, 1},{ 7, 2},{ 7, 2},{ 7, 3},{ 7, 4},{ 7, 4},{ 7, 4}},
31  { { 8, 0},{ 8, 1},{ 8, 1},{ 8, 2},{ 8, 2},{ 8, 3},{ 8, 4},{ 8, 4},{ 8, 4}},
32  { { 8, 0},{ 8, 1},{ 8, 1},{ 8, 2},{ 8, 2},{ 8, 3},{ 8, 4},{ 8, 4},{ 8, 4}}
33  } ;
34 }
35 
36 void fcs_trg_base::stage_2_202203(link_t ecal[], link_t hcal[], link_t pres[], geom_t geo, link_t output[])
37 {
38  int ns=geo.ns;
39  if(fcs_trgDebug>=2) printf("Stage2v3 ns=%d\n",ns);
40 
41  // NS Marker
42 // u_short params ;
43 // if(ns==0) params = 0xBBAA ;
44 // else params = 0xDDCC ;
45 
46  // Creating 2x2 row/column address map when called first time
47  static u_int ETbTdep[16][10]; //DEP#
48  static u_int ETbTadr[16][10]; //Input Link data address
49  static u_int HTbTdep[10][6]; //DEP#
50  static u_int HTbTadr[10][6]; //Input Link data address
51  static int first=0;
52  if(first==0){
53  first=1;
54  //making map of 2x2 Ecal Sums of [4][4]
55  for(int r=0; r<16; r++){
56  printf("Ecal r=%2d : ",r);
57  for(int c=0; c<10; c++){
58  ETbTdep[r][c]= c/2 + (r/4)*5;
59  ETbTadr[r][c]= c%2 + (r%4)*2;
60  printf("%2d-%1d ",ETbTdep[r][c],ETbTadr[r][c]);
61  }
62  printf("\n");
63  }
64  //making map of 2x2 Hcal sums of [10][6]
65  for(int r=0; r<10; r++){
66  printf("HCal r=%2d : ",r);
67  for(int c=0; c<6; c++){
68  if (r==0){
69  HTbTdep[r][c]= 6;
70  HTbTadr[r][c]= c;
71  }else if(r==9){
72  HTbTdep[r][c]= 7;
73  HTbTadr[r][c]= c;
74  }else{
75  HTbTdep[r][c]= c/2 + ((r-1)/4)*3;
76  HTbTadr[r][c]= c%2 + ((r-1)%4)*2;
77  }
78  printf("%2d-%1d ",HTbTdep[r][c],HTbTadr[r][c]);
79  }
80  printf("\n");
81  }
82  }
83 
84  // Ecal 2x2 "HT" trigger
85  int ecal_ht = 0 ;
86  for(int i=0;i<DEP_ECAL_TRG_COU;i++) {// 0..19
87  for(int j=0;j<8;j++) {
88  if(s2_ch_mask[geo.ns] & (1ll<<i)) {
89  ecal[i].d[j] = 0 ;
90  continue ;
91  }
92  if(ecal[i].d[j] > EHTTHR) ecal_ht |= 1 ;
93  }
94  }
95 
96  // Hcal 2x2 "HT" trigger
97  int hcal_ht = 0 ;
98  for(int i=0;i<DEP_HCAL_TRG_COU;i++) {// 20..27
99  for(int j=0;j<8;j++) {
100  if(s2_ch_mask[geo.ns] & (1ll<<(20+i))) {
101  hcal[i].d[j] = 0 ;
102  continue ;
103  }
104  if(hcal[i].d[j] > HHTTHR) hcal_ht |= 1 ;
105  }
106  }
107 
108  // Pres OR trigger
109  int fpre_or = 0 ;
110  for(int i=0;i<DEP_PRE_TRG_COU;i++) {// 28..32
111  for(int j=0;j<8;j++) {
112  if(s2_ch_mask[geo.ns] & (1ll<<(28+i))) {
113  pres[i].d[j] = 0 ;
114  continue ;
115  }
116 // if(pres[i].d[j] > PHTTHR) fpre_or |= 1 ; // Tonko: the FPRE S2 inputs are bitmasks so we _do_not_ apply PHTTHR here
117  if(pres[i].d[j]) fpre_or |= 1 ;
118 
119  //if(pres[i].d[j]) {
120  // printf("S2:DEP %d:%d, j %d = %d\n",geo.ns,i,j,pres[i].d[j]) ;
121  //}
122  }
123  }
124 
125  //mapped Ecal 2x2
126  for(int r=0; r<16; r++){
127  for(int c=0; c<10; c++){
128  e2x2[ns][r][c]=ecal[ETbTdep[r][c]].d[ETbTadr[r][c]];
129  }
130  }
131  //mapped Hcal 2x2
132  for(int r=0; r<10; r++){
133  for(int c=0; c<6; c++){
134  h2x2[ns][r][c]=hcal[HTbTdep[r][c]].d[HTbTadr[r][c]];
135  }
136  }
137 
138  //compute overlapping Hcal 4x4 sum of [9][5]
139  //u_int hsum[9][5];
140  for(int r=0; r<9; r++){
141  if(fcs_trgDebug>=2) printf("H4x4 ");
142  for(int c=0; c<5; c++){
143  hsum[ns][r][c]
144  = hcal[HTbTdep[r ][c ]].d[HTbTadr[r ][c ]]
145  + hcal[HTbTdep[r ][c+1]].d[HTbTadr[r ][c+1]]
146  + hcal[HTbTdep[r+1][c ]].d[HTbTadr[r+1][c ]]
147  + hcal[HTbTdep[r+1][c+1]].d[HTbTadr[r+1][c+1]];
148  //if(hsum[r][c] > 0xff) hsum[r][c]=0xff; //Tonko says no point to saturate at 8bit here
149  if(fcs_trgDebug>=2) printf("%5d ",hsum[ns][r][c]);
150  }
151  if(fcs_trgDebug>=2) printf("\n");
152  }
153 
154  //PRES for QA
155  if(fcs_trgDebug>0){
156  for(int dep=0; dep<6; dep++) {
157  for(int j=0; j<4; j++) {
158  for(int k=0; k<8; k++){
159  phit[ns][dep][j*8+k] = (pres[dep].d[j] >> k) & 0x1;
160  }
161  }
162  }
163  }
164  if(fcs_trgDebug>=2){
165  for(int dep=0; dep<6; dep++) {
166  printf("PRES NS%1d DEP%1d : ",ns,dep);
167  for(int j=0; j<4; j++) {
168  for(int k=0; k<8; k++){
169  phit[ns][dep][j*8+k] = (pres[dep].d[j] >> k) & 0x1;
170  printf("%1d", (pres[dep].d[j]>>k)&0x1);
171  }
172  printf(" ");
173  }
174  printf("\n");
175  }
176  }
177 
178  //compute overlapping Ecal 4x4 sums of [15][9]
179  //take ratio with the closest hcal 4x4
180  //u_int esum[15][9];
181  //u_int sum[15][9];
182  //float ratio[15][9];
183  u_int EM1 =0, EM2 =0, EM3=0;
184  u_int GAM1=0, GAM2=0, GAM3=0;
185  u_int ELE1=0, ELE2=0, ELE3=0;
186  u_int HAD1=0, HAD2=0, HAD3=0;
187  u_int ETOT=0, HTOT=0;
188  for(int r=0; r<15; r++){
189  if(fcs_trgDebug>=2) printf("E4x4+H %2d ",r);
190  for(int c=0; c<9; c++){
191  esum[ns][r][c]
192  = ecal[ETbTdep[r ][c ]].d[ETbTadr[r ][c ]]
193  + ecal[ETbTdep[r ][c+1]].d[ETbTadr[r ][c+1]]
194  + ecal[ETbTdep[r+1][c ]].d[ETbTadr[r+1][c ]]
195  + ecal[ETbTdep[r+1][c+1]].d[ETbTadr[r+1][c+1]];
196  //if(esum[r][c] > 0xff) esum[r][c]=0xff; //Tonko says no point to saturate at 8bit here
197 
198  // locate the closest hcal
199  u_int h=hsum[ns][EtoHmap[r][c][0]][EtoHmap[r][c][1]];
200 
201  // E+H sum
202  sum[ns][r][c] = esum[ns][r][c] + h;
203  if(sum[ns][r][c]>0xff) sum[ns][r][c]=0xff;
204 
205  //in VHDL we will do esum>hsum*threshold. Ratio = H/(E+H) is for human only
206  if(sum[ns][r][c]==0) {
207  ratio[ns][r][c]=0.0;
208  }else{
209  ratio[ns][r][c] = float(esum[ns][r][c]) / float(esum[ns][r][c] + h);
210  }
211 
212  //check EPD hits using the mask
213  epdcoin[ns][r][c]=0;
214  for(int dep=0; dep<6; dep++){
215  int mask;
216  if(fcs_readPresMaskFromText==0){
217  mask = fcs_ecal_epd_mask[r][c][dep]; //from include file
218  }else{
219  mask = PRES_MASK[r][c][dep]; //from static which was from text file
220  }
221  for(int j=0; j<4; j++) {
222  for(int k=0; k<8; k++){
223  if( (mask >> (j*8 + k)) & 0x1) { //if this is 0, don't even put the logic in VHDL
224  epdcoin[ns][r][c] |= (pres[dep].d[j] >> k) & 0x1;
225  }
226  }
227  }
228  }
229 
230  // integer multiplication as in VHDL!
231  // ratio thresholds are in fixed point integer where 1.0==128
232  em[ns][r][c]=0;
233  had[ns][r][c]=0;
234  u_int h128 = h*128 ;
235 
236 // Tonko: matches newest Christian code
237 // if(h128 < esum[ns][r][c] * EM_HERATIO_THR){
238  if(h128 <= esum[ns][r][c] * EM_HERATIO_THR){
239  em[ns][r][c]=1;
240  if(sum[ns][r][c] > EMTHR1){
241  EM1 = 1;
242  if(epdcoin[ns][r][c]==0) {GAM1 = 1;}
243  else {ELE1 = 1;}
244  }
245  if(sum[ns][r][c] > EMTHR2){
246  EM2 = 1;
247  if(epdcoin[ns][r][c]==0) {GAM2 = 1;}
248  else {ELE2 = 1;}
249  }
250  if(sum[ns][r][c] > EMTHR3){
251  EM3 = 1;
252  if(epdcoin[ns][r][c]==0) {GAM3 = 1;}
253  else {ELE3 = 1;}
254  }
255  }
256  if(h128 > esum[ns][r][c] * HAD_HERATIO_THR){
257  had[ns][r][c]=1;
258  if(sum[ns][r][c] > HADTHR1) HAD1 = 1;
259  if(sum[ns][r][c] > HADTHR2) HAD2 = 1;
260  if(sum[ns][r][c] > HADTHR3) HAD3 = 1;
261  }
262  if(fcs_trgDebug>=2) printf("%5d %1d %3.2f ",sum[ns][r][c],epdcoin[ns][r][c],ratio[ns][r][c]);
263  }
264  if(fcs_trgDebug>=2) printf("\n");
265  }
266 
267  //Ecal sub-crate sum
268  u_int esub[4];
269  esub[0] = esum[ns][ 0][0]+esum[ns][ 0][2]+esum[ns][ 0][4]+esum[ns][ 0][6]+esum[ns][ 0][8]
270  + esum[ns][ 2][0]+esum[ns][ 2][2]+esum[ns][ 2][4]+esum[ns][ 2][6]+esum[ns][ 2][8];
271  esub[1] = esum[ns][ 4][0]+esum[ns][ 4][2]+esum[ns][ 4][4]+esum[ns][ 4][6]+esum[ns][ 4][8]
272  + esum[ns][ 6][0]+esum[ns][ 6][2]+esum[ns][ 6][4]+esum[ns][ 6][6]+esum[ns][ 6][8];
273  esub[2] = esum[ns][ 8][0]+esum[ns][ 8][2]+esum[ns][ 8][4]+esum[ns][ 8][6]+esum[ns][ 8][8]
274  + esum[ns][10][0]+esum[ns][10][2]+esum[ns][10][4]+esum[ns][10][6]+esum[ns][10][8];
275  esub[3] = esum[ns][12][0]+esum[ns][12][2]+esum[ns][12][4]+esum[ns][12][6]+esum[ns][12][8]
276  + esum[ns][14][0]+esum[ns][14][2]+esum[ns][14][4]+esum[ns][14][6]+esum[ns][14][8];
277  for(int i=0; i<4; i++) if(esub[i]>0xff) esub[i]=0xff;
278 
279  //Hcal sub-crate sum
280  u_int hsub[4];
281  hsub[0] = hsum[ns][ 1][0]+hsum[ns][ 1][2]+hsum[ns][ 1][4];
282  hsub[1] = hsum[ns][ 3][0]+hsum[ns][ 3][2]+hsum[ns][ 3][4];
283  hsub[2] = hsum[ns][ 5][0]+hsum[ns][ 5][2]+hsum[ns][ 5][4];
284  hsub[3] = hsum[ns][ 7][0]+hsum[ns][ 7][2]+hsum[ns][ 7][4];
285  for(int i=0; i<4; i++) if(hsub[i]>0xff) hsub[i]=0xff;
286 
287  //Jet sum
288  //u_int jet[3];
289  u_int JP1=0,JP2=0;
290  jet[ns][0] = esub[0] + esub[1] + hsub[0] + hsub[1];
291  jet[ns][1] = esub[1] + esub[2] + hsub[1] + hsub[2];
292  jet[ns][2] = esub[2] + esub[3] + hsub[2] + hsub[3];
293  for(int i=0; i<3; i++){
294  //if(jet[ns][i]>0xff) jet[ns][i]=0xff;
295  if(jet[ns][i]>JETTHR1) JP1 = 1;
296  if(jet[ns][i]>JETTHR2) JP2 = 1;
297  }
298  if(fcs_trgDebug>=2) printf("Jet = %3d %3d %3d\n",jet[ns][0],jet[ns][1],jet[ns][2]);
299 
300  //total ET
301  etot[ns] = esub[0] + esub[1] + esub[2] + esub[3];
302  htot[ns] = hsub[0] + hsub[1] + hsub[2] + hsub[3];
303  //if(etot[ns]>0xff) etot[ns]=0xff;
304  //if(htot[ns]>0xff) htot[ns]=0xff;
305  if(etot[ns]>ETOTTHR) ETOT=1;
306  if(htot[ns]>HTOTTHR) HTOT=1;
307  if(fcs_trgDebug>=2) printf("E/H Tot = %3d %3d\n",etot[ns],htot[ns]);
308 
309  //sending output bits lower 8 bits
310  //output[0].d[0] = EM1 + (EM2 <<1) + (EM3 <<2) + 0x80; // Tonko: added last bit
311  output[0].d[0] = EM1 + (EM2 <<1) + (EM3 <<2);
312  output[0].d[1] = ELE1 + (ELE2<<1) + (ELE3<<2);
313  output[0].d[2] = GAM1 + (GAM2<<1) + (GAM3<<2);
314  output[0].d[3] = HAD1 + (HAD2<<1) + (HAD3<<2);
315  output[0].d[4] = JP1 + (JP2 <<1);
316  output[0].d[5] = ETOT + (HTOT<<1);
317  output[0].d[6] = (fpre_or<<2) | (hcal_ht<<1) | (ecal_ht); //HT
318 // output[0].d[7] = 0xCD ;
319  output[0].d[7] = 0 ;
320 
321  // upper 8 bits
322  output[1].d[0] = 0 ;
323  output[1].d[1] = 0 ;
324  output[1].d[2] = 0 ;
325  output[1].d[3] = 0 ;
326  output[1].d[4] = 0 ;
327  output[1].d[5] = 0 ;
328  output[1].d[6] = 0 ;
329 // output[1].d[7] = 0xAB ;
330  output[1].d[7] = 0 ;
331 
332  if(fcs_trgDebug>=1){
333  printf("STG2 NS%1d = %02x%02x %02x%02x %02x%02x %02x%02x %02x%02x %02x%02x %02x%02x %02x%02x\n",
334  ns,
335  output[1].d[0],output[0].d[0],output[1].d[1],output[0].d[1],
336  output[1].d[2],output[0].d[2],output[1].d[3],output[0].d[3],
337  output[1].d[4],output[0].d[4],output[1].d[5],output[0].d[5],
338  output[1].d[6],output[0].d[6],output[1].d[7],output[0].d[7]);
339  }
340 
341  return ;
342 }
343