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