]>
Commit | Line | Data |
---|---|---|
eb7e0771 | 1 | /** @file Altro.C |
2 | * @brief The Altro class implements the Altro digital Chain in C++ | |
3 | * | |
4 | * This Class represents a C++ version of the ALTRO. For a complete Documentation of the Altro | |
5 | * Look at : http://ep-ed-alice-tpc.web.cern.ch/ep-ed-alice-tpc/altro_chip.htm\n | |
6 | * Due to the fact that the real ALTRO constantly samples in between the recorded events, | |
7 | * it has the knowledge on what happened in the period. This affects the BSL1, TCF and BSL2 module. | |
8 | * In the BSL1 the ALTRO follows slow baseline drifts e.g. temperature change, the TCF has a infinite | |
9 | * (IIR Filter) memory of "old samples" i.e. a cluster at the start of a readout cycle will be treated | |
10 | * differently, and the BSL2 has a 8 step pipeline. The ALTRO Class can't emulate this behavior, | |
11 | * since the data is not recorded.\n | |
12 | * | |
13 | * @author Roland Bramm | |
14 | * @version $LastChangedRevision: 688 $ | |
15 | * @date $LastChangedDate: 2005-12-16 14:07:11 +0100 (Fri, 16 Dec 2005) $ | |
16 | * | |
17 | * \verbinclude Altro/Altro.C.log | |
18 | * | |
19 | */ | |
20 | ///////////////////////////////////////////////////////////////////////////////////////////////////// | |
21 | // Class for emulation of the ALTRO chip (Altro digital Chain) in C++ // | |
22 | // Author: Roland Bramm // | |
23 | // // | |
24 | // NOTE: This class has been modified to be conform with the coding conventions of the // | |
25 | // ALICE Off-line Project. Keywords for setting the mode of BSC1 were modified // | |
26 | // and are shown in the header file ... // | |
27 | // Stefan Rossegger, 8th february 2008 // | |
28 | ///////////////////////////////////////////////////////////////////////////////////////////////////// | |
29 | ||
30 | #include "AliTPCAltroEmulator.h" | |
31 | ||
32 | /** @brief Consturctor of Altro Class | |
33 | * | |
34 | * Consturctor of Altro Class, some variables are set.\n | |
35 | * The input Data is altered, so after running the complete emulation you have the | |
36 | * Altro Processed Data in the Channel Pointer.\n | |
37 | * | |
38 | * @param timebins an <tt> int </tt> sets the length of the input Data (Channel) | |
39 | * @param Channel an <tt> short* </tt> Pointer to a 1d short Array with the input Data | |
40 | */ | |
41 | ||
42 | AliTPCAltroEmulator::AliTPCAltroEmulator(int timebins, short* Channel){ | |
43 | // | |
44 | // Constructor of Altro Class | |
45 | // | |
46 | ||
47 | ftimebins = timebins; | |
48 | ||
49 | fChannelShort = Channel; | |
50 | ||
51 | fOnBSL1 = 0; | |
52 | fOnTCF = 0; | |
53 | fOnBSL2 = 0; | |
54 | fOnClip = 0; | |
55 | fOnZSU = 0; | |
56 | ||
57 | fConfiguredAltro = 0; | |
58 | fConfiguredBSL1 = 0; | |
59 | fConfiguredTCF = 0; | |
60 | fConfiguredBSL2 = 0; | |
61 | fConfiguredZSU = 0; | |
62 | } | |
63 | ||
64 | AliTPCAltroEmulator::AliTPCAltroEmulator(const AliTPCAltroEmulator &altro){ | |
65 | // | |
66 | // copy constructor of Altro Class | |
67 | // | |
68 | } | |
69 | ||
70 | ||
71 | /** @brief Destructor of Altro Class | |
72 | * | |
73 | * Destructor of Altro Class\n | |
74 | */ | |
75 | AliTPCAltroEmulator::~AliTPCAltroEmulator(){ | |
76 | // | |
77 | // Destructor of Altro Class | |
78 | // | |
79 | ||
80 | if(fConfiguredZSU == 1) | |
81 | delete fADCkeep; | |
82 | } | |
83 | ||
84 | //_____________________________________________________________________________ | |
85 | AliTPCAltroEmulator& AliTPCAltroEmulator::operator = (const AliTPCAltroEmulator &source) | |
86 | { | |
87 | // | |
88 | // AliTPCAltroEmulator assignment operator | |
89 | // | |
90 | ||
91 | if (&source == this) return *this; | |
92 | new (this) AliTPCAltroEmulator(source); | |
93 | ||
94 | return *this; | |
95 | ||
96 | } | |
97 | ||
98 | ||
99 | ||
100 | /** @brief Configures which modules of the Altro should be on. | |
101 | * | |
102 | * Configures which modules of the Altro should be on. Each of the modules | |
103 | * which are configured to be on, have to be configured later before running | |
104 | * the emulation!\n | |
105 | * | |
106 | * @param ONBaselineCorrection1 an <tt> int </tt> Switch (0,1) to turn on the Base Line Correction 1 (BSL1) Module | |
107 | * @param ONTailcancellation an <tt> int </tt> Switch (0,1) to turn on the Tail Cancellation Filter (TCF) Module | |
108 | * @param ONBaselineCorrection2 an <tt> int </tt> Switch (0,1) to turn on the Moving Average Filter (BSL2) Module | |
109 | * @param ONClipping an <tt> int </tt> Switch (0,1) to turn on the Clipping Module. This is not possible in the real Altro, there it is always on. | |
110 | * @param ONZerosuppression an <tt> int </tt> Switch (0,1) to turn on the Zero Suppression (ZSU) Module | |
111 | * @param ONDataFormatting an <tt> int </tt> Switch (0,1) to turn on the Data Formatting on (not implemented) | |
112 | */ | |
113 | void AliTPCAltroEmulator::ConfigAltro(int ONBaselineCorrection1, int ONTailcancellation, int ONBaselineCorrection2, int ONClipping, int ONZerosuppression, int ONDataFormatting){ | |
114 | // | |
115 | // Configures which modules of the Altro should be on | |
116 | // | |
117 | fOnBSL1 = InRange(ONBaselineCorrection1,0,1,"AliTPCAltroEmulator::ConfigAltro","ONBaselineCorrection1"); | |
118 | fOnTCF = InRange(ONTailcancellation,0,1,"AliTPCAltroEmulator::ConfigAltro","ONTailcancellation"); | |
119 | fOnBSL2 = InRange(ONBaselineCorrection2,0,1,"AliTPCAltroEmulator::ConfigAltro","ONBaselineCorrection2"); | |
120 | fOnClip = InRange(ONClipping,0,1,"AliTPCAltroEmulator::ConfigAltro","ONClipping"); | |
121 | fOnZSU = InRange(ONZerosuppression,0,1,"AliTPCAltroEmulator::ConfigAltro","ONZerosuppression"); | |
122 | fConfiguredAltro = 1; | |
123 | } | |
124 | ||
125 | /** @brief Configures the Base Line Correction 1 (BSL1) Module | |
126 | * | |
127 | * Configures the Base Line Correction 1 (BSL1) Module. You dont have to build a proper pedestalMemory | |
128 | * array, a pointer of the correct type is enough, of course you are not allowed to use Basline | |
129 | * Correction Modes which need then the array ...\n | |
130 | * All configurable values are "Range checked" and if out of the Range set to the nearest extreme. | |
131 | * So the Emulation will work, but the result is maybe not the expected one. | |
132 | * | |
133 | * @param mode an <tt> int </tt> sets the mode of the Baseline Correction. See the Altro manual for a description | |
134 | * @param ValuePeDestal an <tt> int </tt> this is the baseline of the Channel. | |
135 | * @param PedestalMem an <tt> *int </tt> Pointer to a 1d short Array with the pedestal memory Data | |
136 | * @param polarity an <tt> int </tt> Switch (0,1) for the polarity | |
137 | */ | |
138 | void AliTPCAltroEmulator::ConfigBaselineCorrection1(int mode, int ValuePeDestal, int *PedestalMem, int polarity){ | |
139 | // | |
140 | // Configures the Base Line Correction 1 (BSL1) Module | |
141 | // | |
142 | fBSL1mode = InRange(mode,0,10,"AliTPCAltroEmulator::ConfigBaselineCorrection1","mode"); | |
143 | fBSL1ValuePeDestal = InRange(ValuePeDestal,0,1023,"AliTPCAltroEmulator::BaselineCorrection1","ValuePeDestal"); | |
144 | fBSL1PedestalMem = PedestalMem; | |
145 | fBSL1polarity = InRange(polarity,0,1,"AliTPCAltroEmulator::BaselineCorrection1","polarity"); | |
146 | fConfiguredBSL1 = 1; | |
147 | } | |
148 | ||
149 | /** @brief Configures the Tail Cancellation Filter (TCF) Module | |
150 | * | |
151 | * Configures the Tail Cancellation Filter (TCF) Module. You have to set the coefficients in the | |
152 | * Integer version.\n | |
153 | * To convert from int to float use (int)*(pow(2,-16)-1) | |
154 | * To convert from float to int usw (float)*(pow(2,16)-1) | |
155 | * All configurable values are "Range checked" and if out of the Range set to the nearest extreme. | |
156 | * So the Emulation will work, but the result is maybe not the expected one. | |
157 | * | |
158 | * @param K1 an <tt> int </tt> sets the K1 coeeficient of the TCF | |
159 | * @param K2 an <tt> int </tt> sets the K2 coeeficient of the TCF | |
160 | * @param K3 an <tt> int </tt> sets the K3 coeeficient of the TCF | |
161 | * @param L1 an <tt> int </tt> sets the L1 coeeficient of the TCF | |
162 | * @param L2 an <tt> int </tt> sets the L2 coeeficient of the TCF | |
163 | * @param L3 an <tt> int </tt> sets the L3 coeeficient of the TCF | |
164 | */ | |
165 | void AliTPCAltroEmulator::ConfigTailCancellationFilter(int K1, int K2, int K3, int L1, int L2, int L3){ | |
166 | // | |
167 | // Configures the Tail Cancellation Filter (TCF) Module | |
168 | // | |
169 | // conf from int to fp: (int)*(pow(2,-16)-1) | |
170 | // backway: (float)*(pow(2,16)-1) | |
171 | fTCFK1Int = InRange(K1,0,65535,"AliTPCAltroEmulator::ConfigTailCancellationFilter","K1"); | |
172 | fTCFK2Int = InRange(K2,0,65535,"AliTPCAltroEmulator::ConfigTailCancellationFilter","K2"); | |
173 | fTCFK3Int = InRange(K3,0,65535,"AliTPCAltroEmulator::ConfigTailCancellationFilter","K3"); | |
174 | ||
175 | fTCFL1Int = InRange(L1,0,65535,"AliTPCAltroEmulator::ConfigTailCancellationFilter","L1"); | |
176 | fTCFL2Int = InRange(L2,0,65535,"AliTPCAltroEmulator::ConfigTailCancellationFilter","L2"); | |
177 | fTCFL3Int = InRange(L3,0,65535,"AliTPCAltroEmulator::ConfigTailCancellationFilter","L3"); | |
178 | fConfiguredTCF = 1; | |
179 | } | |
180 | ||
181 | /** @brief Configures the Moving Average Filter (BSL2) Module | |
182 | * | |
183 | * Configures the Moving Average Filter (BSL2) Module. | |
184 | * All configurable values are "Range checked" and if out of the Range set to the nearest extreme. | |
185 | * So the Emulation will work, but the result is maybe not the expected one. | |
186 | * | |
187 | * @param HighThreshold an <tt> int </tt> sets the high Threshold | |
188 | * @param LowThreshold an <tt> int </tt> sets the low Theshold | |
189 | * @param Offset an <tt> int </tt> sets the the offset which is added to the Signal | |
190 | * @param Presamples an <tt> int </tt> sets the number of pre samples excluded from the moving average caclulation | |
191 | * @param Postsamples an <tt> int </tt> sets the number of post samples excluded from the moving average caclulation | |
192 | */ | |
193 | void AliTPCAltroEmulator::ConfigBaselineCorrection2(int HighThreshold, int LowThreshold, int Offset, int Presamples, int Postsamples){ | |
194 | // | |
195 | // Configures the Moving Average Filter (BSL2) Module | |
196 | // | |
197 | fBSL2HighThreshold = InRange(HighThreshold,0,1023,"AliTPCAltroEmulator::ConfigBaselineCorrection2","HighThreshold"); | |
198 | fBSL2LowThreshold = InRange(LowThreshold,0,1023,"AliTPCAltroEmulator::ConfigBaselineCorrection2","LowThreshold"); | |
199 | fBSL2Offset = InRange(Offset,0,1023,"AliTPCAltroEmulator::ConfigBaselineCorrection2","Offset"); | |
200 | fBSL2Presamples = InRange(Presamples,0,3,"AliTPCAltroEmulator::ConfigBaselineCorrection2","Presamples"); | |
201 | fBSL2Postsamples = InRange(Postsamples,0,15,"AliTPCAltroEmulator::ConfigBaselineCorrection2","Postsamples"); | |
202 | fConfiguredBSL2 = 1; | |
203 | } | |
204 | ||
205 | /** @brief Configures the Zero Suppression Module (ZSU) | |
206 | * | |
207 | * Configures the Zero Suppression Module (ZSU). | |
208 | * All configurable values are "Range checked" and if out of the Range set to the nearest extreme. | |
209 | * So the Emulation will work, but the result is maybe not the expected one. | |
210 | * | |
211 | * @param Threshold an <tt> int </tt> sets the Threshold | |
212 | * @param MinSamplesaboveThreshold an <tt> int </tt> sets the minimum number of samples which have to be greater than the threshold | |
213 | * @param Presamples an <tt> int </tt> sets the number of pre samples which are kept | |
214 | * @param Postsamples an <tt> int </tt> sets the number of post samples which are kept | |
215 | */ | |
216 | void AliTPCAltroEmulator::ConfigZerosuppression(int Threshold, int MinSamplesaboveThreshold, int Presamples, int Postsamples){ | |
217 | // | |
218 | // Configures the Zero Suppression Module (ZSU) | |
219 | // | |
220 | fZSUThreshold = InRange(Threshold,0,1023,"AliTPCAltroEmulator::BaselineCorrection1","Threshold"); | |
221 | fZSUMinSamplesaboveThreshold = InRange(MinSamplesaboveThreshold,1,3,"AliTPCAltroEmulator::BaselineCorrection1","MinSamplesaboveThreshold"); | |
222 | fZSUPresamples = InRange(Presamples,0,3,"AliTPCAltroEmulator::BaselineCorrection1","Presamples"); | |
223 | fZSUPostsamples = InRange(Postsamples,0,7,"AliTPCAltroEmulator::BaselineCorrection1","Postsamples"); | |
224 | fADCkeep = (short *)calloc(sizeof(short),ftimebins); | |
225 | ||
226 | for(int i = 0; i < ftimebins; i++){ | |
227 | fADCkeep[i] = 0; | |
228 | } | |
229 | fConfiguredZSU = 1; | |
230 | } | |
231 | ||
232 | /** @brief Prints the set Parameters, if module is configured | |
233 | * | |
234 | * Prints the set Parameters, if module is configured. | |
235 | */ | |
236 | void AliTPCAltroEmulator::PrintParameters(){ | |
237 | // | |
238 | // Prints the set Parameters, if module is configured | |
239 | // | |
240 | cout << "+-------------------------------------------+" << endl; | |
241 | cout << "| Configured Parameters of the Altro Module |" << endl; | |
242 | cout << "+-------------------------------------------+" << endl << endl; | |
243 | ||
244 | cout << "Parameters set in the Altro Modules:" << endl << endl; | |
245 | cout << "ONBaselineCorrection1: " << fOnBSL1 << endl; | |
246 | cout << "ONTailcancellation : " << fOnTCF << endl; | |
247 | cout << "ONBaselineCorrection2: " << fOnBSL2 << endl; | |
248 | cout << "ONClipping : " << fOnClip << endl; | |
249 | cout << "ONZerosuppression : " << fOnZSU << endl << endl << endl; | |
250 | if(fConfiguredBSL1 == 1){ | |
251 | cout << "Parameters set in the BSL1 (Baseline Correction 1) Module:" << endl << endl; | |
252 | cout << "mode : " << fBSL1mode << endl; | |
253 | cout << "ValuePeDestal : " << fBSL1ValuePeDestal << endl; | |
254 | cout << "polarity : " << fBSL1ValuePeDestal << endl << endl << endl; | |
255 | }else{ | |
256 | cout << "BSL1 (Baseline Correction 1) Module not configured!" << endl << endl << endl; | |
257 | } | |
258 | if(fConfiguredTCF == 1){ | |
259 | cout << "Parameters set in the TCF (TailCancellation Filter) Module:" << endl << endl; | |
260 | cout << "K1 (int|float) : " << fTCFK1Int << " | " << fTCFK1Int/(float)((1<<16)-1) << endl; | |
261 | cout << "K2 (int|float) : " << fTCFK2Int << " | " << fTCFK2Int/(float)((1<<16)-1) << endl; | |
262 | cout << "K3 (int|float) : " << fTCFK3Int << " | " << fTCFK3Int/(float)((1<<16)-1) << endl; | |
263 | cout << "L1 (int|float) : " << fTCFL1Int << " | " << fTCFL1Int/(float)((1<<16)-1) << endl; | |
264 | cout << "L2 (int|float) : " << fTCFL2Int << " | " << fTCFL2Int/(float)((1<<16)-1) << endl; | |
265 | cout << "L3 (int|float) : " << fTCFL3Int << " | " << fTCFL3Int/(float)((1<<16)-1) << endl << endl << endl; | |
266 | }else{ | |
267 | cout << "TCF (TailCancellation Filter) Module not configured!" << endl << endl << endl; | |
268 | } | |
269 | if(fConfiguredBSL2 == 1){ | |
270 | cout << "Parameters set in the BSL2 (Baseline Correction 2) Module:" << endl << endl; | |
271 | cout << "HighThreshold : " << fBSL2HighThreshold << endl; | |
272 | cout << "LowThreshold : " << fBSL2LowThreshold << endl; | |
273 | cout << "Offset : " << fBSL2Offset << endl; | |
274 | cout << "Presamples : " << fBSL2Presamples << endl; | |
275 | cout << "Postsamples : " << fBSL2Postsamples << endl << endl << endl; | |
276 | }else{ | |
277 | cout << "BSL2 (Baseline Correction 2) Module not configured!" << endl << endl << endl; | |
278 | } | |
279 | if(fConfiguredZSU == 1){ | |
280 | cout << "Parameters set in the ZSU (Zero Suppression Unit) Module:" << endl << endl; | |
281 | cout << "Threshold : " << fZSUThreshold << endl; | |
282 | cout << "MinSampaboveThreshold: " << fZSUMinSamplesaboveThreshold << endl; | |
283 | cout << "Presamples : " << fZSUPresamples << endl; | |
284 | cout << "Postsamples : " << fZSUPostsamples << endl << endl << endl; | |
285 | }else{ | |
286 | cout << "ZSU (Zero Suppression Unit) Module not configured!" << endl << endl << endl; | |
287 | } | |
288 | } | |
289 | ||
290 | /** @brief Runs the emulation of all configured Modules. | |
291 | * | |
292 | * Runs the emulation of all configured Modules. This changes then the content of the | |
293 | * input Array | |
294 | */ | |
295 | void AliTPCAltroEmulator::RunEmulation(){ | |
296 | // | |
297 | // Runs the emulation of all configured Modules. | |
298 | // | |
299 | ||
300 | //cout << "AliTPCAltroEmulator::RunEmulation | start" << endl; | |
301 | if(fConfiguredAltro == 0){ | |
302 | cout << "ERROR cant run Altro Emulation because not configured" << endl; | |
303 | return; | |
304 | } | |
305 | ||
306 | //cout << "AliTPCAltroEmulator::RunEmulation | start BSL1 on: " << fOnBSL1 << " configures: " << fConfiguredBSL1 << endl; | |
307 | if(fOnBSL1 == 1){ | |
308 | if(fConfiguredBSL1 == 1){ | |
309 | BaselineCorrection1(fBSL1mode, fBSL1ValuePeDestal, fBSL1PedestalMem, fBSL1polarity); | |
310 | }else{ | |
311 | cout << "ERROR cant run Baseline Correction 1 because not configured" << endl; | |
312 | return; | |
313 | } | |
314 | } | |
315 | ||
316 | //cout << "AliTPCAltroEmulator::RunEmulation | start TCF on: " << fOnTCF << " configures: " << fConfiguredTCF << endl; | |
317 | if(fOnTCF == 1){ | |
318 | if(fConfiguredTCF == 1){ | |
319 | TailCancellationFilterFixedPoint(fTCFK1Int, fTCFK2Int, fTCFK3Int, fTCFL1Int, fTCFL2Int, fTCFL3Int); | |
320 | }else{ | |
321 | cout << "ERROR cant run Tail Cancellation Filter because not configured" << endl; | |
322 | return; | |
323 | } | |
324 | } | |
325 | ||
326 | //cout << "AliTPCAltroEmulator::RunEmulation | start BSL2 on: " << fOnBSL2 << " configures: " << fConfiguredBSL2 << endl; | |
327 | if(fOnBSL2 == 1){ | |
328 | if(fConfiguredBSL2 == 1){ | |
329 | BaselineCorrection2RTL(fBSL2HighThreshold, fBSL2LowThreshold, fBSL2Offset, fBSL2Presamples, fBSL2Postsamples); | |
330 | }else{ | |
331 | cout << "ERROR cant run Baseline Correction 2 because not configured" << endl; | |
332 | return; | |
333 | } | |
334 | } | |
335 | //cout << "AliTPCAltroEmulator::RunEmulation | start CLIP on: " << fOnClip << endl; | |
336 | if(fOnClip == 1){ | |
337 | Clipping(); | |
338 | } | |
339 | //cout << "AliTPCAltroEmulator::RunEmulation | start ZSU on: " << fOnZSU << " configures: " << fConfiguredZSU << endl; | |
340 | if(fOnZSU == 1){ | |
341 | if(fConfiguredZSU == 1){ | |
342 | Zerosuppression(fZSUThreshold,fZSUMinSamplesaboveThreshold,fZSUPresamples,fZSUPostsamples); | |
343 | }else{ | |
344 | cout << "ERROR cant run Zero Suppression Unit because not configured" << endl; | |
345 | return; | |
346 | } | |
347 | } | |
348 | } | |
349 | ||
350 | void AliTPCAltroEmulator::BaselineCorrection1(int mode, int ValuePeDestal, int *PedestalMem, int polarity){ | |
351 | // | |
352 | // BaselineCorrection1 | |
353 | // | |
354 | ||
355 | //VPD == 0 !! | |
356 | int fixedPeDestal = 0; | |
357 | ||
358 | if(polarity ==1){ | |
359 | for(int i = 0; i < ftimebins; i++){ | |
360 | fChannelShort[i] = 1023 - fChannelShort[i]; | |
361 | } | |
362 | } | |
363 | ||
364 | switch(mode) { | |
365 | case kDINxFPD: | |
366 | for(int i = 0; i < ftimebins; i++) | |
367 | fChannelShort[i] = fChannelShort[i] - fixedPeDestal; | |
368 | break; | |
369 | case kDINxFT: | |
370 | for(int i = 0; i < ftimebins; i++) | |
371 | fChannelShort[i] = fChannelShort[i] - PedestalMem[i]; | |
372 | break; | |
373 | case kDINxFDIN: | |
374 | for(int i = 0; i < ftimebins; i++) | |
375 | fChannelShort[i] = fChannelShort[i] - PedestalMem[ fChannelShort[i] ]; | |
376 | break; | |
377 | case kDINxFDINxVPD: | |
378 | for(int i = 0; i < ftimebins; i++) | |
379 | fChannelShort[i] = fChannelShort[i] - PedestalMem[ fChannelShort[i] - ValuePeDestal]; | |
380 | break; | |
381 | case kDINxVPDxFPD: | |
382 | for(int i = 0; i < ftimebins; i++) | |
383 | fChannelShort[i] = fChannelShort[i] - ValuePeDestal - fixedPeDestal; | |
384 | break; | |
385 | case kDINxVPDxFT: | |
386 | for(int i = 0; i < ftimebins; i++) | |
387 | fChannelShort[i] = fChannelShort[i] - ValuePeDestal - PedestalMem[i]; | |
388 | break; | |
389 | case kDINxVPDxFDIN: | |
390 | for(int i = 0; i < ftimebins; i++) | |
391 | fChannelShort[i] = fChannelShort[i] - ValuePeDestal - PedestalMem[ fChannelShort[i] ]; | |
392 | break; | |
393 | case kDINxVPDxFDINxVPD: | |
394 | for(int i = 0; i < ftimebins; i++) | |
395 | fChannelShort[i] = fChannelShort[i] - ValuePeDestal - PedestalMem[ fChannelShort[i] - ValuePeDestal ]; | |
396 | break; | |
397 | case kFDINxFPD: | |
398 | for(int i = 0; i < ftimebins; i++) | |
399 | fChannelShort[i] = PedestalMem[ fChannelShort[i] ] - fixedPeDestal; | |
400 | break; | |
401 | case kFDINxVPDxFPD: | |
402 | for(int i = 0; i < ftimebins; i++) | |
403 | fChannelShort[i] = PedestalMem[ fChannelShort[i] - ValuePeDestal ] - fixedPeDestal; | |
404 | break; | |
405 | case kFTxFPD: | |
406 | for(int i = 0; i < ftimebins; i++) | |
407 | fChannelShort[i] = PedestalMem[i] - fixedPeDestal; | |
408 | break; | |
409 | } | |
410 | } | |
411 | ||
412 | int AliTPCAltroEmulator::Multiply36(int P, int N){ | |
413 | // | |
414 | // multiply function to emulate the 36 bit fixed point multiplication of the Altro. | |
415 | // | |
416 | long long retval =0; | |
417 | long long temp = 0; | |
418 | long long vAX = 0; | |
419 | temp = (long long)P*(long long)N; | |
420 | vAX = (( Mask(temp,35,18) + ((long long)(-P)<<18) ) + Mask(temp,17,0)); | |
421 | if ( Maskandshift(N,17,17) == 1){ | |
422 | retval = ((Maskandshift(vAX,35,35)<<17) + Maskandshift(vAX,32,16)); | |
423 | }else{ | |
424 | retval = Maskandshift(temp,32,16); | |
425 | } | |
426 | return retval; | |
427 | } | |
428 | long long AliTPCAltroEmulator::Mask(long long in, int left, int right){ | |
429 | // | |
430 | // | |
431 | // | |
432 | long long retval; | |
433 | long long pattern; | |
434 | long long length = abs(left - right)+1; | |
435 | pattern = ((1<<length)-1)<<right; | |
436 | retval = in&pattern; | |
437 | return retval; | |
438 | } | |
439 | ||
440 | long long AliTPCAltroEmulator::Maskandshift(long long in, int left, int right){ | |
441 | // | |
442 | // | |
443 | // | |
444 | long long retval; | |
445 | long long pattern; | |
446 | long long length = abs(left - right)+1; | |
447 | pattern = ((1<<length)-1); | |
448 | retval = (in>>right)&pattern; | |
449 | return retval; | |
450 | } | |
451 | ||
452 | void AliTPCAltroEmulator::TailCancellationFilterFixedPoint(int K1, int K2, int K3, int L1, int L2, int L3){ | |
453 | // | |
454 | // TailCancellationFilterFixedPoint | |
455 | // | |
456 | int c1n = 0, c2n = 0, c3n = 0; | |
457 | int c1o = 0, c2o = 0, c3o = 0; | |
458 | int d1 = 0, d2 = 0; | |
459 | int dout = 0; | |
460 | int din = 0; | |
461 | int bit = 0; | |
462 | for(int i = 0; i < ftimebins; i++){ | |
463 | din = fChannelShort[i]; | |
464 | ||
465 | din = (din<<2); | |
466 | c1n = Mask( (Mask(din,17,0) + Multiply36(K1,Mask(c1o,17,0)) ) ,17,0); | |
467 | d1 = Mask( (Mask(c1n,17,0) - Multiply36(L1,Mask(c1o,17,0)) ) ,17,0); | |
468 | //d1 = Mask( (Mask(c1n,17,0) + Mask(~Multiply36(L1,Mask(c1o,17,0))+1,17,0) ) ,17,0); | |
469 | ||
470 | c2n = Mask( (Mask(d1 ,17,0) + Multiply36(K2,Mask(c2o,17,0)) ) ,17,0); | |
471 | d2 = Mask( (Mask(c2n,17,0) - Multiply36(L2,Mask(c2o,17,0)) ) ,17,0); | |
472 | //d2 = Mask( (Mask(c2n,17,0) + Mask(~Multiply36(L2,Mask(c2o,17,0))+1,17,0) ) ,17,0); | |
473 | ||
474 | c3n = Mask( (Mask(d2 ,17,0) + Multiply36(K3,Mask(c3o,17,0)) ) ,17,0); | |
475 | dout = Mask( (Mask(c3n,17,0) - Multiply36(L3,Mask(c3o,17,0)) ) ,17,0); | |
476 | //dout = Mask( (Mask(c3n,17,0) + Mask(~Multiply36(L3,Mask(c3o,17,0))+1,17,0) ) ,17,0); | |
477 | ||
478 | if( (Maskandshift(dout,2,2) == 1) || (Maskandshift(dout,1,1) == 1)){ | |
479 | bit = 1; | |
480 | }else{ | |
481 | bit = 0; | |
482 | } | |
483 | ||
484 | dout = ((dout>>3)<<1) + bit; | |
485 | if(Maskandshift(dout,15,15) == 1){ | |
486 | //is needed to get the correct coding when getting negative results | |
487 | dout = -Mask((-Mask(dout,9,0)),9,0); | |
488 | }else{ | |
489 | dout = Mask(dout,9,0); | |
490 | } | |
491 | ||
492 | fChannelShort[i] = (short) dout; | |
493 | c1o = c1n; | |
494 | c2o = c2n; | |
495 | c3o = c3n; | |
496 | } | |
497 | } | |
498 | ||
499 | void AliTPCAltroEmulator::BaselineCorrection2RTL(int HighThreshold, int LowThreshold, int Offset, int Presamples, int Postsamples){ | |
500 | // | |
501 | // BaselineCorrection2RTL | |
502 | // | |
503 | ||
504 | //cout << "Altro::BaselineCorrection2RTL | HighThreshold: " << HighThreshold << " LowThreshold: " << LowThreshold << " Offset: " << Offset << " Presamples: " << Presamples << " Postsamples: " << Postsamples << endl; | |
505 | //more or less direct "translation" of the hdl code. | |
506 | //Input signals | |
507 | int din; | |
508 | int dout; | |
509 | int edges[6]; // = Postsamples*4 + Presamples; | |
510 | int offset = Offset; | |
511 | int thrlo = LowThreshold;//called thr_mau[19] ... | |
512 | int thrhi = HighThreshold; | |
513 | ||
514 | // Variables | |
515 | int fOld[4]; //flag pipe | |
516 | int fNew[4]; //flag pipe | |
517 | int dOld[4]; //data pipe | |
518 | int dNew[4]; //data pipe | |
519 | int dxOld; | |
520 | int dxNew; | |
521 | int pstscnt; // Counter for Postsamples | |
522 | int zOld[9]; // Filter stages | |
523 | int zNew[9]; // Filter stages | |
524 | int zxOld; //Accumulator stage | |
525 | int zxNew; //Accumulator stage | |
526 | int valcntOld; //Valid sample counter | |
527 | int valcntNew = 0; //Valid sample counter | |
528 | ||
529 | int valid; //Valid flag | |
530 | int fx; //postsample flag | |
531 | //int s07; // differentiator result | |
532 | int s8; // Acc + Diff result | |
533 | int flag; | |
534 | //int bsth; //baseline threshold | |
535 | //int din_p; //Data input strictly positive | |
536 | int bsl; | |
537 | //int dx_bsls; // dx -bsl | |
538 | //int dx_clip; // dxbsl clipped | |
539 | //int bsl_of = 0; | |
540 | ||
541 | //initialisation | |
542 | for(int i = 0; i < 9 ; i++) | |
543 | zOld[i] = 0; | |
544 | for(int i = 0; i < 4 ; i++){ | |
545 | fOld[i] = 0; | |
546 | dOld[i] = 0; | |
547 | } | |
548 | dxOld= 0; | |
549 | pstscnt = 0; | |
550 | zxOld = 0; | |
551 | valcntOld = 0; | |
552 | valid = 0; | |
553 | for(int i = 0; i < 2 ; i++){ | |
554 | edges[i] = (Presamples&(1<<i))>>i; | |
555 | } | |
556 | for(int i = 0; i < 4 ; i++){ | |
557 | edges[(3-i)+2] = (Postsamples&(1<<i))>>i; | |
558 | } | |
559 | /*cout << "edges :"; | |
560 | for(int i = 0; i < 6 ; i++) | |
561 | cout << edges[i] << ":"; | |
562 | cout << " Presamples: " << Presamples << " Postsamples: " << Postsamples << endl;*/ | |
563 | ||
564 | //Loop | |
565 | //cout << "AliTPCAltroEmulator::BaselineCorrection2_RTL | starting Loop" << endl; | |
566 | for(int timebin = -12; timebin < ftimebins+10; timebin++){ | |
567 | //cout << "AliTPCAltroEmulator::BaselineCorrection2_RTL | in Loop timebin: " << timebin << endl; | |
568 | din = GetElement(fChannelShort,timebin); | |
569 | ||
570 | s8 = zxOld + (zOld[8] - zOld[0]); | |
571 | ||
572 | if(valid == 1) | |
573 | bsl = s8>>3;// ... | |
574 | else | |
575 | bsl = 0; | |
576 | ||
577 | //assign flag = (din_p > thrhi) | (thrlo > din_p); // Signal samples between thresholds | |
578 | if( (din <= (bsl + thrhi)) && (din >= (bsl - thrlo)) ) | |
579 | flag = 0; | |
580 | else | |
581 | flag = 1; | |
582 | ||
583 | if(pstscnt == 0) | |
584 | fx = 0; | |
585 | else | |
586 | fx = 1; | |
587 | ||
588 | if(valcntOld >= 12) | |
589 | valid = 1; | |
590 | else | |
591 | valid = 0; | |
592 | ||
593 | fNew[3] = flag; | |
594 | ||
595 | if( (fOld[3] == 1) || ( (flag == 1) && ( (edges[0] == 1) || (edges[1] == 1) ) ) ) //f[2] = f[3] | (flag&(edges[0]|edges[1])); | |
596 | fNew[2] = 1; | |
597 | else | |
598 | fNew[2] = 0; | |
599 | ||
600 | if( (fOld[2] == 1) || ( (edges[1] == 1) && (flag == 1) ) ) // f[1] = f[2] | (edges[1] & flag); | |
601 | fNew[1] = 1; | |
602 | else | |
603 | fNew[1] = 0; | |
604 | ||
605 | if( ( (fOld[1] == 1) || ( (flag == 1) && (edges[0] == 1) && (edges[1] == 1) ) || (fx==1) ) && (valid==1) ) // f[0] = (f[1] | (edges[1] & edges[0] & flag) | fx) & valid; | |
606 | fNew[0] = 1; | |
607 | else | |
608 | fNew[0] = 0; | |
609 | ||
610 | dxNew = dOld[0]; | |
611 | for(int i = 0; i < 3; i++) | |
612 | dNew[i] = dOld[i+1]; | |
613 | dNew[3] = din; | |
614 | ||
615 | if( (fOld[1]==1) && (fOld[2]==0) ) | |
616 | pstscnt = Postsamples; | |
617 | else if(fx == 1) | |
618 | pstscnt--; | |
619 | ||
620 | if(fOld[0] == 0){ | |
621 | if(valid == 0) | |
622 | valcntNew = ++valcntOld; | |
623 | ||
624 | zxNew = s8; | |
625 | for(int i = 0; i < 8; i++) | |
626 | zNew[i] = zOld[i+1]; | |
627 | zNew[8] = dOld[0]; | |
628 | }else{ | |
629 | zxNew = zxOld; | |
630 | for(int i = 0; i < 9; i++) | |
631 | zNew[i] = zOld[i]; | |
632 | } | |
633 | dout = dxOld - (bsl - offset); | |
634 | //if(dout <0) | |
635 | // dout = 0; | |
636 | ||
637 | SetElement(fChannelShort,timebin-5,(short)dout); | |
638 | //sim clockschange | |
639 | for(int i = 0; i < 9 ; i++) | |
640 | zOld[i] = zNew[i]; | |
641 | zxOld = zxNew; | |
642 | for(int i = 0; i < 4 ; i++){ | |
643 | fOld[i] = fNew[i]; | |
644 | dOld[i] = dNew[i]; | |
645 | } | |
646 | dxOld = dxNew; | |
647 | valcntOld = valcntNew; | |
648 | } | |
649 | } | |
650 | ||
651 | void AliTPCAltroEmulator::Clipping(){ | |
652 | // | |
653 | // implement if no BC2 clipping has to run | |
654 | // | |
655 | for(int i = 0; i < ftimebins; i++){ | |
656 | if(fChannelShort[i] < 0) | |
657 | fChannelShort[i] = 0; | |
658 | } | |
659 | } | |
660 | ||
661 | void AliTPCAltroEmulator::Zerosuppression(int Threshold, int MinSamplesaboveThreshold, int Presamples, int Postsamples){ | |
662 | // | |
663 | // add again altro feature | |
664 | // | |
665 | ||
666 | //TODO: Implement "Altro zsu merging" | |
667 | //int Postsamplecounter = 0; | |
668 | //int setPostsample = 0; | |
669 | for(int i = 0; i < ftimebins; i++){ | |
670 | if(fChannelShort[i] >= Threshold){ | |
671 | fADCkeep[i] = 1; | |
672 | } | |
673 | } | |
674 | ||
675 | int startofclustersequence = -1; | |
676 | int endofClustersInSequence = -1; | |
677 | ||
678 | for(int i = 0; i < ftimebins; i++){ | |
679 | if( (fADCkeep[i] == 1) && (GetElement(fADCkeep,i-1) == 0) ){ | |
680 | startofclustersequence = i; | |
681 | } | |
682 | if( (fADCkeep[i] == 1) && (GetElement(fADCkeep,i+1) == 0) ){ | |
683 | endofClustersInSequence = i; | |
684 | } | |
685 | //cout << i << " startofclustersequence: " << startofclustersequence << " endofClustersInSequence: " << endofClustersInSequence; | |
686 | if( (startofclustersequence != -1) && (endofClustersInSequence != -1) ){ | |
687 | //cout << " found! " << (endofClustersInSequence - startofclustersequence + 1); | |
688 | if ( (endofClustersInSequence - startofclustersequence + 1) < MinSamplesaboveThreshold ){ | |
689 | for(int j = startofclustersequence; j <= endofClustersInSequence ; j++){ | |
690 | fADCkeep[j] = 0; | |
691 | } | |
692 | } | |
693 | startofclustersequence = -1; | |
694 | endofClustersInSequence = -1; | |
695 | } | |
696 | //cout << endl; | |
697 | } | |
698 | ||
699 | /*for(int i = 0; i < ftimebins; i++){ | |
700 | if( (GetElement(fADCkeep,i-1) == 1) && (GetElement(fADCkeep,i) == 0) && (GetElement(fADCkeep,i+1) == 1) ){ | |
701 | SetElement(fADCkeep,i,1); | |
702 | } | |
703 | }*/ | |
704 | ||
705 | for(int i = 0; i < ftimebins; i++){ | |
706 | if( (fADCkeep[i] == 1) && (GetElement(fADCkeep,i-1) == 0) ){ | |
707 | for(int j = i-Presamples ; j <= i; j++){ | |
708 | SetElement(fADCkeep,j,1); | |
709 | } | |
710 | } | |
711 | } | |
712 | for(int i = ftimebins; i >= 0; i--){ | |
713 | if( (fADCkeep[i] == 1) && (GetElement(fADCkeep,i+1) == 0) ){ | |
714 | for(int j = i ; j <= i+Postsamples; j++){ | |
715 | SetElement(fADCkeep,j,1); | |
716 | } | |
717 | } | |
718 | } | |
719 | /*cout << " Postsamplecounter: " << Postsamplecounter; | |
720 | for(int j = i+1 ; j <= i+Postsamples; j++){ | |
721 | SetElement(fADCkeep,j,1); | |
722 | i+=Postsamples; | |
723 | } | |
724 | cout << endl; | |
725 | } | |
726 | cout << i << " ADCK: " << GetElement(fADCkeep,i); | |
727 | cout << " Postsam: " << Postsamplecounter << " ADCK: " << GetElement(fADCkeep,i);*/ | |
728 | ||
729 | for(int i = 0; i < ftimebins; i++){ | |
730 | if( (fADCkeep[i] == 1) && (GetElement(fADCkeep,i+1) == 0) && ( (GetElement(fADCkeep,i+3) == 1) || (GetElement(fADCkeep,i+2) == 1) ) ){ | |
731 | SetElement(fADCkeep,i+1,1); | |
732 | SetElement(fADCkeep,i+2,1); | |
733 | } | |
734 | } | |
735 | } | |
736 | ||
737 | /** @brief formats the data like the ALTRO. Result is a 64 bit array | |
738 | * | |
739 | * formats the data like the ALTRO. Result is a 64 bit array | |
740 | * | |
741 | */ | |
742 | ||
743 | void AliTPCAltroEmulator::DataFormater(){ | |
744 | // | |
745 | // formats the data like the ALTRO. Result is a 64 bit array | |
746 | // | |
747 | ||
748 | ||
749 | } | |
750 | ||
751 | ||
752 | /** @brief calculates the compression out of the bitmask | |
753 | * | |
754 | * calculates the compression out of the bitmask with the set adc values | |
755 | * | |
756 | * @return \c float consisting of the compression factor | |
757 | */ | |
758 | float AliTPCAltroEmulator::CalculateCompression(){ | |
759 | // | |
760 | // calculates the compression out of the bitmask | |
761 | // | |
762 | ||
763 | // calculation is based on altro 10 bit words .. | |
764 | int sample = 0; | |
765 | int cluster = 0; | |
766 | int data = 0; | |
767 | float retval = 0.0; | |
768 | ||
769 | for(int i = 0; i < ftimebins; i++){ | |
770 | if(fADCkeep[i] == 1){ | |
771 | sample++; | |
772 | } | |
773 | if( (fADCkeep[i] == 1) && (GetElement(fADCkeep,i+1) == 0) ){ | |
774 | cluster++; | |
775 | } | |
776 | } | |
777 | data = sample + cluster*2; | |
778 | data = data + data%4 + 4; | |
779 | if(data >0){ | |
780 | retval = ftimebins / (float)data;//num of timebins is equal to max number of samples | |
781 | }else{ | |
782 | retval = 1.0; | |
783 | } | |
784 | return retval; | |
785 | } | |
786 | ||
787 | short AliTPCAltroEmulator::GetElement(short* Array,int index){ | |
788 | // | |
789 | // | |
790 | // | |
791 | if (index < 0) | |
792 | return 0; | |
793 | else if(index >= ftimebins) | |
794 | return 0; | |
795 | else | |
796 | return Array[index]; | |
797 | } | |
798 | ||
799 | void AliTPCAltroEmulator::SetElement(short* Array,int index,short value){ | |
800 | // | |
801 | // | |
802 | // | |
803 | if (index < 0) | |
804 | return; | |
805 | else if(index >= ftimebins) | |
806 | return; | |
807 | else | |
808 | Array[index] = value; | |
809 | } | |
810 | ||
811 | int AliTPCAltroEmulator::InBand(int ADC,int bsl, int LowThreshold, int HighThreshold){ | |
812 | // | |
813 | // | |
814 | // | |
815 | int fLow = bsl - LowThreshold; | |
816 | int fHigh = bsl + HighThreshold; | |
817 | if( (ADC <= fHigh) && (ADC >= fLow) ) | |
818 | return 1; | |
819 | else | |
820 | return 0; | |
821 | } | |
822 | ||
823 | int AliTPCAltroEmulator::InRange(int parameter,int Low,int High,char *Module,char *ParameterName){ | |
824 | // | |
825 | // | |
826 | // | |
827 | ||
828 | char out[255]; | |
829 | int retval; | |
830 | if(parameter > High){ | |
831 | sprintf(out,"Error | %s | Parameter %s is to big, has to be %d <= %s <= %d, is %d, now set to %d",Module,ParameterName,Low,ParameterName,High,parameter,High); | |
832 | cout << out << endl; | |
833 | retval = High; | |
834 | }else if(parameter < Low){ | |
835 | sprintf(out,"Error | %s | Parameter %s is to small, has to be %d <= %s <= %d, is %d, now set to %d",Module,ParameterName,Low,ParameterName,High,parameter,Low); | |
836 | cout << out << endl; | |
837 | retval = Low; | |
838 | }else{ | |
839 | retval = parameter; | |
840 | } | |
841 | return retval; | |
842 | } | |
843 | ||
844 | short AliTPCAltroEmulator::GetShortChannel(int i){ | |
845 | // | |
846 | // | |
847 | // | |
848 | return GetElement(fChannelShort,i); | |
849 | } | |
850 | ||
851 | short AliTPCAltroEmulator::GetKeepChannel(int i){ | |
852 | // | |
853 | // | |
854 | // | |
855 | return GetElement(fADCkeep,i); | |
856 | } |