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