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