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