]> git.uio.no Git - u/mrichter/AliRoot.git/blame - TPC/Util/AliTPCAltroEmulator.cxx
ATO-17 - reset cach matrix and current matrix after dumping to the tree (not before)
[u/mrichter/AliRoot.git] / TPC / Util / AliTPCAltroEmulator.cxx
CommitLineData
eb7e0771 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 */
13af8d96 20
eb7e0771 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
338e0dd9 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>
e9463054 43#include <AliRawDataHeader.h>
44#include <AliRawDataHeaderV3.h>
eb7e0771 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)
338e0dd9 53 * @param Channel an <tt> short* </tt> Pointer to a 1d Short_tArray with the input Data
eb7e0771 54 */
55
9389f9a4 56
57ClassImp(AliTPCAltroEmulator)
58
338e0dd9 59AliTPCAltroEmulator::AliTPCAltroEmulator(Int_t timebins, short* Channel) :
b479e253 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
cd10c6cd 74 fConfiguredTCFraw(0), // ConfiguredTCF
b479e253 75 fConfiguredBSL2(0), // ConfiguredBSL2
76 fConfiguredZSU(0), // ConfiguredZSU
77 fBSL1mode(0), // BSL1mode
78 fBSL1ValuePeDestal(0), // BSL1ValuePeDestal
338e0dd9 79 fBSL1PedestalMem(0), // BSL1PedestalMem
b479e253 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
338e0dd9 106 fZSUPostsamples(0), // ZSUPostsamples
107
108 fReader(0), // for Altro Emulation on Raw Reader
109 fDecoder(0),
13af8d96 110 fRunNumber(0),
9f3b99e2 111 fDDLFolderName("./"),
112 fOutputDateFileName("./tmpRaw.date"),
113 fOutputRootFileName("./tmpRaw.root"),
338e0dd9 114 fIsRandom(kTRUE),
115 fChannels(0),
116 fCDHs(0),
117 fADCs(0),
118 fTrailers(0),
119 fRawData(0) {
eb7e0771 120 //
121 // Constructor of Altro Class
122 //
b479e253 123
b3b5d5c9 124 fADCkeep = new Short_t[1024];
b479e253 125
7ee86790 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
eb7e0771 133}
134
135
b3b5d5c9 136
eb7e0771 137/** @brief Destructor of Altro Class
138 *
139 * Destructor of Altro Class\n
140 */
338e0dd9 141AliTPCAltroEmulator::~AliTPCAltroEmulator() {
eb7e0771 142 //
143 // Destructor of Altro Class
144 //
145
b3b5d5c9 146 // if(fConfiguredZSU == 1)
147 delete[] fADCkeep;
338e0dd9 148
149 delete[] fChannels;
150 delete[] fCDHs ;
151 delete[] fADCs ;
152 delete[] fTrailers;
153 delete[] fRawData ;
154 delete fDecoder ;
155
eb7e0771 156}
157
eb7e0771 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 *
338e0dd9 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)
eb7e0771 171 */
338e0dd9 172void AliTPCAltroEmulator::ConfigAltro(Int_t ONBaselineCorrection1, Int_t ONTailcancellation, Int_t ONBaselineCorrection2, Int_t ONClipping, Int_t ONZerosuppression, Int_t ONDataFormatting){
eb7e0771 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;
7409c8db 182 if (!fConfiguredAltro) { //dummy code to avoid warning
183 printf("%d\n",ONDataFormatting); // does not have to be checked
184 }
eb7e0771 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 *
338e0dd9 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
eb7e0771 199 */
338e0dd9 200void AliTPCAltroEmulator::ConfigBaselineCorrection1(Int_t mode, Int_t ValuePeDestal, Int_t *PedestalMem, Int_t polarity){
eb7e0771 201 //
202 // Configures the Base Line Correction 1 (BSL1) Module
203 //
b3b5d5c9 204 fBSL1mode = InRange(mode,0,16,"AliTPCAltroEmulator::ConfigBaselineCorrection1","mode");
eb7e0771 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
338e0dd9 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)
eb7e0771 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 *
338e0dd9 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
eb7e0771 226 */
338e0dd9 227void AliTPCAltroEmulator::ConfigTailCancellationFilter(Int_t K1, Int_t K2, Int_t K3, Int_t L1, Int_t L2, Int_t L3){
eb7e0771 228 //
229 // Configures the Tail Cancellation Filter (TCF) Module
230 //
338e0dd9 231 // conf from Int_t to fp: (int)*(pow(2,-16)-1)
232 // backway: (Float_t)*(pow(2,16)-1)
eb7e0771 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}
b3b5d5c9 242void 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){
cd10c6cd 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
eb7e0771 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 *
338e0dd9 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
eb7e0771 281 */
338e0dd9 282void AliTPCAltroEmulator::ConfigBaselineCorrection2(Int_t HighThreshold, Int_t LowThreshold, Int_t Offset, Int_t Presamples, Int_t Postsamples){
eb7e0771 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 *
338e0dd9 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
eb7e0771 304 */
338e0dd9 305void AliTPCAltroEmulator::ConfigZerosuppression(Int_t Threshold, Int_t MinSamplesaboveThreshold, Int_t Presamples, Int_t Postsamples){
eb7e0771 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");
eb7e0771 313
338e0dd9 314 for(Int_t i = 0; i < ftimebins; i++){
eb7e0771 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 */
324void 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;
338e0dd9 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;
eb7e0771 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
338e0dd9 378
379void 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
eb7e0771 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 */
cd10c6cd 395void AliTPCAltroEmulator::RunEmulation(Int_t roc){
eb7e0771 396 //
397 // Runs the emulation of all configured Modules.
398 //
399
338e0dd9 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
eb7e0771 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){
cd10c6cd 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
eb7e0771 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 }
338e0dd9 470
471
472
eb7e0771 473}
474
338e0dd9 475void AliTPCAltroEmulator::BaselineCorrection1(Int_t mode, Int_t ValuePeDestal, Int_t *PedestalMem, Int_t polarity){
eb7e0771 476 //
477 // BaselineCorrection1
478 //
479
480 //VPD == 0 !!
338e0dd9 481 Int_t fixedPeDestal = 0;
b3b5d5c9 482
483 // take first and last bins to calculate a mean pedestal value
484 Int_t window = 3;
485 Int_t meanPeDestal = 0;
6036ea97 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);
b3b5d5c9 492 }
6036ea97 493
eb7e0771 494 if(polarity ==1){
338e0dd9 495 for(Int_t i = 0; i < ftimebins; i++){
eb7e0771 496 fChannelShort[i] = 1023 - fChannelShort[i];
497 }
498 }
499
500 switch(mode) {
501 case kDINxFPD:
338e0dd9 502 for(Int_t i = 0; i < ftimebins; i++)
eb7e0771 503 fChannelShort[i] = fChannelShort[i] - fixedPeDestal;
504 break;
505 case kDINxFT:
338e0dd9 506 for(Int_t i = 0; i < ftimebins; i++)
eb7e0771 507 fChannelShort[i] = fChannelShort[i] - PedestalMem[i];
508 break;
509 case kDINxFDIN:
338e0dd9 510 for(Int_t i = 0; i < ftimebins; i++)
eb7e0771 511 fChannelShort[i] = fChannelShort[i] - PedestalMem[ fChannelShort[i] ];
512 break;
513 case kDINxFDINxVPD:
338e0dd9 514 for(Int_t i = 0; i < ftimebins; i++)
eb7e0771 515 fChannelShort[i] = fChannelShort[i] - PedestalMem[ fChannelShort[i] - ValuePeDestal];
516 break;
517 case kDINxVPDxFPD:
338e0dd9 518 for(Int_t i = 0; i < ftimebins; i++)
eb7e0771 519 fChannelShort[i] = fChannelShort[i] - ValuePeDestal - fixedPeDestal;
520 break;
521 case kDINxVPDxFT:
338e0dd9 522 for(Int_t i = 0; i < ftimebins; i++)
eb7e0771 523 fChannelShort[i] = fChannelShort[i] - ValuePeDestal - PedestalMem[i];
524 break;
525 case kDINxVPDxFDIN:
338e0dd9 526 for(Int_t i = 0; i < ftimebins; i++)
eb7e0771 527 fChannelShort[i] = fChannelShort[i] - ValuePeDestal - PedestalMem[ fChannelShort[i] ];
528 break;
529 case kDINxVPDxFDINxVPD:
338e0dd9 530 for(Int_t i = 0; i < ftimebins; i++)
eb7e0771 531 fChannelShort[i] = fChannelShort[i] - ValuePeDestal - PedestalMem[ fChannelShort[i] - ValuePeDestal ];
532 break;
533 case kFDINxFPD:
338e0dd9 534 for(Int_t i = 0; i < ftimebins; i++)
eb7e0771 535 fChannelShort[i] = PedestalMem[ fChannelShort[i] ] - fixedPeDestal;
536 break;
537 case kFDINxVPDxFPD:
338e0dd9 538 for(Int_t i = 0; i < ftimebins; i++)
eb7e0771 539 fChannelShort[i] = PedestalMem[ fChannelShort[i] - ValuePeDestal ] - fixedPeDestal;
540 break;
541 case kFTxFPD:
338e0dd9 542 for(Int_t i = 0; i < ftimebins; i++)
eb7e0771 543 fChannelShort[i] = PedestalMem[i] - fixedPeDestal;
544 break;
b3b5d5c9 545 case kDINxMPD:
546 for(Int_t i = 0; i < ftimebins; i++)
547 fChannelShort[i] = fChannelShort[i] - meanPeDestal;
548 break;
eb7e0771 549 }
550}
551
338e0dd9 552Int_t AliTPCAltroEmulator::Multiply36(Int_t P, Int_t N){
eb7e0771 553 //
cd10c6cd 554 // multiply function to emulate the 36 bit fixed point multiplication of the Altro.
eb7e0771 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}
338e0dd9 568long long AliTPCAltroEmulator::Mask(long long in, Int_t left, Int_t right){
eb7e0771 569 //
338e0dd9 570 // mask
eb7e0771 571 //
572 long long retval;
573 long long pattern;
574 long long length = abs(left - right)+1;
6a281272 575 pattern = ((((long long)1)<<length)-1)<<right;
eb7e0771 576 retval = in&pattern;
577 return retval;
578}
579
338e0dd9 580long long AliTPCAltroEmulator::Maskandshift(long long in, Int_t left, Int_t right){
eb7e0771 581 //
338e0dd9 582 // maskandshift
eb7e0771 583 //
584 long long retval;
585 long long pattern;
586 long long length = abs(left - right)+1;
6a281272 587 pattern = ((((long long)1)<<length)-1);
eb7e0771 588 retval = (in>>right)&pattern;
589 return retval;
590}
591
338e0dd9 592void AliTPCAltroEmulator::TailCancellationFilterFixedPoint(Int_t K1, Int_t K2, Int_t K3, Int_t L1, Int_t L2, Int_t L3){
eb7e0771 593 //
594 // TailCancellationFilterFixedPoint
595 //
338e0dd9 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;
cd10c6cd 602
603 // printf("%5d %5d %5d %5d %5d %5d\n",K1,K2,K3,L1,L2,L3);
604
338e0dd9 605 for(Int_t i = 0; i < ftimebins; i++){
eb7e0771 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
338e0dd9 642void AliTPCAltroEmulator::BaselineCorrection2RTL(Int_t HighThreshold, Int_t LowThreshold, Int_t Offset, Int_t Presamples, Int_t Postsamples){
eb7e0771 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
338e0dd9 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;
eb7e0771 656
657 // Variables
338e0dd9 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
eb7e0771 671
338e0dd9 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;
eb7e0771 683
684 //initialisation
338e0dd9 685 for(Int_t i = 0; i < 9 ; i++)
eb7e0771 686 zOld[i] = 0;
338e0dd9 687 for(Int_t i = 0; i < 4 ; i++){
eb7e0771 688 fOld[i] = 0;
689 dOld[i] = 0;
690 }
691 dxOld= 0;
692 pstscnt = 0;
693 zxOld = 0;
694 valcntOld = 0;
695 valid = 0;
338e0dd9 696 for(Int_t i = 0; i < 2 ; i++){
eb7e0771 697 edges[i] = (Presamples&(1<<i))>>i;
698 }
338e0dd9 699 for(Int_t i = 0; i < 4 ; i++){
eb7e0771 700 edges[(3-i)+2] = (Postsamples&(1<<i))>>i;
701 }
702 /*cout << "edges :";
338e0dd9 703 for(Int_t i = 0; i < 6 ; i++)
eb7e0771 704 cout << edges[i] << ":";
705 cout << " Presamples: " << Presamples << " Postsamples: " << Postsamples << endl;*/
706
707 //Loop
708 //cout << "AliTPCAltroEmulator::BaselineCorrection2_RTL | starting Loop" << endl;
338e0dd9 709 for(Int_t timebin = -12; timebin < ftimebins+10; timebin++){
eb7e0771 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];
338e0dd9 754 for(Int_t i = 0; i < 3; i++)
eb7e0771 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;
338e0dd9 768 for(Int_t i = 0; i < 8; i++)
eb7e0771 769 zNew[i] = zOld[i+1];
770 zNew[8] = dOld[0];
771 }else{
772 zxNew = zxOld;
338e0dd9 773 for(Int_t i = 0; i < 9; i++)
eb7e0771 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
338e0dd9 782 for(Int_t i = 0; i < 9 ; i++)
eb7e0771 783 zOld[i] = zNew[i];
784 zxOld = zxNew;
338e0dd9 785 for(Int_t i = 0; i < 4 ; i++){
eb7e0771 786 fOld[i] = fNew[i];
787 dOld[i] = dNew[i];
788 }
789 dxOld = dxNew;
790 valcntOld = valcntNew;
791 }
792}
793
794void AliTPCAltroEmulator::Clipping(){
795 //
796 // implement if no BC2 clipping has to run
797 //
338e0dd9 798 for(Int_t i = 0; i < ftimebins; i++){
cd10c6cd 799 if(fChannelShort[i] < -1)
800 fChannelShort[i] = -1;
eb7e0771 801 }
802}
803
338e0dd9 804void AliTPCAltroEmulator::Zerosuppression(Int_t Threshold, Int_t MinSamplesaboveThreshold, Int_t Presamples, Int_t Postsamples){
eb7e0771 805 //
806 // add again altro feature
807 //
808
809 //TODO: Implement "Altro zsu merging"
338e0dd9 810 //Int_t Postsamplecounter = 0;
811 //Int_t setPostsample = 0;
cd10c6cd 812
338e0dd9 813 for(Int_t i = 0; i < ftimebins; i++){
b3b5d5c9 814 if(fChannelShort[i] >= Threshold)
eb7e0771 815 fADCkeep[i] = 1;
b3b5d5c9 816 else
817 fADCkeep[i] = 0;
eb7e0771 818 }
338e0dd9 819
820 Int_t startofclustersequence = -1;
821 Int_t endofClustersInSequence = -1;
eb7e0771 822
338e0dd9 823 for(Int_t i = 0; i < ftimebins; i++){
b3b5d5c9 824 if( (fADCkeep[i] == 1) && (GetElement(fADCkeep,i-1) == 0) ){
eb7e0771 825 startofclustersequence = i;
826 }
b3b5d5c9 827 if( (fADCkeep[i] == 1) && (GetElement(fADCkeep,i+1) == 0) ){
eb7e0771 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 ){
338e0dd9 834 for(Int_t j = startofclustersequence; j <= endofClustersInSequence ; j++){
eb7e0771 835 fADCkeep[j] = 0;
836 }
837 }
838 startofclustersequence = -1;
839 endofClustersInSequence = -1;
840 }
841 //cout << endl;
842 }
843
338e0dd9 844 /*for(Int_t i = 0; i < ftimebins; i++){
eb7e0771 845 if( (GetElement(fADCkeep,i-1) == 1) && (GetElement(fADCkeep,i) == 0) && (GetElement(fADCkeep,i+1) == 1) ){
846 SetElement(fADCkeep,i,1);
847 }
848 }*/
849
338e0dd9 850 for(Int_t i = 0; i < ftimebins; i++){
eb7e0771 851 if( (fADCkeep[i] == 1) && (GetElement(fADCkeep,i-1) == 0) ){
338e0dd9 852 for(Int_t j = i-Presamples ; j <= i; j++){
eb7e0771 853 SetElement(fADCkeep,j,1);
854 }
855 }
856 }
338e0dd9 857 for(Int_t i = ftimebins; i >= 0; i--){
eb7e0771 858 if( (fADCkeep[i] == 1) && (GetElement(fADCkeep,i+1) == 0) ){
338e0dd9 859 for(Int_t j = i ; j <= i+Postsamples; j++){
eb7e0771 860 SetElement(fADCkeep,j,1);
861 }
862 }
863 }
864 /*cout << " Postsamplecounter: " << Postsamplecounter;
338e0dd9 865 for(Int_t j = i+1 ; j <= i+Postsamples; j++){
eb7e0771 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
338e0dd9 874 for(Int_t i = 0; i < ftimebins; i++){
eb7e0771 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 }
338e0dd9 880
881 for(Int_t i = 0; i < ftimebins; i++){
b3b5d5c9 882 if( !GetKeepChannel(i) ) {
cd10c6cd 883 SetElement(fChannelShort,i,-1); // set non relevant data to -1
338e0dd9 884 }
885 }
886
887
eb7e0771 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
7ee86790 896void AliTPCAltroEmulator::DataFormater(){
eb7e0771 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 *
338e0dd9 909 * @return \c Float_t consisting of the compression factor
eb7e0771 910 */
338e0dd9 911Float_t AliTPCAltroEmulator::CalculateCompression() {
eb7e0771 912 //
913 // calculates the compression out of the bitmask
914 //
915
916 // calculation is based on altro 10 bit words ..
338e0dd9 917 Int_t sample = 0;
918 Int_t cluster = 0;
919 Int_t data = 0;
920 Float_t retval = 0.0;
eb7e0771 921
338e0dd9 922 for(Int_t i = 0; i < ftimebins; i++){
eb7e0771 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){
338e0dd9 933 retval = ftimebins / (Float_t)data;//num of timebins is equal to max number of samples
eb7e0771 934 }else{
935 retval = 1.0;
936 }
937 return retval;
938}
939
7ee86790 940Short_t AliTPCAltroEmulator::GetElement(short* Array,Int_t index){
eb7e0771 941 //
338e0dd9 942 // GetElement of array
eb7e0771 943 //
944 if (index < 0)
945 return 0;
946 else if(index >= ftimebins)
947 return 0;
948 else
949 return Array[index];
950}
951
338e0dd9 952void AliTPCAltroEmulator::SetElement(short* Array,Int_t index,Short_t value){
eb7e0771 953 //
338e0dd9 954 // SetElement of array
eb7e0771 955 //
956 if (index < 0)
957 return;
958 else if(index >= ftimebins)
959 return;
960 else
961 Array[index] = value;
962}
963
7ee86790 964Int_t AliTPCAltroEmulator::InBand(Int_t ADC,Int_t bsl, Int_t LowThreshold, Int_t HighThreshold){
eb7e0771 965 //
338e0dd9 966 // check if it's within the band of search
eb7e0771 967 //
338e0dd9 968 Int_t fLow = bsl - LowThreshold;
969 Int_t fHigh = bsl + HighThreshold;
eb7e0771 970 if( (ADC <= fHigh) && (ADC >= fLow) )
971 return 1;
972 else
973 return 0;
974}
975
7ee86790 976Int_t AliTPCAltroEmulator::InRange(Int_t parameter,Int_t Low,Int_t High,const char *Module,const char *ParameterName){
eb7e0771 977 //
338e0dd9 978 // checks it it's within the range
eb7e0771 979 //
980
981 char out[255];
338e0dd9 982 Int_t retval;
eb7e0771 983 if(parameter > High){
7ee86790 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);
eb7e0771 985 cout << out << endl;
986 retval = High;
987 }else if(parameter < Low){
7ee86790 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);
eb7e0771 989 cout << out << endl;
990 retval = Low;
991 }else{
992 retval = parameter;
993 }
994 return retval;
995}
996
338e0dd9 997Short_t AliTPCAltroEmulator::GetShortChannel(Int_t i){
eb7e0771 998 //
338e0dd9 999 // GetElement of channel
eb7e0771 1000 //
1001 return GetElement(fChannelShort,i);
1002}
1003
338e0dd9 1004Short_t AliTPCAltroEmulator::GetKeepChannel(Int_t i){
eb7e0771 1005 //
338e0dd9 1006 // GetElement of Keep Channel
eb7e0771 1007 //
1008 return GetElement(fADCkeep,i);
1009}
338e0dd9 1010
1011Bool_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");
7ee86790 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 }
338e0dd9 1048 }
1049 }
7ee86790 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;
338e0dd9 1067 }
7ee86790 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 }
338e0dd9 1075 }
1076 }
7ee86790 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;
338e0dd9 1083 }
7ee86790 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);
5af1bc5b 1094 fclose(file);
1095
7ee86790 1096 if (nwritten!=i32) return kFALSE;
1097
338e0dd9 1098 // clean up
7ee86790 1099 do {fRawData[--i32]=0;} while (i32>0);
338e0dd9 1100 }
338e0dd9 1101 }
1102 return kTRUE;
1103}
1104
1105Bool_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
1137Bool_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;
13af8d96 1146
1147 printf(" RAW to DATE CONVERSION: Run Number %d\n",fRunNumber);
1148
1149 if (fRunNumber>0)
338e0dd9 1150 pipe=gSystem->OpenPipe(Form("dateStream -c -s -D -o %s -C -# %d -run %d",
1151 fOutputDateFileName.Data(),
1152 nevents,
13af8d96 1153 fRunNumber),
338e0dd9 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 }
13af8d96 1164
338e0dd9 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 }
e6cedd06 1197 fprintf(pipe," Equipment Id %d Payload %s/raw%d/%s\n",
338e0dd9 1198 ddlID,
1199 fDDLFolderName.Data(),
1200 ievent,
e6cedd06 1201 (char*)AliDAQ::DdlFileName(iDet,iDDL) );
338e0dd9 1202 }
1203 }
1204 }
1205 Int_t result = gSystem->ClosePipe(pipe);
1206 return (result == 0);
1207}
1208
1209void 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
1226Bool_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
13af8d96 1233 printf(" DATE to ROOT CONVERSION: Run Number %d\n",fRunNumber);
1234
338e0dd9 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
1274void 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
338e0dd9 1291 Int_t chanCount=0;
b3b5d5c9 1292 TH1F hisO("DINO","DINO",1024,0,1024);
1293 TH1F his("DIN","DIN",1024,0,1024);
338e0dd9 1294 his.GetYaxis()->SetRangeUser(-20,90);
b3b5d5c9 1295 Short_t *data = new Short_t[1024];
cd10c6cd 1296 TCanvas *c1 =0;
1297 if (plotFlag) {
1298 c1 = new TCanvas("c1","c1");
1299 c1->SetGridx(); c1->SetGridy();
1300 }
338e0dd9 1301
1302 // event loop
1303 Int_t ievent=0;
1304 while (fReader->NextEvent()) {
1305
13af8d96 1306 if (fReader->GetRunNumber()>0) fRunNumber=fReader->GetRunNumber();
338e0dd9 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();
cd10c6cd 1313 printf("ddl: %d (%d/216)\n",ddlID,++ddlC);
338e0dd9 1314
13af8d96 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 ;
338e0dd9 1319
1320 // CDH
e9463054 1321 const AliRawDataHeader * cdh = fReader->GetDataHeader();
1322 const AliRawDataHeaderV3 * cdhV3 = fReader->GetDataHeaderV3();
1323 for (Int_t i=0;i<8;++i) {
b3b5d5c9 1324 // just to show how ugly it is...
e9463054 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 }
338e0dd9 1330 // PAYLOAD
1331 while (fDecoder->NextChannel()) {
1332 Int_t hwaddr=fDecoder->GetHWAddress();
cd10c6cd 1333 Int_t sector=fDecoder->GetSector();
1334 Int_t row=fDecoder->GetRow();
1335 Int_t pad=fDecoder->GetPad();
338e0dd9 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
b3b5d5c9 1345 if (0<=t&&t<(1024-3)) {
338e0dd9 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
cd10c6cd 1357 // search start of aquisition
1358 Int_t t0 = 0; while (adcsChannel[t0]==-1) t0++;
1359 // search end of aquisition
b3b5d5c9 1360 Int_t tE = 1024; while (adcsChannel[tE]==-1) tE--;
338e0dd9 1361
cd10c6cd 1362 // channel is complete - Perform Altro Emulation
1363 if (plotFlag!=0 && !(chanCount%plotFlag) ) {
b3b5d5c9 1364 for (Int_t t=0; t<1024; t++) {
cd10c6cd 1365 his.SetBinContent(t+1,adcsChannel[t]);
338e0dd9 1366 }
cd10c6cd 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)
b3b5d5c9 1373 Int_t timebins = tE-t0+1;
cd10c6cd 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];
338e0dd9 1382
cd10c6cd 1383 if (plotFlag!=0 && !(chanCount%plotFlag) ) {
b3b5d5c9 1384 for (Int_t t=0; t<1024; t++)
cd10c6cd 1385 hisO.SetBinContent(t+1,adcsChannel[t]);
1386 hisO.SetStats(0); hisO.SetLineColor(2);
1387 hisO.DrawCopy("same");
338e0dd9 1388
7ee86790 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));
338e0dd9 1393
cd10c6cd 1394 his.Reset();
1395 hisO.Reset();
338e0dd9 1396
338e0dd9 1397 }
cd10c6cd 1398 chanCount++;
338e0dd9 1399
1400 }
1401
1402 // TRAILER
1403 UChar_t *rcuTrailer;
1404 fDecoder->GetRCUTrailerData(rcuTrailer);
1405 for (Int_t i=0;i<= /* (!) */ fDecoder->GetRCUTrailerSize()/4;++i)
b3b5d5c9 1406 trailerDDL[i]=reinterpret_cast<UInt_t*>(rcuTrailer)[i]; // again: UGLY!
338e0dd9 1407
1408 }
1409
13af8d96 1410 if (ddlC>0) WriteEvent(ievent++);
338e0dd9 1411 }
1412
b3b5d5c9 1413 delete[] data; // free space
338e0dd9 1414
1415 // convert to date and back
1416 ConvertRawFilesToDate(ievent);
1417 ConvertDateToRoot();
1418
1419
1420}