]> git.uio.no Git - u/mrichter/AliRoot.git/blob - TPC/AliTPCAltroEmulator.cxx
Adding additional documentation (Marian)
[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 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 }