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