]>
Commit | Line | Data |
---|---|---|
0508ca31 | 1 | /************************************************************************** |
2 | * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * | |
3 | * * | |
4 | * Author: The ALICE Off-line Project. * | |
5 | * Contributors are mentioned in the code where appropriate. * | |
6 | * * | |
7 | * Permission to use, copy, modify and distribute this software and its * | |
8 | * documentation strictly for non-commercial purposes is hereby granted * | |
9 | * without fee, provided that the above copyright notice appears in all * | |
10 | * copies and that both the copyright notice and this permission notice * | |
11 | * appear in the supporting documentation. The authors make no claims * | |
12 | * about the suitability of this software for any purpose. It is * | |
13 | * provided "as is" without express or implied warranty. * | |
14 | **************************************************************************/ | |
15 | ||
16 | //////////////////////////////////////////////////////////////////////////// | |
17 | // // | |
18 | // Decoding data from the TRD raw stream // | |
9cb9c409 | 19 | // and translation into ADC values, on-line tracklets and tracks // |
0508ca31 | 20 | // // |
21 | // Author: J. Klein (jochen.klein@cern.ch) // | |
22 | // // | |
23 | //////////////////////////////////////////////////////////////////////////// | |
24 | ||
92223bf6 | 25 | #include <cstdio> |
26 | #include <cstdarg> | |
27 | ||
d60fe037 | 28 | #include "TClonesArray.h" |
29 | #include "TTree.h" | |
30 | ||
31 | #include "AliLog.h" | |
32 | #include "AliRawReader.h" | |
33 | #include "AliTRDdigitsManager.h" | |
34 | #include "AliTRDdigitsParam.h" | |
43573bcf | 35 | #include "AliTRDcalibDB.h" |
36 | #include "AliTRDmcmSim.h" | |
d60fe037 | 37 | #include "AliTRDtrapConfig.h" |
38 | #include "AliTRDarrayADC.h" | |
39 | #include "AliTRDarrayDictionary.h" | |
40 | #include "AliTRDSignalIndex.h" | |
41 | #include "AliTRDtrackletWord.h" | |
52a2b6c0 | 42 | #include "AliTRDtrackletMCM.h" |
5fdfc9e4 | 43 | #include "AliESDTrdTrack.h" |
cc26f39c | 44 | #include "AliTreeLoader.h" |
c93255fe | 45 | #include "AliLoader.h" |
d60fe037 | 46 | |
47 | #include "AliTRDrawStream.h" | |
48 | ||
49 | // temporary | |
50 | #include "AliRunLoader.h" | |
51 | ||
52 | ClassImp(AliTRDrawStream) | |
53 | ||
9cb9c409 | 54 | // some static information |
55 | Int_t AliTRDrawStream::fgMcmOrder[] = {12, 13, 14, 15, | |
56 | 8, 9, 10, 11, | |
57 | 4, 5, 6, 7, | |
58 | 0, 1, 2, 3}; | |
59 | Int_t AliTRDrawStream::fgRobOrder [] = {0, 1, 2, 3}; | |
d60fe037 | 60 | const Int_t AliTRDrawStream::fgkNlinks = 12; |
61 | const Int_t AliTRDrawStream::fgkNstacks = 5; | |
9cb9c409 | 62 | const Int_t AliTRDrawStream::fgkNsectors = 18; |
63 | const Int_t AliTRDrawStream::fgkNtriggers = 12; | |
d60fe037 | 64 | const UInt_t AliTRDrawStream::fgkDataEndmarker = 0x00000000; |
65 | const UInt_t AliTRDrawStream::fgkTrackletEndmarker = 0x10001000; | |
52a2b6c0 | 66 | const UInt_t AliTRDrawStream::fgkStackEndmarker[] = { 0xe0d01000, 0xe0d10000 }; |
d60fe037 | 67 | |
92305359 | 68 | const char* AliTRDrawStream::fgkErrorMessages[] = { |
d60fe037 | 69 | "Unknown error", |
70 | "Link monitor active", | |
52a2b6c0 | 71 | "Event counter mismatch", |
d60fe037 | 72 | "not a TRD equipment (1024-1041)", |
73 | "Invalid Stack header", | |
74 | "Invalid detector number", | |
75 | "No digits could be retrieved from the digitsmanager", | |
5f006bd7 | 76 | "HC header mismatch", |
d60fe037 | 77 | "HC check bits wrong", |
78 | "Unexpected position in readout stream", | |
79 | "Invalid testpattern mode", | |
80 | "Testpattern mismatch", | |
81 | "Number of timebins changed", | |
5f006bd7 | 82 | "ADC mask inconsistent", |
83 | "ADC check bits invalid", | |
d60fe037 | 84 | "Missing ADC data", |
85 | "Missing expected ADC channels", | |
2519cca4 | 86 | "Missing MCM headers", |
52a2b6c0 | 87 | "Missing TP data", |
88 | "CRC mismatch" | |
d60fe037 | 89 | }; |
90 | ||
92305359 | 91 | Int_t AliTRDrawStream::fgErrorDebugLevel[] = { |
92223bf6 | 92 | 0, |
93 | 0, | |
5f006bd7 | 94 | 2, |
95 | 1, | |
96 | 0, | |
97 | 1, | |
98 | 1, | |
99 | 1, | |
92223bf6 | 100 | 1, |
92223bf6 | 101 | 2, |
102 | 1, | |
2519cca4 | 103 | 0, |
92223bf6 | 104 | 1, |
5f006bd7 | 105 | 1, |
106 | 2, | |
107 | 1, | |
108 | 1, | |
2519cca4 | 109 | 1, |
52a2b6c0 | 110 | 0, |
2519cca4 | 111 | 0 |
92223bf6 | 112 | }; |
113 | ||
114 | AliTRDrawStream::ErrorBehav_t AliTRDrawStream::fgErrorBehav[] = { | |
115 | AliTRDrawStream::kTolerate, | |
116 | AliTRDrawStream::kDiscardHC, | |
117 | AliTRDrawStream::kTolerate, | |
118 | AliTRDrawStream::kAbort, | |
119 | AliTRDrawStream::kAbort, | |
120 | AliTRDrawStream::kAbort, | |
121 | AliTRDrawStream::kAbort, | |
122 | AliTRDrawStream::kDiscardHC, | |
123 | AliTRDrawStream::kDiscardHC, | |
124 | AliTRDrawStream::kTolerate, | |
125 | AliTRDrawStream::kTolerate, | |
126 | AliTRDrawStream::kTolerate, | |
127 | AliTRDrawStream::kTolerate, | |
128 | AliTRDrawStream::kTolerate, | |
129 | AliTRDrawStream::kTolerate, | |
130 | AliTRDrawStream::kTolerate, | |
131 | AliTRDrawStream::kTolerate, | |
2519cca4 | 132 | AliTRDrawStream::kTolerate, |
52a2b6c0 | 133 | AliTRDrawStream::kTolerate, |
92223bf6 | 134 | AliTRDrawStream::kTolerate |
135 | }; | |
136 | ||
d60fe037 | 137 | AliTRDrawStream::AliTRDrawStream(AliRawReader *rawReader) : |
f0a345a7 | 138 | fStoreError(&AliTRDrawStream::ForgetError), |
d60fe037 | 139 | fRawReader(rawReader), |
140 | fDigitsManager(0x0), | |
141 | fDigitsParam(0x0), | |
142 | fErrors(0x0), | |
143 | fLastError(), | |
92223bf6 | 144 | fErrorFlags(0), |
2519cca4 | 145 | fStats(), |
d60fe037 | 146 | fPayloadStart(0x0), |
147 | fPayloadCurr(0x0), | |
148 | fPayloadSize(0), | |
149 | fNtimebins(-1), | |
150 | fLastEvId(-1), | |
151 | fCurrSlot(-1), | |
152 | fCurrLink(-1), | |
153 | fCurrRobPos(-1), | |
154 | fCurrMcmPos(-1), | |
155 | fCurrEquipmentId(0), | |
9cb9c409 | 156 | fCurrSmHeaderSize(0), |
157 | fCurrSmHeaderVersion(0), | |
158 | fCurrTrailerReadout(0), | |
159 | fCurrTrgHeaderAvail(0), | |
160 | fCurrTrgHeaderReadout(0), | |
161 | fCurrTrkHeaderAvail(0), | |
52a2b6c0 | 162 | fCurrStackEndmarkerAvail(0), |
9cb9c409 | 163 | fCurrEvType(0), |
164 | fCurrTriggerEnable(0), | |
165 | fCurrTriggerFired(0), | |
d60fe037 | 166 | fCurrTrackEnable(0), |
167 | fCurrTrackletEnable(0), | |
168 | fCurrStackMask(0), | |
9cb9c409 | 169 | fCurrTrkHeaderIndexWord(0x0), |
170 | fCurrTrkHeaderSize(0x0), | |
2519cca4 | 171 | fCurrTrkFlags(0x0), |
9cb9c409 | 172 | fCurrTrgHeaderIndexWord(0x0), |
173 | fCurrTrgHeaderSize(0x0), | |
2519cca4 | 174 | fCurrTrgFlags(0x0), |
d60fe037 | 175 | fCurrStackIndexWord(0x0), |
176 | fCurrStackHeaderSize(0x0), | |
177 | fCurrStackHeaderVersion(0x0), | |
178 | fCurrLinkMask(0x0), | |
179 | fCurrCleanCheckout(0x0), | |
180 | fCurrBoardId(0x0), | |
9cb9c409 | 181 | fCurrHwRev(-1), |
182 | fCurrHwRevTMU(0x0), | |
d60fe037 | 183 | fCurrLinkMonitorFlags(0x0), |
184 | fCurrLinkDataTypeFlags(0x0), | |
185 | fCurrLinkDebugFlags(0x0), | |
52a2b6c0 | 186 | fCurrMatchFlagsSRAM(0), |
187 | fCurrMatchFlagsPostBP(0), | |
188 | fCurrChecksumStack(), | |
189 | fCurrChecksumSIU(0), | |
d60fe037 | 190 | fCurrSpecial(-1), |
191 | fCurrMajor(-1), | |
192 | fCurrMinor(-1), | |
193 | fCurrAddHcWords(-1), | |
194 | fCurrSm(-1), | |
195 | fCurrStack(-1), | |
196 | fCurrLayer(-1), | |
197 | fCurrSide(-1), | |
198 | fCurrHC(-1), | |
199 | fCurrCheck(-1), | |
200 | fCurrNtimebins(-1), | |
201 | fCurrBC(-1), | |
202 | fCurrPtrgCnt(-1), | |
203 | fCurrPtrgPhase(-1), | |
cc26f39c | 204 | fNDumpMCMs(0), |
d60fe037 | 205 | fTrackletArray(0x0), |
206 | fAdcArray(0x0), | |
207 | fSignalIndex(0x0), | |
5fdfc9e4 | 208 | fTrackletTree(0x0), |
209 | fTracklets(0x0), | |
210 | fTracks(0x0), | |
211 | fMarkers(0x0) | |
d60fe037 | 212 | { |
213 | // default constructor | |
214 | ||
9cb9c409 | 215 | fCurrTrkHeaderIndexWord = new UInt_t[fgkNstacks]; |
216 | fCurrTrkHeaderSize = new UInt_t[fgkNstacks]; | |
2519cca4 | 217 | fCurrTrkFlags = new ULong64_t[fgkNsectors*fgkNstacks]; |
9cb9c409 | 218 | fCurrTrgHeaderIndexWord = new UInt_t[fgkNtriggers]; |
219 | fCurrTrgHeaderSize = new UInt_t[fgkNtriggers]; | |
2519cca4 | 220 | fCurrTrgFlags = new UInt_t[fgkNsectors]; |
5f006bd7 | 221 | fCurrStackIndexWord = new UInt_t[fgkNstacks]; |
222 | fCurrStackHeaderSize = new UInt_t[fgkNstacks]; | |
d60fe037 | 223 | fCurrStackHeaderVersion = new UInt_t[fgkNstacks]; |
5f006bd7 | 224 | fCurrLinkMask = new UInt_t[fgkNstacks]; |
225 | fCurrCleanCheckout = new UInt_t[fgkNstacks]; | |
226 | fCurrBoardId = new UInt_t[fgkNstacks]; | |
9cb9c409 | 227 | fCurrHwRevTMU = new UInt_t[fgkNstacks]; |
d60fe037 | 228 | fCurrLinkMonitorFlags = new UInt_t[fgkNstacks * fgkNlinks]; |
229 | fCurrLinkDataTypeFlags = new UInt_t[fgkNstacks * fgkNlinks]; | |
230 | fCurrLinkDebugFlags = new UInt_t[fgkNstacks * fgkNlinks]; | |
2519cca4 | 231 | for (Int_t iSector = 0; iSector < fgkNsectors; iSector++) |
232 | fCurrTrgFlags[iSector] = 0; | |
5fdfc9e4 | 233 | for (Int_t i = 0; i < 100; i++) |
234 | fDumpMCM[i] = 0; | |
d60fe037 | 235 | |
236 | // preparing TClonesArray | |
237 | fTrackletArray = new TClonesArray("AliTRDtrackletWord", 256); | |
238 | ||
239 | // setting up the error tree | |
240 | fErrors = new TTree("errorStats", "Error statistics"); | |
241 | fErrors->SetDirectory(0x0); | |
5fdfc9e4 | 242 | fErrors->Branch("error", &fLastError); |
d60fe037 | 243 | fErrors->SetCircular(1000); |
2f9bdd85 | 244 | for (Int_t i = 0; i < 100; i++) { |
245 | fErrorBuffer[i] = 0; | |
246 | } | |
247 | ||
d60fe037 | 248 | } |
249 | ||
250 | AliTRDrawStream::~AliTRDrawStream() | |
251 | { | |
252 | // destructor | |
253 | ||
254 | delete fErrors; | |
255 | ||
9cb9c409 | 256 | delete [] fCurrTrkHeaderIndexWord; |
257 | delete [] fCurrTrkHeaderSize; | |
2519cca4 | 258 | delete [] fCurrTrkFlags; |
9cb9c409 | 259 | delete [] fCurrTrgHeaderIndexWord; |
260 | delete [] fCurrTrgHeaderSize; | |
2519cca4 | 261 | delete [] fCurrTrgFlags; |
d60fe037 | 262 | delete [] fCurrStackIndexWord; |
263 | delete [] fCurrStackHeaderSize; | |
264 | delete [] fCurrStackHeaderVersion; | |
265 | delete [] fCurrLinkMask; | |
266 | delete [] fCurrCleanCheckout; | |
267 | delete [] fCurrBoardId; | |
9cb9c409 | 268 | delete [] fCurrHwRevTMU; |
d60fe037 | 269 | delete [] fCurrLinkMonitorFlags; |
270 | delete [] fCurrLinkDataTypeFlags; | |
271 | delete [] fCurrLinkDebugFlags; | |
272 | } | |
273 | ||
274 | Bool_t AliTRDrawStream::ReadEvent(TTree *trackletTree) | |
275 | { | |
276 | // read the current event from the raw reader and fill it to the digits manager | |
277 | ||
278 | if (!fRawReader) { | |
279 | AliError("No raw reader available"); | |
280 | return kFALSE; | |
281 | } | |
282 | ||
283 | // tracklet output | |
67271412 | 284 | ConnectTracklets(trackletTree); |
d60fe037 | 285 | |
286 | // some preparations | |
287 | fDigitsParam = 0x0; | |
288 | ||
289 | // loop over all DDLs | |
9cb9c409 | 290 | // data starts with GTU payload, i.e. SM index word |
d60fe037 | 291 | UChar_t *buffer = 0x0; |
292 | ||
293 | while (fRawReader->ReadNextData(buffer)) { | |
294 | ||
295 | fCurrEquipmentId = fRawReader->GetEquipmentId(); | |
296 | AliDebug(2, Form("equipment: %i", fCurrEquipmentId)); | |
297 | ||
9cb9c409 | 298 | if (fCurrEquipmentId < kDDLOffset || fCurrEquipmentId > kDDLMax) { |
92223bf6 | 299 | EquipmentError(kNonTrdEq, "Skipping"); |
d60fe037 | 300 | continue; |
301 | } | |
302 | ||
8df9496c | 303 | if (fMarkers) |
304 | new ((*fMarkers)[fMarkers->GetEntriesFast()]) | |
9cb9c409 | 305 | AliTRDrawStreamError(-kSecactive, fCurrEquipmentId - kDDLOffset); |
8df9496c | 306 | |
9cb9c409 | 307 | ReadGTUHeaders((UInt_t*) buffer); |
d60fe037 | 308 | |
9cb9c409 | 309 | if (fCurrTrailerReadout) |
310 | ReadGTUTrailer(); | |
d60fe037 | 311 | |
9cb9c409 | 312 | // loop over all active links |
313 | AliDebug(2, Form("Stack mask 0x%02x", fCurrStackMask)); | |
314 | for (Int_t iStack = 0; iStack < fgkNstacks; iStack++) { | |
d60fe037 | 315 | fCurrSlot = iStack; |
9cb9c409 | 316 | if ((fCurrStackMask & (1 << fCurrSlot)) == 0) |
d60fe037 | 317 | continue; |
318 | ||
319 | AliDebug(2, Form("Stack %i, Link mask: 0x%02x", fCurrSlot, fCurrLinkMask[fCurrSlot])); | |
9cb9c409 | 320 | for (Int_t iLink = 0; iLink < fgkNlinks; iLink++) { |
d60fe037 | 321 | fCurrLink = iLink; |
9cb9c409 | 322 | fCurrHC = (fCurrEquipmentId - kDDLOffset) * fgkNstacks * fgkNlinks + |
323 | fCurrSlot * fgkNlinks + iLink; | |
d60fe037 | 324 | if ((fCurrLinkMask[fCurrSlot] & (1 << fCurrLink)) == 0) |
325 | continue; | |
9cb9c409 | 326 | |
52a2b6c0 | 327 | Int_t size = 0; |
328 | ||
92223bf6 | 329 | fErrorFlags = 0; |
330 | // check for link monitor error flag | |
2519cca4 | 331 | if (fCurrLinkMonitorFlags[fCurrSlot*fgkNlinks + fCurrLink] != 0) { |
d60fe037 | 332 | LinkError(kLinkMonitor); |
2519cca4 | 333 | if (fgErrorBehav[kLinkMonitor] == kTolerate) |
52a2b6c0 | 334 | size += ReadLinkData(); |
2519cca4 | 335 | } |
7534e6db | 336 | else |
337 | // read the data from one HC | |
52a2b6c0 | 338 | size += ReadLinkData(); |
d60fe037 | 339 | |
340 | // read all data endmarkers | |
52a2b6c0 | 341 | size += SeekNextLink(); |
d60fe037 | 342 | } |
52a2b6c0 | 343 | |
344 | // continue with next stack | |
345 | SeekNextStack(); | |
d60fe037 | 346 | } |
347 | } | |
9cb9c409 | 348 | |
d60fe037 | 349 | return kTRUE; |
350 | } | |
351 | ||
352 | ||
353 | Bool_t AliTRDrawStream::NextDDL() | |
354 | { | |
0508ca31 | 355 | // continue reading with the next equipment |
356 | ||
d60fe037 | 357 | if (!fRawReader) |
358 | return kFALSE; | |
359 | ||
360 | fCurrEquipmentId = 0; | |
361 | fCurrSlot = 0; | |
362 | fCurrLink = 0; | |
363 | ||
364 | UChar_t *buffer = 0x0; | |
365 | ||
366 | while (fRawReader->ReadNextData(buffer)) { | |
367 | ||
368 | fCurrEquipmentId = fRawReader->GetEquipmentId(); | |
369 | AliDebug(2, Form("equipment: %i", fCurrEquipmentId)); | |
5f006bd7 | 370 | |
9cb9c409 | 371 | if (fCurrEquipmentId < kDDLOffset || fCurrEquipmentId > kDDLMax) { |
92223bf6 | 372 | EquipmentError(kNonTrdEq, "Skipping"); |
d60fe037 | 373 | continue; |
374 | } | |
375 | ||
8df9496c | 376 | if (fMarkers) |
377 | new ((*fMarkers)[fMarkers->GetEntriesFast()]) | |
9cb9c409 | 378 | AliTRDrawStreamError(-kSecactive, fCurrEquipmentId - kDDLOffset); |
8df9496c | 379 | |
9cb9c409 | 380 | ReadGTUHeaders((UInt_t*) buffer); |
381 | ||
382 | if (fCurrTrailerReadout) | |
383 | ReadGTUTrailer(); | |
d60fe037 | 384 | |
d60fe037 | 385 | return kTRUE; |
386 | } | |
387 | ||
388 | return kFALSE; | |
389 | } | |
390 | ||
391 | ||
9cb9c409 | 392 | Int_t AliTRDrawStream::NextChamber(AliTRDdigitsManager *digMgr) |
d60fe037 | 393 | { |
0508ca31 | 394 | // read the data for the next chamber |
395 | // in case you only want to read the data of a single chamber | |
396 | // to read all data ReadEvent(...) is recommended | |
397 | ||
5f006bd7 | 398 | fDigitsManager = digMgr; |
d60fe037 | 399 | fDigitsParam = 0x0; |
400 | ||
92223bf6 | 401 | fErrorFlags = 0; |
402 | ||
d60fe037 | 403 | // tracklet output preparation |
67271412 | 404 | TTree *trklTree = 0x0; |
405 | AliRunLoader *rl = AliRunLoader::Instance(); | |
44ac5cbf | 406 | AliLoader* trdLoader = rl ? rl->GetLoader("TRDLoader") : NULL; |
407 | AliDataLoader *trklLoader = trdLoader ? trdLoader->GetDataLoader("tracklets") : NULL; | |
408 | if (trklLoader) { | |
cc26f39c | 409 | AliTreeLoader *trklTreeLoader = (AliTreeLoader*) trklLoader->GetBaseLoader("tracklets-raw"); |
5f006bd7 | 410 | if (trklTreeLoader) |
cc26f39c | 411 | trklTree = trklTreeLoader->Tree(); |
5f006bd7 | 412 | else |
cc26f39c | 413 | trklTree = trklLoader->Tree(); |
67271412 | 414 | } |
415 | ||
416 | if (fTrackletTree != trklTree) | |
417 | ConnectTracklets(trklTree); | |
d60fe037 | 418 | |
419 | if (!fRawReader) { | |
420 | AliError("No raw reader available"); | |
421 | return -1; | |
422 | } | |
423 | ||
9cb9c409 | 424 | while (fCurrSlot < 0 || fCurrSlot >= fgkNstacks) { |
d60fe037 | 425 | if (!NextDDL()) { |
426 | fCurrSlot = -1; | |
427 | return -1; | |
428 | } | |
9cb9c409 | 429 | while ((fCurrSlot < fgkNstacks) && |
9e07aeda | 430 | (((fCurrStackMask & (1 << fCurrSlot)) == 0) || |
431 | ((fCurrLinkMask[fCurrSlot] & (1 << fCurrLink))) == 0)) { | |
432 | fCurrLink++; | |
9cb9c409 | 433 | if (fCurrLink >= fgkNlinks) { |
9e07aeda | 434 | fCurrLink = 0; |
435 | fCurrSlot++; | |
436 | } | |
437 | } | |
d60fe037 | 438 | } |
439 | ||
440 | AliDebug(2, Form("Stack %i, Link %i, mask: 0x%02x", fCurrSlot, fCurrLink, fCurrLinkMask[fCurrSlot])); | |
9cb9c409 | 441 | fCurrHC = (fCurrEquipmentId - kDDLOffset) * fgkNlinks * fgkNstacks + |
442 | fCurrSlot * fgkNlinks + fCurrLink; | |
d60fe037 | 443 | |
2519cca4 | 444 | if (fCurrLinkMonitorFlags[fCurrSlot*fgkNlinks + fCurrLink] != 0) { |
d60fe037 | 445 | LinkError(kLinkMonitor); |
2519cca4 | 446 | if (fgErrorBehav[kLinkMonitor] == kTolerate) |
447 | ReadLinkData(); | |
448 | } | |
7534e6db | 449 | else |
450 | // read the data from one HC | |
451 | ReadLinkData(); | |
5f006bd7 | 452 | |
d60fe037 | 453 | // read all data endmarkers |
92223bf6 | 454 | SeekNextLink(); |
d60fe037 | 455 | |
456 | if (fCurrLink % 2 == 0) { | |
457 | // if we just read the A-side HC then also check the B-side | |
458 | fCurrLink++; | |
1e7466b5 | 459 | fCurrHC++; |
d60fe037 | 460 | if (fCurrLinkMask[fCurrSlot] & (1 << fCurrLink)) { |
2519cca4 | 461 | if (fCurrLinkMonitorFlags[fCurrSlot*fgkNlinks + fCurrLink] != 0) { |
462 | LinkError(kLinkMonitor); | |
463 | if (fgErrorBehav[kLinkMonitor] == kTolerate) | |
464 | ReadLinkData(); | |
465 | } | |
466 | else { | |
467 | ReadLinkData(); | |
468 | } | |
92223bf6 | 469 | SeekNextLink(); |
d60fe037 | 470 | } |
471 | } | |
472 | ||
d60fe037 | 473 | do { |
52a2b6c0 | 474 | if ((fCurrStackMask & (1 << fCurrSlot)) == 0) { |
d60fe037 | 475 | fCurrLink = 0; |
476 | fCurrSlot++; | |
477 | } | |
52a2b6c0 | 478 | else { |
479 | fCurrLink++; | |
480 | if (fCurrLink >= fgkNlinks) { | |
481 | SeekNextStack(); | |
482 | fCurrLink = 0; | |
483 | fCurrSlot++; | |
484 | } | |
485 | } | |
5f006bd7 | 486 | } while ((fCurrSlot < fgkNstacks) && |
487 | (((fCurrStackMask & (1 << fCurrSlot)) == 0) || | |
67271412 | 488 | ((fCurrLinkMask[fCurrSlot] & (1 << fCurrLink))) == 0)); |
d60fe037 | 489 | |
25671e69 | 490 | // return chamber information from HC if it is valid |
491 | // otherwise return information from link position | |
9cb9c409 | 492 | if (fCurrSm < 0 || fCurrSm >= fgkNsectors || fCurrStack < 0 || fCurrStack >= fgkNstacks || fCurrLayer < 0 || fCurrLayer >= fgkNlinks/2) |
493 | return ((fCurrEquipmentId-kDDLOffset) + fCurrSlot * fgkNlinks/2 + fCurrLink/2); | |
25671e69 | 494 | else |
9cb9c409 | 495 | return (fCurrSm * fgkNstacks*fgkNlinks/2 + fCurrStack * fgkNlinks/2 + fCurrLayer); |
d60fe037 | 496 | } |
497 | ||
498 | ||
9cb9c409 | 499 | Int_t AliTRDrawStream::ReadGTUHeaders(UInt_t *buffer) |
500 | { | |
501 | // check the data source and read the headers | |
502 | ||
503 | if (fCurrEquipmentId >= kDDLOffset && fCurrEquipmentId <= kDDLMax) { | |
504 | // this is ROC data | |
505 | ||
506 | // setting the pointer to data and current reading position | |
507 | fPayloadCurr = fPayloadStart = buffer; | |
508 | fPayloadSize = fRawReader->GetDataSize() / sizeof(UInt_t); | |
509 | fStats.fStatsSector[fCurrEquipmentId - kDDLOffset].fBytes = fRawReader->GetDataSize(); | |
510 | AliDebug(2, Form("Read buffer of size: %i", fRawReader->GetDataSize())); | |
511 | ||
512 | AliDebug(1, DumpRaw("raw data", fPayloadCurr, TMath::Min(fPayloadSize, 1000))); | |
513 | ||
514 | // read SM header | |
515 | if (ReadSmHeader() < 0) { | |
516 | AliError(Form("Reading SM header failed, skipping this DDL %i", fCurrEquipmentId)); | |
517 | return -1; | |
518 | } | |
519 | ||
520 | // read tracking headers (if available) | |
521 | if (fCurrTrkHeaderAvail) { | |
522 | for (Int_t iStack = 0; iStack < fgkNstacks; iStack++) { | |
523 | if ((fCurrStackMask & (1 << iStack)) != 0) | |
524 | ReadTrackingHeader(iStack); | |
525 | } | |
526 | } | |
527 | ||
528 | // read trigger header(s) (if available) | |
529 | if (fCurrTrgHeaderAvail) | |
530 | ReadTriggerHeaders(); | |
531 | ||
532 | // read stack header | |
533 | for (Int_t iStack = 0; iStack < fgkNstacks; iStack++) { | |
534 | if ((fCurrStackMask & (1 << iStack)) != 0) | |
535 | ReadStackHeader(iStack); | |
536 | } | |
537 | ||
538 | return 0; | |
539 | } | |
540 | else | |
541 | return -1; | |
542 | } | |
543 | ||
d60fe037 | 544 | Int_t AliTRDrawStream::ReadSmHeader() |
545 | { | |
5f006bd7 | 546 | // read the SMU index header at the current reading position |
d60fe037 | 547 | // and store the information in the corresponding variables |
548 | ||
549 | if (fPayloadCurr - fPayloadStart >= fPayloadSize - 1) { | |
92223bf6 | 550 | EquipmentError(kUnknown, "SM Header incomplete"); |
d60fe037 | 551 | return -1; |
552 | } | |
553 | ||
2519cca4 | 554 | fCurrTrgFlags[fCurrEquipmentId-kDDLOffset] = 0; |
555 | ||
9cb9c409 | 556 | fCurrSmHeaderSize = ((*fPayloadCurr) >> 16) & 0xffff; |
557 | fCurrSmHeaderVersion = ((*fPayloadCurr) >> 12) & 0xf; | |
d60fe037 | 558 | fCurrTrackEnable = ((*fPayloadCurr) >> 6) & 0x1; |
559 | fCurrTrackletEnable = ((*fPayloadCurr) >> 5) & 0x1; | |
560 | fCurrStackMask = ((*fPayloadCurr) ) & 0x1f; | |
9cb9c409 | 561 | fCurrHwRev = (fPayloadCurr[1] >> 12) & 0xffff; |
52a2b6c0 | 562 | fCurrStackEndmarkerAvail = 0; |
9cb9c409 | 563 | |
564 | switch (fCurrSmHeaderVersion) { | |
565 | case 0xb: | |
566 | fCurrTrailerReadout = 0; | |
567 | fCurrTrgHeaderAvail = 0; | |
568 | fCurrEvType = 0; | |
569 | fCurrTrkHeaderAvail = 0; | |
570 | ||
571 | DecodeGTUtracks(); | |
572 | break; | |
573 | ||
574 | case 0xc: | |
575 | fCurrTrailerReadout = ((*fPayloadCurr) >> 10) & 0x1; | |
576 | fCurrTrgHeaderAvail = 1; | |
577 | fCurrTrgHeaderReadout = ((*fPayloadCurr) >> 9) & 0x1; | |
578 | fCurrEvType = ((*fPayloadCurr) >> 7) & 0x3; | |
579 | fCurrTrkHeaderAvail = fCurrTrackEnable; | |
580 | fCurrTriggerEnable = (fPayloadCurr[2] >> 8) & 0xfff; | |
581 | fCurrTriggerFired = (fPayloadCurr[2] >> 20) & 0xfff; | |
2519cca4 | 582 | fCurrTrgFlags[fCurrEquipmentId-kDDLOffset] = fCurrTriggerFired; |
9cb9c409 | 583 | break; |
d60fe037 | 584 | |
52a2b6c0 | 585 | case 0xd: |
586 | fCurrTrailerReadout = ((*fPayloadCurr) >> 10) & 0x1; | |
587 | fCurrTrgHeaderAvail = 1; | |
588 | fCurrTrgHeaderReadout = ((*fPayloadCurr) >> 9) & 0x1; | |
589 | fCurrEvType = ((*fPayloadCurr) >> 7) & 0x3; | |
590 | fCurrTrkHeaderAvail = fCurrTrackEnable; | |
591 | fCurrTriggerEnable = (fPayloadCurr[2] >> 8) & 0xfff; | |
592 | fCurrTriggerFired = (fPayloadCurr[2] >> 20) & 0xfff; | |
593 | fCurrTrgFlags[fCurrEquipmentId-kDDLOffset] = fCurrTriggerFired; | |
594 | fCurrStackEndmarkerAvail = 1; | |
595 | break; | |
596 | ||
9cb9c409 | 597 | default: |
598 | AliError(Form("unknown SM header version: 0x%x", fCurrSmHeaderVersion)); | |
599 | } | |
600 | ||
601 | AliDebug(5, Form("SM header: size: %i, version: %i, track enable: %i, tracklet enable: %i, stack mask: %2x, trailer: %i, trgheader: %i, trkheader: %i", | |
602 | fCurrSmHeaderSize, | |
603 | fCurrSmHeaderVersion, | |
604 | fCurrTrackEnable, | |
d60fe037 | 605 | fCurrTrackletEnable, |
9cb9c409 | 606 | fCurrStackMask, |
607 | fCurrTrailerReadout, | |
608 | fCurrTrgHeaderAvail, | |
609 | fCurrTrkHeaderAvail )); | |
610 | ||
611 | // jump to the first word after the SM header | |
612 | fPayloadCurr += fCurrSmHeaderSize + 1; | |
613 | ||
614 | return fCurrSmHeaderSize + 1; | |
615 | } | |
5fdfc9e4 | 616 | |
9cb9c409 | 617 | Int_t AliTRDrawStream::DecodeGTUtracks() |
618 | { | |
5fdfc9e4 | 619 | // decode GTU track words |
9cb9c409 | 620 | // this depends on the hardware revision of the SMU |
621 | ||
cb8b99ee | 622 | Int_t sector = fCurrEquipmentId-kDDLOffset; |
623 | ||
624 | if ((sector < 0) || (sector > 17)) { | |
625 | AliError(Form("Invalid sector %i for GTU tracks", sector)); | |
626 | return -1; | |
627 | } | |
628 | ||
629 | AliDebug(1, DumpRaw(Form("GTU tracks in sector %2i (hw rev %i)", sector, fCurrHwRev), | |
9cb9c409 | 630 | fPayloadCurr + 4, 10, 0xffe0ffff)); |
631 | ||
2519cca4 | 632 | fCurrTrgFlags[sector] = 0; |
633 | ||
9cb9c409 | 634 | if (fCurrHwRev < 1772) { |
cb8b99ee | 635 | UInt_t fastWord; // fast trigger word |
636 | ULong64_t trackWord = 0; // extended track word | |
9cb9c409 | 637 | Int_t stack = 0; |
638 | Int_t idx = 0; | |
639 | for (UInt_t iWord = 4; iWord < fCurrSmHeaderSize; iWord++) { | |
cb8b99ee | 640 | if (fPayloadCurr[iWord] == 0x10000000) { // stack boundary marker |
9cb9c409 | 641 | stack++; |
642 | idx = 0; | |
643 | } | |
644 | else { | |
645 | if ((idx == 0) && | |
646 | ((fPayloadCurr[iWord] & 0xfffff0f0) == 0x13370000)) { | |
cb8b99ee | 647 | fastWord = fPayloadCurr[iWord]; |
2519cca4 | 648 | fCurrTrgFlags[sector] |= 1 << (stack+11); // assume tracking done if fast word sent |
cb8b99ee | 649 | AliDebug(1, Form("stack %i: fast trigger word: 0x%08x", stack, fastWord)); |
9cb9c409 | 650 | continue; |
651 | } | |
652 | else if ((idx & 0x1) == 0x1) { | |
cb8b99ee | 653 | trackWord |= ((ULong64_t) fPayloadCurr[iWord]) << 32; |
654 | AliDebug(1,Form("track debug word: 0x%016llx", trackWord)); | |
655 | if (fTracks) { | |
656 | AliESDTrdTrack *trk = new ((*fTracks)[fTracks->GetEntriesFast()]) | |
657 | AliESDTrdTrack(); | |
658 | ||
659 | trk->SetSector(sector); | |
660 | trk->SetStack((trackWord >> 60) & 0x7); | |
661 | trk->SetA(0); | |
662 | trk->SetB(0); | |
663 | trk->SetPID(0); | |
664 | trk->SetLayerMask((trackWord >> 16) & 0x3f); | |
665 | trk->SetTrackletIndex((trackWord >> 22) & 0x3f, 0); | |
666 | trk->SetTrackletIndex((trackWord >> 28) & 0x3f, 1); | |
667 | trk->SetTrackletIndex((trackWord >> 34) & 0x3f, 2); | |
668 | trk->SetTrackletIndex((trackWord >> 40) & 0x3f, 3); | |
669 | trk->SetTrackletIndex((trackWord >> 46) & 0x3f, 4); | |
670 | trk->SetTrackletIndex((trackWord >> 52) & 0x3f, 5); | |
671 | ||
672 | trk->SetFlags(0); | |
673 | trk->SetReserved(0); | |
52a2b6c0 | 674 | trk->SetLabel(-3); |
cb8b99ee | 675 | |
676 | Float_t pt = (((Int_t) (trackWord & 0xffff) ^ 0x8000) - 0x8000)/128.; | |
677 | if (TMath::Abs(pt) > 0.1) { | |
678 | trk->SetA((Int_t) (0.15*51625./100./pt / 160e-4 * 2)); | |
679 | } | |
680 | } | |
681 | } | |
9cb9c409 | 682 | else { |
cb8b99ee | 683 | trackWord = fPayloadCurr[iWord]; |
9cb9c409 | 684 | } |
685 | idx++; | |
686 | } | |
5fdfc9e4 | 687 | } |
9cb9c409 | 688 | } |
689 | else if (fCurrHwRev < 1804) { | |
cb8b99ee | 690 | UInt_t fastWord; // fast trigger word |
691 | ULong64_t trackWord = 0; // extended track word | |
9cb9c409 | 692 | Int_t stack = 0; |
693 | Int_t idx = 0; | |
694 | for (UInt_t iWord = 4; iWord < fCurrSmHeaderSize; iWord++) { | |
cb8b99ee | 695 | if (fPayloadCurr[iWord] == 0xffe0ffff) { // stack boundary marker |
9cb9c409 | 696 | stack++; |
697 | idx = 0; | |
698 | } | |
699 | else { | |
700 | if ((idx == 0) && | |
701 | ((fPayloadCurr[iWord] & 0xfffff0f0) == 0x13370000)) { | |
cb8b99ee | 702 | fastWord = fPayloadCurr[iWord]; |
2519cca4 | 703 | fCurrTrgFlags[sector] |= 1 << (stack+11); // assume tracking done if fast word sent |
cb8b99ee | 704 | AliDebug(1, Form("stack %i: fast trigger word: 0x%08x", stack, fastWord)); |
9cb9c409 | 705 | continue; |
706 | } | |
707 | else if ((idx & 0x1) == 0x1) { | |
cb8b99ee | 708 | trackWord |= ((ULong64_t) fPayloadCurr[iWord]) << 32; |
709 | AliDebug(1, Form("track debug word: 0x%016llx", trackWord)); | |
710 | if (fTracks) { | |
711 | AliESDTrdTrack *trk = new ((*fTracks)[fTracks->GetEntriesFast()]) | |
712 | AliESDTrdTrack(); | |
713 | ||
714 | trk->SetSector(fCurrEquipmentId-kDDLOffset); | |
715 | trk->SetStack((trackWord >> 60) & 0x7); | |
716 | trk->SetA(0); | |
717 | trk->SetB(0); | |
718 | trk->SetPID(0); | |
719 | trk->SetLayerMask((trackWord >> 16) & 0x3f); | |
720 | trk->SetTrackletIndex((trackWord >> 22) & 0x3f, 0); | |
721 | trk->SetTrackletIndex((trackWord >> 28) & 0x3f, 1); | |
722 | trk->SetTrackletIndex((trackWord >> 34) & 0x3f, 2); | |
723 | trk->SetTrackletIndex((trackWord >> 40) & 0x3f, 3); | |
724 | trk->SetTrackletIndex((trackWord >> 46) & 0x3f, 4); | |
725 | trk->SetTrackletIndex((trackWord >> 52) & 0x3f, 5); | |
726 | ||
727 | trk->SetFlags(0); | |
728 | trk->SetReserved(0); | |
52a2b6c0 | 729 | trk->SetLabel(-3); |
cb8b99ee | 730 | |
731 | Float_t pt = (((Int_t) (trackWord & 0xffff) ^ 0x8000) - 0x8000)/128.; | |
732 | if (TMath::Abs(pt) > 0.1) { | |
c4daee41 | 733 | trk->SetA((Int_t) (-0.15*51625./100./pt / 160e-4 * 2)); |
cb8b99ee | 734 | } |
735 | } | |
9cb9c409 | 736 | } |
737 | else { | |
cb8b99ee | 738 | trackWord = fPayloadCurr[iWord]; |
9cb9c409 | 739 | } |
740 | idx++; | |
741 | } | |
742 | } | |
743 | } | |
744 | else if (fCurrHwRev < 1819) { | |
cb8b99ee | 745 | UInt_t fastWord; // fast trigger word |
746 | ULong64_t trackWord = 0; // extended track word | |
9cb9c409 | 747 | Int_t stack = 0; |
748 | Int_t idx = 0; | |
749 | for (UInt_t iWord = 4; iWord < fCurrSmHeaderSize; iWord++) { | |
cb8b99ee | 750 | if (fPayloadCurr[iWord] == 0xffe0ffff) { // stack boundary marker |
9cb9c409 | 751 | stack++; |
752 | idx = 0; | |
753 | } | |
754 | else { | |
755 | if ((idx == 0) && | |
756 | ((fPayloadCurr[iWord] & 0xfffff0f0) == 0x13370000)) { | |
cb8b99ee | 757 | fastWord = fPayloadCurr[iWord]; |
c4daee41 | 758 | if (fastWord & (1 << 13)) |
759 | fCurrTrgFlags[sector] |= 1 << (stack+11); | |
cb8b99ee | 760 | AliDebug(1, Form("stack %i: fast trigger word: 0x%08x", stack, fastWord)); |
9cb9c409 | 761 | continue; |
762 | } | |
763 | else if ((idx & 0x1) == 0x1) { | |
cb8b99ee | 764 | trackWord |= ((ULong64_t) fPayloadCurr[iWord]) << 32; |
765 | AliDebug(1, Form("track debug word: 0x%016llx", trackWord)); | |
766 | ||
767 | if (fTracks) { | |
768 | AliESDTrdTrack *trk = new ((*fTracks)[fTracks->GetEntriesFast()]) | |
769 | AliESDTrdTrack(); | |
770 | ||
771 | trk->SetSector(fCurrEquipmentId-kDDLOffset); | |
772 | trk->SetStack((trackWord >> 60) & 0x7); | |
773 | trk->SetA(0); | |
774 | trk->SetB(0); | |
775 | // trk->SetPt(((trackWord & 0xffff) ^ 0x8000) - 0x8000); | |
776 | trk->SetPID(0); | |
777 | trk->SetLayerMask((trackWord >> 16) & 0x3f); | |
778 | trk->SetTrackletIndex((trackWord >> 22) & 0x3f, 0); | |
779 | trk->SetTrackletIndex((trackWord >> 28) & 0x3f, 1); | |
780 | trk->SetTrackletIndex((trackWord >> 34) & 0x3f, 2); | |
781 | trk->SetTrackletIndex((trackWord >> 40) & 0x3f, 3); | |
782 | trk->SetTrackletIndex((trackWord >> 46) & 0x3f, 4); | |
783 | trk->SetTrackletIndex((trackWord >> 52) & 0x3f, 5); | |
784 | ||
785 | trk->SetFlags(0); | |
786 | trk->SetReserved(0); | |
52a2b6c0 | 787 | trk->SetLabel(-3); |
cb8b99ee | 788 | |
789 | Float_t pt = (((Int_t) (trackWord & 0xffff) ^ 0x8000) - 0x8000)/128.; | |
790 | if (TMath::Abs(pt) > 0.1) { | |
791 | trk->SetA((Int_t) (0.15*51625./100./trk->Pt() / 160e-4 * 2)); | |
792 | } | |
793 | } | |
9cb9c409 | 794 | } |
795 | else { | |
cb8b99ee | 796 | trackWord = fPayloadCurr[iWord]; |
9cb9c409 | 797 | } |
798 | idx++; | |
5fdfc9e4 | 799 | } |
9cb9c409 | 800 | } |
801 | } | |
802 | else if (fCurrHwRev < 1860) { | |
cb8b99ee | 803 | UInt_t fastWord; // fast trigger word |
804 | ULong64_t trackWord = 0; // extended track word | |
805 | Int_t stack = 0; | |
806 | Int_t idx = 0; | |
807 | Bool_t upperWord = kFALSE; | |
808 | Int_t word = 0; | |
809 | for (UInt_t iWord = 4; iWord < fCurrSmHeaderSize; iWord++) { | |
810 | if (fPayloadCurr[iWord] == 0xffe0ffff) { // stack boundary marker | |
811 | stack++; | |
812 | idx = 0; | |
813 | upperWord = kFALSE; | |
814 | } | |
815 | else { | |
816 | // assemble the 32-bit words out of 16-bit blocks | |
817 | if (upperWord) { | |
818 | word |= (fPayloadCurr[iWord] & 0xffff0000); | |
819 | upperWord = kFALSE; | |
820 | } | |
821 | else { | |
822 | // lower word is read first | |
823 | word = (fPayloadCurr[iWord] & 0xffff0000) >> 16; | |
824 | upperWord = kTRUE; | |
825 | continue; | |
826 | } | |
827 | ||
828 | if ((word & 0xffff0008) == 0x13370008) { | |
829 | fastWord = word; | |
830 | AliDebug(1, Form("stack %i: fast track word: 0x%08x", stack, fastWord)); | |
2519cca4 | 831 | if (fastWord & (1 << 13)) |
832 | fCurrTrgFlags[sector] |= 1 << (stack+11); | |
cb8b99ee | 833 | continue; |
834 | } | |
835 | else if ((idx & 0x1) == 0x1) { | |
836 | trackWord |= ((ULong64_t) word) << 32; | |
837 | AliDebug(1, Form("track debug word: 0x%016llx", trackWord)); | |
838 | if (fTracks) { | |
839 | AliESDTrdTrack *trk = new ((*fTracks)[fTracks->GetEntriesFast()]) | |
840 | AliESDTrdTrack(); | |
841 | ||
842 | trk->SetSector(fCurrEquipmentId-kDDLOffset); | |
843 | trk->SetStack((trackWord >> 60) & 0x7); | |
844 | trk->SetA(0); | |
845 | trk->SetB(0); | |
846 | trk->SetPID(0); | |
847 | trk->SetLayerMask((trackWord >> 16) & 0x3f); | |
848 | trk->SetTrackletIndex((trackWord >> 22) & 0x3f, 0); | |
849 | trk->SetTrackletIndex((trackWord >> 28) & 0x3f, 1); | |
850 | trk->SetTrackletIndex((trackWord >> 34) & 0x3f, 2); | |
851 | trk->SetTrackletIndex((trackWord >> 40) & 0x3f, 3); | |
852 | trk->SetTrackletIndex((trackWord >> 46) & 0x3f, 4); | |
853 | trk->SetTrackletIndex((trackWord >> 52) & 0x3f, 5); | |
854 | ||
855 | trk->SetFlags(0); | |
856 | trk->SetReserved(0); | |
52a2b6c0 | 857 | trk->SetLabel(-3); |
cb8b99ee | 858 | |
859 | Float_t pt = (((Int_t) (trackWord & 0xffff) ^ 0x8000) - 0x8000)/128.; | |
860 | if (TMath::Abs(pt) > 0.1) { | |
861 | trk->SetA((Int_t) (0.15*51625./100./pt / 160e-4 * 2)); | |
862 | } | |
863 | } | |
864 | } | |
865 | else { | |
866 | trackWord = word; | |
867 | } | |
868 | idx++; | |
869 | } | |
870 | } | |
871 | ||
9cb9c409 | 872 | } |
873 | else { | |
cb8b99ee | 874 | ULong64_t trackWord = 0; // this is the debug word |
9cb9c409 | 875 | Int_t stack = 0; |
876 | Int_t idx = 0; | |
877 | Bool_t upperWord = kFALSE; | |
878 | Int_t word = 0; | |
879 | for (UInt_t iWord = 4; iWord < fCurrSmHeaderSize; iWord++) { | |
880 | if (fPayloadCurr[iWord] == 0xffe0ffff) { | |
881 | stack++; | |
882 | idx = 0; | |
883 | upperWord = kFALSE; | |
5fdfc9e4 | 884 | } |
885 | else { | |
9cb9c409 | 886 | // assemble the 32-bit words out of 16-bit blocks |
887 | if (upperWord) { | |
888 | word |= (fPayloadCurr[iWord] & 0xffff0000); | |
889 | upperWord = kFALSE; | |
890 | } | |
891 | else { | |
892 | // lower word is read first | |
893 | word = (fPayloadCurr[iWord] & 0xffff0000) >> 16; | |
894 | upperWord = kTRUE; | |
895 | continue; | |
896 | } | |
897 | ||
898 | if ((word & 0xffff0008) == 0x13370008) { | |
899 | AliDebug(1, Form("stack %i: fast track word: 0x%08x", stack, word)); | |
900 | continue; | |
901 | } | |
902 | else if ((word & 0xffff0010) == 0x13370010) { | |
903 | AliDebug(1, Form("stack %i: tracking done word: 0x%08x", stack, word)); | |
2519cca4 | 904 | fCurrTrgFlags[sector] |= 1 << (stack+11); |
9cb9c409 | 905 | continue; |
906 | } | |
907 | else if ((idx & 0x1) == 0x1) { | |
cb8b99ee | 908 | trackWord |= ((ULong64_t) word) << 32; |
909 | AliDebug(1, Form("track debug word: 0x%16llx", trackWord)); | |
910 | if (fTracks) { | |
911 | AliESDTrdTrack *trk = new ((*fTracks)[fTracks->GetEntriesFast()]) | |
912 | AliESDTrdTrack(); | |
913 | trk->SetSector(fCurrEquipmentId-kDDLOffset); | |
914 | trk->SetStack((trackWord >> 60) & 0x7); | |
915 | trk->SetA(0); | |
916 | trk->SetB(0); | |
917 | trk->SetPID(0); | |
918 | trk->SetLayerMask((trackWord >> 16) & 0x3f); | |
919 | trk->SetTrackletIndex((trackWord >> 22) & 0x3f, 0); | |
920 | trk->SetTrackletIndex((trackWord >> 28) & 0x3f, 1); | |
921 | trk->SetTrackletIndex((trackWord >> 34) & 0x3f, 2); | |
922 | trk->SetTrackletIndex((trackWord >> 40) & 0x3f, 3); | |
923 | trk->SetTrackletIndex((trackWord >> 46) & 0x3f, 4); | |
924 | trk->SetTrackletIndex((trackWord >> 52) & 0x3f, 5); | |
925 | ||
926 | trk->SetFlags(0); | |
927 | trk->SetReserved(0); | |
52a2b6c0 | 928 | trk->SetLabel(-3); |
cb8b99ee | 929 | |
930 | Float_t pt = (((Int_t) (trackWord & 0xffff) ^ 0x8000) - 0x8000)/128.; | |
931 | if (TMath::Abs(pt) > 0.1) { | |
932 | trk->SetA(-(Int_t) (0.15*51625./100./pt / 160e-4 * 2)); | |
933 | } | |
934 | } | |
9cb9c409 | 935 | } |
936 | else { | |
cb8b99ee | 937 | trackWord = word; |
9cb9c409 | 938 | } |
939 | idx++; | |
5fdfc9e4 | 940 | } |
5fdfc9e4 | 941 | } |
942 | } | |
9cb9c409 | 943 | return 0; |
944 | } | |
945 | ||
946 | Int_t AliTRDrawStream::ReadTrackingHeader(Int_t stack) | |
947 | { | |
948 | // read the tracking information and store it for the given stack | |
949 | ||
950 | // index word | |
951 | ||
952 | fCurrTrkHeaderIndexWord[stack] = *fPayloadCurr; | |
953 | fCurrTrkHeaderSize[stack] = ((*fPayloadCurr) >> 16) & 0x3ff; | |
9cb9c409 | 954 | |
cb8b99ee | 955 | AliDebug(1, Form("tracking header index word: 0x%08x, size: %i (hw rev: %i)", |
956 | fCurrTrkHeaderIndexWord[stack], fCurrTrkHeaderSize[stack], fCurrHwRev)); | |
957 | Int_t trackingTime = *fPayloadCurr & 0x3ff; | |
958 | ||
2519cca4 | 959 | fCurrTrgFlags[fCurrEquipmentId-kDDLOffset] |= ((fCurrTrkHeaderIndexWord[stack] >> 10) & 0x1) << (22 + stack); |
cb8b99ee | 960 | fPayloadCurr++; |
9cb9c409 | 961 | |
962 | // data words | |
cb8b99ee | 963 | ULong64_t trackWord = 0; |
9cb9c409 | 964 | Int_t idx = 0; |
cb8b99ee | 965 | Int_t trackIndex = fTracks ? fTracks->GetEntriesFast() : -1; |
966 | ||
9cb9c409 | 967 | for (UInt_t iWord = 0; iWord < fCurrTrkHeaderSize[stack]; iWord++) { |
5f006bd7 | 968 | |
cb8b99ee | 969 | if (!(idx & 0x1)) { |
970 | // first part of 64-bit word | |
971 | trackWord = fPayloadCurr[iWord]; | |
9cb9c409 | 972 | } |
973 | else { | |
cb8b99ee | 974 | trackWord |= ((ULong64_t) fPayloadCurr[iWord]) << 32; |
975 | ||
976 | if (trackWord & (1ul << 63)) { | |
977 | if ((trackWord & (0x3ful << 56)) != 0) { | |
978 | // track word | |
979 | AliDebug(2, Form("track word: 0x%016llx", trackWord)); | |
980 | ||
981 | if (fTracks) { | |
982 | AliESDTrdTrack *trk = new ((*fTracks)[fTracks->GetEntriesFast()]) | |
983 | AliESDTrdTrack(); | |
984 | ||
985 | trk->SetSector(fCurrEquipmentId-kDDLOffset); | |
986 | trk->SetLayerMask((trackWord >> 56) & 0x3f); | |
987 | trk->SetA( (((trackWord >> 38) & 0x3ffff) ^ 0x20000) - 0x20000); | |
988 | trk->SetB( (((trackWord >> 20) & 0x3ffff) ^ 0x20000) - 0x20000); | |
989 | trk->SetC( (((trackWord >> 8) & 0xffff) ^ 0x8000) - 0x8000); | |
990 | trk->SetPID((trackWord >> 0) & 0xff); | |
991 | trk->SetStack(stack); | |
52a2b6c0 | 992 | trk->SetLabel(-3); |
cb8b99ee | 993 | |
994 | // now compare the track word with the one generated from the ESD information | |
995 | if (trackWord != trk->GetTrackWord(0)) { | |
996 | AliError(Form("track word 0x%016llx does not match the read one 0x%016llx", | |
997 | trk->GetTrackWord(0), trackWord)); | |
998 | } | |
999 | } | |
1000 | } | |
1001 | else { | |
1002 | // done marker (so far only used to set trigger flag) | |
2519cca4 | 1003 | fCurrTrgFlags[fCurrEquipmentId-kDDLOffset] |= 1 << (27 + stack); |
bc425b5d | 1004 | fCurrTrkFlags[(fCurrEquipmentId-kDDLOffset)*fgkNstacks + stack] = trackWord; |
cb8b99ee | 1005 | |
2519cca4 | 1006 | AliDebug(2, Form("tracking done marker: 0x%016llx, trigger flags: 0x%08x", |
1007 | trackWord, fCurrTrgFlags[fCurrEquipmentId-kDDLOffset])); | |
cb8b99ee | 1008 | AliDebug(2, Form("seg / stack / first / last / done / index : %i %i %lli %lli %lli %i", |
1009 | fCurrEquipmentId - kDDLOffset, stack, | |
1010 | (trackWord >> 20) & 0x3ff, | |
1011 | (trackWord >> 10) & 0x3ff, | |
1012 | (trackWord >> 0) & 0x3ff, | |
1013 | trackingTime)); | |
1014 | } | |
1015 | } | |
1016 | else { | |
1017 | // extended track word | |
1018 | AliDebug(2, Form("extended track word: 0x%016llx", trackWord)); | |
1019 | ||
1020 | if (fTracks) { | |
1021 | AliESDTrdTrack *trk = (AliESDTrdTrack*) (*fTracks)[trackIndex]; | |
1022 | ||
1023 | trk->SetFlags((trackWord >> 52) & 0x7ff); | |
1024 | trk->SetReserved((trackWord >> 49) & 0x7); | |
1025 | trk->SetY((trackWord >> 36) & 0x1fff); | |
1026 | trk->SetTrackletIndex((trackWord >> 0) & 0x3f, 0); | |
1027 | trk->SetTrackletIndex((trackWord >> 6) & 0x3f, 1); | |
1028 | trk->SetTrackletIndex((trackWord >> 12) & 0x3f, 2); | |
1029 | trk->SetTrackletIndex((trackWord >> 18) & 0x3f, 3); | |
1030 | trk->SetTrackletIndex((trackWord >> 24) & 0x3f, 4); | |
1031 | trk->SetTrackletIndex((trackWord >> 30) & 0x3f, 5); | |
1032 | ||
1033 | if (trackWord != trk->GetExtendedTrackWord(0)) { | |
1034 | AliError(Form("extended track word 0x%016llx does not match the read one 0x%016llx", | |
1035 | trk->GetExtendedTrackWord(0), trackWord)); | |
1036 | } | |
1037 | ||
1038 | trackIndex++; | |
1039 | } | |
1040 | } | |
9cb9c409 | 1041 | } |
1042 | idx++; | |
1043 | } | |
1044 | ||
1045 | fPayloadCurr += fCurrTrkHeaderSize[stack]; | |
1046 | ||
1047 | return fCurrTrkHeaderSize[stack]; | |
1048 | } | |
5fdfc9e4 | 1049 | |
9cb9c409 | 1050 | Int_t AliTRDrawStream::ReadTriggerHeaders() |
1051 | { | |
1052 | // read all trigger headers present | |
1053 | ||
1054 | AliDebug(1, Form("trigger mask: 0x%03x, fired: 0x%03x\n", | |
1055 | fCurrTriggerEnable, fCurrTriggerFired)); | |
1056 | // loop over potential trigger blocks | |
1057 | for (Int_t iTrigger = 0; iTrigger < fgkNtriggers; iTrigger++) { | |
1058 | // check for trigger enable | |
1059 | if (fCurrTriggerEnable & (1 << iTrigger)) { | |
1060 | // check for readout mode and trigger fired | |
1061 | if ((fCurrTrgHeaderReadout == 0) || (fCurrTriggerFired & (1 << iTrigger))) { | |
1062 | // index word | |
1063 | AliDebug(1, Form("trigger index word %i: 0x%08x\n", iTrigger, *fPayloadCurr)); | |
1064 | fCurrTrgHeaderIndexWord[iTrigger] = *fPayloadCurr; | |
a11bb3f3 | 1065 | fCurrTrgHeaderSize[iTrigger] = ((*fPayloadCurr) >> 16) & 0x3ff; |
2519cca4 | 1066 | if (iTrigger == 7) { |
1067 | // timeout trigger, use to extract tracking time | |
1068 | fCurrTrgFlags[fCurrEquipmentId-kDDLOffset] |= (*fPayloadCurr & 0x3ff) << 12; | |
1069 | } | |
1070 | ||
9cb9c409 | 1071 | fPayloadCurr++; |
1072 | // data words | |
1073 | fPayloadCurr += fCurrTrgHeaderSize[iTrigger]; | |
1074 | } | |
1075 | } | |
1076 | } | |
d60fe037 | 1077 | |
9cb9c409 | 1078 | return 0; |
d60fe037 | 1079 | } |
1080 | ||
9cb9c409 | 1081 | Int_t AliTRDrawStream::ReadStackHeader(Int_t stack) |
d60fe037 | 1082 | { |
9cb9c409 | 1083 | // read the stack header |
d60fe037 | 1084 | // and store the information in the corresponding variables |
1085 | ||
1086 | fCurrStackIndexWord[stack] = *fPayloadCurr; | |
1087 | fCurrStackHeaderSize[stack] = (((*fPayloadCurr) >> 16) & 0xffff) + 1; | |
1088 | fCurrStackHeaderVersion[stack] = ((*fPayloadCurr) >> 12) & 0xf; | |
1089 | fCurrLinkMask[stack] = (*fPayloadCurr) & 0xfff; | |
1090 | ||
9cb9c409 | 1091 | // dumping stack header |
1092 | AliDebug(1, DumpRaw(Form("stack %i header", stack), fPayloadCurr, fCurrStackHeaderSize[stack])); | |
1093 | ||
67271412 | 1094 | if (fPayloadCurr - fPayloadStart >= fPayloadSize - (Int_t) fCurrStackHeaderSize[stack]) { |
6419bebb | 1095 | EquipmentError(kStackHeaderInvalid, "Stack index header %i incomplete", stack); |
52a2b6c0 | 1096 | // dumping stack header |
1097 | AliError(DumpRaw(Form("stack %i header", stack), fPayloadCurr, fCurrStackHeaderSize[stack])); | |
1098 | ||
d60fe037 | 1099 | return -1; |
1100 | } | |
1101 | ||
1102 | switch (fCurrStackHeaderVersion[stack]) { | |
9cb9c409 | 1103 | case 0xa: |
d60fe037 | 1104 | if (fCurrStackHeaderSize[stack] < 8) { |
9cb9c409 | 1105 | LinkError(kStackHeaderInvalid, "Stack header smaller than expected!"); |
d60fe037 | 1106 | return -1; |
1107 | } | |
9cb9c409 | 1108 | |
d60fe037 | 1109 | fCurrCleanCheckout[stack] = fPayloadCurr[1] & 0x1; |
1110 | fCurrBoardId[stack] = (fPayloadCurr[1] >> 8) & 0xff; | |
9cb9c409 | 1111 | fCurrHwRevTMU[stack] = (fPayloadCurr[1] >> 16) & 0xffff; |
1112 | ||
d60fe037 | 1113 | for (Int_t iLayer = 0; iLayer < 6; iLayer++) { |
1114 | // A side | |
1115 | fCurrLinkMonitorFlags [stack*fgkNlinks + iLayer*2] = fPayloadCurr[iLayer+2] & 0xf; | |
1116 | fCurrLinkDataTypeFlags [stack*fgkNlinks + iLayer*2] = (fPayloadCurr[iLayer+2] >> 4) & 0x3; | |
1117 | fCurrLinkDebugFlags [stack*fgkNlinks + iLayer*2] = (fPayloadCurr[iLayer+2] >> 12) & 0xf; | |
1118 | // B side | |
1119 | fCurrLinkMonitorFlags [stack*fgkNlinks + iLayer*2 + 1] = (fPayloadCurr[iLayer+2] >> 16) & 0xf; | |
1120 | fCurrLinkDataTypeFlags [stack*fgkNlinks + iLayer*2 + 1] = (fPayloadCurr[iLayer+2] >> 20) & 0x3; | |
1121 | fCurrLinkDebugFlags [stack*fgkNlinks + iLayer*2 + 1] = (fPayloadCurr[iLayer+2] >> 28) & 0xf; | |
1122 | } | |
1123 | break; | |
9cb9c409 | 1124 | |
d60fe037 | 1125 | default: |
9cb9c409 | 1126 | LinkError(kStackHeaderInvalid, "Invalid Stack Header version %x", fCurrStackHeaderVersion[stack]); |
d60fe037 | 1127 | } |
9cb9c409 | 1128 | |
d60fe037 | 1129 | fPayloadCurr += fCurrStackHeaderSize[stack]; |
1130 | ||
1131 | return fCurrStackHeaderSize[stack]; | |
1132 | } | |
1133 | ||
9cb9c409 | 1134 | Int_t AliTRDrawStream::ReadGTUTrailer() |
1135 | { | |
1136 | // read the SM trailer containing CRCs from various stages | |
1137 | ||
1138 | UInt_t* trailer = fPayloadStart + fPayloadSize -1; | |
1139 | ||
1140 | // look for the trailer index word from the end | |
1141 | for (Int_t iWord = 0; iWord < fPayloadSize; iWord++) { | |
1142 | if ((fPayloadStart[fPayloadSize-1-iWord] & 0xffff) == 0x1f51) { | |
1143 | trailer = fPayloadStart + fPayloadSize - 1 - iWord; | |
1144 | break; | |
1145 | } | |
1146 | } | |
1147 | ||
1148 | if (((*trailer) & 0xffff) == 0x1f51) { | |
1149 | UInt_t trailerIndexWord = (*trailer); | |
1150 | Int_t trailerSize = (trailerIndexWord >> 16) & 0xffff; | |
1151 | AliDebug(2, DumpRaw("GTU trailer", trailer, trailerSize+1)); | |
1152 | // parse the trailer | |
52a2b6c0 | 1153 | if (trailerSize >= 4) { |
1154 | // match flags from GTU | |
1155 | fCurrMatchFlagsSRAM = (trailer[1] >> 0) & 0x1f; | |
1156 | fCurrMatchFlagsPostBP = (trailer[1] >> 5) & 0x1f; | |
1157 | // individual checksums | |
1158 | fCurrChecksumStack[0] = (trailer[1] >> 16) & 0xffff; | |
1159 | fCurrChecksumStack[1] = (trailer[2] >> 0) & 0xffff; | |
1160 | fCurrChecksumStack[2] = (trailer[2] >> 16) & 0xffff; | |
1161 | fCurrChecksumStack[3] = (trailer[3] >> 0) & 0xffff; | |
1162 | fCurrChecksumStack[4] = (trailer[3] >> 16) & 0xffff; | |
1163 | fCurrChecksumSIU = trailer[4]; | |
1164 | ||
1165 | if ((fCurrMatchFlagsSRAM & fCurrStackMask) != fCurrStackMask) | |
1166 | EquipmentError(kCRCmismatch, "CRC mismatch SRAM: 0x%02x", fCurrMatchFlagsSRAM); | |
1167 | if ((fCurrMatchFlagsPostBP & fCurrStackMask) != fCurrStackMask) | |
1168 | EquipmentError(kCRCmismatch, "CRC mismatch BP: 0x%02x", fCurrMatchFlagsPostBP); | |
1169 | ||
1170 | } | |
1171 | else { | |
1172 | LinkError(kUnknown, "Invalid GTU trailer"); | |
1173 | } | |
9cb9c409 | 1174 | } |
1175 | else | |
1176 | EquipmentError(kUnknown, "trailer index marker mismatch"); | |
1177 | ||
1178 | return 0; | |
1179 | } | |
1180 | ||
d60fe037 | 1181 | Int_t AliTRDrawStream::ReadLinkData() |
1182 | { | |
1183 | // read the data in one link (one HC) until the data endmarker is reached | |
cc26f39c | 1184 | // returns the number of words read! |
d60fe037 | 1185 | |
1186 | Int_t count = 0; | |
cc26f39c | 1187 | UInt_t* startPosLink = fPayloadCurr; |
1188 | ||
9cb9c409 | 1189 | AliDebug(1, DumpRaw(Form("link data from seg %2i slot %i link %2i", fCurrEquipmentId-kDDLOffset, fCurrSlot, fCurrLink), |
1190 | fPayloadCurr, TMath::Min((Int_t) (fPayloadSize - (fPayloadCurr-fPayloadStart)), 100), 0x00000000)); | |
d60fe037 | 1191 | |
5fdfc9e4 | 1192 | if (fMarkers) |
1193 | new ((*fMarkers)[fMarkers->GetEntriesFast()]) | |
0d0618dd | 1194 | AliTRDrawStreamError(-kHCactive, fCurrEquipmentId-kDDLOffset, fCurrSlot, fCurrLink); |
5fdfc9e4 | 1195 | |
92223bf6 | 1196 | if (fErrorFlags & kDiscardHC) |
1197 | return count; | |
1198 | ||
52a2b6c0 | 1199 | if (fCurrTrackletEnable) { |
1200 | count += ReadTracklets(); | |
1201 | if (fErrorFlags & kDiscardHC) | |
1202 | return count; | |
1203 | } | |
d60fe037 | 1204 | |
9cb9c409 | 1205 | AliDebug(1, DumpRaw("HC header", fPayloadCurr, 4, 0x00000000)); |
d60fe037 | 1206 | count += ReadHcHeader(); |
92223bf6 | 1207 | if (fErrorFlags & kDiscardHC) |
1208 | return count; | |
d60fe037 | 1209 | |
1210 | Int_t det = fCurrSm * 30 + fCurrStack * 6 + fCurrLayer; | |
d5a821ac | 1211 | |
d60fe037 | 1212 | if (det > -1 && det < 540) { |
d5a821ac | 1213 | |
d60fe037 | 1214 | // ----- check which kind of data ----- |
1215 | if (fCurrMajor & 0x40) { | |
1216 | if ((fCurrMajor & 0x7) == 0x7) { | |
d5a821ac | 1217 | AliDebug(1, "This is a config event"); |
1218 | UInt_t *startPos = fPayloadCurr; | |
1219 | while (fPayloadCurr - fPayloadStart < fPayloadSize && | |
1220 | *fPayloadCurr != fgkDataEndmarker) | |
1221 | fPayloadCurr++; | |
1222 | count += fPayloadCurr - startPos; | |
1223 | ||
1224 | // feeding TRAP config | |
43573bcf | 1225 | AliTRDtrapConfig *trapcfg = AliTRDcalibDB::Instance()->GetTrapConfig(); |
1226 | AliTRDmcmSim::ReadPackedConfig(trapcfg, fCurrHC, startPos, fPayloadCurr - startPos); | |
d5a821ac | 1227 | } |
1228 | else { | |
1229 | Int_t tpmode = fCurrMajor & 0x7; | |
1230 | AliDebug(1, Form("Checking testpattern (mode %i) data", tpmode)); | |
52a2b6c0 | 1231 | count += ReadTPData(tpmode); |
d60fe037 | 1232 | } |
d5a821ac | 1233 | } |
1234 | else { | |
2519cca4 | 1235 | // reading real data |
1236 | if (fDigitsManager) { | |
d5a821ac | 1237 | if ((fAdcArray = fDigitsManager->GetDigits(det))) { |
1238 | //fAdcArray->Expand(); | |
1239 | if (fAdcArray->GetNtime() != fCurrNtimebins) | |
1240 | fAdcArray->Allocate(16, 144, fCurrNtimebins); | |
1241 | } | |
1242 | else { | |
1243 | LinkError(kNoDigits); | |
1244 | } | |
2519cca4 | 1245 | |
d5a821ac | 1246 | if (!fDigitsParam) { |
1247 | fDigitsParam = fDigitsManager->GetDigitsParam(); | |
1248 | } | |
1249 | if (fDigitsParam) { | |
1250 | fDigitsParam->SetPretriggerPhase(det, fCurrPtrgPhase); | |
1251 | fDigitsParam->SetNTimeBins(det, fCurrNtimebins); | |
1252 | fDigitsParam->SetADCbaseline(det, 10); | |
1253 | } | |
2519cca4 | 1254 | |
d5a821ac | 1255 | if (fDigitsManager->UsesDictionaries()) { |
1256 | fDigitsManager->GetDictionary(det, 0)->Reset(); | |
1257 | fDigitsManager->GetDictionary(det, 1)->Reset(); | |
1258 | fDigitsManager->GetDictionary(det, 2)->Reset(); | |
1259 | } | |
2519cca4 | 1260 | |
d5a821ac | 1261 | if ((fSignalIndex = fDigitsManager->GetIndexes(det))) { |
1262 | fSignalIndex->SetSM(fCurrSm); | |
1263 | fSignalIndex->SetStack(fCurrStack); | |
1264 | fSignalIndex->SetLayer(fCurrLayer); | |
1265 | fSignalIndex->SetDetNumber(det); | |
1266 | if (!fSignalIndex->IsAllocated()) | |
1267 | fSignalIndex->Allocate(16, 144, fCurrNtimebins); | |
1268 | } | |
1269 | ||
1270 | if (fCurrMajor & 0x20) { | |
1271 | AliDebug(1, "This is a zs event"); | |
1272 | count += ReadZSData(); | |
1273 | } | |
1274 | else { | |
1275 | AliDebug(1, "This is a nozs event"); | |
1276 | count += ReadNonZSData(); | |
1277 | } | |
1278 | } | |
1279 | else { | |
1280 | // just read until data endmarkers | |
1281 | while (fPayloadCurr - fPayloadStart < fPayloadSize && | |
1282 | *fPayloadCurr != fgkDataEndmarker) | |
1283 | fPayloadCurr++; | |
2519cca4 | 1284 | } |
d60fe037 | 1285 | } |
d5a821ac | 1286 | } |
1287 | else { | |
92223bf6 | 1288 | LinkError(kInvalidDetector, "%i", det); |
d60fe037 | 1289 | while (fPayloadCurr - fPayloadStart < fPayloadSize && |
d5a821ac | 1290 | *fPayloadCurr != fgkDataEndmarker) |
1291 | fPayloadCurr++; | |
d60fe037 | 1292 | } |
637666cd | 1293 | |
1294 | if (fCurrSm > -1 && fCurrSm < 18) { | |
1295 | fStats.fStatsSector[fCurrSm].fStatsHC[fCurrHC%60].fBytes += (fPayloadCurr - startPosLink) * sizeof(UInt_t); | |
1296 | fStats.fStatsSector[fCurrSm].fStatsHC[fCurrHC%60].fBytesRead += count * sizeof(UInt_t); | |
1297 | fStats.fStatsSector[fCurrSm].fBytesRead += count * sizeof(UInt_t); | |
1298 | fStats.fBytesRead += count * sizeof(UInt_t); | |
1299 | } | |
cc26f39c | 1300 | |
d60fe037 | 1301 | return count; |
1302 | } | |
1303 | ||
1304 | Int_t AliTRDrawStream::ReadTracklets() | |
1305 | { | |
1306 | // read the tracklets from one HC | |
1307 | ||
1308 | fTrackletArray->Clear(); | |
1309 | ||
1310 | UInt_t *start = fPayloadCurr; | |
5f006bd7 | 1311 | while (*(fPayloadCurr) != fgkTrackletEndmarker && |
d60fe037 | 1312 | fPayloadCurr - fPayloadStart < fPayloadSize) { |
5fdfc9e4 | 1313 | new ((*fTrackletArray)[fTrackletArray->GetEntriesFast()]) AliTRDtrackletWord(*(fPayloadCurr), fCurrHC); |
d60fe037 | 1314 | |
1315 | fPayloadCurr++; | |
1316 | } | |
1317 | ||
1318 | if (fTrackletArray->GetEntriesFast() > 0) { | |
5f006bd7 | 1319 | AliDebug(1, Form("Found %i tracklets in %i %i %i (ev. %i)", fTrackletArray->GetEntriesFast(), |
9cb9c409 | 1320 | (fCurrEquipmentId-kDDLOffset), fCurrSlot, fCurrLink, fRawReader->GetEventIndex())); |
5fdfc9e4 | 1321 | if (fCurrSm > -1 && fCurrSm < 18) { |
1322 | fStats.fStatsSector[fCurrSm].fStatsHC[fCurrHC%60].fNTracklets += fTrackletArray->GetEntriesFast(); | |
1323 | fStats.fStatsSector[fCurrSm].fNTracklets += fTrackletArray->GetEntriesFast(); | |
1324 | } | |
d60fe037 | 1325 | if (fTrackletTree) |
1326 | fTrackletTree->Fill(); | |
5fdfc9e4 | 1327 | if (fTracklets) |
1328 | for (Int_t iTracklet = 0; iTracklet < fTrackletArray->GetEntriesFast(); iTracklet++) { | |
1329 | new ((*fTracklets)[fTracklets->GetEntriesFast()]) AliTRDtrackletWord(*((AliTRDtrackletWord*)(*fTrackletArray)[iTracklet])); | |
1330 | } | |
d60fe037 | 1331 | } |
1332 | ||
1333 | // loop over remaining tracklet endmarkers | |
5f006bd7 | 1334 | while ((*(fPayloadCurr) == fgkTrackletEndmarker && |
1335 | fPayloadCurr - fPayloadStart < fPayloadSize)) | |
d60fe037 | 1336 | fPayloadCurr++; |
5f006bd7 | 1337 | |
cc26f39c | 1338 | return fPayloadCurr - start; |
d60fe037 | 1339 | } |
1340 | ||
1341 | Int_t AliTRDrawStream::ReadHcHeader() | |
1342 | { | |
1343 | // read and parse the HC header of one HC | |
1344 | // and store the information in the corresponding variables | |
1345 | ||
9cb9c409 | 1346 | AliDebug(1, Form("HC header: 0x%08x", *fPayloadCurr)); |
d60fe037 | 1347 | UInt_t *start = fPayloadCurr; |
1348 | // check not to be at the data endmarker | |
1349 | if (*fPayloadCurr == fgkDataEndmarker) | |
1350 | return 0; | |
1351 | ||
1352 | fCurrSpecial = (*fPayloadCurr >> 31) & 0x1; | |
1353 | fCurrMajor = (*fPayloadCurr >> 24) & 0x7f; | |
1354 | fCurrMinor = (*fPayloadCurr >> 17) & 0x7f; | |
1355 | fCurrAddHcWords = (*fPayloadCurr >> 14) & 0x7; | |
1356 | fCurrSm = (*fPayloadCurr >> 9) & 0x1f; | |
1357 | fCurrLayer = (*fPayloadCurr >> 6) & 0x7; | |
1358 | fCurrStack = (*fPayloadCurr >> 3) & 0x7; | |
1359 | fCurrSide = (*fPayloadCurr >> 2) & 0x1; | |
1360 | fCurrCheck = (*fPayloadCurr) & 0x3; | |
1361 | ||
5f006bd7 | 1362 | if ((fCurrSm != (((Int_t) fCurrEquipmentId) - kDDLOffset)) || |
1363 | (fCurrStack != fCurrSlot) || | |
1364 | (fCurrLayer != fCurrLink / 2) || | |
9cb9c409 | 1365 | (fCurrSide != fCurrLink % 2)) { |
92223bf6 | 1366 | LinkError(kHCmismatch, |
5f006bd7 | 1367 | "HC: %i, %i, %i, %i\n 0x%08x 0x%08x 0x%08x 0x%08x", |
92223bf6 | 1368 | fCurrSm, fCurrStack, fCurrLayer, fCurrSide, |
9cb9c409 | 1369 | fPayloadCurr[0], fPayloadCurr[1], fPayloadCurr[2], fPayloadCurr[3]); |
d60fe037 | 1370 | } |
1371 | if (fCurrCheck != 0x1) { | |
92223bf6 | 1372 | LinkError(kHCcheckFailed); |
d60fe037 | 1373 | } |
5f006bd7 | 1374 | |
d60fe037 | 1375 | if (fCurrAddHcWords > 0) { |
1376 | fCurrNtimebins = (fPayloadCurr[1] >> 26) & 0x3f; | |
1377 | fCurrBC = (fPayloadCurr[1] >> 10) & 0xffff; | |
1378 | fCurrPtrgCnt = (fPayloadCurr[1] >> 6) & 0xf; | |
1379 | fCurrPtrgPhase = (fPayloadCurr[1] >> 2) & 0xf; | |
1380 | } | |
5f006bd7 | 1381 | |
d60fe037 | 1382 | fPayloadCurr += 1 + fCurrAddHcWords; |
5f006bd7 | 1383 | |
5fdfc9e4 | 1384 | return (fPayloadCurr - start); |
d60fe037 | 1385 | } |
1386 | ||
1387 | Int_t AliTRDrawStream::ReadTPData(Int_t mode) | |
1388 | { | |
1389 | // testing of testpattern 1 to 3 (hardcoded), 0 missing | |
1390 | // evcnt checking missing | |
1391 | Int_t cpu = 0; | |
1392 | Int_t cpufromchannel[] = {0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3}; | |
52a2b6c0 | 1393 | Int_t evno = -1; |
d60fe037 | 1394 | Int_t evcnt = 0; |
1395 | Int_t count = 0; | |
1396 | Int_t mcmcount = -1; | |
1397 | Int_t wordcount = 0; | |
1398 | Int_t channelcount = 0; | |
1399 | UInt_t expword = 0; | |
1400 | UInt_t expadcval = 0; | |
1401 | UInt_t diff = 0; | |
1402 | Int_t lastmcmpos = -1; | |
1403 | Int_t lastrobpos = -1; | |
1404 | ||
1405 | UInt_t* start = fPayloadCurr; | |
1406 | ||
5f006bd7 | 1407 | while (*(fPayloadCurr) != fgkDataEndmarker && |
d60fe037 | 1408 | fPayloadCurr - fPayloadStart < fPayloadSize - 1) { |
1409 | ||
1410 | // ----- Checking MCM Header ----- | |
2519cca4 | 1411 | AliDebug(2, DumpMcmHeader("MCM header: ", *fPayloadCurr)); |
1412 | UInt_t *startPosMCM = fPayloadCurr; | |
d60fe037 | 1413 | mcmcount++; |
5f006bd7 | 1414 | |
d60fe037 | 1415 | // ----- checking for proper readout order - ROB ----- |
52a2b6c0 | 1416 | fCurrRobPos = ROB(*fPayloadCurr); |
d60fe037 | 1417 | if (GetROBReadoutPos(ROB(*fPayloadCurr) / 2) >= lastrobpos) { |
52a2b6c0 | 1418 | if (GetROBReadoutPos(ROB(*fPayloadCurr) / 2) > lastrobpos) |
1419 | lastmcmpos = -1; | |
d60fe037 | 1420 | lastrobpos = GetROBReadoutPos(ROB(*fPayloadCurr) / 2); |
1421 | } | |
1422 | else { | |
9cb9c409 | 1423 | ROBError(kPosUnexp, Form("#%i after #%i in readout order", GetROBReadoutPos(ROB(*fPayloadCurr) / 2), lastrobpos)); |
d60fe037 | 1424 | } |
5f006bd7 | 1425 | |
d60fe037 | 1426 | // ----- checking for proper readout order - MCM ----- |
52a2b6c0 | 1427 | fCurrMcmPos = MCM(*fPayloadCurr); |
1428 | if (GetMCMReadoutPos(MCM(*fPayloadCurr)) > lastmcmpos) { | |
d60fe037 | 1429 | lastmcmpos = GetMCMReadoutPos(MCM(*fPayloadCurr)); |
1430 | } | |
1431 | else { | |
9cb9c409 | 1432 | MCMError(kPosUnexp, Form("#%i after #%i in readout order", GetMCMReadoutPos(MCM(*fPayloadCurr)), lastmcmpos)); |
d60fe037 | 1433 | } |
5f006bd7 | 1434 | |
52a2b6c0 | 1435 | if (EvNo(*fPayloadCurr) != evno) { |
1436 | if (evno == -1) { | |
1437 | evno = EvNo(*fPayloadCurr); | |
1438 | } | |
1439 | else { | |
1440 | MCMError(kEvCntMismatch, "%i <-> %i", evno, EvNo(*fPayloadCurr)); | |
1441 | } | |
1442 | } | |
d60fe037 | 1443 | |
1444 | fPayloadCurr++; | |
5f006bd7 | 1445 | |
d60fe037 | 1446 | evcnt = 0x3f & *fPayloadCurr >> 26; |
1447 | cpu = -1; | |
1448 | channelcount = 0; | |
1449 | while (channelcount < 21) { | |
1450 | count = 0; | |
1451 | if (cpu != cpufromchannel[channelcount]) { | |
1452 | cpu = cpufromchannel[channelcount]; | |
1453 | expadcval = (1 << 9) | (fCurrRobPos << 6) | (fCurrMcmPos << 2) | cpu; | |
1454 | wordcount = 0; | |
1455 | } | |
5f006bd7 | 1456 | |
d60fe037 | 1457 | while (count < 10) { |
2519cca4 | 1458 | if (*fPayloadCurr == fgkDataEndmarker) { |
1459 | MCMError(kMissTpData); | |
1460 | return (fPayloadCurr - start); | |
1461 | } | |
1462 | ||
d60fe037 | 1463 | if (channelcount % 2 == 0) |
1464 | expword = 0x3; | |
5f006bd7 | 1465 | else |
d60fe037 | 1466 | expword = 0x2; |
5f006bd7 | 1467 | |
d60fe037 | 1468 | if (mode == 1) { |
1469 | // ----- TP 1 ----- | |
1470 | expword |= expadcval << 2; | |
1471 | expadcval = ( (expadcval << 1) | ( ( (expadcval >> 9) ^ (expadcval >> 6) ) & 1) ) & 0x3FF; | |
1472 | expword |= expadcval << 12; | |
1473 | expadcval = ( (expadcval << 1) | ( ( (expadcval >> 9) ^ (expadcval >> 6) ) & 1) ) & 0x3FF; | |
1474 | expword |= expadcval << 22; | |
1475 | expadcval = ( (expadcval << 1) | ( ( (expadcval >> 9) ^ (expadcval >> 6) ) & 1) ) & 0x3FF; | |
1476 | } | |
1477 | else if (mode == 2) { | |
1478 | // ----- TP 2 ------ | |
5f006bd7 | 1479 | expword = ((0x3f & evcnt) << 26) | ((fCurrSm + 1) << 21) | ((fCurrLayer + 1) << 18) | |
1480 | ((fCurrStack + 1) << 15) | | |
1481 | (fCurrRobPos << 12) | (fCurrMcmPos << 8) | (cpu << 6) | (wordcount + 1); | |
d60fe037 | 1482 | } |
1483 | else if (mode == 3) { | |
1484 | // ----- TP 3 ----- | |
5f006bd7 | 1485 | expword = ((0xfff & evcnt) << 20) | (fCurrSm << 15) | (fCurrLink/2 << 12) | (fCurrStack << 9) | |
1486 | (fCurrRobPos << 6) | (fCurrMcmPos << 2) | (cpu << 0); | |
d60fe037 | 1487 | } |
1488 | else { | |
1489 | expword = 0; | |
92223bf6 | 1490 | LinkError(kTPmodeInvalid, "Just reading"); |
d60fe037 | 1491 | } |
1492 | ||
1493 | diff = *fPayloadCurr ^ expword; | |
2519cca4 | 1494 | AliDebug(11, Form("Comparing ch %2i, word %2i (cpu %i): 0x%08x <-> 0x%08x", |
1495 | channelcount, wordcount, cpu, *fPayloadCurr, expword)); | |
1496 | ||
d60fe037 | 1497 | if (diff != 0) { |
92223bf6 | 1498 | MCMError(kTPmismatch, |
52a2b6c0 | 1499 | "Seen 0x%08x, expected 0x%08x, diff: 0x%08x, 0x%04x, 0x%02x - word %2i (cpu %i, ch %i)", |
c4daee41 | 1500 | *fPayloadCurr, expword, diff, |
c4daee41 | 1501 | 0xffff & (diff | diff >> 16), |
52a2b6c0 | 1502 | 0xff & (diff | diff >> 8 | diff >> 16 | diff >> 24), |
2519cca4 | 1503 | wordcount, cpu, channelcount);; |
d60fe037 | 1504 | } |
1505 | fPayloadCurr++; | |
1506 | count++; | |
1507 | wordcount++; | |
52a2b6c0 | 1508 | if (*fPayloadCurr == fgkDataEndmarker) |
1509 | return (fPayloadCurr - start); | |
d60fe037 | 1510 | } |
1511 | channelcount++; | |
1512 | } | |
1513 | // continue with next MCM | |
2519cca4 | 1514 | |
1515 | if (IsDumping() && DumpingMCM(fCurrHC/2, fCurrRobPos, fCurrMcmPos)) { | |
1516 | AliInfo(DumpRaw(Form("Event %i: Det %3i ROB %i MCM %2i", fRawReader->GetEventIndex(), fCurrHC/2, fCurrRobPos, fCurrMcmPos), | |
1517 | startPosMCM, fPayloadCurr - startPosMCM)); | |
1518 | } | |
1519 | ||
d60fe037 | 1520 | } |
5f006bd7 | 1521 | return fPayloadCurr - start; |
d60fe037 | 1522 | } |
1523 | ||
1524 | ||
1525 | Int_t AliTRDrawStream::ReadZSData() | |
1526 | { | |
1527 | // read the zs data from one link from the current reading position | |
5f006bd7 | 1528 | |
d60fe037 | 1529 | UInt_t *start = fPayloadCurr; |
5f006bd7 | 1530 | |
d60fe037 | 1531 | Int_t mcmcount = 0; |
0508ca31 | 1532 | Int_t mcmcountExp = fCurrStack == 2 ? 48 : 64; |
d60fe037 | 1533 | Int_t channelcount = 0; |
0508ca31 | 1534 | Int_t channelcountExp = 0; |
1535 | Int_t channelcountMax = 0; | |
d60fe037 | 1536 | Int_t timebins; |
1537 | Int_t currentTimebin = 0; | |
1538 | Int_t adcwc = 0; | |
1539 | Int_t evno = -1; | |
1540 | Int_t lastmcmpos = -1; | |
1541 | Int_t lastrobpos = -1; | |
1542 | ||
1543 | if (fCurrNtimebins != fNtimebins) { | |
5f006bd7 | 1544 | if (fNtimebins > 0) |
92223bf6 | 1545 | LinkError(kNtimebinsChanged, |
1546 | "No. of timebins changed from %i to %i", fNtimebins, fCurrNtimebins); | |
d60fe037 | 1547 | fNtimebins = fCurrNtimebins; |
1548 | } | |
5f006bd7 | 1549 | |
d60fe037 | 1550 | timebins = fNtimebins; |
5f006bd7 | 1551 | |
1552 | while (*(fPayloadCurr) != fgkDataEndmarker && | |
d60fe037 | 1553 | fPayloadCurr - fPayloadStart < fPayloadSize) { |
5f006bd7 | 1554 | |
d60fe037 | 1555 | // ----- Checking MCM Header ----- |
9cb9c409 | 1556 | AliDebug(2, DumpMcmHeader("MCM header: ", *fPayloadCurr)); |
cc26f39c | 1557 | UInt_t *startPosMCM = fPayloadCurr; |
5f006bd7 | 1558 | |
d60fe037 | 1559 | // ----- checking for proper readout order - ROB ----- |
52a2b6c0 | 1560 | fCurrRobPos = ROB(*fPayloadCurr); |
d60fe037 | 1561 | if (GetROBReadoutPos(ROB(*fPayloadCurr) / 2) >= lastrobpos) { |
9cb9c409 | 1562 | if (GetROBReadoutPos(ROB(*fPayloadCurr) / 2) > lastrobpos) |
1563 | lastmcmpos = -1; | |
d60fe037 | 1564 | lastrobpos = GetROBReadoutPos(ROB(*fPayloadCurr) / 2); |
1565 | } | |
1566 | else { | |
9cb9c409 | 1567 | ROBError(kPosUnexp, Form("#%i after #%i and #%i in readout order", |
1568 | GetROBReadoutPos(ROB(*fPayloadCurr) / 2), lastrobpos, GetROBReadoutPos(fCurrRobPos))); | |
d60fe037 | 1569 | } |
5f006bd7 | 1570 | |
d60fe037 | 1571 | // ----- checking for proper readout order - MCM ----- |
52a2b6c0 | 1572 | fCurrMcmPos = MCM(*fPayloadCurr); |
d60fe037 | 1573 | if (GetMCMReadoutPos(MCM(*fPayloadCurr)) > lastmcmpos) { |
9cb9c409 | 1574 | lastmcmpos = GetMCMReadoutPos(MCM(*fPayloadCurr)); |
d60fe037 | 1575 | } |
1576 | else { | |
9cb9c409 | 1577 | MCMError(kPosUnexp, Form("#%i after #%i and #%i in readout order", |
1578 | GetMCMReadoutPos(MCM(*fPayloadCurr)), lastmcmpos, GetMCMReadoutPos(fCurrMcmPos))); | |
d60fe037 | 1579 | } |
5f006bd7 | 1580 | |
d60fe037 | 1581 | if (EvNo(*fPayloadCurr) != evno) { |
1582 | if (evno == -1) | |
1583 | evno = EvNo(*fPayloadCurr); | |
1584 | else { | |
52a2b6c0 | 1585 | MCMError(kEvCntMismatch, "%i <-> %i", evno, EvNo(*fPayloadCurr)); |
d60fe037 | 1586 | } |
1587 | } | |
1588 | Int_t adccoloff = AdcColOffset(*fPayloadCurr); | |
1589 | Int_t padcoloff = PadColOffset(*fPayloadCurr); | |
1590 | Int_t row = Row(*fPayloadCurr); | |
1591 | fPayloadCurr++; | |
5f006bd7 | 1592 | |
52a2b6c0 | 1593 | if ((row > 11) && (fCurrStack == 2)) { |
1594 | MCMError(kUnknown, "Data in padrow > 11 for stack 2"); | |
1595 | } | |
1596 | ||
d60fe037 | 1597 | // ----- Reading ADC channels ----- |
9cb9c409 | 1598 | AliDebug(2, DumpAdcMask("ADC mask: ", *fPayloadCurr)); |
5f006bd7 | 1599 | |
d60fe037 | 1600 | // ----- analysing the ADC mask ----- |
1601 | channelcount = 0; | |
0508ca31 | 1602 | channelcountExp = GetNActiveChannelsFromMask(*fPayloadCurr); |
1603 | channelcountMax = GetNActiveChannels(*fPayloadCurr); | |
d60fe037 | 1604 | Int_t channelmask = GetActiveChannels(*fPayloadCurr); |
1605 | Int_t channelno = -1; | |
5f006bd7 | 1606 | fPayloadCurr++; |
d60fe037 | 1607 | |
0508ca31 | 1608 | if (channelcountExp != channelcountMax) { |
1609 | if (channelcountExp > channelcountMax) { | |
1610 | Int_t temp = channelcountExp; | |
1611 | channelcountExp = channelcountMax; | |
1612 | channelcountMax = temp; | |
d60fe037 | 1613 | } |
5f006bd7 | 1614 | while (channelcountExp < channelcountMax && channelcountExp < 21 && |
0508ca31 | 1615 | fPayloadCurr - fPayloadStart < fPayloadSize - 10 * channelcountExp - 1) { |
92223bf6 | 1616 | MCMError(kAdcMaskInconsistent, |
5f006bd7 | 1617 | "Possible MCM-H: 0x%08x, possible ADC-mask: 0x%08x", |
1618 | *(fPayloadCurr + 10 * channelcountExp), | |
92223bf6 | 1619 | *(fPayloadCurr + 10 * channelcountExp + 1) ); |
5f006bd7 | 1620 | if (!CouldBeMCMhdr( *(fPayloadCurr + 10 * channelcountExp)) && !CouldBeADCmask( *(fPayloadCurr + 10 * channelcountExp + 1))) |
0508ca31 | 1621 | channelcountExp++; |
d60fe037 | 1622 | else { |
1623 | break; | |
1624 | } | |
1625 | } | |
92223bf6 | 1626 | MCMError(kAdcMaskInconsistent, |
5f006bd7 | 1627 | "Inconsistency in no. of active channels: Counter: %i, Mask: %i, chosen: %i!", |
92223bf6 | 1628 | GetNActiveChannels(fPayloadCurr[-1]), GetNActiveChannelsFromMask(fPayloadCurr[-1]), channelcountExp); |
d60fe037 | 1629 | } |
9cb9c409 | 1630 | AliDebug(2, Form("expecting %i active channels, %i timebins", channelcountExp, fCurrNtimebins)); |
5f006bd7 | 1631 | |
d60fe037 | 1632 | // ----- reading marked ADC channels ----- |
0508ca31 | 1633 | while (channelcount < channelcountExp && *(fPayloadCurr) != fgkDataEndmarker) { |
e29e514c | 1634 | if (channelno < 20) |
d60fe037 | 1635 | channelno++; |
e29e514c | 1636 | while (channelno < 20 && (channelmask & 1 << channelno) == 0) |
d60fe037 | 1637 | channelno++; |
5f006bd7 | 1638 | |
d60fe037 | 1639 | if (fCurrNtimebins > 30) { |
1640 | currentTimebin = ((*fPayloadCurr >> 2) & 0x3f); | |
1641 | timebins = ((*fPayloadCurr >> 8) & 0xf) * 3; | |
5f006bd7 | 1642 | } |
d60fe037 | 1643 | else { |
1644 | currentTimebin = 0; | |
1645 | } | |
5f006bd7 | 1646 | |
d60fe037 | 1647 | adcwc = 0; |
cb8b99ee | 1648 | Int_t nADCwords = (timebins + 2) / 3; |
1649 | AliDebug(3, Form("Now reading %i words for channel %2i", nADCwords, channelno)); | |
d60fe037 | 1650 | Int_t adccol = adccoloff - channelno; |
1651 | Int_t padcol = padcoloff - channelno; | |
5f006bd7 | 1652 | // if (adccol < 3 || adccol > 165) |
1653 | // AliInfo(Form("writing channel %i of det %3i %i:%2i to adcrow/-col: %i/%i padcol: %i", | |
cc26f39c | 1654 | // channelno, fCurrHC/2, fCurrRobPos, fCurrMcmPos, row, adccol, padcol)); |
1655 | ||
cb8b99ee | 1656 | while ((adcwc < nADCwords) && |
1657 | (*(fPayloadCurr) != fgkDataEndmarker) && | |
1658 | (fPayloadCurr - fPayloadStart < fPayloadSize)) { | |
d60fe037 | 1659 | int check = 0x3 & *fPayloadCurr; |
1660 | if (channelno % 2 != 0) { // odd channel | |
1661 | if (check != 0x2 && channelno < 21) { | |
92223bf6 | 1662 | MCMError(kAdcCheckInvalid, |
5f006bd7 | 1663 | "%i for %2i. ADC word in odd channel %i", |
92223bf6 | 1664 | check, adcwc+1, channelno); |
d60fe037 | 1665 | } |
1666 | } | |
1667 | else { // even channel | |
1668 | if (check != 0x3 && channelno < 21) { | |
92223bf6 | 1669 | MCMError(kAdcCheckInvalid, |
5f006bd7 | 1670 | "%i for %2i. ADC word in even channel %i", |
92223bf6 | 1671 | check, adcwc+1, channelno); |
d60fe037 | 1672 | } |
1673 | } | |
5f006bd7 | 1674 | |
d60fe037 | 1675 | // filling the actual timebin data |
1676 | int tb2 = 0x3ff & *fPayloadCurr >> 22; | |
1677 | int tb1 = 0x3ff & *fPayloadCurr >> 12; | |
1678 | int tb0 = 0x3ff & *fPayloadCurr >> 2; | |
5f006bd7 | 1679 | if (adcwc != 0 || fCurrNtimebins <= 30) |
d60fe037 | 1680 | fAdcArray->SetDataByAdcCol(row, adccol, currentTimebin++, tb0); |
1681 | else | |
1682 | tb0 = -1; | |
1683 | fAdcArray->SetDataByAdcCol(row, adccol, currentTimebin++, tb1); | |
1684 | fAdcArray->SetDataByAdcCol(row, adccol, currentTimebin++, tb2); | |
5f006bd7 | 1685 | |
d60fe037 | 1686 | adcwc++; |
1687 | fPayloadCurr++; | |
1688 | } | |
5f006bd7 | 1689 | |
cb8b99ee | 1690 | if (adcwc != nADCwords) |
92223bf6 | 1691 | MCMError(kAdcDataAbort); |
5f006bd7 | 1692 | |
1693 | // adding index | |
d60fe037 | 1694 | if (padcol > 0 && padcol < 144) { |
1695 | fSignalIndex->AddIndexRC(row, padcol); | |
1696 | } | |
5f006bd7 | 1697 | |
d60fe037 | 1698 | channelcount++; |
1699 | } | |
cc26f39c | 1700 | |
637666cd | 1701 | if (fCurrSm > -1 && fCurrSm < 18) { |
1702 | fStats.fStatsSector[fCurrSm].fStatsHC[fCurrHC%60].fNChannels += channelcount; | |
1703 | fStats.fStatsSector[fCurrSm].fNChannels += channelcount; | |
1704 | } | |
0508ca31 | 1705 | if (channelcount != channelcountExp) |
92223bf6 | 1706 | MCMError(kAdcChannelsMiss); |
5f006bd7 | 1707 | |
d60fe037 | 1708 | mcmcount++; |
637666cd | 1709 | if (fCurrSm > -1 && fCurrSm < 18) { |
1710 | fStats.fStatsSector[fCurrSm].fStatsHC[fCurrHC%60].fNMCMs++; | |
1711 | fStats.fStatsSector[fCurrSm].fNMCMs++; | |
1712 | } | |
cc26f39c | 1713 | |
1714 | if (IsDumping() && DumpingMCM(fCurrHC/2, fCurrRobPos, fCurrMcmPos)) { | |
9cb9c409 | 1715 | AliInfo(DumpRaw(Form("Event %i: Det %3i ROB %i MCM %2i", fRawReader->GetEventIndex(), fCurrHC/2, fCurrRobPos, fCurrMcmPos), |
1716 | startPosMCM, fPayloadCurr - startPosMCM)); | |
cc26f39c | 1717 | } |
1718 | ||
d60fe037 | 1719 | // continue with next MCM |
1720 | } | |
1721 | ||
1722 | // check for missing MCMs (if header suppression is inactive) | |
67271412 | 1723 | if (((fCurrMajor & 0x1) == 0) && (mcmcount != mcmcountExp)) { |
92223bf6 | 1724 | LinkError(kMissMcmHeaders, |
5f006bd7 | 1725 | "No. of MCM headers %i not as expected: %i", |
92223bf6 | 1726 | mcmcount, mcmcountExp); |
d60fe037 | 1727 | } |
1728 | ||
1729 | return (fPayloadCurr - start); | |
1730 | } | |
1731 | ||
1732 | Int_t AliTRDrawStream::ReadNonZSData() | |
1733 | { | |
1734 | // read the non-zs data from one link from the current reading position | |
5f006bd7 | 1735 | |
d60fe037 | 1736 | UInt_t *start = fPayloadCurr; |
5f006bd7 | 1737 | |
d60fe037 | 1738 | Int_t mcmcount = 0; |
0508ca31 | 1739 | Int_t mcmcountExp = fCurrStack == 2 ? 48 : 64; |
d60fe037 | 1740 | Int_t channelcount = 0; |
0508ca31 | 1741 | Int_t channelcountExp = 0; |
d60fe037 | 1742 | Int_t timebins; |
1743 | Int_t currentTimebin = 0; | |
1744 | Int_t adcwc = 0; | |
1745 | Int_t evno = -1; | |
1746 | Int_t lastmcmpos = -1; | |
1747 | Int_t lastrobpos = -1; | |
1748 | ||
1749 | if (fCurrNtimebins != fNtimebins) { | |
5f006bd7 | 1750 | if (fNtimebins > 0) |
92223bf6 | 1751 | LinkError(kNtimebinsChanged, |
1752 | "No. of timebins changed from %i to %i", fNtimebins, fCurrNtimebins); | |
d60fe037 | 1753 | fNtimebins = fCurrNtimebins; |
1754 | } | |
5f006bd7 | 1755 | |
d60fe037 | 1756 | timebins = fNtimebins; |
5f006bd7 | 1757 | |
1758 | while (*(fPayloadCurr) != fgkDataEndmarker && | |
d60fe037 | 1759 | fPayloadCurr - fPayloadStart < fPayloadSize - 2) { |
5f006bd7 | 1760 | |
d60fe037 | 1761 | // ----- Checking MCM Header ----- |
1762 | AliDebug(2, Form("MCM header: 0x%08x", *fPayloadCurr)); | |
5f006bd7 | 1763 | |
d60fe037 | 1764 | // ----- checking for proper readout order - ROB ----- |
52a2b6c0 | 1765 | fCurrRobPos = ROB(*fPayloadCurr); |
d60fe037 | 1766 | if (GetROBReadoutPos(ROB(*fPayloadCurr) / 2) >= lastrobpos) { |
52a2b6c0 | 1767 | if (GetROBReadoutPos(ROB(*fPayloadCurr) / 2) > lastrobpos) |
1768 | lastmcmpos = -1; | |
d60fe037 | 1769 | lastrobpos = GetROBReadoutPos(ROB(*fPayloadCurr) / 2); |
1770 | } | |
1771 | else { | |
9cb9c409 | 1772 | ROBError(kPosUnexp, Form("#%i after #%i in readout order", GetROBReadoutPos(ROB(*fPayloadCurr) / 2), lastrobpos)); |
d60fe037 | 1773 | } |
5f006bd7 | 1774 | |
d60fe037 | 1775 | // ----- checking for proper readout order - MCM ----- |
52a2b6c0 | 1776 | fCurrMcmPos = MCM(*fPayloadCurr); |
1777 | if (GetMCMReadoutPos(MCM(*fPayloadCurr)) > lastmcmpos) { | |
9cb9c409 | 1778 | lastmcmpos = GetMCMReadoutPos(MCM(*fPayloadCurr)); |
d60fe037 | 1779 | } |
1780 | else { | |
9cb9c409 | 1781 | MCMError(kPosUnexp, Form("#%i after #%i in readout order", GetMCMReadoutPos(MCM(*fPayloadCurr)), lastmcmpos)); |
d60fe037 | 1782 | } |
5f006bd7 | 1783 | |
d60fe037 | 1784 | if (EvNo(*fPayloadCurr) != evno) { |
1785 | if (evno == -1) | |
1786 | evno = EvNo(*fPayloadCurr); | |
1787 | else { | |
52a2b6c0 | 1788 | MCMError(kEvCntMismatch, "%i <-> %i", evno, EvNo(*fPayloadCurr)); |
d60fe037 | 1789 | } |
1790 | } | |
5f006bd7 | 1791 | |
d60fe037 | 1792 | channelcount = 0; |
0508ca31 | 1793 | channelcountExp = 21; |
d60fe037 | 1794 | int channelno = -1; |
1795 | ||
1796 | Int_t adccoloff = AdcColOffset(*fPayloadCurr); | |
1797 | Int_t padcoloff = PadColOffset(*fPayloadCurr); | |
1798 | Int_t row = Row(*fPayloadCurr); | |
1799 | ||
1800 | fPayloadCurr++; | |
1801 | ||
1802 | // ----- reading marked ADC channels ----- | |
5f006bd7 | 1803 | while (channelcount < channelcountExp && |
d60fe037 | 1804 | *(fPayloadCurr) != fgkDataEndmarker) { |
e29e514c | 1805 | if (channelno < 20) |
d60fe037 | 1806 | channelno++; |
5f006bd7 | 1807 | |
d60fe037 | 1808 | currentTimebin = 0; |
5f006bd7 | 1809 | |
d60fe037 | 1810 | adcwc = 0; |
cb8b99ee | 1811 | Int_t nADCwords = (timebins + 2) / 3; |
1812 | AliDebug(2, Form("Now looking %i words", nADCwords)); | |
d60fe037 | 1813 | Int_t adccol = adccoloff - channelno; |
1814 | Int_t padcol = padcoloff - channelno; | |
cb8b99ee | 1815 | while ((adcwc < nADCwords) && |
1816 | (*(fPayloadCurr) != fgkDataEndmarker) && | |
1817 | (fPayloadCurr - fPayloadStart < fPayloadSize)) { | |
d60fe037 | 1818 | int check = 0x3 & *fPayloadCurr; |
1819 | if (channelno % 2 != 0) { // odd channel | |
1820 | if (check != 0x2 && channelno < 21) { | |
92223bf6 | 1821 | MCMError(kAdcCheckInvalid, |
5f006bd7 | 1822 | "%i for %2i. ADC word in odd channel %i", |
92223bf6 | 1823 | check, adcwc+1, channelno); |
d60fe037 | 1824 | } |
1825 | } | |
1826 | else { // even channel | |
1827 | if (check != 0x3 && channelno < 21) { | |
92223bf6 | 1828 | MCMError(kAdcCheckInvalid, |
5f006bd7 | 1829 | "%i for %2i. ADC word in even channel %i", |
92223bf6 | 1830 | check, adcwc+1, channelno); |
d60fe037 | 1831 | } |
1832 | } | |
5f006bd7 | 1833 | |
d60fe037 | 1834 | // filling the actual timebin data |
1835 | int tb2 = 0x3ff & *fPayloadCurr >> 22; | |
1836 | int tb1 = 0x3ff & *fPayloadCurr >> 12; | |
1837 | int tb0 = 0x3ff & *fPayloadCurr >> 2; | |
5f006bd7 | 1838 | if (adcwc != 0 || fCurrNtimebins <= 30) |
d60fe037 | 1839 | fAdcArray->SetDataByAdcCol(row, adccol, currentTimebin++, tb0); |
1840 | else | |
1841 | tb0 = -1; | |
1842 | fAdcArray->SetDataByAdcCol(row, adccol, currentTimebin++, tb1); | |
1843 | fAdcArray->SetDataByAdcCol(row, adccol, currentTimebin++, tb2); | |
1844 | ||
1845 | adcwc++; | |
1846 | fPayloadCurr++; | |
1847 | } | |
1848 | ||
cb8b99ee | 1849 | if (adcwc != nADCwords) |
92223bf6 | 1850 | MCMError(kAdcDataAbort); |
5f006bd7 | 1851 | |
1852 | // adding index | |
d60fe037 | 1853 | if (padcol > 0 && padcol < 144) { |
1854 | fSignalIndex->AddIndexRC(row, padcol); | |
1855 | } | |
1856 | ||
1857 | channelcount++; | |
1858 | } | |
1859 | ||
0508ca31 | 1860 | if (channelcount != channelcountExp) |
92223bf6 | 1861 | MCMError(kAdcChannelsMiss); |
d60fe037 | 1862 | mcmcount++; |
1863 | // continue with next MCM | |
1864 | } | |
1865 | ||
1866 | // check for missing MCMs (if header suppression is inactive) | |
0508ca31 | 1867 | if (mcmcount != mcmcountExp) { |
92223bf6 | 1868 | LinkError(kMissMcmHeaders, |
1869 | "%i not as expected: %i", mcmcount, mcmcountExp); | |
d60fe037 | 1870 | } |
1871 | ||
1872 | return (fPayloadCurr - start); | |
1873 | } | |
1874 | ||
52a2b6c0 | 1875 | Int_t AliTRDrawStream::SeekNextStack() |
1876 | { | |
1877 | // proceed in raw data stream till the next stack | |
1878 | ||
1879 | if (!fCurrStackEndmarkerAvail) | |
1880 | return 0; | |
1881 | ||
1882 | UInt_t *start = fPayloadCurr; | |
1883 | ||
1884 | // read until data endmarkers | |
1885 | while ((fPayloadCurr - fPayloadStart < fPayloadSize-1) && | |
1886 | ((fPayloadCurr[0] != fgkStackEndmarker[0]) || | |
1887 | (fPayloadCurr[1] != fgkStackEndmarker[1]))) | |
1888 | fPayloadCurr++; | |
1889 | ||
1890 | if ((fPayloadCurr - start) != 0) | |
1891 | StackError(kUnknown, "skipped %i words to reach stack endmarker", fPayloadCurr - start); | |
1892 | ||
1893 | AliDebug(2, Form("stack endmarker: 0x%08x 0x%08x", fPayloadCurr[0], fPayloadCurr[1])); | |
1894 | ||
1895 | // goto next stack | |
1896 | fPayloadCurr++; | |
1897 | fPayloadCurr++; | |
1898 | ||
1899 | return (fPayloadCurr-start); | |
1900 | } | |
1901 | ||
92223bf6 | 1902 | Int_t AliTRDrawStream::SeekNextLink() |
1903 | { | |
92305359 | 1904 | // proceed in raw data stream till the next link |
1905 | ||
92223bf6 | 1906 | UInt_t *start = fPayloadCurr; |
1907 | ||
1908 | // read until data endmarkers | |
1909 | while (fPayloadCurr - fPayloadStart < fPayloadSize && | |
1910 | *fPayloadCurr != fgkDataEndmarker) | |
1911 | fPayloadCurr++; | |
1912 | ||
1913 | // read all data endmarkers | |
1914 | while (fPayloadCurr - fPayloadStart < fPayloadSize && | |
1915 | *fPayloadCurr == fgkDataEndmarker) | |
1916 | fPayloadCurr++; | |
1917 | ||
1918 | return (fPayloadCurr - start); | |
1919 | } | |
1920 | ||
5f006bd7 | 1921 | Bool_t AliTRDrawStream::ConnectTracklets(TTree *trklTree) |
67271412 | 1922 | { |
92305359 | 1923 | // connect the tracklet tree used to store the tracklet output |
1924 | ||
67271412 | 1925 | fTrackletTree = trklTree; |
5f006bd7 | 1926 | if (!fTrackletTree) |
67271412 | 1927 | return kTRUE; |
1928 | ||
5f006bd7 | 1929 | if (!fTrackletTree->GetBranch("hc")) |
67271412 | 1930 | fTrackletTree->Branch("hc", &fCurrHC, "hc/I"); |
5f006bd7 | 1931 | else |
67271412 | 1932 | fTrackletTree->SetBranchAddress("hc", &fCurrHC); |
cc26f39c | 1933 | |
5f006bd7 | 1934 | if (!fTrackletTree->GetBranch("trkl")) |
cc26f39c | 1935 | fTrackletTree->Branch("trkl", &fTrackletArray); |
5f006bd7 | 1936 | else |
67271412 | 1937 | fTrackletTree->SetBranchAddress("trkl", &fTrackletArray); |
cc26f39c | 1938 | |
67271412 | 1939 | return kTRUE; |
1940 | } | |
1941 | ||
1942 | ||
1d62be37 | 1943 | void AliTRDrawStream::EquipmentError(ErrorCode_t err, const char *const msg, ...) |
5f006bd7 | 1944 | { |
1945 | // register error according to error code on equipment level | |
0508ca31 | 1946 | // and return the corresponding error message |
1947 | ||
9cb9c409 | 1948 | fLastError.fSector = fCurrEquipmentId - kDDLOffset; |
d60fe037 | 1949 | fLastError.fStack = -1; |
1950 | fLastError.fLink = -1; | |
1951 | fLastError.fRob = -1; | |
1952 | fLastError.fMcm = -1; | |
1953 | fLastError.fError = err; | |
f4b3235e | 1954 | (this->*fStoreError)(); |
d60fe037 | 1955 | |
92223bf6 | 1956 | va_list ap; |
5f006bd7 | 1957 | if (fgErrorDebugLevel[err] > 10) |
92223bf6 | 1958 | AliDebug(fgErrorDebugLevel[err], |
5f006bd7 | 1959 | Form("Event %6i: Eq. %2d - %s : %s", |
92305359 | 1960 | fRawReader->GetEventIndex(), fCurrEquipmentId, fgkErrorMessages[err], |
1d62be37 | 1961 | (va_start(ap, msg), vsprintf(fErrorBuffer, msg, ap), va_end(ap), fErrorBuffer) )); |
5f006bd7 | 1962 | else |
1963 | AliError(Form("Event %6i: Eq. %2d - %s : %s", | |
92305359 | 1964 | fRawReader->GetEventIndex(), fCurrEquipmentId, fgkErrorMessages[err], |
1d62be37 | 1965 | (va_start(ap, msg), vsprintf(fErrorBuffer, msg, ap), va_end(ap), fErrorBuffer) )); |
92223bf6 | 1966 | fErrorFlags |= fgErrorBehav[err]; |
5f006bd7 | 1967 | } |
d60fe037 | 1968 | |
1969 | ||
1d62be37 | 1970 | void AliTRDrawStream::StackError(ErrorCode_t err, const char *const msg, ...) |
5f006bd7 | 1971 | { |
1972 | // register error according to error code on stack level | |
0508ca31 | 1973 | // and return the corresponding error message |
1974 | ||
9cb9c409 | 1975 | fLastError.fSector = fCurrEquipmentId - kDDLOffset; |
d60fe037 | 1976 | fLastError.fStack = fCurrSlot; |
1977 | fLastError.fLink = -1; | |
1978 | fLastError.fRob = -1; | |
1979 | fLastError.fMcm = -1; | |
1980 | fLastError.fError = err; | |
f4b3235e | 1981 | (this->*fStoreError)(); |
d60fe037 | 1982 | |
92223bf6 | 1983 | va_list ap; |
5f006bd7 | 1984 | if (fgErrorDebugLevel[err] > 0) |
1985 | AliDebug(fgErrorDebugLevel[err], | |
1986 | Form("Event %6i: Eq. %2d S %i - %s : %s", | |
92305359 | 1987 | fRawReader->GetEventIndex(), fCurrEquipmentId, fCurrSlot, fgkErrorMessages[err], |
1d62be37 | 1988 | (va_start(ap, msg), vsprintf(fErrorBuffer, msg, ap), va_end(ap), fErrorBuffer) )); |
5f006bd7 | 1989 | else |
1990 | AliError(Form("Event %6i: Eq. %2d S %i - %s : %s", | |
92305359 | 1991 | fRawReader->GetEventIndex(), fCurrEquipmentId, fCurrSlot, fgkErrorMessages[err], |
1d62be37 | 1992 | (va_start(ap, msg), vsprintf(fErrorBuffer, msg, ap), va_end(ap), fErrorBuffer) )); |
92223bf6 | 1993 | fErrorFlags |= fgErrorBehav[err]; |
5f006bd7 | 1994 | } |
d60fe037 | 1995 | |
1996 | ||
1d62be37 | 1997 | void AliTRDrawStream::LinkError(ErrorCode_t err, const char *const msg, ...) |
5f006bd7 | 1998 | { |
1999 | // register error according to error code on link level | |
0508ca31 | 2000 | // and return the corresponding error message |
2001 | ||
9cb9c409 | 2002 | fLastError.fSector = fCurrEquipmentId - kDDLOffset; |
d60fe037 | 2003 | fLastError.fStack = fCurrSlot; |
2004 | fLastError.fLink = fCurrLink; | |
2005 | fLastError.fRob = -1; | |
2006 | fLastError.fMcm = -1; | |
2007 | fLastError.fError = err; | |
f4b3235e | 2008 | (this->*fStoreError)(); |
d60fe037 | 2009 | |
92223bf6 | 2010 | va_list ap; |
e29e514c | 2011 | if (fgErrorDebugLevel[err] > 0) |
5f006bd7 | 2012 | AliDebug(fgErrorDebugLevel[err], |
2013 | Form("Event %6i: Eq. %2d S %i l %2i - %s : %s", | |
92305359 | 2014 | fRawReader->GetEventIndex(), fCurrEquipmentId, fCurrSlot, fCurrLink, fgkErrorMessages[err], |
1d62be37 | 2015 | (va_start(ap, msg), vsprintf(fErrorBuffer, msg, ap), va_end(ap), fErrorBuffer) )); |
5f006bd7 | 2016 | else |
2017 | AliError(Form("Event %6i: Eq. %2d S %i l %2i - %s : %s", | |
92305359 | 2018 | fRawReader->GetEventIndex(), fCurrEquipmentId, fCurrSlot, fCurrLink, fgkErrorMessages[err], |
1d62be37 | 2019 | (va_start(ap, msg), vsprintf(fErrorBuffer, msg, ap), va_end(ap), fErrorBuffer) )); |
92223bf6 | 2020 | fErrorFlags |= fgErrorBehav[err]; |
5f006bd7 | 2021 | } |
d60fe037 | 2022 | |
2023 | ||
1d62be37 | 2024 | void AliTRDrawStream::ROBError(ErrorCode_t err, const char *const msg, ...) |
5f006bd7 | 2025 | { |
2026 | // register error according to error code on ROB level | |
0508ca31 | 2027 | // and return the corresponding error message |
2028 | ||
9cb9c409 | 2029 | fLastError.fSector = fCurrEquipmentId - kDDLOffset; |
d60fe037 | 2030 | fLastError.fStack = fCurrSlot; |
2031 | fLastError.fLink = fCurrLink; | |
2032 | fLastError.fRob = fCurrRobPos; | |
2033 | fLastError.fMcm = -1; | |
2034 | fLastError.fError = err; | |
f4b3235e | 2035 | (this->*fStoreError)(); |
d60fe037 | 2036 | |
92223bf6 | 2037 | va_list ap; |
5f006bd7 | 2038 | if (fgErrorDebugLevel[err] > 0) |
2039 | AliDebug(fgErrorDebugLevel[err], | |
2040 | Form("Event %6i: Eq. %2d S %i l %2i ROB %i - %s : %s", | |
92305359 | 2041 | fRawReader->GetEventIndex(), fCurrEquipmentId, fCurrSlot, fCurrLink, fCurrRobPos, fgkErrorMessages[err], |
1d62be37 | 2042 | (va_start(ap, msg), vsprintf(fErrorBuffer, msg, ap), va_end(ap), fErrorBuffer) )); |
5f006bd7 | 2043 | else |
2044 | AliError(Form("Event %6i: Eq. %2d S %i l %2i ROB %i - %s : %s", | |
2045 | fRawReader->GetEventIndex(), fCurrEquipmentId, fCurrSlot, fCurrLink, fCurrRobPos, fgkErrorMessages[err], | |
1d62be37 | 2046 | (va_start(ap, msg), vsprintf(fErrorBuffer, msg, ap), va_end(ap), fErrorBuffer) )); |
92223bf6 | 2047 | fErrorFlags |= fgErrorBehav[err]; |
5f006bd7 | 2048 | } |
d60fe037 | 2049 | |
2050 | ||
1d62be37 | 2051 | void AliTRDrawStream::MCMError(ErrorCode_t err, const char *const msg, ...) |
5f006bd7 | 2052 | { |
2053 | // register error according to error code on MCM level | |
0508ca31 | 2054 | // and return the corresponding error message |
2055 | ||
9cb9c409 | 2056 | fLastError.fSector = fCurrEquipmentId - kDDLOffset; |
d60fe037 | 2057 | fLastError.fStack = fCurrSlot; |
2058 | fLastError.fLink = fCurrLink; | |
2059 | fLastError.fRob = fCurrRobPos; | |
2060 | fLastError.fMcm = fCurrMcmPos; | |
2061 | fLastError.fError = err; | |
f4b3235e | 2062 | (this->*fStoreError)(); |
d60fe037 | 2063 | |
92223bf6 | 2064 | va_list ap; |
5f006bd7 | 2065 | if (fgErrorDebugLevel[err] > 0) |
2066 | AliDebug(fgErrorDebugLevel[err], | |
92223bf6 | 2067 | Form("Event %6i: Eq. %2d S %i l %2i ROB %i MCM %2i - %s : %s", |
5f006bd7 | 2068 | fRawReader->GetEventIndex(), fCurrEquipmentId, fCurrSlot, fCurrLink, fCurrRobPos, fCurrMcmPos, fgkErrorMessages[err], |
1d62be37 | 2069 | (va_start(ap, msg), vsprintf(fErrorBuffer, msg, ap), va_end(ap), fErrorBuffer) )); |
5f006bd7 | 2070 | else |
92223bf6 | 2071 | AliError(Form("Event %6i: Eq. %2d S %i l %2i ROB %i MCM %2i - %s : %s", |
5f006bd7 | 2072 | fRawReader->GetEventIndex(), fCurrEquipmentId, fCurrSlot, fCurrLink, fCurrRobPos, fCurrMcmPos, fgkErrorMessages[err], |
1d62be37 | 2073 | (va_start(ap, msg), vsprintf(fErrorBuffer, msg, ap), va_end(ap), fErrorBuffer) )); |
92223bf6 | 2074 | fErrorFlags |= fgErrorBehav[err]; |
d60fe037 | 2075 | } |
2076 | ||
2077 | const char* AliTRDrawStream::GetErrorMessage(ErrorCode_t errCode) | |
5f006bd7 | 2078 | { |
0508ca31 | 2079 | // return the error message for the given error code |
2080 | ||
5f006bd7 | 2081 | if (errCode > 0 && errCode < kLastErrorCode) |
92305359 | 2082 | return fgkErrorMessages[errCode]; |
5f006bd7 | 2083 | else |
2084 | return ""; | |
2085 | } | |
cc26f39c | 2086 | |
2087 | void AliTRDrawStream::AliTRDrawStats::ClearStats() | |
2088 | { | |
2089 | // clear statistics (includes clearing sector-wise statistics) | |
2090 | ||
2091 | fBytesRead = 0; | |
2092 | for (Int_t iSector = 0; iSector < 18; iSector++) { | |
2093 | fStatsSector[iSector].ClearStats(); | |
2094 | } | |
2095 | ||
2096 | } | |
2097 | ||
2098 | void AliTRDrawStream::AliTRDrawStats::AliTRDrawStatsSector::ClearStats() | |
2099 | { | |
2100 | // clear statistics (includes clearing HC-wise statistics) | |
2101 | ||
2102 | fBytes = 0; | |
2103 | fBytesRead = 0; | |
2104 | fNTracklets = 0; | |
2105 | fNMCMs = 0; | |
2106 | fNChannels = 0; | |
2107 | ||
2108 | for (Int_t iHC = 0; iHC < 60; iHC++) { | |
2109 | fStatsHC[iHC].ClearStats(); | |
2110 | } | |
2111 | } | |
2112 | ||
2113 | void AliTRDrawStream::AliTRDrawStats::AliTRDrawStatsSector::AliTRDrawStatsHC::ClearStats() | |
2114 | { | |
2115 | // clear statistics | |
2116 | ||
2117 | fBytes = 0; | |
2118 | fBytesRead = 0; | |
2119 | fNTracklets = 0; | |
2120 | fNMCMs = 0; | |
2121 | fNChannels = 0; | |
2122 | } | |
2123 | ||
2124 | void AliTRDrawStream::SetDumpMCM(Int_t det, Int_t rob, Int_t mcm, Bool_t dump) | |
5f006bd7 | 2125 | { |
cc26f39c | 2126 | // mark MCM for dumping of raw data |
2127 | ||
2128 | if (dump) { | |
5f006bd7 | 2129 | fDumpMCM[fNDumpMCMs++] = (det << 7) | (rob << 4) | mcm; |
cc26f39c | 2130 | } |
2131 | else { | |
2132 | Int_t iMCM; | |
2133 | for (iMCM = 0; iMCM < fNDumpMCMs; iMCM++) { | |
2134 | if (fDumpMCM[iMCM] == ((det << 7) | (rob << 4) | mcm)) { | |
2135 | fNDumpMCMs--; | |
2136 | break; | |
2137 | } | |
2138 | } | |
2139 | for ( ; iMCM < fNDumpMCMs; iMCM++) { | |
2140 | fDumpMCM[iMCM] = fDumpMCM[iMCM+1]; | |
2141 | } | |
2142 | } | |
2143 | } | |
2144 | ||
92305359 | 2145 | Bool_t AliTRDrawStream::DumpingMCM(Int_t det, Int_t rob, Int_t mcm) const |
cc26f39c | 2146 | { |
2147 | // check if MCM data should be dumped | |
2148 | ||
2149 | for (Int_t iMCM = 0; iMCM < fNDumpMCMs; iMCM++) { | |
2150 | if (fDumpMCM[iMCM] == ((det << 7) | (rob << 4) | mcm)) { | |
2151 | return kTRUE; | |
2152 | } | |
2153 | } | |
2154 | return kFALSE; | |
2155 | } | |
2156 | ||
6419bebb | 2157 | TString AliTRDrawStream::DumpRaw(TString title, const UInt_t *start, Int_t length, UInt_t endmarker) |
cc26f39c | 2158 | { |
2159 | // dump raw data | |
2160 | ||
2161 | title += "\n"; | |
9cb9c409 | 2162 | for (Int_t pos = 0; pos < length; pos += 4) { |
2163 | if ((start[pos+0] != endmarker) && pos+0 < length) | |
2164 | if ((start[pos+1] != endmarker && pos+1 < length)) | |
2165 | if ((start[pos+2] != endmarker && pos+2 < length)) | |
2166 | if ((start[pos+3] != endmarker && pos+3 < length)) | |
5f006bd7 | 2167 | title += Form(" 0x%08x 0x%08x 0x%08x 0x%08x\n", |
9cb9c409 | 2168 | start[pos+0], start[pos+1], start[pos+2], start[pos+3]); |
2169 | else { | |
5f006bd7 | 2170 | title += Form(" 0x%08x 0x%08x 0x%08x 0x%08x\n", |
9cb9c409 | 2171 | start[pos+0], start[pos+1], start[pos+2], start[pos+3]); |
2172 | return title; | |
2173 | } | |
2174 | else { | |
5f006bd7 | 2175 | title += Form(" 0x%08x 0x%08x 0x%08x\n", |
9cb9c409 | 2176 | start[pos+0], start[pos+1], start[pos+2]); |
2177 | return title; | |
2178 | } | |
2179 | else { | |
5f006bd7 | 2180 | title += Form(" 0x%08x 0x%08x\n", |
9cb9c409 | 2181 | start[pos+0], start[pos+1]); |
2182 | return title; | |
2183 | } | |
2184 | else { | |
5f006bd7 | 2185 | title += Form(" 0x%08x\n", |
9cb9c409 | 2186 | start[pos+0]); |
2187 | return title; | |
2188 | } | |
cc26f39c | 2189 | } |
9cb9c409 | 2190 | return title; |
2191 | } | |
2192 | ||
2193 | TString AliTRDrawStream::DumpMcmHeader(TString title, UInt_t word) | |
2194 | { | |
2195 | title += Form("0x%08x -> ROB: %i, MCM: %2i", | |
2196 | word, ROB(word), MCM(word)); | |
2197 | return title; | |
2198 | } | |
2199 | ||
2200 | TString AliTRDrawStream::DumpAdcMask(TString title, UInt_t word) | |
2201 | { | |
2202 | title += Form("0x%08x -> #ch : %2i, 0x%06x (%2i ch)", | |
2203 | word, GetNActiveChannels(word), GetActiveChannels(word), GetNActiveChannelsFromMask(word)); | |
2204 | return title; | |
cc26f39c | 2205 | } |
f4b3235e | 2206 | |
5f006bd7 | 2207 | AliTRDrawStream::AliTRDrawStreamError::AliTRDrawStreamError(Int_t error, Int_t sector, Int_t stack, Int_t link, Int_t rob, Int_t mcm) : |
f4b3235e | 2208 | fError(error), |
2209 | fSector(sector), | |
2210 | fStack(stack), | |
5f006bd7 | 2211 | fLink(link), |
f4b3235e | 2212 | fRob(rob), |
2213 | fMcm(mcm) | |
2214 | { | |
2215 | // ctor | |
2216 | ||
2217 | } | |
52a2b6c0 | 2218 | |
2219 | void AliTRDrawStream::SortTracklets(TClonesArray *trklArray, TList &sortedTracklets, Int_t *indices) | |
2220 | { | |
2221 | // sort tracklets for referencing from GTU tracks | |
2222 | ||
2223 | Int_t nTracklets = trklArray->GetEntriesFast(); | |
2224 | ||
2225 | Int_t lastHC = -1; | |
2226 | for (Int_t iTracklet = 0; iTracklet < nTracklets; iTracklet++) { | |
2227 | AliTRDtrackletBase *trkl = (AliTRDtrackletBase*) ((*trklArray)[iTracklet]); | |
2228 | Int_t hc = trkl->GetHCId(); | |
2229 | if ((hc < 0) || (hc >= 1080)) { | |
2230 | AliErrorClass(Form("HC for tracklet: 0x%08x out of range: %i", trkl->GetTrackletWord(), trkl->GetHCId())); | |
2231 | continue; | |
2232 | } | |
2233 | AliDebugClass(5, Form("hc: %4i : 0x%08x z: %2i", hc, trkl->GetTrackletWord(), trkl->GetZbin())); | |
2234 | if (hc != lastHC) { | |
2235 | AliDebugClass(2, Form("set tracklet index for HC %i to %i", hc, iTracklet)); | |
2236 | indices[hc] = iTracklet + 1; | |
2237 | lastHC = hc; | |
2238 | } | |
2239 | } | |
2240 | ||
2241 | for (Int_t iDet = 0; iDet < 540; iDet++) { | |
2242 | Int_t trklIndexA = indices[2*iDet + 0] - 1; | |
2243 | Int_t trklIndexB = indices[2*iDet + 1] - 1; | |
2244 | Int_t trklIndex = sortedTracklets.GetEntries(); | |
2245 | AliTRDtrackletBase *trklA = trklIndexA > -1 ? (AliTRDtrackletBase*) ((*trklArray)[trklIndexA]) : 0x0; | |
2246 | AliTRDtrackletBase *trklB = trklIndexB > -1 ? (AliTRDtrackletBase*) ((*trklArray)[trklIndexB]) : 0x0; | |
2247 | AliTRDtrackletBase *trklNext = 0x0; | |
2248 | while (trklA != 0x0 || trklB != 0x0) { | |
2249 | AliDebugClass(5, Form("det %i - A: %i/%i -> %p, B: %i/%i -> %p", | |
2250 | iDet, trklIndexA, nTracklets, trklA, trklIndexB, nTracklets, trklB)); | |
2251 | if (trklA == 0x0) { | |
2252 | trklNext = trklB; | |
2253 | trklIndexB++; | |
2254 | trklB = trklIndexB < nTracklets ? (AliTRDtrackletBase*) ((*trklArray)[trklIndexB]) : 0x0; | |
2255 | if (trklB && trklB->GetHCId() != 2*iDet + 1) | |
2256 | trklB = 0x0; | |
2257 | } | |
2258 | else if (trklB == 0x0) { | |
2259 | trklNext = trklA; | |
2260 | trklIndexA++; | |
2261 | trklA = trklIndexA < nTracklets ? (AliTRDtrackletBase*) ((*trklArray)[trklIndexA]) : 0x0; | |
2262 | if (trklA && trklA->GetHCId() != 2*iDet) | |
2263 | trklA = 0x0; | |
2264 | } | |
2265 | else { | |
2266 | if ((trklA->GetZbin() < trklB->GetZbin()) || | |
2267 | ((trklA->GetZbin() == trklB->GetZbin()) && (trklA->GetYbin() < trklB->GetYbin()))) { | |
2268 | trklNext = trklA; | |
2269 | trklIndexA++; | |
2270 | trklA = trklIndexA < nTracklets ? (AliTRDtrackletBase*) ((*trklArray)[trklIndexA]) : 0x0; | |
2271 | if (trklA && trklA->GetHCId() != 2*iDet) | |
2272 | trklA = 0x0; | |
2273 | } | |
2274 | else { | |
2275 | trklNext = trklB; | |
2276 | trklIndexB++; | |
2277 | trklB = trklIndexB < nTracklets ? (AliTRDtrackletBase*) ((*trklArray)[trklIndexB]) : 0x0; | |
2278 | if (trklB && trklB->GetHCId() != 2*iDet + 1) | |
2279 | trklB = 0x0; | |
2280 | } | |
2281 | } | |
2282 | if (trklNext) { | |
2283 | Int_t label = -2; // mark raw tracklets with label -2 | |
2284 | if (AliTRDtrackletMCM *trklMCM = dynamic_cast<AliTRDtrackletMCM*> (trklNext)) | |
2285 | label = trklMCM->GetLabel(); | |
2286 | AliESDTrdTracklet *esdTracklet = new AliESDTrdTracklet(trklNext->GetTrackletWord(), trklNext->GetHCId(), label); | |
2287 | sortedTracklets.Add(esdTracklet); | |
2288 | } | |
2289 | ||
2290 | // updating tracklet indices as in output | |
2291 | if (sortedTracklets.GetEntries() != trklIndex) { | |
2292 | indices[2*iDet + 0] = indices[2*iDet + 1] = trklIndex; | |
2293 | } | |
2294 | else | |
2295 | indices[2*iDet + 0] = indices[2*iDet + 1] = -1; | |
2296 | } | |
2297 | } | |
2298 | } |