2 * @brief The Altro class implements the Altro digital Chain in C++
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
13 * @author Roland Bramm
14 * @version $LastChangedRevision: 688 $
15 * @date $LastChangedDate: 2005-12-16 14:07:11 +0100 (Fri, 16 Dec 2005) $
17 * \verbinclude Altro/Altro.C.log
20 /////////////////////////////////////////////////////////////////////////////////////////////////////
21 // Class for emulation of the ALTRO chip (Altro digital Chain) in C++ //
22 // Author: Roland Bramm //
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 /////////////////////////////////////////////////////////////////////////////////////////////////////
30 #include "AliTPCAltroEmulator.h"
32 /** @brief Consturctor of Altro Class
34 * Consturctor of Altro Class, some variables are set.\n
35 * The input Data is altered, so after running the complete emulation you have the
36 * Altro Processed Data in the Channel Pointer.\n
38 * @param timebins an <tt> int </tt> sets the length of the input Data (Channel)
39 * @param Channel an <tt> short* </tt> Pointer to a 1d short Array with the input Data
43 ClassImp(AliTPCAltroEmulator)
45 AliTPCAltroEmulator::AliTPCAltroEmulator(int timebins, short* Channel) :
48 // fChannelIn(Channel),
49 fChannelShort(Channel),
57 fConfiguredAltro(0), // ConfiguredAltro
58 fConfiguredBSL1(0), // ConfiguredBSL1
59 fConfiguredTCF(0), // ConfiguredTCF
60 fConfiguredBSL2(0), // ConfiguredBSL2
61 fConfiguredZSU(0), // ConfiguredZSU
62 fBSL1mode(0), // BSL1mode
63 fBSL1ValuePeDestal(0), // BSL1ValuePeDestal
64 fBSL1PedestalMem(0), // BSL1PedestalMem
65 fBSL1polarity(0), // BSL1polarity
74 fTCFK1Int(0), // K1Int
75 fTCFK2Int(0), // K2Int
76 fTCFK3Int(0), // K3Int
77 fTCFL1Int(0), // L1Int
78 fTCFL2Int(0), // L2Int
79 fTCFL3Int(0), // L3Int
81 fBSL2HighThreshold(0), // BSL2HighThreshold
82 fBSL2LowThreshold(0), // BSL2LowThreshold
83 fBSL2Offset(0), // BSL2Offset
84 fBSL2Presamples(0), // BSL2Presamples(0),
85 fBSL2Postsamples(0), // BSL2Postsamples
87 fZSUThreshold(0), // ZSUThreshold
89 fZSUMinSamplesaboveThreshold(0), // ZSUMinSamplesaboveThreshold
90 fZSUPresamples(0), // ZSUPresamples
91 fZSUPostsamples(0) // ZSUPostsamples
95 // Constructor of Altro Class
100 fChannelShort = Channel;
108 fConfiguredAltro = 0;
117 AliTPCAltroEmulator::AliTPCAltroEmulator(const AliTPCAltroEmulator &altro):
119 ftimebins(altro.ftimebins),
120 // fChannelIn(Channel),
121 fChannelShort(altro.fChannelShort),
129 fConfiguredAltro(0), // ConfiguredAltro
130 fConfiguredBSL1(0), // ConfiguredBSL1
131 fConfiguredTCF(0), // ConfiguredTCF
132 fConfiguredBSL2(0), // ConfiguredBSL2
133 fConfiguredZSU(0), // ConfiguredZSU
134 fBSL1mode(0), // BSL1mode
135 fBSL1ValuePeDestal(0), // BSL1ValuePeDestal
136 fBSL1PedestalMem(0), // BSL1PedestalMem
137 fBSL1polarity(0), // BSL1polarity
146 fTCFK1Int(0), // K1Int
147 fTCFK2Int(0), // K2Int
148 fTCFK3Int(0), // K3Int
149 fTCFL1Int(0), // L1Int
150 fTCFL2Int(0), // L2Int
151 fTCFL3Int(0), // L3Int
153 fBSL2HighThreshold(0), // BSL2HighThreshold
154 fBSL2LowThreshold(0), // BSL2LowThreshold
155 fBSL2Offset(0), // BSL2Offset
156 fBSL2Presamples(0), // BSL2Presamples(0),
157 fBSL2Postsamples(0), // BSL2Postsamples
159 fZSUThreshold(0), // ZSUThreshold
161 fZSUMinSamplesaboveThreshold(0), // ZSUMinSamplesaboveThreshold
162 fZSUPresamples(0), // ZSUPresamples
163 fZSUPostsamples(0) // ZSUPostsamples
167 // copy constructor of Altro Class
173 /** @brief Destructor of Altro Class
175 * Destructor of Altro Class\n
177 AliTPCAltroEmulator::~AliTPCAltroEmulator(){
179 // Destructor of Altro Class
182 if(fConfiguredZSU == 1)
186 //_____________________________________________________________________________
187 AliTPCAltroEmulator& AliTPCAltroEmulator::operator = (const AliTPCAltroEmulator &source)
190 // AliTPCAltroEmulator assignment operator
193 if (&source == this) return *this;
194 new (this) AliTPCAltroEmulator(source);
202 /** @brief Configures which modules of the Altro should be on.
204 * Configures which modules of the Altro should be on. Each of the modules
205 * which are configured to be on, have to be configured later before running
208 * @param ONBaselineCorrection1 an <tt> int </tt> Switch (0,1) to turn on the Base Line Correction 1 (BSL1) Module
209 * @param ONTailcancellation an <tt> int </tt> Switch (0,1) to turn on the Tail Cancellation Filter (TCF) Module
210 * @param ONBaselineCorrection2 an <tt> int </tt> Switch (0,1) to turn on the Moving Average Filter (BSL2) Module
211 * @param ONClipping an <tt> int </tt> Switch (0,1) to turn on the Clipping Module. This is not possible in the real Altro, there it is always on.
212 * @param ONZerosuppression an <tt> int </tt> Switch (0,1) to turn on the Zero Suppression (ZSU) Module
213 * @param ONDataFormatting an <tt> int </tt> Switch (0,1) to turn on the Data Formatting on (not implemented)
215 void AliTPCAltroEmulator::ConfigAltro(int ONBaselineCorrection1, int ONTailcancellation, int ONBaselineCorrection2, int ONClipping, int ONZerosuppression, int ONDataFormatting){
217 // Configures which modules of the Altro should be on
219 fOnBSL1 = InRange(ONBaselineCorrection1,0,1,"AliTPCAltroEmulator::ConfigAltro","ONBaselineCorrection1");
220 fOnTCF = InRange(ONTailcancellation,0,1,"AliTPCAltroEmulator::ConfigAltro","ONTailcancellation");
221 fOnBSL2 = InRange(ONBaselineCorrection2,0,1,"AliTPCAltroEmulator::ConfigAltro","ONBaselineCorrection2");
222 fOnClip = InRange(ONClipping,0,1,"AliTPCAltroEmulator::ConfigAltro","ONClipping");
223 fOnZSU = InRange(ONZerosuppression,0,1,"AliTPCAltroEmulator::ConfigAltro","ONZerosuppression");
224 ONDataFormatting; // does not have to be checked
225 fConfiguredAltro = 1;
228 /** @brief Configures the Base Line Correction 1 (BSL1) Module
230 * Configures the Base Line Correction 1 (BSL1) Module. You dont have to build a proper pedestalMemory
231 * array, a pointer of the correct type is enough, of course you are not allowed to use Basline
232 * Correction Modes which need then the array ...\n
233 * All configurable values are "Range checked" and if out of the Range set to the nearest extreme.
234 * So the Emulation will work, but the result is maybe not the expected one.
236 * @param mode an <tt> int </tt> sets the mode of the Baseline Correction. See the Altro manual for a description
237 * @param ValuePeDestal an <tt> int </tt> this is the baseline of the Channel.
238 * @param PedestalMem an <tt> *int </tt> Pointer to a 1d short Array with the pedestal memory Data
239 * @param polarity an <tt> int </tt> Switch (0,1) for the polarity
241 void AliTPCAltroEmulator::ConfigBaselineCorrection1(int mode, int ValuePeDestal, int *PedestalMem, int polarity){
243 // Configures the Base Line Correction 1 (BSL1) Module
245 fBSL1mode = InRange(mode,0,10,"AliTPCAltroEmulator::ConfigBaselineCorrection1","mode");
246 fBSL1ValuePeDestal = InRange(ValuePeDestal,0,1023,"AliTPCAltroEmulator::BaselineCorrection1","ValuePeDestal");
247 fBSL1PedestalMem = PedestalMem;
248 fBSL1polarity = InRange(polarity,0,1,"AliTPCAltroEmulator::BaselineCorrection1","polarity");
252 /** @brief Configures the Tail Cancellation Filter (TCF) Module
254 * Configures the Tail Cancellation Filter (TCF) Module. You have to set the coefficients in the
256 * To convert from int to float use (int)*(pow(2,-16)-1)
257 * To convert from float to int usw (float)*(pow(2,16)-1)
258 * All configurable values are "Range checked" and if out of the Range set to the nearest extreme.
259 * So the Emulation will work, but the result is maybe not the expected one.
261 * @param K1 an <tt> int </tt> sets the K1 coeeficient of the TCF
262 * @param K2 an <tt> int </tt> sets the K2 coeeficient of the TCF
263 * @param K3 an <tt> int </tt> sets the K3 coeeficient of the TCF
264 * @param L1 an <tt> int </tt> sets the L1 coeeficient of the TCF
265 * @param L2 an <tt> int </tt> sets the L2 coeeficient of the TCF
266 * @param L3 an <tt> int </tt> sets the L3 coeeficient of the TCF
268 void AliTPCAltroEmulator::ConfigTailCancellationFilter(int K1, int K2, int K3, int L1, int L2, int L3){
270 // Configures the Tail Cancellation Filter (TCF) Module
272 // conf from int to fp: (int)*(pow(2,-16)-1)
273 // backway: (float)*(pow(2,16)-1)
274 fTCFK1Int = InRange(K1,0,65535,"AliTPCAltroEmulator::ConfigTailCancellationFilter","K1");
275 fTCFK2Int = InRange(K2,0,65535,"AliTPCAltroEmulator::ConfigTailCancellationFilter","K2");
276 fTCFK3Int = InRange(K3,0,65535,"AliTPCAltroEmulator::ConfigTailCancellationFilter","K3");
278 fTCFL1Int = InRange(L1,0,65535,"AliTPCAltroEmulator::ConfigTailCancellationFilter","L1");
279 fTCFL2Int = InRange(L2,0,65535,"AliTPCAltroEmulator::ConfigTailCancellationFilter","L2");
280 fTCFL3Int = InRange(L3,0,65535,"AliTPCAltroEmulator::ConfigTailCancellationFilter","L3");
284 /** @brief Configures the Moving Average Filter (BSL2) Module
286 * Configures the Moving Average Filter (BSL2) Module.
287 * All configurable values are "Range checked" and if out of the Range set to the nearest extreme.
288 * So the Emulation will work, but the result is maybe not the expected one.
290 * @param HighThreshold an <tt> int </tt> sets the high Threshold
291 * @param LowThreshold an <tt> int </tt> sets the low Theshold
292 * @param Offset an <tt> int </tt> sets the the offset which is added to the Signal
293 * @param Presamples an <tt> int </tt> sets the number of pre samples excluded from the moving average caclulation
294 * @param Postsamples an <tt> int </tt> sets the number of post samples excluded from the moving average caclulation
296 void AliTPCAltroEmulator::ConfigBaselineCorrection2(int HighThreshold, int LowThreshold, int Offset, int Presamples, int Postsamples){
298 // Configures the Moving Average Filter (BSL2) Module
300 fBSL2HighThreshold = InRange(HighThreshold,0,1023,"AliTPCAltroEmulator::ConfigBaselineCorrection2","HighThreshold");
301 fBSL2LowThreshold = InRange(LowThreshold,0,1023,"AliTPCAltroEmulator::ConfigBaselineCorrection2","LowThreshold");
302 fBSL2Offset = InRange(Offset,0,1023,"AliTPCAltroEmulator::ConfigBaselineCorrection2","Offset");
303 fBSL2Presamples = InRange(Presamples,0,3,"AliTPCAltroEmulator::ConfigBaselineCorrection2","Presamples");
304 fBSL2Postsamples = InRange(Postsamples,0,15,"AliTPCAltroEmulator::ConfigBaselineCorrection2","Postsamples");
308 /** @brief Configures the Zero Suppression Module (ZSU)
310 * Configures the Zero Suppression Module (ZSU).
311 * All configurable values are "Range checked" and if out of the Range set to the nearest extreme.
312 * So the Emulation will work, but the result is maybe not the expected one.
314 * @param Threshold an <tt> int </tt> sets the Threshold
315 * @param MinSamplesaboveThreshold an <tt> int </tt> sets the minimum number of samples which have to be greater than the threshold
316 * @param Presamples an <tt> int </tt> sets the number of pre samples which are kept
317 * @param Postsamples an <tt> int </tt> sets the number of post samples which are kept
319 void AliTPCAltroEmulator::ConfigZerosuppression(int Threshold, int MinSamplesaboveThreshold, int Presamples, int Postsamples){
321 // Configures the Zero Suppression Module (ZSU)
323 fZSUThreshold = InRange(Threshold,0,1023,"AliTPCAltroEmulator::BaselineCorrection1","Threshold");
324 fZSUMinSamplesaboveThreshold = InRange(MinSamplesaboveThreshold,1,3,"AliTPCAltroEmulator::BaselineCorrection1","MinSamplesaboveThreshold");
325 fZSUPresamples = InRange(Presamples,0,3,"AliTPCAltroEmulator::BaselineCorrection1","Presamples");
326 fZSUPostsamples = InRange(Postsamples,0,7,"AliTPCAltroEmulator::BaselineCorrection1","Postsamples");
327 fADCkeep = (short *)calloc(sizeof(short),ftimebins);
329 for(int i = 0; i < ftimebins; i++){
335 /** @brief Prints the set Parameters, if module is configured
337 * Prints the set Parameters, if module is configured.
339 void AliTPCAltroEmulator::PrintParameters(){
341 // Prints the set Parameters, if module is configured
343 cout << "+-------------------------------------------+" << endl;
344 cout << "| Configured Parameters of the Altro Module |" << endl;
345 cout << "+-------------------------------------------+" << endl << endl;
347 cout << "Parameters set in the Altro Modules:" << endl << endl;
348 cout << "ONBaselineCorrection1: " << fOnBSL1 << endl;
349 cout << "ONTailcancellation : " << fOnTCF << endl;
350 cout << "ONBaselineCorrection2: " << fOnBSL2 << endl;
351 cout << "ONClipping : " << fOnClip << endl;
352 cout << "ONZerosuppression : " << fOnZSU << endl << endl << endl;
353 if(fConfiguredBSL1 == 1){
354 cout << "Parameters set in the BSL1 (Baseline Correction 1) Module:" << endl << endl;
355 cout << "mode : " << fBSL1mode << endl;
356 cout << "ValuePeDestal : " << fBSL1ValuePeDestal << endl;
357 cout << "polarity : " << fBSL1ValuePeDestal << endl << endl << endl;
359 cout << "BSL1 (Baseline Correction 1) Module not configured!" << endl << endl << endl;
361 if(fConfiguredTCF == 1){
362 cout << "Parameters set in the TCF (TailCancellation Filter) Module:" << endl << endl;
363 cout << "K1 (int|float) : " << fTCFK1Int << " | " << fTCFK1Int/(float)((1<<16)-1) << endl;
364 cout << "K2 (int|float) : " << fTCFK2Int << " | " << fTCFK2Int/(float)((1<<16)-1) << endl;
365 cout << "K3 (int|float) : " << fTCFK3Int << " | " << fTCFK3Int/(float)((1<<16)-1) << endl;
366 cout << "L1 (int|float) : " << fTCFL1Int << " | " << fTCFL1Int/(float)((1<<16)-1) << endl;
367 cout << "L2 (int|float) : " << fTCFL2Int << " | " << fTCFL2Int/(float)((1<<16)-1) << endl;
368 cout << "L3 (int|float) : " << fTCFL3Int << " | " << fTCFL3Int/(float)((1<<16)-1) << endl << endl << endl;
370 cout << "TCF (TailCancellation Filter) Module not configured!" << endl << endl << endl;
372 if(fConfiguredBSL2 == 1){
373 cout << "Parameters set in the BSL2 (Baseline Correction 2) Module:" << endl << endl;
374 cout << "HighThreshold : " << fBSL2HighThreshold << endl;
375 cout << "LowThreshold : " << fBSL2LowThreshold << endl;
376 cout << "Offset : " << fBSL2Offset << endl;
377 cout << "Presamples : " << fBSL2Presamples << endl;
378 cout << "Postsamples : " << fBSL2Postsamples << endl << endl << endl;
380 cout << "BSL2 (Baseline Correction 2) Module not configured!" << endl << endl << endl;
382 if(fConfiguredZSU == 1){
383 cout << "Parameters set in the ZSU (Zero Suppression Unit) Module:" << endl << endl;
384 cout << "Threshold : " << fZSUThreshold << endl;
385 cout << "MinSampaboveThreshold: " << fZSUMinSamplesaboveThreshold << endl;
386 cout << "Presamples : " << fZSUPresamples << endl;
387 cout << "Postsamples : " << fZSUPostsamples << endl << endl << endl;
389 cout << "ZSU (Zero Suppression Unit) Module not configured!" << endl << endl << endl;
393 /** @brief Runs the emulation of all configured Modules.
395 * Runs the emulation of all configured Modules. This changes then the content of the
398 void AliTPCAltroEmulator::RunEmulation(){
400 // Runs the emulation of all configured Modules.
403 //cout << "AliTPCAltroEmulator::RunEmulation | start" << endl;
404 if(fConfiguredAltro == 0){
405 cout << "ERROR cant run Altro Emulation because not configured" << endl;
409 //cout << "AliTPCAltroEmulator::RunEmulation | start BSL1 on: " << fOnBSL1 << " configures: " << fConfiguredBSL1 << endl;
411 if(fConfiguredBSL1 == 1){
412 BaselineCorrection1(fBSL1mode, fBSL1ValuePeDestal, fBSL1PedestalMem, fBSL1polarity);
414 cout << "ERROR cant run Baseline Correction 1 because not configured" << endl;
419 //cout << "AliTPCAltroEmulator::RunEmulation | start TCF on: " << fOnTCF << " configures: " << fConfiguredTCF << endl;
421 if(fConfiguredTCF == 1){
422 TailCancellationFilterFixedPoint(fTCFK1Int, fTCFK2Int, fTCFK3Int, fTCFL1Int, fTCFL2Int, fTCFL3Int);
424 cout << "ERROR cant run Tail Cancellation Filter because not configured" << endl;
429 //cout << "AliTPCAltroEmulator::RunEmulation | start BSL2 on: " << fOnBSL2 << " configures: " << fConfiguredBSL2 << endl;
431 if(fConfiguredBSL2 == 1){
432 BaselineCorrection2RTL(fBSL2HighThreshold, fBSL2LowThreshold, fBSL2Offset, fBSL2Presamples, fBSL2Postsamples);
434 cout << "ERROR cant run Baseline Correction 2 because not configured" << endl;
438 //cout << "AliTPCAltroEmulator::RunEmulation | start CLIP on: " << fOnClip << endl;
442 //cout << "AliTPCAltroEmulator::RunEmulation | start ZSU on: " << fOnZSU << " configures: " << fConfiguredZSU << endl;
444 if(fConfiguredZSU == 1){
445 Zerosuppression(fZSUThreshold,fZSUMinSamplesaboveThreshold,fZSUPresamples,fZSUPostsamples);
447 cout << "ERROR cant run Zero Suppression Unit because not configured" << endl;
453 void AliTPCAltroEmulator::BaselineCorrection1(int mode, int ValuePeDestal, int *PedestalMem, int polarity){
455 // BaselineCorrection1
459 int fixedPeDestal = 0;
462 for(int i = 0; i < ftimebins; i++){
463 fChannelShort[i] = 1023 - fChannelShort[i];
469 for(int i = 0; i < ftimebins; i++)
470 fChannelShort[i] = fChannelShort[i] - fixedPeDestal;
473 for(int i = 0; i < ftimebins; i++)
474 fChannelShort[i] = fChannelShort[i] - PedestalMem[i];
477 for(int i = 0; i < ftimebins; i++)
478 fChannelShort[i] = fChannelShort[i] - PedestalMem[ fChannelShort[i] ];
481 for(int i = 0; i < ftimebins; i++)
482 fChannelShort[i] = fChannelShort[i] - PedestalMem[ fChannelShort[i] - ValuePeDestal];
485 for(int i = 0; i < ftimebins; i++)
486 fChannelShort[i] = fChannelShort[i] - ValuePeDestal - fixedPeDestal;
489 for(int i = 0; i < ftimebins; i++)
490 fChannelShort[i] = fChannelShort[i] - ValuePeDestal - PedestalMem[i];
493 for(int i = 0; i < ftimebins; i++)
494 fChannelShort[i] = fChannelShort[i] - ValuePeDestal - PedestalMem[ fChannelShort[i] ];
496 case kDINxVPDxFDINxVPD:
497 for(int i = 0; i < ftimebins; i++)
498 fChannelShort[i] = fChannelShort[i] - ValuePeDestal - PedestalMem[ fChannelShort[i] - ValuePeDestal ];
501 for(int i = 0; i < ftimebins; i++)
502 fChannelShort[i] = PedestalMem[ fChannelShort[i] ] - fixedPeDestal;
505 for(int i = 0; i < ftimebins; i++)
506 fChannelShort[i] = PedestalMem[ fChannelShort[i] - ValuePeDestal ] - fixedPeDestal;
509 for(int i = 0; i < ftimebins; i++)
510 fChannelShort[i] = PedestalMem[i] - fixedPeDestal;
515 int AliTPCAltroEmulator::Multiply36(int P, int N){
517 // multiply function to emulate the 36 bit fixed point multiplication of the Altro.
522 temp = (long long)P*(long long)N;
523 vAX = (( Mask(temp,35,18) + ((long long)(-P)<<18) ) + Mask(temp,17,0));
524 if ( Maskandshift(N,17,17) == 1){
525 retval = ((Maskandshift(vAX,35,35)<<17) + Maskandshift(vAX,32,16));
527 retval = Maskandshift(temp,32,16);
531 long long AliTPCAltroEmulator::Mask(long long in, int left, int right){
537 long long length = abs(left - right)+1;
538 pattern = ((1<<length)-1)<<right;
543 long long AliTPCAltroEmulator::Maskandshift(long long in, int left, int right){
549 long long length = abs(left - right)+1;
550 pattern = ((1<<length)-1);
551 retval = (in>>right)&pattern;
555 void AliTPCAltroEmulator::TailCancellationFilterFixedPoint(int K1, int K2, int K3, int L1, int L2, int L3){
557 // TailCancellationFilterFixedPoint
559 int c1n = 0, c2n = 0, c3n = 0;
560 int c1o = 0, c2o = 0, c3o = 0;
565 for(int i = 0; i < ftimebins; i++){
566 din = fChannelShort[i];
569 c1n = Mask( (Mask(din,17,0) + Multiply36(K1,Mask(c1o,17,0)) ) ,17,0);
570 d1 = Mask( (Mask(c1n,17,0) - Multiply36(L1,Mask(c1o,17,0)) ) ,17,0);
571 //d1 = Mask( (Mask(c1n,17,0) + Mask(~Multiply36(L1,Mask(c1o,17,0))+1,17,0) ) ,17,0);
573 c2n = Mask( (Mask(d1 ,17,0) + Multiply36(K2,Mask(c2o,17,0)) ) ,17,0);
574 d2 = Mask( (Mask(c2n,17,0) - Multiply36(L2,Mask(c2o,17,0)) ) ,17,0);
575 //d2 = Mask( (Mask(c2n,17,0) + Mask(~Multiply36(L2,Mask(c2o,17,0))+1,17,0) ) ,17,0);
577 c3n = Mask( (Mask(d2 ,17,0) + Multiply36(K3,Mask(c3o,17,0)) ) ,17,0);
578 dout = Mask( (Mask(c3n,17,0) - Multiply36(L3,Mask(c3o,17,0)) ) ,17,0);
579 //dout = Mask( (Mask(c3n,17,0) + Mask(~Multiply36(L3,Mask(c3o,17,0))+1,17,0) ) ,17,0);
581 if( (Maskandshift(dout,2,2) == 1) || (Maskandshift(dout,1,1) == 1)){
587 dout = ((dout>>3)<<1) + bit;
588 if(Maskandshift(dout,15,15) == 1){
589 //is needed to get the correct coding when getting negative results
590 dout = -Mask((-Mask(dout,9,0)),9,0);
592 dout = Mask(dout,9,0);
595 fChannelShort[i] = (short) dout;
602 void AliTPCAltroEmulator::BaselineCorrection2RTL(int HighThreshold, int LowThreshold, int Offset, int Presamples, int Postsamples){
604 // BaselineCorrection2RTL
607 //cout << "Altro::BaselineCorrection2RTL | HighThreshold: " << HighThreshold << " LowThreshold: " << LowThreshold << " Offset: " << Offset << " Presamples: " << Presamples << " Postsamples: " << Postsamples << endl;
608 //more or less direct "translation" of the hdl code.
612 int edges[6]; // = Postsamples*4 + Presamples;
614 int thrlo = LowThreshold;//called thr_mau[19] ...
615 int thrhi = HighThreshold;
618 int fOld[4]; //flag pipe
619 int fNew[4]; //flag pipe
620 int dOld[4]; //data pipe
621 int dNew[4]; //data pipe
624 int pstscnt; // Counter for Postsamples
625 int zOld[9]; // Filter stages
626 int zNew[9]; // Filter stages
627 int zxOld; //Accumulator stage
628 int zxNew; //Accumulator stage
629 int valcntOld; //Valid sample counter
630 int valcntNew = 0; //Valid sample counter
632 int valid; //Valid flag
633 int fx; //postsample flag
634 //int s07; // differentiator result
635 int s8; // Acc + Diff result
637 //int bsth; //baseline threshold
638 //int din_p; //Data input strictly positive
640 //int dx_bsls; // dx -bsl
641 //int dx_clip; // dxbsl clipped
645 for(int i = 0; i < 9 ; i++)
647 for(int i = 0; i < 4 ; i++){
656 for(int i = 0; i < 2 ; i++){
657 edges[i] = (Presamples&(1<<i))>>i;
659 for(int i = 0; i < 4 ; i++){
660 edges[(3-i)+2] = (Postsamples&(1<<i))>>i;
663 for(int i = 0; i < 6 ; i++)
664 cout << edges[i] << ":";
665 cout << " Presamples: " << Presamples << " Postsamples: " << Postsamples << endl;*/
668 //cout << "AliTPCAltroEmulator::BaselineCorrection2_RTL | starting Loop" << endl;
669 for(int timebin = -12; timebin < ftimebins+10; timebin++){
670 //cout << "AliTPCAltroEmulator::BaselineCorrection2_RTL | in Loop timebin: " << timebin << endl;
671 din = GetElement(fChannelShort,timebin);
673 s8 = zxOld + (zOld[8] - zOld[0]);
680 //assign flag = (din_p > thrhi) | (thrlo > din_p); // Signal samples between thresholds
681 if( (din <= (bsl + thrhi)) && (din >= (bsl - thrlo)) )
698 if( (fOld[3] == 1) || ( (flag == 1) && ( (edges[0] == 1) || (edges[1] == 1) ) ) ) //f[2] = f[3] | (flag&(edges[0]|edges[1]));
703 if( (fOld[2] == 1) || ( (edges[1] == 1) && (flag == 1) ) ) // f[1] = f[2] | (edges[1] & flag);
708 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;
714 for(int i = 0; i < 3; i++)
718 if( (fOld[1]==1) && (fOld[2]==0) )
719 pstscnt = Postsamples;
725 valcntNew = ++valcntOld;
728 for(int i = 0; i < 8; i++)
733 for(int i = 0; i < 9; i++)
736 dout = dxOld - (bsl - offset);
740 SetElement(fChannelShort,timebin-5,(short)dout);
742 for(int i = 0; i < 9 ; i++)
745 for(int i = 0; i < 4 ; i++){
750 valcntOld = valcntNew;
754 void AliTPCAltroEmulator::Clipping(){
756 // implement if no BC2 clipping has to run
758 for(int i = 0; i < ftimebins; i++){
759 if(fChannelShort[i] < 0)
760 fChannelShort[i] = 0;
764 void AliTPCAltroEmulator::Zerosuppression(int Threshold, int MinSamplesaboveThreshold, int Presamples, int Postsamples){
766 // add again altro feature
769 //TODO: Implement "Altro zsu merging"
770 //int Postsamplecounter = 0;
771 //int setPostsample = 0;
772 for(int i = 0; i < ftimebins; i++){
773 if(fChannelShort[i] >= Threshold){
778 int startofclustersequence = -1;
779 int endofClustersInSequence = -1;
781 for(int i = 0; i < ftimebins; i++){
782 if( (fADCkeep[i] == 1) && (GetElement(fADCkeep,i-1) == 0) ){
783 startofclustersequence = i;
785 if( (fADCkeep[i] == 1) && (GetElement(fADCkeep,i+1) == 0) ){
786 endofClustersInSequence = i;
788 //cout << i << " startofclustersequence: " << startofclustersequence << " endofClustersInSequence: " << endofClustersInSequence;
789 if( (startofclustersequence != -1) && (endofClustersInSequence != -1) ){
790 //cout << " found! " << (endofClustersInSequence - startofclustersequence + 1);
791 if ( (endofClustersInSequence - startofclustersequence + 1) < MinSamplesaboveThreshold ){
792 for(int j = startofclustersequence; j <= endofClustersInSequence ; j++){
796 startofclustersequence = -1;
797 endofClustersInSequence = -1;
802 /*for(int i = 0; i < ftimebins; i++){
803 if( (GetElement(fADCkeep,i-1) == 1) && (GetElement(fADCkeep,i) == 0) && (GetElement(fADCkeep,i+1) == 1) ){
804 SetElement(fADCkeep,i,1);
808 for(int i = 0; i < ftimebins; i++){
809 if( (fADCkeep[i] == 1) && (GetElement(fADCkeep,i-1) == 0) ){
810 for(int j = i-Presamples ; j <= i; j++){
811 SetElement(fADCkeep,j,1);
815 for(int i = ftimebins; i >= 0; i--){
816 if( (fADCkeep[i] == 1) && (GetElement(fADCkeep,i+1) == 0) ){
817 for(int j = i ; j <= i+Postsamples; j++){
818 SetElement(fADCkeep,j,1);
822 /*cout << " Postsamplecounter: " << Postsamplecounter;
823 for(int j = i+1 ; j <= i+Postsamples; j++){
824 SetElement(fADCkeep,j,1);
829 cout << i << " ADCK: " << GetElement(fADCkeep,i);
830 cout << " Postsam: " << Postsamplecounter << " ADCK: " << GetElement(fADCkeep,i);*/
832 for(int i = 0; i < ftimebins; i++){
833 if( (fADCkeep[i] == 1) && (GetElement(fADCkeep,i+1) == 0) && ( (GetElement(fADCkeep,i+3) == 1) || (GetElement(fADCkeep,i+2) == 1) ) ){
834 SetElement(fADCkeep,i+1,1);
835 SetElement(fADCkeep,i+2,1);
840 /** @brief formats the data like the ALTRO. Result is a 64 bit array
842 * formats the data like the ALTRO. Result is a 64 bit array
846 void AliTPCAltroEmulator::DataFormater(){
848 // formats the data like the ALTRO. Result is a 64 bit array
855 /** @brief calculates the compression out of the bitmask
857 * calculates the compression out of the bitmask with the set adc values
859 * @return \c float consisting of the compression factor
861 float AliTPCAltroEmulator::CalculateCompression(){
863 // calculates the compression out of the bitmask
866 // calculation is based on altro 10 bit words ..
872 for(int i = 0; i < ftimebins; i++){
873 if(fADCkeep[i] == 1){
876 if( (fADCkeep[i] == 1) && (GetElement(fADCkeep,i+1) == 0) ){
880 data = sample + cluster*2;
881 data = data + data%4 + 4;
883 retval = ftimebins / (float)data;//num of timebins is equal to max number of samples
890 short AliTPCAltroEmulator::GetElement(short* Array,int index){
896 else if(index >= ftimebins)
902 void AliTPCAltroEmulator::SetElement(short* Array,int index,short value){
908 else if(index >= ftimebins)
911 Array[index] = value;
914 int AliTPCAltroEmulator::InBand(int ADC,int bsl, int LowThreshold, int HighThreshold){
918 int fLow = bsl - LowThreshold;
919 int fHigh = bsl + HighThreshold;
920 if( (ADC <= fHigh) && (ADC >= fLow) )
926 int AliTPCAltroEmulator::InRange(int parameter,int Low,int High,char *Module,char *ParameterName){
933 if(parameter > High){
934 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);
937 }else if(parameter < Low){
938 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);
947 short AliTPCAltroEmulator::GetShortChannel(int i){
951 return GetElement(fChannelShort,i);
954 short AliTPCAltroEmulator::GetKeepChannel(int i){
958 return GetElement(fADCkeep,i);