StRoot  1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
BEMC_DSM_decoder.cxx
1 #include "BEMC_DSM_decoder.h"
2 
3 #include <math.h>
4 #include <stdlib.h>
5 #include <iostream>
6 #include <stdio.h>
7 using namespace std;
8 
9 // rawDsmL0West and rawDsmL0East are the raw DSM level-0 inputs from the TRGD bank
10 // HighTower and PatchSum are the arrays to store the decoded values in the triggerPatch order (0 <= triggerPatch < 300)
11 // See the StEmcDecoder for the conversions between triggerPatch, JetPatch and towers
12 int BEMC_DSM_L0_decoder(const unsigned char* rawDsmL0West, const unsigned char* rawDsmL0East, int *HighTower, int* PatchSum) {
13 
14  if (!rawDsmL0West && !rawDsmL0East) return 0;
15  int dsm_to_patch[30] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29};
16  int patch;
17  int dsm_read_map[16]={7,6,5,4,3,2,1,0,15,14,13,12,11,10,9,8};
18  int tower_map[10]={0,1,2,3,4,5,6,7,8,9}; // map into DSM board
19  unsigned char dsmby[30][16];
20  unsigned char ch[16];
21  for (int i = 0;i < 30;i++) {
22  for (int j = 0;j < 16;j++) {
23  int k = (16 * (i % 15)) + j;
24  dsmby[i][j] = (i < 15) ? (rawDsmL0East ? rawDsmL0East[k] : 0) : (rawDsmL0West ? rawDsmL0West[k] : 0);
25  }
26  }
27  for(int i = 0;i < 30;i++) {
28  patch = dsm_to_patch[i];
29  for(int j = 0;j < 16;j++) {
30  int k = dsm_read_map[j];
31  ch[k] = dsmby[i][j];
32  }
33  int nt=0;
34  for(int k = 0;k < 5;k++) {
35  int nby = 3 * k;
36  int hi_tower = (ch[nby]) & 0x3f;
37  int sum_tower = ((ch[nby]>>6) & 0x3) + (((ch[nby+1]) & 0xf) << 2);
38  int it = tower_map[nt] + 10*(patch);
39  if (HighTower) HighTower[it] = hi_tower;
40  if (PatchSum) PatchSum[it] = sum_tower;
41  nt++;
42  hi_tower = ((ch[nby+1]>>4) & 0xf) + (((ch[nby+2]) & 0x3) << 4);
43  sum_tower = ((ch[nby+2]>>2) & 0x3f);
44  it = tower_map[nt] + 10*(patch);
45  if (HighTower) HighTower[it]=hi_tower;
46  if (PatchSum) PatchSum[it]= sum_tower;
47  nt++;
48  }
49  }
50  return 1;
51 }
52 
53 // rawDsmL1 is the raw DSM level-1 input from the TRGD bank
54 // HighTowerBits[nDSML1Boards][nDSMInputChannels] is the HT threshold bits '00' < th0 < '01' < th1 < '10' < th2 < '11'
55 // PatchSum[nDSML1Boards][nDSMInputChannels] is the patch sums
56 // nDSML1Boards = 6, nDSMInputChannels = 6
57 int BEMC_DSM_L1_decoder(const unsigned short* rawDsmL1, int* HighTowerBits, int* PatchSum) {
58  if (!rawDsmL1) return 0;
59  int ch[] = {3, 2, 1, 0, 7, 6, 5, 4};
60  for (int idsm = 0;idsm < 6;idsm++) {
61  for (int ichannel = 0;ichannel < 6;ichannel++) {
62  unsigned short channelData = rawDsmL1[(idsm * 8) + ch[ichannel]];
63  if (HighTowerBits) HighTowerBits[(idsm * 6) + ichannel] = (channelData >> 10) & 0x3;
64  if (PatchSum) PatchSum[(idsm * 6) + ichannel] = channelData & (((ichannel == 2) || (ichannel == 3)) ? 0x1f : 0x3f);
65  }
66  }
67  return 1;
68 }
69 
70 // rawDsmL2[8] is the raw DSM level-2 input from the TRGD bank (i.e. from BC1 to EM201)
71 // HighTowerBits[12] is the HT threshold bits for all 12 JetPatches
72 // PatchSumBits[12] is the PatchSum threshold bits for all 12 JetPatches
73 // PatchSum[6] is the PatchSums for 6 pairs of JetPatches (JP 6+7, JP 8+9, JP 10+11, JP 0+1, JP 2+3, JP 4+5)
74 int BEMC_DSM_L2_decoder(const unsigned short* rawDsmL2, int* HighTowerBits, int* PatchSumBits, int* PatchSum) {
75  if (!rawDsmL2) return 0;
76  int ch[] = {3, 2, 1, 0, 7, 6, 5, 4};
77  int JP[] = {6, 7, 8, 9, 10, 11, 0, 1, 2, 3, 4, 5};
78  for (int ich = 0;ich < 6;ich++) {
79  unsigned int data = rawDsmL2[ch[ich]];
80  if (HighTowerBits) {
81  HighTowerBits[JP[(ich * 2) + 0]] = (data >> 12) & 0x3;
82  HighTowerBits[JP[(ich * 2) + 1]] = (data >> 14) & 0x3;
83  }
84  if (PatchSumBits) {
85  PatchSumBits[JP[(ich * 2) + 0]] = (data >> 8) & 0x3;
86  PatchSumBits[JP[(ich * 2) + 1]] = (data >> 10) & 0x3;
87  }
88  if (PatchSum) {
89  PatchSum[ich] = (data >> 0) & 0xf;
90  }
91  }
92  return 1;
93 }
94 
95 // rawDsmL3[8] is the raw DSM level-3 input from the TRGD bank (i.e. from EM201 to the last DSM)
96 // HighTowerBits[1] is the HT threshold bits for the whole BEMC
97 // PatchSumBits[1] is the PatchSum threshold bits for the whole BEMC
98 // BackToBackBit[1] is the Back-To-Back bit for BEMC
99 // JPsiTopoBit[1] is the J/Psi topology bit for BEMC
100 // JetPatchTopoBit[1] is the jet patch topology bit for BEMC or EEMC
101 int BEMC_DSM_L3_decoder(const unsigned short* rawDsmL3, int* HighTowerBits, int* PatchSumBits, int* BackToBackBit, int *JPsiTopoBit, int *JetPatchTopoBit) {
102  if (!rawDsmL3) return 0;
103  unsigned int data = rawDsmL3[0];
104  if (HighTowerBits) HighTowerBits[0] = (data >> 2) & 0x3;
105  if (PatchSumBits) PatchSumBits[0] = (data >> 0) & 0x3;
106  if (BackToBackBit) BackToBackBit[0] = (data >> 4) & 0x1;
107  if (JPsiTopoBit) JPsiTopoBit[0] = (data >> 5) & 0x1;
108  if (JetPatchTopoBit) JetPatchTopoBit[0] = (data >> 6) & 0x1;
109  return 0;
110 }
111 
112 // The function to translate the tower pedestals (in ADC counts) into FEE pedestals to be loaded into the tower crates
113 // It was originally written in TCL (emc.tcl)
114 int getFEEpedestal(float towerPedestal, float pedestalShift, bool debug) {
115  /*
116  set scale10bits 4
117  set operationBit 1
118  # operationBit == 1 means subtract (default)
119  # operationBit == 0 means add
120  set pedestal1 [expr $pedestal - $PedestalShift]
121  if ($pedestal1<0) then {
122  set pedestal1 [expr $pedestal1*(-1)]
123  set operationBit 0
124  }
125  set operationBit [format "%1.0f" $operationBit]
126  set value2 [expr $pedestal1/$scale10bits]
127  set value1 [format "%3.0f" $value2]
128  set value2 [expr $pedestal1 - $value1*$scale10bits]
129  if ($value2>2) then {
130  set value2 [expr $value1 + 1]
131  set value1 [format "%3.0f" $value2]
132  }
133  if ($value1>15) then {
134  set value3 [expr ($value1-11)/$scale10bits]
135  set value3 [format "%3.0f" $value3]
136  set value3 [expr $value3*$scale10bits]
137  set value2 [expr $value1-$value3]
138  set value1 [format "%3.0f" $value2]
139  }
140  if {$operationBit == 1} {set value [expr ($value1&0x0F)|(0x10)]}
141  if {$operationBit == 0} {set value [expr ($value1&0x0F)]}
142  return $value
143  */
144  char buffer[10];
145  int scale10bits = 4;
146  int operationBit = 1;
147  double ped1 = towerPedestal - pedestalShift;
148  if (ped1 < 0) {
149  ped1 = -ped1;
150  operationBit = 0;
151  }
152  double value2 = ped1 / scale10bits;
153  sprintf(buffer, "%3.0f", value2);
154  int value1 = atoi(buffer);
155  value2 = ped1 - value1 * scale10bits;
156  if (value2 > 2) {
157  value2 = value1 + 1;
158  sprintf(buffer, "%3.0f", value2);
159  value1 = atoi(buffer);
160  }
161  if (value1 > 15) {
162  sprintf(buffer, "%3.0f", double(value1 - 11) / scale10bits);
163  int value3 = atoi(buffer);
164  value3 *= scale10bits;
165  value2 = value1 - value3;
166  sprintf(buffer, "%3.0f", value2);
167  value1 = atoi(buffer);
168  }
169  int value = 0;
170  if (operationBit == 1) {
171  value = (value1 & 0x0F) | 0x10;
172  }
173  if (operationBit == 0) {
174  value = (value1 & 0x0F);
175  }
176  if (debug) cout << "Calculating FEE pedestal: pedAdc = " << towerPedestal << ", shift = " << pedestalShift << "; PED = " << value << endl;
177  return value;
178 }
179 
180 void simulateFEEaction(int adc, int ped, int bitConv, int &ht, int &pa, bool debug) {
181 
182  int operationBit = ped & 0x10;
183  int pedestal = ped & 0x0F;
184  int adc1 = adc >> 2;
185  int adc2 = operationBit ? (adc1 - pedestal) : (adc1 + pedestal);
186  int adc3 = adc2 >> 2;
187  pa = adc3;
188  if (bitConv == 0) {
189  ht = adc2;
190  } else if (bitConv == 1) {
191  int adc4 = ((adc2 >> 1) & 0x1F) | ((adc2 & 0x03C0) ? 0x20 : 0);
192  ht = adc4;
193  } else if (bitConv == 2) {
194  int adc4 = ((adc2 >> 2) & 0x1F) | ((adc2 & 0x0380) ? 0x20 : 0);
195  ht = adc4;
196  } else if (bitConv == 3) {
197  int adc4 = ((adc2 >> 3) & 0x1F) | ((adc2 & 0x0300) ? 0x20 : 0);
198  ht = adc4;
199  }
200 
201 
202  //if (debug) cout << "Simulating FEE: adc = " << adc << ", ped = " << ped << ", bitConv = " << bitConv;
203  //if (debug) cout << ";pedestal = " << pedestal << ", adc2 = " << adc2;
204  //if (debug) cout << "; HT = " << ht << ", PA = " << pa << endl;
205 }
206 
207 // This function calculates lookup table (LUT)
208 // Originally written in TCL (emc.tcl)
209 void simulateFEELUT(int sum, int formula, int lutScale, int lutPed, int lutSigma, int lutUsePowerup, int parameter4, int parameter5, int numberOfMaskedTowers, int pedestalShift, int &lut, bool debug) {
210 /*
211 proc getLUTscale { board patch } { global lutScale lutPed lutSigma lutUseMask lutUsePowerup
212  global triggermask1 triggermask2
213 
214  set patchLutScale $lutScale
215  if {$lutUseMask == 1} {
216  if {$patch == 0} {set triggerMask $triggermask1($board)} else {set triggerMask $triggermask2($board)}
217  set numberOfMaskedChannels 0
218  for {set bit 1} {$bit <= 0xffff} {set bit [expr $bit * 2]} {
219  if {[expr ($triggerMask & $bit)] == 0} {incr numberOfMaskedChannels}
220  }
221  if {$numberOfMaskedChannels != 16} {
222  set patchLutScale [expr $lutScale * ((16.0 - $numberOfMaskedChannels) / 16.0)]
223  } else {
224  set patchLutScale 1
225  }
226  }
227  return $patchLutScale
228 }
229 
230 proc getLUTped { board patch } {
231  global lutScale lutPed lutSigma lutUseMask lutUsePowerup
232  global triggermask1 triggermask2 PedestalShift
233 
234  set ped $lutPed([expr $patch+1],$board)
235  if {$lutUsePowerup} {set ped [expr $ped + 15]}
236  if {$lutUseMask == 2} {
237  set triggerMask 0xffff
238  if {$patch == 0} {set triggerMask $triggermask1($board)}
239  if {$patch == 1} {set triggerMask $triggermask2($board)}
240  set numberOfMaskedChannels 0
241  for {set bit 1} {$bit <= 0xffff} {set bit [expr $bit * 2]} {
242  if {[expr ($triggerMask & $bit)] == 0} {incr numberOfMaskedChannels}
243  }
244  set ped [expr $ped - ($numberOfMaskedChannels) * (($PedestalShift - 8) / 16)]
245  }
246  return $ped
247 }
248 
249 proc getLUTrange { board patch fast } {
250  global lutScale lutPed lutSigma lutUseMask lutUsePowerup
251  global triggermask1 triggermask2
252 
253  set ped [getLUTped $board $patch]
254  set patchLutScale [getLUTscale $board $patch]
255  set range [expr $patchLutScale * ($ped + 62)]
256  if {$range < 78} {set range 78}
257  if {$fast == "slow"} {set range 4096}
258  return $range
259 }
260 
261 proc getLUTvalue { board patch index } {
262  global lutScale lutPed lutSigma lutUseMask lutUsePowerup
263  global triggermask1 triggermask2
264 
265  set ped [getLUTped $board $patch]
266  set nsigma $lutSigma([expr $patch+1],$board)
267  set patchLutScale [getLUTscale $board $patch]
268  set value [expr ($index - $ped) / $patchLutScale]
269  if {$value < 0} then {set value 0}
270  if {$value > 62} then {set value 62}
271  if {[expr $index - $ped] < $nsigma} then {set value 0}
272  return [expr round($value)]
273 }
274 */
275  if (!((sum + lutPed) & ~0x7F) && (formula == 2) && (lutScale == 1) && (!lutSigma) && (lutUsePowerup) && (pedestalShift == 24)) {
276  // The usual running mode
277  static int commonLUT[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
278  10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34,
279  35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59,
280  60, 61, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62,
281  62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62,
282  62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62};
283  // more than 0x7F + 16 elements
284  lut = commonLUT[sum + lutPed + numberOfMaskedTowers];
285  return;
286  }
287 
288  float scale = lutScale;
289  if (formula == 1) {
290  if (numberOfMaskedTowers != 16) {
291  scale *= (16.0 - numberOfMaskedTowers) / 16.0;
292  } else {
293  scale = 1;
294  }
295  }
296  float ped = lutPed;
297  if (lutUsePowerup) ped += 15;
298  if (formula == 2) {
299  ped -= numberOfMaskedTowers * ((pedestalShift - 8.0) / 16.0);
300  }
301  float value = (sum - ped) / scale;
302  if (value < 0) value = 0;
303  if (value > 62) value = 62;
304  if (sum - ped < lutSigma) value = 0;
305  lut = int(round(value));
306  if (debug) cout << "Simulating LUT: sum = " << sum << ", formula = " << formula << ", lutPed = " << lutPed << ", lutScale = " << lutScale << ", lutUsePowerup = " << lutUsePowerup << ", numberOfMaskedTowers = " << numberOfMaskedTowers << ", pedestalShift = " << pedestalShift << "; LUT = " << lut << endl;
307 }
308 
309