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