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