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