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 <cstdio>
4 #include <cmath>
5 #include <cstdlib>
6 #include <iostream>
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  << ";pedestal = " << pedestal << ", adc2 = " << adc2
204  << "; 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  float scale = lutScale;
276  if (formula == 1) {
277  if (numberOfMaskedTowers != 16) {
278  scale *= (16.0 - numberOfMaskedTowers) / 16.0;
279  } else {
280  scale = 1;
281  }
282  }
283  float ped = lutPed;
284  if (lutUsePowerup) ped += 15;
285  if (formula == 2) {
286  ped -= numberOfMaskedTowers * ((pedestalShift - 8.0) / 16.0);
287  }
288  float value = (sum - ped) / scale;
289  if (value < 0) value = 0;
290  if (value > 62) value = 62;
291  if (sum - ped < lutSigma) value = 0;
292  lut = int(round(value));
293  if (debug) cout << "Simulating LUT: sum = " << sum << ", formula = " << formula << ", lutPed = " << lutPed << ", lutScale = " << lutScale << ", lutUsePowerup = " << lutUsePowerup << ", numberOfMaskedTowers = " << numberOfMaskedTowers << ", pedestalShift = " << pedestalShift << "; LUT = " << lut << endl;
294 }