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