Update to use independent TCF settings for IROC and OROC
[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 #include <TH1F.h>
32 #include <TMath.h>
33 #include <TSystem.h>
34 #include <AliDAQ.h>
35 #include <AliRawReader.h>
36 #include <AliRawVEvent.h>
37 #include <AliRawData.h>
38 #include <AliRawVEquipment.h>
39 #include <AliRawEquipmentHeader.h>
40 #include <AliTPCRawStreamV3.h>
41 #include <TCanvas.h>
42
43
44 /**     @brief Consturctor of Altro Class
45  *
46  *      Consturctor of Altro Class, some variables are set.\n
47  *      The input Data is altered, so after running the complete emulation you have the
48  *      Altro Processed Data in the Channel Pointer.\n
49  *
50  *      @param timebins an <tt> int </tt> sets the length of the input Data (Channel)
51  *      @param Channel an <tt> short* </tt> Pointer to a 1d Short_tArray with the input Data
52  */
53
54
55 ClassImp(AliTPCAltroEmulator)
56
57 AliTPCAltroEmulator::AliTPCAltroEmulator(Int_t timebins, short* Channel) : 
58   TNamed(),
59   ftimebins(timebins),
60 //  fChannelIn(Channel),
61   fChannelShort(Channel), 
62   fADCkeep(0),     
63   fOnBSL1(0), 
64   fOnTCF(0),  
65   fOnBSL2(0), 
66   fOnClip(0), 
67   fOnZSU(0),  
68
69   fConfiguredAltro(0),   // ConfiguredAltro
70   fConfiguredBSL1(0),    // ConfiguredBSL1
71   fConfiguredTCF(0),     // ConfiguredTCF
72   fConfiguredTCFraw(0),     // ConfiguredTCF
73   fConfiguredBSL2(0),    // ConfiguredBSL2
74   fConfiguredZSU(0),     // ConfiguredZSU
75   fBSL1mode(0),          // BSL1mode
76   fBSL1ValuePeDestal(0), // BSL1ValuePeDestal
77   fBSL1PedestalMem(0),   // BSL1PedestalMem
78   fBSL1polarity(0),      // BSL1polarity
79
80   fTCFK1(0), // K1
81   fTCFK2(0), // K2
82   fTCFK3(0), // K3
83   fTCFL1(0), // L1
84   fTCFL2(0), // L2
85   fTCFL3(0), // L3
86
87   fTCFK1Int(0), // K1Int
88   fTCFK2Int(0), // K2Int
89   fTCFK3Int(0), // K3Int
90   fTCFL1Int(0), // L1Int
91   fTCFL2Int(0), // L2Int
92   fTCFL3Int(0), // L3Int
93
94   fBSL2HighThreshold(0), // BSL2HighThreshold
95   fBSL2LowThreshold(0),  // BSL2LowThreshold
96   fBSL2Offset(0),        // BSL2Offset
97   fBSL2Presamples(0),    // BSL2Presamples(0),
98   fBSL2Postsamples(0),   // BSL2Postsamples
99
100   fZSUThreshold(0),      // ZSUThreshold
101
102   fZSUMinSamplesaboveThreshold(0), // ZSUMinSamplesaboveThreshold
103   fZSUPresamples(0),     // ZSUPresamples
104   fZSUPostsamples(0),     // ZSUPostsamples
105   
106   fReader(0),           // for Altro Emulation on Raw Reader
107   fDecoder(0),
108   fDDLFolderName("/tmp/"),
109   fOutputDateFileName("/tmp/tmp.date"),
110   fOutputRootFileName("/tmp/tmp.root"),
111   fIsRandom(kTRUE),
112   fChannels(0),
113   fCDHs(0),
114   fADCs(0),
115   fTrailers(0),
116   fRawData(0) {
117   //
118   // Constructor of Altro Class
119   //
120   /*
121   ftimebins = timebins;
122   
123   fChannelShort_T = Channel;
124   
125   fOnBSL1 = 0;
126   fOnTCF = 0;
127   fOnBSL2 = 0;
128   fOnClip = 0;
129   fOnZSU = 0;
130   
131   fConfiguredAltro = 0;
132   fConfiguredBSL1 = 0;
133   fConfiguredTCF = 0;
134   fConfiguredBSL2 = 0;
135   fConfiguredZSU = 0;
136   */
137 }
138
139
140 AliTPCAltroEmulator::AliTPCAltroEmulator(const AliTPCAltroEmulator &altro):
141   TNamed(),
142   ftimebins(altro.ftimebins),
143 //  fChannelIn(Channel),
144   fChannelShort(altro.fChannelShort), 
145   fADCkeep(0),     
146   fOnBSL1(0), 
147   fOnTCF(0),  
148   fOnBSL2(0), 
149   fOnClip(0), 
150   fOnZSU(0),  
151
152   fConfiguredAltro(0),   // ConfiguredAltro
153   fConfiguredBSL1(0),    // ConfiguredBSL1
154   fConfiguredTCF(0),     // ConfiguredTCF
155   fConfiguredTCFraw(0),  // ConfiguredTCF
156   fConfiguredBSL2(0),    // ConfiguredBSL2
157   fConfiguredZSU(0),     // ConfiguredZSU
158   fBSL1mode(0),          // BSL1mode
159   fBSL1ValuePeDestal(0), // BSL1ValuePeDestal
160   fBSL1PedestalMem(0),  // BSL1PedestalMem
161   fBSL1polarity(0),      // BSL1polarity
162
163   fTCFK1(0), // K1
164   fTCFK2(0), // K2
165   fTCFK3(0), // K3
166   fTCFL1(0), // L1
167   fTCFL2(0), // L2
168   fTCFL3(0), // L3
169
170   fTCFK1Int(0), // K1Int
171   fTCFK2Int(0), // K2Int
172   fTCFK3Int(0), // K3Int
173   fTCFL1Int(0), // L1Int
174   fTCFL2Int(0), // L2Int
175   fTCFL3Int(0), // L3Int
176
177   fBSL2HighThreshold(0), // BSL2HighThreshold
178   fBSL2LowThreshold(0),  // BSL2LowThreshold
179   fBSL2Offset(0),        // BSL2Offset
180   fBSL2Presamples(0),    // BSL2Presamples(0),
181   fBSL2Postsamples(0),   // BSL2Postsamples
182
183   fZSUThreshold(0),      // ZSUThreshold
184
185   fZSUMinSamplesaboveThreshold(0), // ZSUMinSamplesaboveThreshold
186   fZSUPresamples(0),     // ZSUPresamples
187   fZSUPostsamples(0),     // ZSUPostsamples
188
189   fReader(0),           // for Altro Emulation on Raw Reader
190   fDecoder(0),
191   fDDLFolderName("/tmp/"),
192   fOutputDateFileName("/tmp/tmp.date"),
193   fOutputRootFileName("/tmp/tmp.root"),
194   fIsRandom(kTRUE),
195   fChannels(0),
196   fCDHs(0),
197   fADCs(0),
198   fTrailers(0),
199   fRawData(0) {
200   //
201   // copy constructor of Altro Class
202   //
203
204 }
205
206
207 /**     @brief Destructor of Altro Class
208  *
209  *      Destructor of Altro Class\n
210  */
211 AliTPCAltroEmulator::~AliTPCAltroEmulator() {
212   //
213   // Destructor of Altro Class
214   //
215
216   if(fConfiguredZSU == 1)
217     delete fADCkeep;
218
219   delete[] fChannels;
220   delete[] fCDHs    ;
221   delete[] fADCs    ;
222   delete[] fTrailers;
223   delete[] fRawData ;
224   delete fDecoder   ;
225
226 }
227
228 //_____________________________________________________________________________
229 AliTPCAltroEmulator& AliTPCAltroEmulator::operator = (const AliTPCAltroEmulator &source)
230 {
231   //
232   // AliTPCAltroEmulator assignment operator
233   //
234
235   if (&source == this) return *this;
236   new (this) AliTPCAltroEmulator(source);
237
238   return *this;
239
240 }
241
242
243
244 /**  @brief Configures which modules of the Altro should be on.
245  *
246  *      Configures which modules of the Altro should be on. Each of the modules
247  *      which are configured to be on, have to be configured later before running
248  *      the emulation!\n
249  *
250  *      @param ONBaselineCorrection1 an <tt> Int_t </tt> Switch (0,1) to turn on the Base Line Correction 1 (BSL1) Module
251  *      @param ONTailcancellation an <tt> Int_t </tt> Switch (0,1) to turn on the Tail Cancellation Filter (TCF) Module
252  *      @param ONBaselineCorrection2 an <tt> Int_t </tt> Switch (0,1) to turn on the Moving Average Filter (BSL2) Module
253  *      @param ONClipping an <tt> Int_t </tt> Switch (0,1) to turn on the Clipping Module. This is not possible in the real Altro, there it is always on.
254  *      @param ONZerosuppression an <tt> Int_t </tt> Switch (0,1) to turn on the Zero Suppression (ZSU) Module
255  *      @param ONDataFormatting an <tt> Int_t </tt> Switch (0,1) to turn on the Data Formatting on (not implemented)
256  */
257 void AliTPCAltroEmulator::ConfigAltro(Int_t ONBaselineCorrection1, Int_t ONTailcancellation, Int_t ONBaselineCorrection2, Int_t ONClipping, Int_t ONZerosuppression, Int_t ONDataFormatting){
258   //
259   // Configures which modules of the Altro should be on 
260   //
261   fOnBSL1 = InRange(ONBaselineCorrection1,0,1,"AliTPCAltroEmulator::ConfigAltro","ONBaselineCorrection1");
262   fOnTCF  = InRange(ONTailcancellation,0,1,"AliTPCAltroEmulator::ConfigAltro","ONTailcancellation");
263   fOnBSL2 = InRange(ONBaselineCorrection2,0,1,"AliTPCAltroEmulator::ConfigAltro","ONBaselineCorrection2");
264   fOnClip = InRange(ONClipping,0,1,"AliTPCAltroEmulator::ConfigAltro","ONClipping");
265   fOnZSU = InRange(ONZerosuppression,0,1,"AliTPCAltroEmulator::ConfigAltro","ONZerosuppression");
266   fConfiguredAltro = 1;
267   if (!fConfiguredAltro) { //dummy code to avoid warning
268     printf("%d\n",ONDataFormatting); // does not have to be checked
269   }
270 }
271
272 /**  @brief Configures the Base Line Correction 1 (BSL1) Module
273  *
274  *      Configures the Base Line Correction 1 (BSL1) Module. You dont have to build a proper pedestalMemory
275  *      array, a pointer of the correct type is enough, of course you are not allowed to use Basline
276  *      Correction Modes which need then the array ...\n
277  *      All configurable values are "Range checked" and if out of the Range set to the nearest extreme.
278  *      So the Emulation will work, but the result is maybe not the expected one.
279  *
280  *      @param mode an <tt> Int_t </tt> sets the mode of the Baseline Correction. See the Altro manual for a description
281  *      @param ValuePeDestal an <tt> Int_t </tt> this is the baseline of the Channel.
282  *      @param PedestalMem an <tt> *Int_t </tt> Pointer to a 1d Short_t Array with the pedestal memory Data
283  *      @param polarity an <tt> Int_t </tt> Switch (0,1) for the polarity
284  */
285 void AliTPCAltroEmulator::ConfigBaselineCorrection1(Int_t mode, Int_t ValuePeDestal, Int_t *PedestalMem, Int_t polarity){
286   //
287   // Configures the Base Line Correction 1 (BSL1) Module
288   //
289   fBSL1mode          = InRange(mode,0,10,"AliTPCAltroEmulator::ConfigBaselineCorrection1","mode");
290   fBSL1ValuePeDestal = InRange(ValuePeDestal,0,1023,"AliTPCAltroEmulator::BaselineCorrection1","ValuePeDestal");
291   fBSL1PedestalMem = PedestalMem;
292   fBSL1polarity = InRange(polarity,0,1,"AliTPCAltroEmulator::BaselineCorrection1","polarity");
293   fConfiguredBSL1 = 1;
294 }
295
296 /**  @brief Configures the Tail Cancellation Filter (TCF) Module
297  *
298  *      Configures the Tail Cancellation Filter (TCF) Module. You have to set the coefficients in the
299  *      Integer version.\n
300  *      To convert from Int_t to Float_t use (int)*(pow(2,-16)-1)
301  *      To convert from Float_t to Int_t usw (Float_t)*(pow(2,16)-1)
302  *      All configurable values are "Range checked" and if out of the Range set to the nearest extreme.
303  *      So the Emulation will work, but the result is maybe not the expected one.
304  *
305  *      @param K1 an <tt> Int_t </tt> sets the K1 coeeficient of the TCF
306  *      @param K2 an <tt> Int_t </tt> sets the K2 coeeficient of the TCF
307  *      @param K3 an <tt> Int_t </tt> sets the K3 coeeficient of the TCF
308  *      @param L1 an <tt> Int_t </tt> sets the L1 coeeficient of the TCF
309  *      @param L2 an <tt> Int_t </tt> sets the L2 coeeficient of the TCF
310  *      @param L3 an <tt> Int_t </tt> sets the L3 coeeficient of the TCF
311  */
312 void AliTPCAltroEmulator::ConfigTailCancellationFilter(Int_t K1, Int_t K2, Int_t K3, Int_t L1, Int_t L2, Int_t L3){
313   //
314   // Configures the Tail Cancellation Filter (TCF) Module
315   //
316   // conf from Int_t to fp:  (int)*(pow(2,-16)-1)
317   //             backway:  (Float_t)*(pow(2,16)-1)
318   fTCFK1Int = InRange(K1,0,65535,"AliTPCAltroEmulator::ConfigTailCancellationFilter","K1");
319   fTCFK2Int = InRange(K2,0,65535,"AliTPCAltroEmulator::ConfigTailCancellationFilter","K2");
320   fTCFK3Int = InRange(K3,0,65535,"AliTPCAltroEmulator::ConfigTailCancellationFilter","K3");
321   
322   fTCFL1Int = InRange(L1,0,65535,"AliTPCAltroEmulator::ConfigTailCancellationFilter","L1");
323   fTCFL2Int = InRange(L2,0,65535,"AliTPCAltroEmulator::ConfigTailCancellationFilter","L2");
324   fTCFL3Int = InRange(L3,0,65535,"AliTPCAltroEmulator::ConfigTailCancellationFilter","L3");
325   fConfiguredTCF = 1;
326 }
327 void AliTPCAltroEmulator::ConfigTailCancellationFilterForRAWfiles(Int_t *K1, Int_t *K2, Int_t *K3, Int_t *L1, Int_t *L2, Int_t *L3){
328   //
329   // Configures the Tail Cancellation Filter (TCF) Module - Different settings for IROC and OROC
330   //
331   // conf from Int_t to fp:  (int)*(pow(2,-16)-1)
332   //             backway:  (Float_t)*(pow(2,16)-1)
333
334   // IROC
335   fTCFK1IntROC[0] = InRange(K1[0],0,65535,"AliTPCAltroEmulator::ConfigTailCancellationFilter","K1[0]");
336   fTCFK2IntROC[0] = InRange(K2[0],0,65535,"AliTPCAltroEmulator::ConfigTailCancellationFilter","K2[0]");
337   fTCFK3IntROC[0] = InRange(K3[0],0,65535,"AliTPCAltroEmulator::ConfigTailCancellationFilter","K3[0]");
338   fTCFL1IntROC[0] = InRange(L1[0],0,65535,"AliTPCAltroEmulator::ConfigTailCancellationFilter","L1[0]");
339   fTCFL2IntROC[0] = InRange(L2[0],0,65535,"AliTPCAltroEmulator::ConfigTailCancellationFilter","L2[0]");
340   fTCFL3IntROC[0] = InRange(L3[0],0,65535,"AliTPCAltroEmulator::ConfigTailCancellationFilter","L3[0]");
341   // OROC
342   fTCFK1IntROC[1] = InRange(K1[1],0,65535,"AliTPCAltroEmulator::ConfigTailCancellationFilter","K1[1]");
343   fTCFK2IntROC[1] = InRange(K2[1],0,65535,"AliTPCAltroEmulator::ConfigTailCancellationFilter","K2[1]");
344   fTCFK3IntROC[1] = InRange(K3[1],0,65535,"AliTPCAltroEmulator::ConfigTailCancellationFilter","K3[1]");
345   fTCFL1IntROC[1] = InRange(L1[1],0,65535,"AliTPCAltroEmulator::ConfigTailCancellationFilter","L1[1]");
346   fTCFL2IntROC[1] = InRange(L2[1],0,65535,"AliTPCAltroEmulator::ConfigTailCancellationFilter","L2[1]");
347   fTCFL3IntROC[1] = InRange(L3[1],0,65535,"AliTPCAltroEmulator::ConfigTailCancellationFilter","L3[1]");
348
349
350   fConfiguredTCFraw = 1;
351 }
352
353
354 /**  @brief Configures the Moving Average Filter (BSL2) Module
355  *
356  *      Configures the Moving Average Filter (BSL2) Module.
357  *      All configurable values are "Range checked" and if out of the Range set to the nearest extreme.
358  *      So the Emulation will work, but the result is maybe not the expected one.
359  *
360  *      @param HighThreshold an <tt> Int_t </tt> sets the high Threshold
361  *      @param LowThreshold an <tt> Int_t </tt> sets the low Theshold
362  *      @param Offset an <tt> Int_t </tt> sets the the offset which is added to the Signal
363  *      @param Presamples an <tt> Int_t </tt> sets the number of pre samples excluded from the moving average caclulation
364  *      @param Postsamples an <tt> Int_t </tt> sets the number of post samples excluded from the moving average caclulation
365  */
366 void AliTPCAltroEmulator::ConfigBaselineCorrection2(Int_t HighThreshold, Int_t LowThreshold, Int_t Offset, Int_t Presamples, Int_t Postsamples){
367   //
368   // Configures the Moving Average Filter (BSL2) Module
369   //
370   fBSL2HighThreshold = InRange(HighThreshold,0,1023,"AliTPCAltroEmulator::ConfigBaselineCorrection2","HighThreshold");
371   fBSL2LowThreshold  = InRange(LowThreshold,0,1023,"AliTPCAltroEmulator::ConfigBaselineCorrection2","LowThreshold");
372   fBSL2Offset        = InRange(Offset,0,1023,"AliTPCAltroEmulator::ConfigBaselineCorrection2","Offset");
373   fBSL2Presamples    = InRange(Presamples,0,3,"AliTPCAltroEmulator::ConfigBaselineCorrection2","Presamples");
374   fBSL2Postsamples   = InRange(Postsamples,0,15,"AliTPCAltroEmulator::ConfigBaselineCorrection2","Postsamples");
375   fConfiguredBSL2 = 1;
376 }
377
378 /**  @brief Configures the Zero Suppression Module (ZSU)
379  *
380  *      Configures the Zero Suppression Module (ZSU).
381  *      All configurable values are "Range checked" and if out of the Range set to the nearest extreme.
382  *      So the Emulation will work, but the result is maybe not the expected one.
383  *
384  *      @param Threshold an <tt> Int_t </tt> sets the Threshold
385  *      @param MinSamplesaboveThreshold an <tt> Int_t </tt> sets the minimum number of samples which have to be greater than the threshold
386  *      @param Presamples an <tt> Int_t </tt> sets the number of pre samples which are kept
387  *      @param Postsamples an <tt> Int_t </tt> sets the number of post samples which are kept
388  */
389 void AliTPCAltroEmulator::ConfigZerosuppression(Int_t Threshold, Int_t MinSamplesaboveThreshold, Int_t Presamples, Int_t Postsamples){
390   //
391   // Configures the Zero Suppression Module (ZSU)
392   //
393   fZSUThreshold                = InRange(Threshold,0,1023,"AliTPCAltroEmulator::BaselineCorrection1","Threshold");
394   fZSUMinSamplesaboveThreshold = InRange(MinSamplesaboveThreshold,1,3,"AliTPCAltroEmulator::BaselineCorrection1","MinSamplesaboveThreshold");
395   fZSUPresamples               = InRange(Presamples,0,3,"AliTPCAltroEmulator::BaselineCorrection1","Presamples");
396   fZSUPostsamples              = InRange(Postsamples,0,7,"AliTPCAltroEmulator::BaselineCorrection1","Postsamples");
397   fADCkeep = (Short_t *)calloc(sizeof(short),ftimebins);
398   
399   for(Int_t i = 0; i < ftimebins; i++){
400     fADCkeep[i] = 0;
401   }
402   fConfiguredZSU = 1;
403 }
404
405 /**  @brief Prints the set Parameters, if module is configured
406  *
407  *      Prints the set Parameters, if module is configured.
408  */
409 void AliTPCAltroEmulator::PrintParameters(){
410   //
411   // Prints the set Parameters, if module is configured
412   //
413   cout << "+-------------------------------------------+" << endl;
414   cout << "| Configured Parameters of the Altro Module |" << endl;
415   cout << "+-------------------------------------------+" << endl << endl;
416   
417   cout << "Parameters set in the Altro Modules:" << endl << endl;
418   cout << "ONBaselineCorrection1: " << fOnBSL1 << endl;
419   cout << "ONTailcancellation   : " << fOnTCF << endl;
420   cout << "ONBaselineCorrection2: " << fOnBSL2 << endl;
421   cout << "ONClipping           : " << fOnClip << endl;
422   cout << "ONZerosuppression    : " << fOnZSU << endl << endl << endl;
423   if(fConfiguredBSL1 == 1){
424     cout << "Parameters set in the BSL1 (Baseline Correction 1) Module:" << endl << endl;
425     cout << "mode                 : " << fBSL1mode << endl;
426     cout << "ValuePeDestal        : " << fBSL1ValuePeDestal << endl;
427     cout << "polarity             : " << fBSL1ValuePeDestal << endl << endl << endl;
428   }else{
429     cout << "BSL1 (Baseline Correction 1) Module not configured!" << endl << endl << endl;
430   }
431   if(fConfiguredTCF == 1){
432     cout << "Parameters set in the TCF (TailCancellation Filter) Module:" << endl << endl;
433     cout << "K1       (int|Float_t) : " << fTCFK1Int << " | " << fTCFK1Int/(Float_t)((1<<16)-1) << endl;
434     cout << "K2       (int|Float_t) : " << fTCFK2Int << " | " << fTCFK2Int/(Float_t)((1<<16)-1) << endl;
435     cout << "K3       (int|Float_t) : " << fTCFK3Int << " | " << fTCFK3Int/(Float_t)((1<<16)-1) << endl;
436     cout << "L1       (int|Float_t) : " << fTCFL1Int << " | " << fTCFL1Int/(Float_t)((1<<16)-1) << endl;
437     cout << "L2       (int|Float_t) : " << fTCFL2Int << " | " << fTCFL2Int/(Float_t)((1<<16)-1) << endl;
438     cout << "L3       (int|Float_t) : " << fTCFL3Int << " | " << fTCFL3Int/(Float_t)((1<<16)-1) << endl << endl << endl;
439   }else{
440     cout << "TCF (TailCancellation Filter) Module not configured!" << endl << endl << endl;
441   }
442   if(fConfiguredBSL2 == 1){
443     cout << "Parameters set in the BSL2 (Baseline Correction 2) Module:" << endl << endl;
444     cout << "HighThreshold        : " << fBSL2HighThreshold << endl;
445     cout << "LowThreshold         : " << fBSL2LowThreshold << endl;
446     cout << "Offset               : " << fBSL2Offset << endl;
447     cout << "Presamples           : " << fBSL2Presamples << endl;
448     cout << "Postsamples          : " << fBSL2Postsamples << endl << endl << endl;
449   }else{
450     cout << "BSL2 (Baseline Correction 2) Module not configured!" << endl << endl << endl;
451   }
452   if(fConfiguredZSU == 1){
453     cout << "Parameters set in the ZSU (Zero Suppression Unit) Module:" << endl << endl;
454     cout << "Threshold            : " << fZSUThreshold << endl;
455     cout << "MinSampaboveThreshold: " << fZSUMinSamplesaboveThreshold << endl;
456     cout << "Presamples           : " << fZSUPresamples << endl;
457     cout << "Postsamples          : " << fZSUPostsamples << endl << endl << endl;
458   }else{
459     cout << "ZSU (Zero Suppression Unit) Module not configured!" << endl << endl << endl;
460   }
461 }
462
463
464 void AliTPCAltroEmulator::SetChannelData(Int_t timebins, Short_t* channelData) {
465   //
466   // Set channel data, for example a new channel
467   //
468
469   ftimebins = timebins;
470   fChannelShort = channelData;
471
472 }
473  
474
475 /**  @brief Runs the emulation of all configured Modules.
476  *
477  *      Runs the emulation of all configured Modules. This changes then the content of the
478  *      input Array
479  */
480 void AliTPCAltroEmulator::RunEmulation(Int_t roc){
481   //
482   // Runs the emulation of all configured Modules.
483   //
484
485   if (!fChannelShort) {
486     printf("ERROR cant run Altro Emulation: Channel input not set.\nUse for example: SetChannelData(Int_t timebins, Short_t* Channel)\n");
487     return;
488   }
489
490   //cout << "AliTPCAltroEmulator::RunEmulation | start" << endl;
491   if(fConfiguredAltro == 0){
492     cout << "ERROR cant run Altro Emulation because not configured" << endl;
493     return;
494   }
495   
496   //cout << "AliTPCAltroEmulator::RunEmulation | start BSL1 on: " << fOnBSL1 << " configures: " << fConfiguredBSL1 << endl;
497   if(fOnBSL1 == 1){
498     if(fConfiguredBSL1 == 1){
499       BaselineCorrection1(fBSL1mode, fBSL1ValuePeDestal, fBSL1PedestalMem, fBSL1polarity);
500     }else{
501       cout << "ERROR cant run Baseline Correction 1 because not configured" << endl;
502       return;
503     }
504   }
505   
506   //cout << "AliTPCAltroEmulator::RunEmulation | start TCF on: " << fOnTCF << " configures: " << fConfiguredTCF << endl;
507   if(fOnTCF == 1){
508     if (roc==-1) { // use one set of TCF params
509       if(fConfiguredTCF == 1){
510         TailCancellationFilterFixedPoint(fTCFK1Int, fTCFK2Int, fTCFK3Int, fTCFL1Int, fTCFL2Int, fTCFL3Int);
511       }else{
512         cout << "ERROR cant run Tail Cancellation Filter because not configured" << endl;
513         return;
514       }
515     } else { // use different TCF params for IROC and OROC
516       if(fConfiguredTCFraw == 1){
517         if (roc==0)      //IROC
518           TailCancellationFilterFixedPoint(fTCFK1IntROC[0], fTCFK2IntROC[0], fTCFK3IntROC[0], 
519                                            fTCFL1IntROC[0], fTCFL2IntROC[0], fTCFL3IntROC[0]);
520         else if (roc==1) // OROC
521           TailCancellationFilterFixedPoint(fTCFK1IntROC[1], fTCFK2IntROC[1], fTCFK3IntROC[1], 
522                                            fTCFL1IntROC[1], fTCFL2IntROC[1], fTCFL3IntROC[1]);
523         else
524           cout << "ERROR cant run Tail Cancellation Filter because TCF settings for ROC not found" << endl;
525       } else {
526         cout << "ERROR cant run Tail Cancellation Filter because not configured (for RAW data files!)" << endl;
527         return;
528       }
529
530     }
531   }
532   
533   //cout << "AliTPCAltroEmulator::RunEmulation | start BSL2 on: " << fOnBSL2 << " configures: " << fConfiguredBSL2 << endl;
534   if(fOnBSL2 == 1){
535     if(fConfiguredBSL2 == 1){
536       BaselineCorrection2RTL(fBSL2HighThreshold, fBSL2LowThreshold, fBSL2Offset, fBSL2Presamples, fBSL2Postsamples);
537     }else{
538       cout << "ERROR cant run Baseline Correction 2 because not configured" << endl;
539       return;
540     }
541   }
542   //cout << "AliTPCAltroEmulator::RunEmulation | start CLIP on: " << fOnClip << endl;
543   if(fOnClip == 1){
544     Clipping();
545   }
546   //cout << "AliTPCAltroEmulator::RunEmulation | start ZSU on: " << fOnZSU << " configures: " << fConfiguredZSU << endl;
547   if(fOnZSU == 1){
548     if(fConfiguredZSU == 1){
549       Zerosuppression(fZSUThreshold,fZSUMinSamplesaboveThreshold,fZSUPresamples,fZSUPostsamples);
550     }else{
551       cout << "ERROR cant run Zero Suppression Unit because not configured" << endl;
552       return;
553     }
554   }
555
556   
557
558 }
559
560 void AliTPCAltroEmulator::BaselineCorrection1(Int_t mode, Int_t ValuePeDestal, Int_t *PedestalMem, Int_t polarity){
561   //
562   // BaselineCorrection1
563   //
564
565   //VPD == 0 !!
566   Int_t fixedPeDestal = 0;
567   
568   if(polarity ==1){
569     for(Int_t i = 0; i < ftimebins; i++){
570       fChannelShort[i]  = 1023 - fChannelShort[i];
571     }
572   }
573   
574   switch(mode) {
575   case kDINxFPD:
576     for(Int_t i = 0; i < ftimebins; i++)
577       fChannelShort[i]  = fChannelShort[i]  - fixedPeDestal;
578     break;
579   case kDINxFT:
580     for(Int_t i = 0; i < ftimebins; i++)
581       fChannelShort[i]  = fChannelShort[i]  - PedestalMem[i];
582     break;
583   case kDINxFDIN:
584     for(Int_t i = 0; i < ftimebins; i++)
585       fChannelShort[i]  = fChannelShort[i]  - PedestalMem[ fChannelShort[i] ];
586     break;
587   case kDINxFDINxVPD:
588     for(Int_t i = 0; i < ftimebins; i++)
589       fChannelShort[i]  = fChannelShort[i]  - PedestalMem[ fChannelShort[i] - ValuePeDestal];
590     break;
591   case kDINxVPDxFPD:
592     for(Int_t i = 0; i < ftimebins; i++)
593       fChannelShort[i]  = fChannelShort[i]  - ValuePeDestal - fixedPeDestal;
594     break;
595   case kDINxVPDxFT:
596     for(Int_t i = 0; i < ftimebins; i++)
597       fChannelShort[i]  = fChannelShort[i]  - ValuePeDestal - PedestalMem[i];
598     break;
599   case kDINxVPDxFDIN:
600     for(Int_t i = 0; i < ftimebins; i++)
601       fChannelShort[i]  = fChannelShort[i]  - ValuePeDestal - PedestalMem[ fChannelShort[i] ];
602     break;
603   case kDINxVPDxFDINxVPD:
604     for(Int_t i = 0; i < ftimebins; i++)
605       fChannelShort[i]  = fChannelShort[i]  - ValuePeDestal - PedestalMem[ fChannelShort[i] - ValuePeDestal ];
606     break;
607   case kFDINxFPD:
608     for(Int_t i = 0; i < ftimebins; i++)
609       fChannelShort[i]  = PedestalMem[ fChannelShort[i] ] - fixedPeDestal;
610     break;
611   case kFDINxVPDxFPD:
612     for(Int_t i = 0; i < ftimebins; i++)
613       fChannelShort[i]  = PedestalMem[ fChannelShort[i] - ValuePeDestal ] - fixedPeDestal;
614     break;
615   case kFTxFPD:
616     for(Int_t i = 0; i < ftimebins; i++)
617       fChannelShort[i]  = PedestalMem[i] - fixedPeDestal;
618     break;
619   }
620 }
621
622 Int_t AliTPCAltroEmulator::Multiply36(Int_t P, Int_t N){
623   //
624   // multiply function to emulate the 36 bit fixed point multiplication of the Altro.
625   //
626   long long retval =0;
627   long long temp = 0;
628   long long vAX = 0;
629   temp = (long long)P*(long long)N;
630   vAX = (( Mask(temp,35,18) + ((long long)(-P)<<18) ) + Mask(temp,17,0));
631   if ( Maskandshift(N,17,17) == 1){
632     retval = ((Maskandshift(vAX,35,35)<<17) + Maskandshift(vAX,32,16));
633   }else{
634     retval = Maskandshift(temp,32,16);
635   }
636   return retval;
637 }
638 long long AliTPCAltroEmulator::Mask(long long in, Int_t left, Int_t right){
639   //
640   // mask
641   //
642   long long retval;
643   long long pattern;
644   long long length = abs(left - right)+1;
645   pattern = ((1<<length)-1)<<right;
646   retval = in&pattern;
647   return retval;
648 }
649
650 long long AliTPCAltroEmulator::Maskandshift(long long in, Int_t left, Int_t right){
651   //
652   // maskandshift
653   //
654   long long retval;
655   long long pattern;
656   long long length = abs(left - right)+1;
657   pattern = ((1<<length)-1);
658   retval = (in>>right)&pattern;
659   return retval;
660 }
661
662 void AliTPCAltroEmulator::TailCancellationFilterFixedPoint(Int_t K1, Int_t K2, Int_t K3, Int_t L1, Int_t L2, Int_t L3){
663   //
664   // TailCancellationFilterFixedPoint
665   //
666   Int_t c1n = 0, c2n = 0, c3n = 0;
667   Int_t c1o = 0, c2o = 0, c3o = 0;
668   Int_t d1  = 0, d2  = 0;
669   Int_t dout = 0;
670   Int_t din = 0;
671   Int_t bit = 0;
672
673   //  printf("%5d %5d %5d %5d %5d %5d\n",K1,K2,K3,L1,L2,L3);
674
675   for(Int_t i = 0; i < ftimebins; i++){
676     din = fChannelShort[i];
677     
678     din = (din<<2);
679     c1n             = Mask( (Mask(din,17,0) + Multiply36(K1,Mask(c1o,17,0)) ) ,17,0);
680     d1              = Mask( (Mask(c1n,17,0) - Multiply36(L1,Mask(c1o,17,0)) ) ,17,0);
681     //d1              = Mask( (Mask(c1n,17,0) + Mask(~Multiply36(L1,Mask(c1o,17,0))+1,17,0) ) ,17,0);
682     
683     c2n             = Mask( (Mask(d1 ,17,0) + Multiply36(K2,Mask(c2o,17,0)) ) ,17,0);
684     d2              = Mask( (Mask(c2n,17,0) - Multiply36(L2,Mask(c2o,17,0)) ) ,17,0);
685     //d2              = Mask( (Mask(c2n,17,0) + Mask(~Multiply36(L2,Mask(c2o,17,0))+1,17,0) ) ,17,0);
686     
687     c3n             = Mask( (Mask(d2 ,17,0) + Multiply36(K3,Mask(c3o,17,0)) ) ,17,0);
688     dout            = Mask( (Mask(c3n,17,0) - Multiply36(L3,Mask(c3o,17,0)) ) ,17,0);
689     //dout            = Mask( (Mask(c3n,17,0) + Mask(~Multiply36(L3,Mask(c3o,17,0))+1,17,0) ) ,17,0);
690     
691     if( (Maskandshift(dout,2,2) == 1) || (Maskandshift(dout,1,1) == 1)){
692       bit = 1;
693     }else{
694       bit = 0;
695     }
696     
697     dout = ((dout>>3)<<1) + bit;
698     if(Maskandshift(dout,15,15) == 1){
699       //is needed to get the correct coding when getting negative results
700       dout = -Mask((-Mask(dout,9,0)),9,0);
701     }else{
702       dout = Mask(dout,9,0);
703     }
704     
705     fChannelShort[i] = (short) dout;
706     c1o = c1n;
707     c2o = c2n;
708     c3o = c3n;
709   }
710 }
711
712 void AliTPCAltroEmulator::BaselineCorrection2RTL(Int_t HighThreshold, Int_t LowThreshold, Int_t Offset, Int_t Presamples, Int_t Postsamples){
713   //
714   // BaselineCorrection2RTL
715   //
716
717   //cout << "Altro::BaselineCorrection2RTL | HighThreshold: " << HighThreshold << " LowThreshold: " << LowThreshold << " Offset: " << Offset << " Presamples: " << Presamples << " Postsamples: " << Postsamples << endl;
718   //more or less direct "translation" of the hdl code.
719   //Input signals
720   Int_t din;
721   Int_t dout;
722   Int_t edges[6]; // = Postsamples*4 + Presamples;
723   Int_t offset = Offset;
724   Int_t thrlo = LowThreshold;//called thr_mau[19] ...
725   Int_t thrhi = HighThreshold;
726   
727   // Variables
728   Int_t fOld[4]; //flag pipe
729   Int_t fNew[4]; //flag pipe
730   Int_t dOld[4]; //data pipe
731   Int_t dNew[4]; //data pipe
732   Int_t dxOld;
733   Int_t dxNew;
734   Int_t pstscnt; // Counter for Postsamples
735   Int_t zOld[9]; // Filter stages
736   Int_t zNew[9]; // Filter stages
737   Int_t zxOld; //Accumulator stage
738   Int_t zxNew; //Accumulator stage
739   Int_t valcntOld; //Valid sample counter
740   Int_t valcntNew = 0; //Valid sample counter
741   
742   Int_t valid; //Valid flag
743   Int_t fx; //postsample flag
744   //Int_t s07; // differentiator result
745   Int_t s8; // Acc + Diff result
746   Int_t flag;
747   //Int_t bsth; //baseline threshold
748   //Int_t din_p; //Data input strictly positive
749   Int_t bsl;
750   //Int_t dx_bsls; // dx -bsl
751   //Int_t dx_clip; // dxbsl clipped
752   //Int_t bsl_of = 0;
753   
754   //initialisation
755   for(Int_t i = 0; i < 9 ; i++)
756     zOld[i] = 0;
757   for(Int_t i = 0; i < 4 ; i++){
758     fOld[i] = 0;
759     dOld[i] = 0;
760   }
761   dxOld= 0;
762   pstscnt = 0;
763   zxOld = 0;
764   valcntOld = 0;
765   valid = 0;
766   for(Int_t i = 0; i < 2 ; i++){
767     edges[i] = (Presamples&(1<<i))>>i;
768   }
769   for(Int_t i = 0; i < 4 ; i++){
770     edges[(3-i)+2] = (Postsamples&(1<<i))>>i;
771   }
772   /*cout << "edges :";
773     for(Int_t i = 0; i < 6 ; i++)
774     cout << edges[i] << ":";
775     cout << " Presamples: " << Presamples << " Postsamples: " << Postsamples << endl;*/
776   
777   //Loop
778   //cout << "AliTPCAltroEmulator::BaselineCorrection2_RTL | starting Loop" << endl;
779   for(Int_t timebin = -12; timebin < ftimebins+10; timebin++){
780     //cout << "AliTPCAltroEmulator::BaselineCorrection2_RTL | in Loop timebin: " << timebin << endl;
781     din = GetElement(fChannelShort,timebin);
782     
783     s8 = zxOld + (zOld[8] - zOld[0]);
784     
785     if(valid == 1)
786       bsl = s8>>3;// ...
787     else
788       bsl = 0;
789     
790     //assign flag = (din_p > thrhi) | (thrlo > din_p);  // Signal samples between thresholds
791     if( (din <= (bsl + thrhi)) && (din >= (bsl - thrlo)) )
792       flag = 0;
793     else
794       flag = 1;
795     
796     if(pstscnt == 0)
797       fx = 0;
798     else
799       fx = 1;
800     
801     if(valcntOld >= 12)
802       valid = 1;
803     else
804       valid = 0;
805     
806     fNew[3] = flag;
807     
808     if( (fOld[3] == 1) || ( (flag == 1) && ( (edges[0] == 1) || (edges[1] == 1) ) ) ) //f[2] =  f[3] | (flag&(edges[0]|edges[1]));
809       fNew[2] = 1;
810     else
811       fNew[2] = 0;
812     
813     if( (fOld[2] == 1) || ( (edges[1] == 1) && (flag == 1) ) ) //               f[1] =  f[2] | (edges[1] & flag);
814       fNew[1] = 1;
815     else
816       fNew[1] = 0;
817     
818     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;
819       fNew[0] = 1;
820     else
821       fNew[0] = 0;
822     
823     dxNew = dOld[0];
824     for(Int_t i = 0; i < 3; i++)
825       dNew[i] = dOld[i+1];
826     dNew[3] = din;
827     
828     if( (fOld[1]==1) && (fOld[2]==0) )
829       pstscnt = Postsamples;
830     else if(fx == 1)
831       pstscnt--;
832     
833     if(fOld[0] == 0){
834       if(valid == 0)
835         valcntNew =  ++valcntOld;
836       
837       zxNew = s8;
838       for(Int_t i = 0; i < 8; i++)
839         zNew[i] = zOld[i+1];
840       zNew[8] = dOld[0];
841     }else{
842       zxNew = zxOld;
843       for(Int_t i = 0; i < 9; i++)
844         zNew[i] = zOld[i];
845     }
846     dout = dxOld - (bsl - offset);
847     //if(dout <0)
848     //  dout = 0;
849     
850     SetElement(fChannelShort,timebin-5,(short)dout);
851     //sim clockschange
852     for(Int_t i = 0; i < 9 ; i++)
853       zOld[i] = zNew[i];
854     zxOld = zxNew;
855     for(Int_t i = 0; i < 4 ; i++){
856       fOld[i] = fNew[i];
857       dOld[i] = dNew[i];
858     }
859     dxOld = dxNew;
860     valcntOld = valcntNew;
861   }
862 }
863
864 void AliTPCAltroEmulator::Clipping(){ 
865   //
866   // implement if no BC2 clipping has to run
867   //
868   for(Int_t i = 0; i < ftimebins; i++){
869     if(fChannelShort[i] < -1)
870       fChannelShort[i] = -1;
871   }
872 }
873
874 void AliTPCAltroEmulator::Zerosuppression(Int_t Threshold, Int_t MinSamplesaboveThreshold, Int_t Presamples, Int_t Postsamples){
875   //
876   // add again altro feature
877   //
878
879   //TODO: Implement "Altro zsu merging"
880   //Int_t Postsamplecounter = 0;
881   //Int_t setPostsample = 0;
882
883   for(Int_t i = 0; i < ftimebins; i++){
884     if(fChannelShort[i] >= Threshold){
885       fADCkeep[i] = 1;
886     }
887   }
888
889   Int_t startofclustersequence = -1;
890   Int_t endofClustersInSequence = -1;
891   
892   for(Int_t i = 0; i < ftimebins; i++){
893     if( (fADCkeep[i] == 1) && (GetElement(fADCkeep,i-1) == -1) ){
894       startofclustersequence = i;
895     }
896     if( (fADCkeep[i] == 1) && (GetElement(fADCkeep,i+1) == -1) ){
897       endofClustersInSequence = i;
898     }
899     //cout << i << " startofclustersequence: " << startofclustersequence << " endofClustersInSequence: " << endofClustersInSequence;
900     if( (startofclustersequence != -1) && (endofClustersInSequence != -1) ){
901       //cout << " found! " <<  (endofClustersInSequence - startofclustersequence + 1);
902       if ( (endofClustersInSequence - startofclustersequence + 1) < MinSamplesaboveThreshold ){
903         for(Int_t j = startofclustersequence; j <= endofClustersInSequence ; j++){
904           fADCkeep[j] = 0;
905         }
906       }
907       startofclustersequence = -1;
908       endofClustersInSequence = -1;
909     }
910     //cout << endl;
911   }
912   
913   /*for(Int_t i = 0; i < ftimebins; i++){
914     if( (GetElement(fADCkeep,i-1) == 1) && (GetElement(fADCkeep,i) == 0) && (GetElement(fADCkeep,i+1) == 1) ){
915     SetElement(fADCkeep,i,1);
916     }
917     }*/
918   
919   for(Int_t i = 0; i < ftimebins; i++){
920     if( (fADCkeep[i] == 1) && (GetElement(fADCkeep,i-1) == 0) ){
921       for(Int_t j = i-Presamples ; j <= i; j++){
922         SetElement(fADCkeep,j,1);
923       }
924     }
925   }
926   for(Int_t i = ftimebins; i >= 0; i--){
927     if( (fADCkeep[i] == 1) && (GetElement(fADCkeep,i+1) == 0) ){
928       for(Int_t j = i ; j <= i+Postsamples; j++){
929         SetElement(fADCkeep,j,1);
930       }
931     }
932   }
933   /*cout << " Postsamplecounter: " << Postsamplecounter;
934     for(Int_t j = i+1 ; j <= i+Postsamples; j++){
935     SetElement(fADCkeep,j,1);
936     i+=Postsamples;
937     }
938     cout << endl;
939     }
940     cout << i << " ADCK: " << GetElement(fADCkeep,i);
941     cout << " Postsam: " << Postsamplecounter << " ADCK: " << GetElement(fADCkeep,i);*/
942   
943   for(Int_t i = 0; i < ftimebins; i++){
944     if( (fADCkeep[i] == 1) && (GetElement(fADCkeep,i+1) == 0) && ( (GetElement(fADCkeep,i+3) == 1) || (GetElement(fADCkeep,i+2) == 1) ) ){
945       SetElement(fADCkeep,i+1,1);
946       SetElement(fADCkeep,i+2,1);
947     }
948   }
949
950   for(Int_t i = 0; i < ftimebins; i++){
951     if( !GetKeepChannel(i) || GetShortChannel(i)<Threshold) {
952       SetElement(fChannelShort,i,-1); // set non relevant data to -1
953     }
954   }
955
956
957 }
958
959 /**  @brief formats the data like the ALTRO. Result is a 64 bit array
960  *
961  *      formats the data like the ALTRO. Result is a 64 bit array
962  *
963  */
964
965 void AliTPCAltroEmulator::DataFormater(){
966   //
967   // formats the data like the ALTRO. Result is a 64 bit array
968   //
969
970
971 }
972
973
974 /**  @brief calculates the compression out of the bitmask
975  *
976  *      calculates the compression out of the bitmask with the set adc values
977  *
978  *      @return \c Float_t consisting of the compression factor
979  */
980 Float_t AliTPCAltroEmulator::CalculateCompression() {
981   //
982   // calculates the compression out of the bitmask
983   //
984
985   // calculation is based on altro 10 bit words ..
986   Int_t sample = 0;
987   Int_t cluster = 0;
988   Int_t data = 0;
989   Float_t retval = 0.0;
990   
991   for(Int_t i = 0; i < ftimebins; i++){
992     if(fADCkeep[i] == 1){
993       sample++;
994     }
995     if( (fADCkeep[i] == 1) && (GetElement(fADCkeep,i+1) == 0) ){
996       cluster++;
997     }
998   }
999   data = sample + cluster*2;
1000   data = data + data%4 + 4;
1001   if(data >0){
1002     retval = ftimebins / (Float_t)data;//num of timebins is equal to max number of samples
1003   }else{
1004     retval = 1.0;
1005   }
1006   return retval;
1007 }
1008
1009 Short_t AliTPCAltroEmulator::GetElement(short* Array,Int_t index){
1010   //
1011   // GetElement of array
1012   //
1013   if (index < 0)
1014     return 0;
1015   else if(index >= ftimebins)
1016     return 0;
1017   else
1018     return Array[index];
1019 }
1020
1021 void AliTPCAltroEmulator::SetElement(short* Array,Int_t index,Short_t value){
1022   //
1023   // SetElement of array
1024   //
1025   if (index < 0)
1026     return;
1027   else if(index >= ftimebins)
1028     return;
1029   else
1030     Array[index] = value;
1031 }
1032
1033 Int_t AliTPCAltroEmulator::InBand(Int_t ADC,Int_t bsl, Int_t LowThreshold, Int_t HighThreshold){
1034   //
1035   // check if it's within the band of search
1036   //
1037   Int_t fLow = bsl - LowThreshold;
1038   Int_t fHigh = bsl + HighThreshold;
1039   if( (ADC <= fHigh) && (ADC >= fLow) )
1040     return 1;
1041   else
1042     return 0;
1043 }
1044
1045 Int_t AliTPCAltroEmulator::InRange(Int_t parameter,Int_t Low,Int_t High,const char *Module,const char *ParameterName){
1046   //
1047   // checks it it's within the range
1048   //
1049
1050   char out[255];
1051   Int_t retval;
1052   if(parameter > High){
1053     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);
1054     cout << out << endl;
1055     retval = High;
1056   }else if(parameter < Low){
1057     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);
1058     cout << out << endl;
1059     retval = Low;
1060   }else{
1061     retval = parameter;
1062   }
1063   return retval;
1064 }
1065
1066 Short_t AliTPCAltroEmulator::GetShortChannel(Int_t i){
1067   //
1068   // GetElement of channel
1069   //
1070   return GetElement(fChannelShort,i);
1071 }
1072
1073 Short_t AliTPCAltroEmulator::GetKeepChannel(Int_t i){
1074   //
1075   // GetElement of Keep Channel
1076   //
1077   return GetElement(fADCkeep,i);
1078 }
1079
1080 Bool_t AliTPCAltroEmulator::WriteEvent(Int_t ievent) {
1081   //
1082   // Write event to the DDL data folders
1083   //
1084
1085   for (Int_t ddlID=0;ddlID<216;++ddlID) {
1086     Bool_t  *channelsDDL=fChannels+ddlID*4096     ;
1087     Short_t *adcsDDL    =fADCs    +ddlID*4096*1024;
1088     UInt_t  *cdhDDL     =fCDHs    +ddlID*8        ;
1089     UInt_t  *trailerDDL =fTrailers+ddlID*9        ;
1090     
1091     FILE *file=fopen(Form("%s/raw%d/TPC_%03d.ddl",
1092                           fDDLFolderName.Data(),ievent,768+ddlID),
1093                      "wb");
1094     if (!file) return kFALSE;
1095     Int_t i32;
1096     // write CDH (first word to be altered later)
1097     for (i32=0;i32<8;++i32)
1098       fRawData[i32]=cdhDDL[i32];
1099
1100     // process payload
1101     for (Int_t hwaddr=0;hwaddr<4096;++hwaddr) if (channelsDDL[hwaddr]) {
1102       Short_t *adcsChannel=adcsDDL+hwaddr*1024;
1103       // merge custers
1104       // TODO: acqusition window
1105       for (Int_t it=0;it<1024-3;++it) {
1106         if (adcsChannel[it]>=0&&adcsChannel[it+3]>=0) {
1107           if (adcsChannel[it+1]<0) {
1108             //      printf("merge");
1109             adcsChannel[it+1]=0;
1110           }
1111           if (adcsChannel[it+2]<0) {
1112             //      printf("merge");
1113             adcsChannel[it+2]=0;
1114           }
1115         }
1116       }
1117       Int_t i10=3;
1118       Int_t icw=0;
1119       Int_t its=1;
1120       Int_t cw =0;
1121       Int_t ts =0;
1122       for (Int_t it=1023;it>=0;--it) {
1123         Short_t w10=adcsChannel[it];
1124         if (w10>=0) {
1125           if (cw<0) {
1126             icw=i10++;
1127             its=i10++;
1128             cw =0    ;
1129             ts=it    ;
1130           }
1131           fRawData[i32+i10/3]|=w10<<(10*(2-i10%3));
1132           ++i10;
1133           ++cw;
1134         }
1135         else {
1136           if (cw>=0) {
1137             cw+=2;
1138             fRawData[i32+icw/3]|=cw <<(10*(2-icw%3));
1139             fRawData[i32+its/3]|=ts <<(10*(2-its%3));
1140             cw=-1;
1141           }
1142         }
1143       }
1144       fRawData[i32]=0x1<<30|(i10-3)<<16|hwaddr;
1145       i32+=(i10+2)/3;
1146
1147       // clean up
1148       for (Int_t i=0;i<1024;++i) adcsChannel[i]=-1;
1149       channelsDDL[hwaddr]=kFALSE;
1150     }
1151
1152     // write RCU trailer
1153     fRawData[i32]=0x2<<30|(i32-8);i32++;
1154     for (Int_t i=0;i<8;++i)
1155       fRawData[i32++]=trailerDDL[i];
1156
1157     // write first word of CDH
1158     fRawData[0]=i32*4;
1159     
1160     Int_t nwritten=fwrite(fRawData,sizeof(UInt_t),i32,file);
1161     if (nwritten!=i32) return kFALSE;
1162
1163     // clean up
1164     do {fRawData[--i32]=0;} while (i32>0);
1165
1166     fclose(file);
1167   }
1168   return kTRUE;
1169 }
1170
1171 Bool_t AliTPCAltroEmulator::GDC2DDLs(AliRawVEvent *gdc,Int_t ievent) {
1172   //
1173   // Converte GDC data to DDL format
1174   //
1175   for(Int_t iLDC=0;iLDC<gdc->GetNSubEvents();++iLDC) {
1176     AliRawVEvent *ldc=gdc->GetSubEvent(iLDC);
1177     for(Int_t iEq=0;iEq<ldc->GetNEquipments();++iEq) {
1178       AliRawVEquipment *eq=ldc->GetEquipment(iEq);
1179       AliRawEquipmentHeader *eqHeader=eq->GetEquipmentHeader();
1180       Int_t eqSize=eqHeader->GetEquipmentSize();
1181       if (eqSize>0) {
1182         Int_t ddlIndex;
1183         Int_t detId=AliDAQ::DetectorIDFromDdlID(eqHeader->GetId(),ddlIndex);
1184         Int_t nwritten=0;
1185         FILE *ddlFile=fopen(Form("%s/raw%d/%s",
1186                                  fDDLFolderName.Data(),
1187                                  ievent,
1188                                  AliDAQ::DdlFileName(detId,ddlIndex)),
1189                             "wb");
1190         AliRawData *rawData=eq->GetRawData();
1191         if (ddlFile) {
1192           nwritten=fwrite(rawData->GetBuffer(),1,rawData->GetSize(),ddlFile);
1193           fclose(ddlFile);
1194         }
1195         if (nwritten<rawData->GetSize()) return kFALSE;
1196       }
1197     }
1198   }
1199   return kTRUE;
1200 }
1201
1202
1203 Bool_t AliTPCAltroEmulator::ConvertRawFilesToDate(Int_t nevents) {
1204   //
1205   //  Convertes Raw files to Date format
1206   //
1207   
1208   // from $ALICE_ROOT/STEER/AliSimulation.cxx
1209   
1210   char command[100];
1211   FILE *pipe;
1212   if (fReader->GetRunNumber()>0)
1213     pipe=gSystem->OpenPipe(Form("dateStream -c -s -D -o %s -C -# %d -run %d", 
1214                                 fOutputDateFileName.Data(),
1215                                 nevents,
1216                                 fReader->GetRunNumber()),
1217                            "w");
1218   else
1219     pipe=gSystem->OpenPipe(Form("dateStream -c -s -D -o %s -C -# %d", 
1220                                 fOutputDateFileName.Data(),
1221                                 nevents),
1222                            "w");
1223   if (!pipe) {
1224     fprintf(stderr,"error: cannot execute command: %s",command);
1225     return kFALSE;
1226   }
1227   
1228   for (Int_t ievent=0;ievent<nevents;++ievent) {
1229     UInt_t detectorPattern = 0xFFFFFFFF;
1230     fprintf(pipe, "GDC DetectorPattern %u\n", detectorPattern);
1231
1232     Float_t ldc = 0;
1233     Int_t prevLDC = -1;
1234   
1235     // loop over detectors and DDLs
1236     for (Int_t iDet = 0; iDet < AliDAQ::kNDetectors; iDet++) {
1237       if (!(iDet<=5 || iDet==17 )) continue;
1238       for (Int_t iDDL = 0; iDDL < AliDAQ::NumberOfDdls(iDet); iDDL++) {
1239         //      printf("iDet=%d, iDDL=%d, filenmae=%s\n",iDet,iDDL,filename);
1240         Int_t ddlID = AliDAQ::DdlID(iDet,iDDL);
1241         Int_t ldcID = Int_t(ldc + 0.0001);
1242         ldc += AliDAQ::NumberOfLdcs(iDet) / AliDAQ::NumberOfDdls(iDet);
1243
1244         // check existence and size of raw data file
1245         FILE* file = fopen(Form("%s/raw%d/%s",
1246                                 fDDLFolderName.Data(),
1247                                 ievent,
1248                                 AliDAQ::DdlFileName(iDet,iDDL)),
1249                            "rb");
1250         if (!file) continue;
1251         fseek(file, 0, SEEK_END);
1252         unsigned long size = ftell(file);
1253         fclose(file);
1254         if (!size) continue;
1255
1256         if (ldcID != prevLDC) {
1257           fprintf(pipe, " LDC Id %d\n", ldcID);
1258           prevLDC = ldcID;
1259         }
1260         fprintf(pipe,Form("  Equipment Id %d Payload %s/raw%d/%s\n",
1261                           ddlID,
1262                           fDDLFolderName.Data(),
1263                           ievent,
1264                           AliDAQ::DdlFileName(iDet,iDDL))
1265                 );
1266       }
1267     }
1268   }
1269   Int_t result = gSystem->ClosePipe(pipe);
1270   return (result == 0);
1271 }
1272
1273 void AliTPCAltroEmulator::InitBuffers() {
1274   // 
1275   // Initialization of the Buffers
1276   //
1277   if (!fChannels) fChannels=new Bool_t [216*4096     ];
1278   if (!fCDHs    ) fCDHs    =new UInt_t [216*8        ];
1279   if (!fADCs    ) fADCs    =new Short_t[216*4096*1024];
1280   if (!fTrailers) fTrailers=new UInt_t [216*9        ];
1281   if (!fRawData ) fRawData =new UInt_t [  1*4096*1024]; // be save...
1282
1283   for (Int_t i=0;i<216*4096     ;++i) fChannels[i]=kFALSE;
1284   // no need to init CDHs
1285   for (Int_t i=0;i<216*4096*1024;++i) fADCs    [i]=-1    ;
1286   // no need to init trailers
1287   for (Int_t i=0;i<  1*4096*1024;++i) fRawData [i]= 0    ;
1288 }
1289
1290 Bool_t AliTPCAltroEmulator::ConvertDateToRoot() {
1291   //
1292   // convert a DATE file to a root file with the program "alimdc"
1293   //
1294
1295   // from $ALICE_ROOT/STEER/AliSimulation.cxx
1296
1297   // ALIMDC setup
1298   const Int_t kDBSize    = 2000000000; //2GB
1299   const Int_t kTagDBSize = 1000000000;
1300   const Bool_t kFilter = kFALSE;
1301   const Int_t kCompression = 1;
1302
1303   //  AliInfo(Form("converting DATE file %s to root file %s", 
1304   //               dateFileName, rootFileName));
1305
1306   const char* rawDBFS[2] = { "/tmp/mdc1", "/tmp/mdc2" };
1307   const char* tagDBFS    = "/tmp/mdc1/tags";
1308
1309   // User defined file system locations
1310   if (gSystem->Getenv("ALIMDC_RAWDB1")) 
1311     rawDBFS[0] = gSystem->Getenv("ALIMDC_RAWDB1");
1312   if (gSystem->Getenv("ALIMDC_RAWDB2")) 
1313     rawDBFS[1] = gSystem->Getenv("ALIMDC_RAWDB2");
1314   if (gSystem->Getenv("ALIMDC_TAGDB")) 
1315     tagDBFS = gSystem->Getenv("ALIMDC_TAGDB");
1316
1317   gSystem->Exec(Form("rm -rf %s",rawDBFS[0]));
1318   gSystem->Exec(Form("rm -rf %s",rawDBFS[1]));
1319   gSystem->Exec(Form("rm -rf %s",tagDBFS));
1320
1321   gSystem->Exec(Form("mkdir %s",rawDBFS[0]));
1322   gSystem->Exec(Form("mkdir %s",rawDBFS[1]));
1323   gSystem->Exec(Form("mkdir %s",tagDBFS));
1324
1325   Int_t result = gSystem->Exec(Form("alimdc %d %d %d %d %s", 
1326                                     kDBSize, kTagDBSize, kFilter, kCompression, fOutputDateFileName.Data()));
1327   gSystem->Exec(Form("mv %s/*.root %s", rawDBFS[0],fOutputRootFileName.Data()));
1328
1329   gSystem->Exec(Form("rm -rf %s",rawDBFS[0]));
1330   gSystem->Exec(Form("rm -rf %s",rawDBFS[1]));
1331   gSystem->Exec(Form("rm -rf %s",tagDBFS));
1332
1333   return (result == 0);
1334 }
1335
1336 void AliTPCAltroEmulator::RunEmulationOnRAWdata(AliRawReader *reader, Int_t plotFlag) {
1337   //
1338   // Run the Altro Emulation on a full Raw data set (AliRawReader)
1339   // plus write the outcome in a RAW data format
1340   //
1341
1342   if (!reader) {
1343     printf("ERROR cant run Altro Emulation: AliRawReader is zero. No RAW data file.\n");
1344     return;
1345   }
1346
1347   fReader=reader;
1348   if (fDecoder) delete fDecoder;
1349   fDecoder=new AliTPCRawStreamV3(reader);
1350
1351   InitBuffers();
1352   
1353   TH1F hisO("DINO","DINO",1014,0,1014); 
1354   TH1F his("DIN","DIN",1014,0,1014); 
1355
1356   Int_t chanCount=0;
1357   his.GetYaxis()->SetRangeUser(-20,90);
1358   Short_t *data = new Short_t[1014]; 
1359   TCanvas *c1 =0;
1360   if (plotFlag) {
1361     c1 = new TCanvas("c1","c1");
1362     c1->SetGridx(); c1->SetGridy();
1363   }
1364
1365   // event loop
1366   Int_t ievent=0;
1367   while (fReader->NextEvent()) {
1368     
1369     gSystem->Exec(Form("mkdir -p %s/raw%d/",fDDLFolderName.Data(),ievent));
1370     GDC2DDLs(const_cast<AliRawVEvent*>(fReader->GetEvent()),ievent);
1371     
1372     Int_t ddlC =0;
1373     while (fDecoder->NextDDL()) {
1374       Int_t ddlID=fDecoder->GetDDLNumber();
1375       printf("ddl: %d (%d/216)\n",ddlID,++ddlC);
1376      
1377       Bool_t  *channelsDDL=fChannels+ddlID*4096     ;
1378       Short_t *adcsDDL    =fADCs    +ddlID*4096*1024;
1379       UInt_t  *cdhDDL     =fCDHs    +ddlID*8        ;
1380       UInt_t  *trailerDDL =fTrailers+ddlID*9        ;
1381       
1382       // CDH 
1383       for (Int_t i=0;i<8;++i)
1384         // just to show how ugly it is...
1385         cdhDDL[i]=reinterpret_cast<UInt_t*>(const_cast<AliRawDataHeader*>(fReader->GetDataHeader()))[i]; 
1386       
1387       // PAYLOAD
1388       while (fDecoder->NextChannel()) {
1389         Int_t hwaddr=fDecoder->GetHWAddress();
1390         Int_t sector=fDecoder->GetSector();
1391         Int_t row=fDecoder->GetRow();
1392         Int_t pad=fDecoder->GetPad();
1393         Short_t *adcsChannel=adcsDDL+hwaddr*1024;
1394         while (fDecoder->NextBunch()) {
1395           UInt_t          ts     =fDecoder->GetStartTimeBin();
1396           Int_t           cw     =fDecoder->GetBunchLength() ;
1397           const UShort_t *signals=fDecoder->GetSignals()     ;
1398           for (Int_t ci=0;ci<cw;++ci) {
1399             Short_t s=signals[ci];
1400             Int_t   t=ts-ci;
1401             // TODO aqcuisition window
1402             if (20<=t&&t<=1014) {
1403               channelsDDL[hwaddr]=kTRUE;
1404               if (adcsChannel[t]<0)
1405                 adcsChannel[t]=s;
1406               else
1407                 adcsChannel[t]+=s;
1408               if (adcsChannel[t]>0x3ff)
1409                 adcsChannel[t]=0x3ff;
1410             }
1411           }
1412         }
1413
1414         // search start of aquisition
1415         Int_t t0 = 0;    while (adcsChannel[t0]==-1) t0++;
1416         // search end of aquisition
1417         Int_t tE = 1014; while (adcsChannel[tE]==-1) tE--;
1418         
1419         // SR TEST:
1420         // channel is complete - Perform Altro Emulation
1421         if (plotFlag!=0 && !(chanCount%plotFlag) ) {
1422           for (Int_t t=0; t<1014; t++) {
1423             his.SetBinContent(t+1,adcsChannel[t]);
1424           }
1425           his.SetTitle(Form("sig_sec%d_row%d_pad%d",sector,row,pad));
1426           his.SetStats(0); his.GetXaxis()->SetTitle("timebin"); 
1427           his.DrawCopy();
1428         }
1429
1430         // FEED THE ALTRO EMULATOR WITH CLEAN SIGNAL (no aquisition-window ghosts)
1431         Int_t timebins = tE-t0;
1432         for (Int_t t=t0;t<(t0+timebins);t++)
1433           data[t-t0]=adcsChannel[t];
1434         SetChannelData(timebins,data);
1435         
1436         Int_t roc = (sector%36)>=18; // 0 for IROC, 1 for OROC
1437         RunEmulation(roc); 
1438         for (Int_t t=t0;t<(t0+timebins);t++) 
1439           adcsChannel[t]=data[t-t0];
1440           
1441         // SR TEST:
1442         if (plotFlag!=0 && !(chanCount%plotFlag) ) {
1443           for (Int_t t=0; t<1014; t++)
1444             hisO.SetBinContent(t+1,adcsChannel[t]);
1445           hisO.SetStats(0); hisO.SetLineColor(2);
1446           hisO.DrawCopy("same");
1447             
1448           c1->SaveAs(Form("/tmp/sig_sec%02d_row%02d_pad%03d_%d%d%d%d%d.png",
1449                           sector,row,pad,fOnBSL1,fOnTCF,fOnBSL2,fOnClip,fOnZSU));
1450             
1451           his.Reset();
1452           hisO.Reset();
1453
1454         }
1455         chanCount++;
1456
1457       }
1458       
1459       // TRAILER 
1460       UChar_t *rcuTrailer;
1461       fDecoder->GetRCUTrailerData(rcuTrailer);
1462       for (Int_t i=0;i<= /* (!) */ fDecoder->GetRCUTrailerSize()/4;++i)
1463         trailerDDL[i]=reinterpret_cast<UInt_t*>(rcuTrailer)[i]; // again: UGLY!
1464       
1465     }
1466             
1467     WriteEvent(ievent++);
1468   }
1469
1470   delete data; // free space
1471
1472   // convert to date and back
1473   ConvertRawFilesToDate(ievent);
1474   ConvertDateToRoot();
1475
1476
1477 }