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