1 /**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
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 **************************************************************************/
16 ////////////////////////////////////////////////////////////////////////////
18 // Decoding data from the TRD raw stream //
19 // and translation into ADC values, on-line tracklets and tracks //
21 // CRC checks rely on boost, and are enabled only when TRD_RAW_CRC //
24 // Additional debug features can be enabled by defining TRD_RAW_DEBUG //
26 // Author: J. Klein (jochen.klein@cern.ch) //
28 ////////////////////////////////////////////////////////////////////////////
33 #if defined(TRD_RAW_CRC)
34 #include <boost/crc.hpp>
37 #include "TClonesArray.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"
55 #include "AliTRDrawStream.h"
57 ClassImp(AliTRDrawStream)
59 // some static information
60 Int_t AliTRDrawStream::fgMcmOrder[] = {12, 13, 14, 15,
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 };
73 const char* AliTRDrawStream::fgkErrorMessages[] = {
75 "Link monitor active",
76 "Event counter mismatch",
77 "not a TRD equipment (1024-1041)",
78 "Invalid Stack header",
79 "Invalid detector number",
81 "No digits could be retrieved from the digitsmanager",
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",
91 "Missing expected ADC channels",
92 "Missing MCM headers",
97 Int_t AliTRDrawStream::fgErrorDebugLevel[] = {
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
145 AliTRDrawStream::AliTRDrawStream(AliRawReader *rawReader) :
146 fStoreError(&AliTRDrawStream::ForgetError),
147 fRawReader(rawReader),
164 fCurrSmHeaderSize(0),
165 fCurrSmHeaderVersion(0),
166 fCurrTrailerReadout(0),
167 fCurrTrgHeaderAvail(0),
168 fCurrTrgHeaderReadout(0),
169 fCurrTrkHeaderAvail(0),
170 fCurrStackEndmarkerAvail(0),
172 fCurrTriggerEnable(0),
173 fCurrTriggerFired(0),
175 fCurrTrackletEnable(0),
185 fCurrTrkHeaderIndexWord(0x0),
186 fCurrTrkHeaderSize(0x0),
188 fCurrTrgHeaderIndexWord(0x0),
189 fCurrTrgHeaderSize(0x0),
191 fCurrStackIndexWord(0x0),
192 fCurrStackHeaderSize(0x0),
193 fCurrStackHeaderVersion(0x0),
195 fCurrCleanCheckout(0x0),
199 fCurrLinkMonitorFlags(0x0),
200 fCurrLinkDataTypeFlags(0x0),
201 fCurrLinkDebugFlags(0x0),
202 fCurrMatchFlagsSRAM(),
203 fCurrMatchFlagsPostBP(),
204 fCurrChecksumStack(),
229 // default constructor
231 fCurrTrkHeaderIndexWord = new UInt_t[fgkNstacks];
232 fCurrTrkHeaderSize = new UInt_t[fgkNstacks];
233 fCurrTrkFlags = new ULong64_t[fgkNsectors*fgkNstacks];
234 fCurrTrgHeaderIndexWord = new UInt_t[fgkNtriggers];
235 fCurrTrgHeaderSize = new UInt_t[fgkNtriggers];
236 fCurrTrgFlags = new UInt_t[fgkNsectors];
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];
244 fCurrStackIndexWord = new UInt_t[fgkNstacks];
245 fCurrStackHeaderSize = new UInt_t[fgkNstacks];
246 fCurrStackHeaderVersion = new UInt_t[fgkNstacks];
247 fCurrLinkMask = new UInt_t[fgkNstacks];
248 fCurrCleanCheckout = new UInt_t[fgkNstacks];
249 fCurrBoardId = new UInt_t[fgkNstacks];
250 fCurrHwRevTMU = new UInt_t[fgkNstacks];
251 fCurrLinkMonitorFlags = new UInt_t[fgkNsectors * fgkNstacks * fgkNlinks];
252 fCurrLinkDataTypeFlags = new UInt_t[fgkNstacks * fgkNlinks];
253 fCurrLinkDebugFlags = new UInt_t[fgkNstacks * fgkNlinks];
254 for (Int_t iSector = 0; iSector < fgkNsectors; iSector++)
255 fCurrTrgFlags[iSector] = 0;
256 for (Int_t i = 0; i < 100; i++)
259 // setting up the error tree
260 fErrors = new TTree("errorStats", "Error statistics");
261 fErrors->SetDirectory(0x0);
262 fErrors->Branch("error", &fLastError);
263 fErrors->SetCircular(1000);
264 for (Int_t i = 0; i < 100; i++) {
270 AliTRDrawStream::~AliTRDrawStream()
276 delete [] fCurrTrkHeaderIndexWord;
277 delete [] fCurrTrkHeaderSize;
278 delete [] fCurrTrkFlags;
279 delete [] fCurrTrgHeaderIndexWord;
280 delete [] fCurrTrgHeaderSize;
281 delete [] fCurrTrgFlags;
282 delete [] fCurrStackIndexWord;
283 delete [] fCurrStackHeaderSize;
284 delete [] fCurrStackHeaderVersion;
285 delete [] fCurrLinkMask;
286 delete [] fCurrCleanCheckout;
287 delete [] fCurrBoardId;
288 delete [] fCurrHwRevTMU;
289 delete [] fCurrLinkMonitorFlags;
290 delete [] fCurrLinkDataTypeFlags;
291 delete [] fCurrLinkDebugFlags;
294 Bool_t AliTRDrawStream::ReadEvent()
296 // read the current event from the raw reader and fill it to the digits manager
299 AliError("No raw reader available");
306 // loop over all DDLs
307 // data starts with GTU payload, i.e. SM index word
308 UChar_t *buffer = 0x0;
310 while (fRawReader->ReadNextData(buffer)) {
312 fCurrEquipmentId = fRawReader->GetEquipmentId();
313 AliDebug(2, Form("equipment: %i", fCurrEquipmentId));
315 if (fCurrEquipmentId < kDDLOffset || fCurrEquipmentId > kDDLMax) {
316 EquipmentError(kNonTrdEq, "Skipping");
321 new ((*fMarkers)[fMarkers->GetEntriesFast()])
322 AliTRDrawStreamError(-kSecactive, fCurrEquipmentId - kDDLOffset);
324 ReadGTUHeaders((UInt_t*) buffer);
326 if (fCurrTrailerReadout)
330 boost::crc_optimal<16, 0x8005, 0, 0, false, false> checksumStack[5];
331 boost::crc_optimal<32, 0x04C11DB7, 0, 0, false, false> checksumSIU;
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);
342 if (checksumSIU() != fCurrChecksumSIU) {
343 EquipmentError(kCRCmismatch, "SIU data - recalc: 0x%08x - 0x%08x", fCurrChecksumSIU, checksumSIU());
347 // loop over all active links
348 AliDebug(2, Form("Stack mask 0x%02x", fCurrStackMask));
349 for (Int_t iStack = 0; iStack < fgkNstacks; iStack++) {
352 checksumStack[iStack].reset();
355 if ((fCurrStackMask & (1 << fCurrSlot)) == 0)
358 AliDebug(2, Form("Stack %i, Link mask: 0x%02x", fCurrSlot, fCurrLinkMask[fCurrSlot]));
359 for (Int_t iLink = 0; iLink < fgkNlinks; iLink++) {
361 fCurrHC = (fCurrEquipmentId - kDDLOffset) * fgkNstacks * fgkNlinks +
362 fCurrSlot * fgkNlinks + iLink;
363 if ((fCurrLinkMask[fCurrSlot] & (1 << fCurrLink)) == 0)
367 UInt_t *start = fPayloadCurr;
372 // check for link monitor error flag
373 if (fCurrLinkMonitorFlags[(((fCurrEquipmentId - kDDLOffset) * fgkNstacks) + fCurrSlot) * fgkNlinks + fCurrLink] != 0) {
374 LinkError(kLinkMonitor);
375 if (fgErrorBehav[kLinkMonitor] == kTolerate)
376 size += ReadLinkData();
379 // read the data from one HC
380 size += ReadLinkData();
382 // read all data endmarkers
383 size += SeekNextLink();
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));
393 if (fDigitsManager && (checksumStack[iStack]() != fCurrChecksumStack[fCurrEquipmentId - kDDLOffset][iStack])) {
394 StackError(kCRCmismatch, "data - recalc: 0x%04x - 0x%04x", fCurrChecksumStack[fCurrEquipmentId - kDDLOffset][iStack], checksumStack[iStack]());
398 // continue with next stack
407 Bool_t AliTRDrawStream::NextDDL()
409 // continue reading with the next equipment
414 fCurrEquipmentId = 0;
418 UChar_t *buffer = 0x0;
420 while (fRawReader->ReadNextData(buffer)) {
422 fCurrEquipmentId = fRawReader->GetEquipmentId();
423 AliDebug(2, Form("equipment: %i", fCurrEquipmentId));
425 if (fCurrEquipmentId < kDDLOffset || fCurrEquipmentId > kDDLMax) {
426 EquipmentError(kNonTrdEq, "Skipping");
431 new ((*fMarkers)[fMarkers->GetEntriesFast()])
432 AliTRDrawStreamError(-kSecactive, fCurrEquipmentId - kDDLOffset);
434 ReadGTUHeaders((UInt_t*) buffer);
436 if (fCurrTrailerReadout)
446 Int_t AliTRDrawStream::NextChamber(AliTRDdigitsManager *digMgr)
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
452 fDigitsManager = digMgr;
458 AliError("No raw reader available");
462 while (fCurrSlot < 0 || fCurrSlot >= fgkNstacks) {
467 while ((fCurrSlot < fgkNstacks) &&
468 (((fCurrStackMask & (1 << fCurrSlot)) == 0) ||
469 ((fCurrLinkMask[fCurrSlot] & (1 << fCurrLink))) == 0)) {
470 if ((fCurrStackMask & (1 << fCurrSlot)) == 0) {
476 if (fCurrLink >= fgkNlinks) {
484 AliDebug(2, Form("Stack %i, Link %i, mask: 0x%02x", fCurrSlot, fCurrLink, fCurrLinkMask[fCurrSlot]));
485 fCurrHC = (fCurrEquipmentId - kDDLOffset) * fgkNlinks * fgkNstacks +
486 fCurrSlot * fgkNlinks + fCurrLink;
488 if (fCurrLinkMonitorFlags[(((fCurrEquipmentId - kDDLOffset) * fgkNstacks) + fCurrSlot) * fgkNlinks + fCurrLink] != 0) {
489 LinkError(kLinkMonitor);
490 if (fgErrorBehav[kLinkMonitor] == kTolerate)
494 // read the data from one HC
497 // read all data endmarkers
500 if (fCurrLink % 2 == 0) {
501 // if we just read the A-side HC then also check the B-side
504 if (fCurrLinkMask[fCurrSlot] & (1 << fCurrLink)) {
505 if (fCurrLinkMonitorFlags[(((fCurrEquipmentId - kDDLOffset) * fgkNstacks) + fCurrSlot) * fgkNlinks + fCurrLink] != 0) {
506 LinkError(kLinkMonitor);
507 if (fgErrorBehav[kLinkMonitor] == kTolerate)
518 if ((fCurrStackMask & (1 << fCurrSlot)) == 0) {
524 if (fCurrLink >= fgkNlinks) {
530 } while ((fCurrSlot < fgkNstacks) &&
531 (((fCurrStackMask & (1 << fCurrSlot)) == 0) ||
532 ((fCurrLinkMask[fCurrSlot] & (1 << fCurrLink))) == 0));
534 // return chamber information from HC if it is valid
535 // otherwise return information from link position
536 if (fCurrSm < 0 || fCurrSm >= fgkNsectors || fCurrStack < 0 || fCurrStack >= fgkNstacks || fCurrLayer < 0 || fCurrLayer >= fgkNlinks/2)
537 return ((fCurrEquipmentId-kDDLOffset) + fCurrSlot * fgkNlinks/2 + fCurrLink/2);
539 return (fCurrSm * fgkNstacks*fgkNlinks/2 + fCurrStack * fgkNlinks/2 + fCurrLayer);
543 Int_t AliTRDrawStream::ReadGTUHeaders(UInt_t *buffer)
545 // check the data source and read the headers
547 if (fCurrEquipmentId >= kDDLOffset && fCurrEquipmentId <= kDDLMax) {
550 // setting the pointer to data and current reading position
551 fPayloadCurr = fPayloadStart = buffer;
552 fPayloadSize = fRawReader->GetDataSize() / sizeof(UInt_t);
553 fStats.fStatsSector[fCurrEquipmentId - kDDLOffset].fBytes = fRawReader->GetDataSize();
554 AliDebug(2, Form("Read buffer of size: %i", fRawReader->GetDataSize()));
556 AliDebug(1, DumpRaw("raw data", fPayloadCurr, TMath::Min(fPayloadSize, 1000)));
559 if (ReadSmHeader() < 0) {
560 AliError(Form("Reading SM header failed, skipping this DDL %i", fCurrEquipmentId));
564 // read tracking headers (if available)
565 if (fCurrTrkHeaderAvail) {
566 for (Int_t iStack = 0; iStack < fgkNstacks; iStack++) {
567 if ((fCurrStackMask & (1 << iStack)) != 0)
568 ReadTrackingHeader(iStack);
572 // read trigger header(s) (if available)
573 if (fCurrTrgHeaderAvail)
574 ReadTriggerHeaders();
577 for (Int_t iStack = 0; iStack < fgkNstacks; iStack++) {
578 if ((fCurrStackMask & (1 << iStack)) != 0)
579 ReadStackHeader(iStack);
588 Int_t AliTRDrawStream::ReadSmHeader()
590 // read the SMU index header at the current reading position
591 // and store the information in the corresponding variables
593 if (fPayloadCurr - fPayloadStart >= fPayloadSize - 1) {
594 EquipmentError(kUnknown, "SM Header incomplete");
598 fCurrTrgFlags[fCurrEquipmentId-kDDLOffset] = 0;
600 fCurrSmHeaderSize = ((*fPayloadCurr) >> 16) & 0xffff;
601 fCurrSmHeaderVersion = ((*fPayloadCurr) >> 12) & 0xf;
602 fCurrTrackEnable = ((*fPayloadCurr) >> 6) & 0x1;
603 fCurrTrackletEnable = ((*fPayloadCurr) >> 5) & 0x1;
604 fCurrStackMask = ((*fPayloadCurr) ) & 0x1f;
605 fCurrHwRev = (fPayloadCurr[1] >> 12) & 0xffff;
606 fCurrStackEndmarkerAvail = 0;
608 switch (fCurrSmHeaderVersion) {
610 fCurrTrailerReadout = 0;
611 fCurrTrgHeaderAvail = 0;
613 fCurrTrkHeaderAvail = 0;
619 fCurrTrailerReadout = ((*fPayloadCurr) >> 10) & 0x1;
620 fCurrTrgHeaderAvail = 1;
621 fCurrTrgHeaderReadout = ((*fPayloadCurr) >> 9) & 0x1;
622 fCurrEvType = ((*fPayloadCurr) >> 7) & 0x3;
623 fCurrTrkHeaderAvail = fCurrTrackEnable;
624 fCurrTriggerEnable = (fPayloadCurr[2] >> 8) & 0xfff;
625 fCurrTriggerFired = (fPayloadCurr[2] >> 20) & 0xfff;
626 fCurrTrgFlags[fCurrEquipmentId-kDDLOffset] = fCurrTriggerFired;
630 fCurrTrailerReadout = ((*fPayloadCurr) >> 10) & 0x1;
631 fCurrTrgHeaderAvail = 1;
632 fCurrTrgHeaderReadout = ((*fPayloadCurr) >> 9) & 0x1;
633 fCurrEvType = ((*fPayloadCurr) >> 7) & 0x3;
634 fCurrTrkHeaderAvail = fCurrTrackEnable;
635 fCurrTriggerEnable = (fPayloadCurr[2] >> 8) & 0xfff;
636 fCurrTriggerFired = (fPayloadCurr[2] >> 20) & 0xfff;
637 fCurrTrgFlags[fCurrEquipmentId-kDDLOffset] = fCurrTriggerFired;
638 fCurrStackEndmarkerAvail = 1;
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];
651 AliError(Form("unknown SM header version: 0x%x", fCurrSmHeaderVersion));
654 AliDebug(5, Form("SM header: size: %i, version: %i, track enable: %i, tracklet enable: %i, stack mask: %2x, trailer: %i, trgheader: %i, trkheader: %i",
656 fCurrSmHeaderVersion,
662 fCurrTrkHeaderAvail ));
664 // jump to the first word after the SM header
665 fPayloadCurr += fCurrSmHeaderSize + 1;
667 return fCurrSmHeaderSize + 1;
670 Int_t AliTRDrawStream::DecodeGTUtracks()
672 // decode GTU track words
673 // this depends on the hardware revision of the SMU
675 Int_t sector = fCurrEquipmentId-kDDLOffset;
677 if ((sector < 0) || (sector > 17)) {
678 AliError(Form("Invalid sector %i for GTU tracks", sector));
682 AliDebug(1, DumpRaw(Form("GTU tracks in sector %2i (hw rev %i)", sector, fCurrHwRev),
683 fPayloadCurr + 4, 10, 0xffe0ffff));
685 fCurrTrgFlags[sector] = 0;
687 if (fCurrHwRev < 1772) {
688 UInt_t fastWord; // fast trigger word
689 ULong64_t trackWord = 0; // extended track word
692 for (UInt_t iWord = 4; iWord < fCurrSmHeaderSize; iWord++) {
693 if (fPayloadCurr[iWord] == 0x10000000) { // stack boundary marker
699 ((fPayloadCurr[iWord] & 0xfffff0f0) == 0x13370000)) {
700 fastWord = fPayloadCurr[iWord];
701 fCurrTrgFlags[sector] |= 1 << (stack+11); // assume tracking done if fast word sent
702 AliDebug(1, Form("stack %i: fast trigger word: 0x%08x", stack, fastWord));
705 else if ((idx & 0x1) == 0x1) {
706 trackWord |= ((ULong64_t) fPayloadCurr[iWord]) << 32;
707 AliDebug(1,Form("track debug word: 0x%016llx", trackWord));
709 AliESDTrdTrack *trk = new ((*fTracks)[fTracks->GetEntriesFast()])
712 trk->SetSector(sector);
713 trk->SetStack((trackWord >> 60) & 0x7);
717 trk->SetLayerMask((trackWord >> 16) & 0x3f);
718 trk->SetTrackletIndex((trackWord >> 22) & 0x3f, 0);
719 trk->SetTrackletIndex((trackWord >> 28) & 0x3f, 1);
720 trk->SetTrackletIndex((trackWord >> 34) & 0x3f, 2);
721 trk->SetTrackletIndex((trackWord >> 40) & 0x3f, 3);
722 trk->SetTrackletIndex((trackWord >> 46) & 0x3f, 4);
723 trk->SetTrackletIndex((trackWord >> 52) & 0x3f, 5);
729 Float_t pt = (((Int_t) (trackWord & 0xffff) ^ 0x8000) - 0x8000)/128.;
730 if (TMath::Abs(pt) > 0.1) {
731 trk->SetA((Int_t) (0.15*51625./100./pt / 160e-4 * 2));
736 trackWord = fPayloadCurr[iWord];
742 else if (fCurrHwRev < 1804) {
743 UInt_t fastWord; // fast trigger word
744 ULong64_t trackWord = 0; // extended track word
747 for (UInt_t iWord = 4; iWord < fCurrSmHeaderSize; iWord++) {
748 if (fPayloadCurr[iWord] == 0xffe0ffff) { // stack boundary marker
754 ((fPayloadCurr[iWord] & 0xfffff0f0) == 0x13370000)) {
755 fastWord = fPayloadCurr[iWord];
756 fCurrTrgFlags[sector] |= 1 << (stack+11); // assume tracking done if fast word sent
757 AliDebug(1, Form("stack %i: fast trigger word: 0x%08x", stack, fastWord));
760 else if ((idx & 0x1) == 0x1) {
761 trackWord |= ((ULong64_t) fPayloadCurr[iWord]) << 32;
762 AliDebug(1, Form("track debug word: 0x%016llx", trackWord));
764 AliESDTrdTrack *trk = new ((*fTracks)[fTracks->GetEntriesFast()])
767 trk->SetSector(fCurrEquipmentId-kDDLOffset);
768 trk->SetStack((trackWord >> 60) & 0x7);
772 trk->SetLayerMask((trackWord >> 16) & 0x3f);
773 trk->SetTrackletIndex((trackWord >> 22) & 0x3f, 0);
774 trk->SetTrackletIndex((trackWord >> 28) & 0x3f, 1);
775 trk->SetTrackletIndex((trackWord >> 34) & 0x3f, 2);
776 trk->SetTrackletIndex((trackWord >> 40) & 0x3f, 3);
777 trk->SetTrackletIndex((trackWord >> 46) & 0x3f, 4);
778 trk->SetTrackletIndex((trackWord >> 52) & 0x3f, 5);
784 Float_t pt = (((Int_t) (trackWord & 0xffff) ^ 0x8000) - 0x8000)/128.;
785 if (TMath::Abs(pt) > 0.1) {
786 trk->SetA((Int_t) (-0.15*51625./100./pt / 160e-4 * 2));
791 trackWord = fPayloadCurr[iWord];
797 else if (fCurrHwRev < 1819) {
798 UInt_t fastWord; // fast trigger word
799 ULong64_t trackWord = 0; // extended track word
802 for (UInt_t iWord = 4; iWord < fCurrSmHeaderSize; iWord++) {
803 if (fPayloadCurr[iWord] == 0xffe0ffff) { // stack boundary marker
809 ((fPayloadCurr[iWord] & 0xfffff0f0) == 0x13370000)) {
810 fastWord = fPayloadCurr[iWord];
811 if (fastWord & (1 << 13))
812 fCurrTrgFlags[sector] |= 1 << (stack+11);
813 AliDebug(1, Form("stack %i: fast trigger word: 0x%08x", stack, fastWord));
816 else if ((idx & 0x1) == 0x1) {
817 trackWord |= ((ULong64_t) fPayloadCurr[iWord]) << 32;
818 AliDebug(1, Form("track debug word: 0x%016llx", trackWord));
821 AliESDTrdTrack *trk = new ((*fTracks)[fTracks->GetEntriesFast()])
824 trk->SetSector(fCurrEquipmentId-kDDLOffset);
825 trk->SetStack((trackWord >> 60) & 0x7);
828 // trk->SetPt(((trackWord & 0xffff) ^ 0x8000) - 0x8000);
830 trk->SetLayerMask((trackWord >> 16) & 0x3f);
831 trk->SetTrackletIndex((trackWord >> 22) & 0x3f, 0);
832 trk->SetTrackletIndex((trackWord >> 28) & 0x3f, 1);
833 trk->SetTrackletIndex((trackWord >> 34) & 0x3f, 2);
834 trk->SetTrackletIndex((trackWord >> 40) & 0x3f, 3);
835 trk->SetTrackletIndex((trackWord >> 46) & 0x3f, 4);
836 trk->SetTrackletIndex((trackWord >> 52) & 0x3f, 5);
842 Float_t pt = (((Int_t) (trackWord & 0xffff) ^ 0x8000) - 0x8000)/128.;
843 if (TMath::Abs(pt) > 0.1) {
844 trk->SetA((Int_t) (0.15*51625./100./trk->Pt() / 160e-4 * 2));
849 trackWord = fPayloadCurr[iWord];
855 else if (fCurrHwRev < 1860) {
856 UInt_t fastWord; // fast trigger word
857 ULong64_t trackWord = 0; // extended track word
860 Bool_t upperWord = kFALSE;
862 for (UInt_t iWord = 4; iWord < fCurrSmHeaderSize; iWord++) {
863 if (fPayloadCurr[iWord] == 0xffe0ffff) { // stack boundary marker
869 // assemble the 32-bit words out of 16-bit blocks
871 word |= (fPayloadCurr[iWord] & 0xffff0000);
875 // lower word is read first
876 word = (fPayloadCurr[iWord] & 0xffff0000) >> 16;
881 if ((word & 0xffff0008) == 0x13370008) {
883 AliDebug(1, Form("stack %i: fast track word: 0x%08x", stack, fastWord));
884 if (fastWord & (1 << 13))
885 fCurrTrgFlags[sector] |= 1 << (stack+11);
888 else if ((idx & 0x1) == 0x1) {
889 trackWord |= ((ULong64_t) word) << 32;
890 AliDebug(1, Form("track debug word: 0x%016llx", trackWord));
892 AliESDTrdTrack *trk = new ((*fTracks)[fTracks->GetEntriesFast()])
895 trk->SetSector(fCurrEquipmentId-kDDLOffset);
896 trk->SetStack((trackWord >> 60) & 0x7);
900 trk->SetLayerMask((trackWord >> 16) & 0x3f);
901 trk->SetTrackletIndex((trackWord >> 22) & 0x3f, 0);
902 trk->SetTrackletIndex((trackWord >> 28) & 0x3f, 1);
903 trk->SetTrackletIndex((trackWord >> 34) & 0x3f, 2);
904 trk->SetTrackletIndex((trackWord >> 40) & 0x3f, 3);
905 trk->SetTrackletIndex((trackWord >> 46) & 0x3f, 4);
906 trk->SetTrackletIndex((trackWord >> 52) & 0x3f, 5);
912 Float_t pt = (((Int_t) (trackWord & 0xffff) ^ 0x8000) - 0x8000)/128.;
913 if (TMath::Abs(pt) > 0.1) {
914 trk->SetA((Int_t) (0.15*51625./100./pt / 160e-4 * 2));
927 ULong64_t trackWord = 0; // this is the debug word
930 Bool_t upperWord = kFALSE;
932 for (UInt_t iWord = 4; iWord < fCurrSmHeaderSize; iWord++) {
933 if (fPayloadCurr[iWord] == 0xffe0ffff) {
939 // assemble the 32-bit words out of 16-bit blocks
941 word |= (fPayloadCurr[iWord] & 0xffff0000);
945 // lower word is read first
946 word = (fPayloadCurr[iWord] & 0xffff0000) >> 16;
951 if ((word & 0xffff0008) == 0x13370008) {
952 AliDebug(1, Form("stack %i: fast track word: 0x%08x", stack, word));
955 else if ((word & 0xffff0010) == 0x13370010) {
956 AliDebug(1, Form("stack %i: tracking done word: 0x%08x", stack, word));
957 fCurrTrgFlags[sector] |= 1 << (stack+11);
960 else if ((idx & 0x1) == 0x1) {
961 trackWord |= ((ULong64_t) word) << 32;
962 AliDebug(1, Form("track debug word: 0x%16llx", trackWord));
964 AliESDTrdTrack *trk = new ((*fTracks)[fTracks->GetEntriesFast()])
966 trk->SetSector(fCurrEquipmentId-kDDLOffset);
967 trk->SetStack((trackWord >> 60) & 0x7);
971 trk->SetLayerMask((trackWord >> 16) & 0x3f);
972 trk->SetTrackletIndex((trackWord >> 22) & 0x3f, 0);
973 trk->SetTrackletIndex((trackWord >> 28) & 0x3f, 1);
974 trk->SetTrackletIndex((trackWord >> 34) & 0x3f, 2);
975 trk->SetTrackletIndex((trackWord >> 40) & 0x3f, 3);
976 trk->SetTrackletIndex((trackWord >> 46) & 0x3f, 4);
977 trk->SetTrackletIndex((trackWord >> 52) & 0x3f, 5);
983 Float_t pt = (((Int_t) (trackWord & 0xffff) ^ 0x8000) - 0x8000)/128.;
984 if (TMath::Abs(pt) > 0.1) {
985 trk->SetA(-(Int_t) (0.15*51625./100./pt / 160e-4 * 2));
999 Int_t AliTRDrawStream::ReadTrackingHeader(Int_t stack)
1001 // read the tracking information and store it for the given stack
1005 fCurrTrkHeaderIndexWord[stack] = *fPayloadCurr;
1006 fCurrTrkHeaderSize[stack] = ((*fPayloadCurr) >> 16) & 0x3ff;
1008 AliDebug(1, Form("tracking header index word: 0x%08x, size: %i (hw rev: %i)",
1009 fCurrTrkHeaderIndexWord[stack], fCurrTrkHeaderSize[stack], fCurrHwRev));
1010 Int_t trackingTime = *fPayloadCurr & 0x3ff;
1012 fCurrTrgFlags[fCurrEquipmentId-kDDLOffset] |= ((fCurrTrkHeaderIndexWord[stack] >> 10) & 0x1) << (22 + stack);
1016 ULong64_t trackWord = 0;
1018 Int_t trackIndex = fTracks ? fTracks->GetEntriesFast() : -1;
1020 for (UInt_t iWord = 0; iWord < fCurrTrkHeaderSize[stack]; iWord++) {
1023 // first part of 64-bit word
1024 trackWord = fPayloadCurr[iWord];
1027 trackWord |= ((ULong64_t) fPayloadCurr[iWord]) << 32;
1029 if (trackWord & (1ul << 63)) {
1030 if ((trackWord & (0x3ful << 56)) != 0) {
1032 AliDebug(2, Form("track word: 0x%016llx", trackWord));
1035 AliESDTrdTrack *trk = new ((*fTracks)[fTracks->GetEntriesFast()])
1038 trk->SetSector(fCurrEquipmentId-kDDLOffset);
1039 trk->SetLayerMask((trackWord >> 56) & 0x3f);
1040 trk->SetA( (((trackWord >> 38) & 0x3ffff) ^ 0x20000) - 0x20000);
1041 trk->SetB( (((trackWord >> 20) & 0x3ffff) ^ 0x20000) - 0x20000);
1042 trk->SetC( (((trackWord >> 8) & 0xffff) ^ 0x8000) - 0x8000);
1043 trk->SetPID((trackWord >> 0) & 0xff);
1044 trk->SetStack(stack);
1047 // now compare the track word with the one generated from the ESD information
1048 if (trackWord != trk->GetTrackWord(0)) {
1049 AliError(Form("track word 0x%016llx does not match the read one 0x%016llx",
1050 trk->GetTrackWord(0), trackWord));
1055 // done marker (so far only used to set trigger flag)
1056 fCurrTrgFlags[fCurrEquipmentId-kDDLOffset] |= 1 << (27 + stack);
1057 fCurrTrkFlags[(fCurrEquipmentId-kDDLOffset)*fgkNstacks + stack] = trackWord;
1059 AliDebug(2, Form("tracking done marker: 0x%016llx, trigger flags: 0x%08x",
1060 trackWord, fCurrTrgFlags[fCurrEquipmentId-kDDLOffset]));
1061 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,
1070 // extended track word
1071 AliDebug(2, Form("extended track word: 0x%016llx", trackWord));
1074 AliESDTrdTrack *trk = (AliESDTrdTrack*) (*fTracks)[trackIndex];
1076 trk->SetFlags((trackWord >> 52) & 0x7ff);
1077 trk->SetFlagsTiming((trackWord >> 51) & 0x1);
1078 trk->SetReserved((trackWord >> 49) & 0x3);
1079 trk->SetY((trackWord >> 36) & 0x1fff);
1080 trk->SetTrackletIndex((trackWord >> 0) & 0x3f, 0);
1081 trk->SetTrackletIndex((trackWord >> 6) & 0x3f, 1);
1082 trk->SetTrackletIndex((trackWord >> 12) & 0x3f, 2);
1083 trk->SetTrackletIndex((trackWord >> 18) & 0x3f, 3);
1084 trk->SetTrackletIndex((trackWord >> 24) & 0x3f, 4);
1085 trk->SetTrackletIndex((trackWord >> 30) & 0x3f, 5);
1087 if (trk->GetFlagsTiming() == 0) {
1088 AliError(Form("*** track not in time: 0x%016llx", trk->GetExtendedTrackWord(0)));
1091 if (trackWord != trk->GetExtendedTrackWord(0)) {
1092 AliError(Form("extended track word 0x%016llx does not match the read one 0x%016llx",
1093 trk->GetExtendedTrackWord(0), trackWord));
1103 fPayloadCurr += fCurrTrkHeaderSize[stack];
1105 return fCurrTrkHeaderSize[stack];
1108 Int_t AliTRDrawStream::ReadTriggerHeaders()
1110 // read all trigger headers present
1112 AliDebug(1, Form("trigger mask: 0x%03x, fired: 0x%03x\n",
1113 fCurrTriggerEnable, fCurrTriggerFired));
1114 // loop over potential trigger blocks
1115 for (Int_t iTrigger = 0; iTrigger < fgkNtriggers; iTrigger++) {
1116 // check for trigger enable
1117 if (fCurrTriggerEnable & (1 << iTrigger)) {
1118 // check for readout mode and trigger fired
1119 if ((fCurrTrgHeaderReadout == 0) || (fCurrTriggerFired & (1 << iTrigger))) {
1121 AliDebug(1, Form("trigger index word %i: 0x%08x\n", iTrigger, *fPayloadCurr));
1122 fCurrTrgHeaderIndexWord[iTrigger] = *fPayloadCurr;
1123 fCurrTrgHeaderSize[iTrigger] = ((*fPayloadCurr) >> 16) & 0x3ff;
1124 if (iTrigger == 7) {
1125 // timeout trigger, use to extract tracking time
1126 fCurrTrgFlags[fCurrEquipmentId-kDDLOffset] |= (*fPayloadCurr & 0x3ff) << 12;
1131 fPayloadCurr += fCurrTrgHeaderSize[iTrigger];
1139 Int_t AliTRDrawStream::ReadStackHeader(Int_t stack)
1141 // read the stack header
1142 // and store the information in the corresponding variables
1144 fCurrStackIndexWord[stack] = *fPayloadCurr;
1145 fCurrStackHeaderSize[stack] = (((*fPayloadCurr) >> 16) & 0xffff) + 1;
1146 fCurrStackHeaderVersion[stack] = ((*fPayloadCurr) >> 12) & 0xf;
1147 fCurrLinkMask[stack] = (*fPayloadCurr) & 0xfff;
1149 // dumping stack header
1150 AliDebug(1, DumpRaw(Form("stack %i header", stack), fPayloadCurr, fCurrStackHeaderSize[stack]));
1152 if (fPayloadCurr - fPayloadStart >= fPayloadSize - (Int_t) fCurrStackHeaderSize[stack]) {
1153 EquipmentError(kStackHeaderInvalid, "Stack index header %i incomplete", stack);
1154 // dumping stack header
1155 AliError(DumpRaw(Form("stack %i header", stack), fPayloadCurr, fCurrStackHeaderSize[stack]));
1160 switch (fCurrStackHeaderVersion[stack]) {
1163 if (fCurrStackHeaderSize[stack] < 8) {
1164 LinkError(kStackHeaderInvalid, "Stack header smaller than expected!");
1168 fCurrCleanCheckout[stack] = fPayloadCurr[1] & 0x1;
1169 fCurrBoardId[stack] = (fPayloadCurr[1] >> 8) & 0xff;
1170 fCurrHwRevTMU[stack] = (fPayloadCurr[1] >> 16) & 0xffff;
1172 for (Int_t iLayer = 0; iLayer < 6; iLayer++) {
1174 fCurrLinkMonitorFlags [((fCurrEquipmentId - kDDLOffset) * fgkNstacks + stack) *fgkNlinks + iLayer*2] = fPayloadCurr[iLayer+2] & 0xf;
1175 fCurrLinkDataTypeFlags [stack * fgkNlinks + iLayer*2] = (fPayloadCurr[iLayer+2] >> 4) & 0x3;
1176 fCurrLinkDebugFlags [stack * fgkNlinks + iLayer*2] = (fPayloadCurr[iLayer+2] >> 12) & 0xf;
1178 fCurrLinkMonitorFlags [((fCurrEquipmentId - kDDLOffset) * fgkNstacks + stack) *fgkNlinks + iLayer*2 + 1] = (fPayloadCurr[iLayer+2] >> 16) & 0xf;
1179 fCurrLinkDataTypeFlags [stack * fgkNlinks + iLayer*2 + 1] = (fPayloadCurr[iLayer+2] >> 20) & 0x3;
1180 fCurrLinkDebugFlags [stack * fgkNlinks + iLayer*2 + 1] = (fPayloadCurr[iLayer+2] >> 28) & 0xf;
1185 EquipmentError(kStackHeaderInvalid, "Invalid Stack Header version %x", fCurrStackHeaderVersion[stack]);
1188 fPayloadCurr += fCurrStackHeaderSize[stack];
1190 return fCurrStackHeaderSize[stack];
1193 Int_t AliTRDrawStream::ReadGTUTrailer()
1195 // read the SM trailer containing CRCs from various stages
1197 UInt_t* trailer = fPayloadStart + fPayloadSize -1;
1199 // look for the trailer index word from the end
1200 for (Int_t iWord = 0; iWord < fPayloadSize-2; iWord++) {
1201 if ((fPayloadStart[fPayloadSize-3-iWord] == fgkStackEndmarker[0]) &&
1202 (fPayloadStart[fPayloadSize-2-iWord] == fgkStackEndmarker[1]) &&
1203 ((fPayloadStart[fPayloadSize-1-iWord] & 0xfff) == 0xf51)) {
1204 trailer = fPayloadStart + fPayloadSize - 1 - iWord;
1209 if (((*trailer) & 0xfff) == 0xf51) {
1210 UInt_t trailerIndexWord = (*trailer);
1211 Int_t trailerSize = (trailerIndexWord >> 16) & 0xffff;
1212 // Int_t trailerVersion = (trailerIndexWord >> 12) & 0xf;
1213 AliDebug(2, DumpRaw("GTU trailer", trailer, trailerSize+1));
1214 // parse the trailer
1215 if (trailerSize >= 4) {
1216 // match flags from GTU
1217 fCurrMatchFlagsSRAM[fCurrEquipmentId-kDDLOffset] = (trailer[1] >> 0) & 0x1f;
1218 fCurrMatchFlagsPostBP[fCurrEquipmentId-kDDLOffset] = (trailer[1] >> 5) & 0x1f;
1219 // individual checksums
1220 fCurrChecksumStack[fCurrEquipmentId - kDDLOffset][0] = (trailer[1] >> 16) & 0xffff;
1221 fCurrChecksumStack[fCurrEquipmentId - kDDLOffset][1] = (trailer[2] >> 0) & 0xffff;
1222 fCurrChecksumStack[fCurrEquipmentId - kDDLOffset][2] = (trailer[2] >> 16) & 0xffff;
1223 fCurrChecksumStack[fCurrEquipmentId - kDDLOffset][3] = (trailer[3] >> 0) & 0xffff;
1224 fCurrChecksumStack[fCurrEquipmentId - kDDLOffset][4] = (trailer[3] >> 16) & 0xffff;
1225 fCurrChecksumSIU = trailer[trailerSize];
1227 if ((fCurrMatchFlagsSRAM[fCurrEquipmentId-kDDLOffset] & fCurrStackMask) != fCurrStackMask)
1228 EquipmentError(kCRCmismatch, "CRC mismatch SRAM: 0x%02x", fCurrMatchFlagsSRAM[fCurrEquipmentId-kDDLOffset]);
1229 if ((fCurrMatchFlagsPostBP[fCurrEquipmentId-kDDLOffset] & fCurrStackMask) != fCurrStackMask)
1230 EquipmentError(kCRCmismatch, "CRC mismatch BP: 0x%02x", fCurrMatchFlagsPostBP[fCurrEquipmentId-kDDLOffset]);
1234 LinkError(kUnknown, "Invalid GTU trailer");
1238 EquipmentError(kUnknown, "trailer index marker mismatch");
1243 Int_t AliTRDrawStream::ReadLinkData()
1245 // read the data in one link (one HC) until the data endmarker is reached
1246 // returns the number of words read!
1249 UInt_t* startPosLink = fPayloadCurr;
1251 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));
1255 new ((*fMarkers)[fMarkers->GetEntriesFast()])
1256 AliTRDrawStreamError(-kHCactive, fCurrEquipmentId-kDDLOffset, fCurrSlot, fCurrLink);
1258 if (fErrorFlags & kDiscardHC)
1261 if (fCurrTrackletEnable) {
1262 count += ReadTracklets();
1263 if (fErrorFlags & kDiscardHC)
1267 AliDebug(1, DumpRaw("HC header", fPayloadCurr, 4, 0x00000000));
1268 count += ReadHcHeader();
1269 if (fErrorFlags & kDiscardHC)
1272 Int_t det = fCurrSm * 30 + fCurrStack * 6 + fCurrLayer;
1274 if (det > -1 && det < 540) {
1276 // ----- check which kind of data -----
1277 if (fCurrMajor & 0x40) {
1278 if ((fCurrMajor & 0x7) == 0x7) {
1279 AliDebug(1, "This is a config event");
1280 UInt_t *startPos = fPayloadCurr;
1281 while (fPayloadCurr - fPayloadStart < fPayloadSize &&
1282 *fPayloadCurr != fgkDataEndmarker)
1284 count += fPayloadCurr - startPos;
1286 // feeding TRAP config
1287 AliTRDtrapConfig *trapcfg = AliTRDcalibDB::Instance()->GetTrapConfig();
1288 AliTRDmcmSim::ReadPackedConfig(trapcfg, fCurrHC, startPos, fPayloadCurr - startPos);
1291 Int_t tpmode = fCurrMajor & 0x7;
1292 AliDebug(1, Form("Checking testpattern (mode %i) data", tpmode));
1293 count += ReadTPData(tpmode);
1297 // reading real data
1298 if (fDigitsManager) {
1299 if ((fAdcArray = fDigitsManager->GetDigits(det))) {
1300 //fAdcArray->Expand();
1301 if (fAdcArray->GetNtime() != fCurrNtimebins)
1302 fAdcArray->Allocate(16, 144, fCurrNtimebins);
1305 LinkError(kNoDigits);
1308 if (!fDigitsParam) {
1309 fDigitsParam = fDigitsManager->GetDigitsParam();
1312 fDigitsParam->SetPretriggerPhase(det, fCurrPtrgPhase);
1313 fDigitsParam->SetNTimeBins(det, fCurrNtimebins);
1314 fDigitsParam->SetADCbaseline(det, 10);
1317 if (fDigitsManager->UsesDictionaries()) {
1318 fDigitsManager->GetDictionary(det, 0)->Reset();
1319 fDigitsManager->GetDictionary(det, 1)->Reset();
1320 fDigitsManager->GetDictionary(det, 2)->Reset();
1323 if ((fSignalIndex = fDigitsManager->GetIndexes(det))) {
1324 fSignalIndex->SetSM(fCurrSm);
1325 fSignalIndex->SetStack(fCurrStack);
1326 fSignalIndex->SetLayer(fCurrLayer);
1327 fSignalIndex->SetDetNumber(det);
1328 if (!fSignalIndex->IsAllocated())
1329 fSignalIndex->Allocate(16, 144, fCurrNtimebins);
1332 if (fCurrMajor & 0x20) {
1333 AliDebug(1, "This is a zs event");
1334 count += ReadZSData();
1337 AliDebug(1, "This is a nozs event");
1338 count += ReadNonZSData();
1342 // just read until data endmarkers
1343 while (fPayloadCurr - fPayloadStart < fPayloadSize &&
1344 *fPayloadCurr != fgkDataEndmarker)
1350 LinkError(kInvalidDetector, "%i", det);
1351 while (fPayloadCurr - fPayloadStart < fPayloadSize &&
1352 *fPayloadCurr != fgkDataEndmarker)
1356 if (fCurrSm > -1 && fCurrSm < 18) {
1357 fStats.fStatsSector[fCurrSm].fStatsHC[fCurrHC%60].fBytes += (fPayloadCurr - startPosLink) * sizeof(UInt_t);
1358 fStats.fStatsSector[fCurrSm].fStatsHC[fCurrHC%60].fBytesRead += count * sizeof(UInt_t);
1359 fStats.fStatsSector[fCurrSm].fBytesRead += count * sizeof(UInt_t);
1360 fStats.fBytesRead += count * sizeof(UInt_t);
1363 if ((fErrorFlags & kDiscardHC) && fAdcArray)
1364 fAdcArray->SetDataInvalid(); // invalidate the data
1369 Int_t AliTRDrawStream::ReadTracklets()
1371 // read the tracklets from one HC
1373 Int_t nTracklets = 0;
1375 UInt_t *start = fPayloadCurr;
1376 while (*(fPayloadCurr) != fgkTrackletEndmarker &&
1377 *(fPayloadCurr) != fgkStackEndmarker[0] &&
1378 *(fPayloadCurr) != fgkStackEndmarker[1] &&
1379 fPayloadCurr - fPayloadStart < (fPayloadSize - 1)) {
1382 new ((*fTracklets)[fTracklets->GetEntriesFast()]) AliTRDtrackletWord(*(fPayloadCurr), fCurrHC);
1387 if (nTracklets > 0) {
1388 AliDebug(1, Form("Found %i tracklets in %i %i %i (ev. %i)", nTracklets,
1389 (fCurrEquipmentId-kDDLOffset), fCurrSlot, fCurrLink, fRawReader->GetEventIndex()));
1390 if (fCurrSm > -1 && fCurrSm < 18) {
1391 fStats.fStatsSector[fCurrSm].fStatsHC[fCurrHC%60].fNTracklets += nTracklets;
1392 fStats.fStatsSector[fCurrSm].fNTracklets += nTracklets;
1396 // loop over remaining tracklet endmarkers
1397 while ((*(fPayloadCurr) == fgkTrackletEndmarker &&
1398 fPayloadCurr - fPayloadStart < fPayloadSize))
1401 return fPayloadCurr - start;
1404 Int_t AliTRDrawStream::ReadHcHeader()
1406 // read and parse the HC header of one HC
1407 // and store the information in the corresponding variables
1409 AliDebug(1, Form("HC header: 0x%08x", *fPayloadCurr));
1410 UInt_t *start = fPayloadCurr;
1411 // check not to be at the data endmarker
1412 if (*fPayloadCurr == fgkDataEndmarker ||
1413 *(fPayloadCurr) == fgkStackEndmarker[0] ||
1414 *(fPayloadCurr) == fgkStackEndmarker[1]) {
1415 LinkError(kHCmismatch, "found endmarker where HC header should be");
1419 fCurrSpecial = (*fPayloadCurr >> 31) & 0x1;
1420 fCurrMajor = (*fPayloadCurr >> 24) & 0x7f;
1421 fCurrMinor = (*fPayloadCurr >> 17) & 0x7f;
1422 fCurrAddHcWords = (*fPayloadCurr >> 14) & 0x7;
1423 fCurrSm = (*fPayloadCurr >> 9) & 0x1f;
1424 fCurrLayer = (*fPayloadCurr >> 6) & 0x7;
1425 fCurrStack = (*fPayloadCurr >> 3) & 0x7;
1426 fCurrSide = (*fPayloadCurr >> 2) & 0x1;
1427 fCurrCheck = (*fPayloadCurr) & 0x3;
1429 if ((fCurrSm != (((Int_t) fCurrEquipmentId) - kDDLOffset)) ||
1430 (fCurrStack != fCurrSlot) ||
1431 (fCurrLayer != fCurrLink / 2) ||
1432 (fCurrSide != fCurrLink % 2)) {
1433 LinkError(kHCmismatch,
1434 "HC: %i, %i, %i, %i\n 0x%08x 0x%08x 0x%08x 0x%08x",
1435 fCurrSm, fCurrStack, fCurrLayer, fCurrSide,
1436 fPayloadCurr[0], fPayloadCurr[1], fPayloadCurr[2], fPayloadCurr[3]);
1438 if (fCurrCheck != 0x1) {
1439 LinkError(kHCcheckFailed);
1442 if (fCurrAddHcWords > 0) {
1443 fCurrNtimebins = (fPayloadCurr[1] >> 26) & 0x3f;
1444 #ifdef TRD_RAW_DEBUG
1445 fCurrBC[fCurrHC] = (fPayloadCurr[1] >> 10) & 0xffff;
1447 fCurrPtrgCnt = (fPayloadCurr[1] >> 6) & 0xf;
1448 fCurrPtrgPhase = (fPayloadCurr[1] >> 2) & 0xf;
1451 fPayloadCurr += 1 + fCurrAddHcWords;
1453 return (fPayloadCurr - start);
1456 Int_t AliTRDrawStream::ReadTPData(Int_t mode)
1458 // testing of testpattern 1 to 3 (hardcoded), 0 missing
1459 // evcnt checking missing
1461 Int_t cpufromchannel[] = {0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3};
1465 Int_t mcmcount = -1;
1466 Int_t wordcount = 0;
1467 Int_t channelcount = 0;
1469 UInt_t expadcval = 0;
1471 Int_t lastmcmpos = -1;
1472 Int_t lastrobpos = -1;
1474 UInt_t* start = fPayloadCurr;
1476 while (*(fPayloadCurr) != fgkDataEndmarker &&
1477 fPayloadCurr - fPayloadStart < fPayloadSize - 1) {
1479 // ----- Checking MCM Header -----
1480 AliDebug(2, DumpMcmHeader("MCM header: ", *fPayloadCurr));
1481 UInt_t *startPosMCM = fPayloadCurr;
1484 // ----- checking for proper readout order - ROB -----
1485 fCurrRobPos = ROB(*fPayloadCurr);
1486 if (GetROBReadoutPos(ROB(*fPayloadCurr) / 2) >= lastrobpos) {
1487 if (GetROBReadoutPos(ROB(*fPayloadCurr) / 2) > lastrobpos)
1489 lastrobpos = GetROBReadoutPos(ROB(*fPayloadCurr) / 2);
1492 ROBError(kPosUnexp, Form("#%i after #%i in readout order", GetROBReadoutPos(ROB(*fPayloadCurr) / 2), lastrobpos));
1495 // ----- checking for proper readout order - MCM -----
1496 fCurrMcmPos = MCM(*fPayloadCurr);
1497 if (GetMCMReadoutPos(MCM(*fPayloadCurr)) > lastmcmpos) {
1498 lastmcmpos = GetMCMReadoutPos(MCM(*fPayloadCurr));
1501 MCMError(kPosUnexp, Form("#%i after #%i in readout order", GetMCMReadoutPos(MCM(*fPayloadCurr)), lastmcmpos));
1504 if (EvNo(*fPayloadCurr) != (evno & 0xfffff)) {
1506 evno = EvNo(*fPayloadCurr);
1509 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];
1524 evcnt = 0x3f & *fPayloadCurr >> 26;
1527 while (channelcount < 21) {
1529 if (cpu != cpufromchannel[channelcount]) {
1530 cpu = cpufromchannel[channelcount];
1531 expadcval = (1 << 9) | (fCurrRobPos << 6) | (fCurrMcmPos << 2) | cpu;
1535 while (count < 10) {
1536 if (*fPayloadCurr == fgkDataEndmarker) {
1537 MCMError(kMissTpData);
1538 return (fPayloadCurr - start);
1541 if (channelcount % 2 == 0)
1548 expword |= expadcval << 2;
1549 expadcval = ( (expadcval << 1) | ( ( (expadcval >> 9) ^ (expadcval >> 6) ) & 1) ) & 0x3FF;
1550 expword |= expadcval << 12;
1551 expadcval = ( (expadcval << 1) | ( ( (expadcval >> 9) ^ (expadcval >> 6) ) & 1) ) & 0x3FF;
1552 expword |= expadcval << 22;
1553 expadcval = ( (expadcval << 1) | ( ( (expadcval >> 9) ^ (expadcval >> 6) ) & 1) ) & 0x3FF;
1555 else if (mode == 2) {
1556 // ----- TP 2 ------
1557 expword = ((0x3f & evcnt) << 26) | ((fCurrSm + 1) << 21) | ((fCurrLayer + 1) << 18) |
1558 ((fCurrStack + 1) << 15) |
1559 (fCurrRobPos << 12) | (fCurrMcmPos << 8) | (cpu << 6) | (wordcount + 1);
1561 else if (mode == 3) {
1563 expword = ((0xfff & evcnt) << 20) | (fCurrSm << 15) | (fCurrLink/2 << 12) | (fCurrStack << 9) |
1564 (fCurrRobPos << 6) | (fCurrMcmPos << 2) | (cpu << 0);
1568 LinkError(kTPmodeInvalid, "Just reading");
1571 diff = *fPayloadCurr ^ expword;
1572 AliDebug(11, Form("Comparing ch %2i, word %2i (cpu %i): 0x%08x <-> 0x%08x",
1573 channelcount, wordcount, cpu, *fPayloadCurr, expword));
1576 MCMError(kTPmismatch,
1577 "Seen 0x%08x, expected 0x%08x, diff: 0x%08x, 0x%04x, 0x%02x - word %2i (cpu %i, ch %i)",
1578 *fPayloadCurr, expword, diff,
1579 0xffff & (diff | diff >> 16),
1580 0xff & (diff | diff >> 8 | diff >> 16 | diff >> 24),
1581 wordcount, cpu, channelcount);;
1586 if (*fPayloadCurr == fgkDataEndmarker)
1587 return (fPayloadCurr - start);
1591 // continue with next MCM
1593 if (IsDumping() && DumpingMCM(fCurrHC/2, fCurrRobPos, fCurrMcmPos)) {
1594 AliInfo(DumpRaw(Form("Event %i: Det %3i ROB %i MCM %2i", fRawReader->GetEventIndex(), fCurrHC/2, fCurrRobPos, fCurrMcmPos),
1595 startPosMCM, fPayloadCurr - startPosMCM));
1599 return fPayloadCurr - start;
1603 Int_t AliTRDrawStream::ReadZSData()
1605 // read the zs data from one link from the current reading position
1607 UInt_t *start = fPayloadCurr;
1610 Int_t mcmcountExp = fCurrStack == 2 ? 48 : 64;
1611 Int_t channelcount = 0;
1612 Int_t channelcountExp = 0;
1613 Int_t channelcountMax = 0;
1615 Int_t currentTimebin = 0;
1618 Int_t lastmcmpos = -1;
1619 Int_t lastrobpos = -1;
1621 if (fCurrNtimebins != fNtimebins) {
1623 LinkError(kNtimebinsChanged,
1624 "No. of timebins changed from %i to %i", fNtimebins, fCurrNtimebins);
1625 fNtimebins = fCurrNtimebins;
1628 timebins = fNtimebins;
1630 while (*(fPayloadCurr) != fgkDataEndmarker &&
1631 *(fPayloadCurr) != fgkStackEndmarker[0] &&
1632 *(fPayloadCurr) != fgkStackEndmarker[1] &&
1633 fPayloadCurr - fPayloadStart < fPayloadSize) {
1635 // ----- Checking MCM Header -----
1636 AliDebug(2, DumpMcmHeader("MCM header: ", *fPayloadCurr));
1637 UInt_t *startPosMCM = fPayloadCurr;
1639 // ----- checking for proper readout order - ROB -----
1640 fCurrRobPos = ROB(*fPayloadCurr);
1641 if (GetROBReadoutPos(ROB(*fPayloadCurr) / 2) >= lastrobpos) {
1642 if (GetROBReadoutPos(ROB(*fPayloadCurr) / 2) > lastrobpos)
1644 lastrobpos = GetROBReadoutPos(ROB(*fPayloadCurr) / 2);
1647 ROBError(kPosUnexp, Form("#%i after #%i and #%i in readout order",
1648 GetROBReadoutPos(ROB(*fPayloadCurr) / 2), lastrobpos, GetROBReadoutPos(fCurrRobPos)));
1651 // ----- checking for proper readout order - MCM -----
1652 fCurrMcmPos = MCM(*fPayloadCurr);
1653 if (GetMCMReadoutPos(MCM(*fPayloadCurr)) > lastmcmpos) {
1654 lastmcmpos = GetMCMReadoutPos(MCM(*fPayloadCurr));
1657 MCMError(kPosUnexp, Form("#%i after #%i and #%i in readout order",
1658 GetMCMReadoutPos(MCM(*fPayloadCurr)), lastmcmpos, GetMCMReadoutPos(fCurrMcmPos)));
1661 #ifdef TRD_RAW_DEBUG
1662 if (fCurrL0Count[fCurrEquipmentId-kDDLOffset] > 0) {
1663 evno = fCurrL0Count[fCurrEquipmentId-kDDLOffset] + fCurrL0offset[fCurrHC/2];
1665 fCurrEvCount[fCurrEquipmentId-kDDLOffset] = EvNo(*fPayloadCurr);
1668 if (EvNo(*fPayloadCurr) != (evno & 0xfffff)) {
1670 evno = EvNo(*fPayloadCurr);
1673 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,
1684 fCurrL0offset[fCurrHC/2],
1685 fCurrL0Count[fCurrEquipmentId-kDDLOffset],
1686 EvNo(*fPayloadCurr));
1690 Int_t adccoloff = AdcColOffset(*fPayloadCurr);
1691 Int_t padcoloff = PadColOffset(*fPayloadCurr);
1692 Int_t row = Row(*fPayloadCurr);
1695 if ((row > 11) && (fCurrStack == 2)) {
1696 MCMError(kInvalidPadRow, "Data in padrow > 11 for stack 2");
1699 if (fErrorFlags & (kDiscardHC | kDiscardDDL))
1702 // ----- Reading ADC channels -----
1703 AliDebug(2, DumpAdcMask("ADC mask: ", *fPayloadCurr));
1705 // ----- analysing the ADC mask -----
1707 channelcountExp = GetNActiveChannelsFromMask(*fPayloadCurr);
1708 channelcountMax = GetNActiveChannels(*fPayloadCurr);
1709 Int_t channelmask = GetActiveChannels(*fPayloadCurr);
1710 Int_t channelno = -1;
1713 if (channelcountExp != channelcountMax) {
1714 if (channelcountExp > channelcountMax) {
1715 Int_t temp = channelcountExp;
1716 channelcountExp = channelcountMax;
1717 channelcountMax = temp;
1719 while (channelcountExp < channelcountMax && channelcountExp < 21 &&
1720 fPayloadCurr - fPayloadStart < fPayloadSize - 10 * channelcountExp - 1) {
1721 MCMError(kAdcMaskInconsistent,
1722 "Possible MCM-H: 0x%08x, possible ADC-mask: 0x%08x",
1723 *(fPayloadCurr + 10 * channelcountExp),
1724 *(fPayloadCurr + 10 * channelcountExp + 1) );
1725 if (!CouldBeMCMhdr( *(fPayloadCurr + 10 * channelcountExp)) && !CouldBeADCmask( *(fPayloadCurr + 10 * channelcountExp + 1)))
1731 MCMError(kAdcMaskInconsistent,
1732 "Inconsistency in no. of active channels: Counter: %i, Mask: %i, chosen: %i!",
1733 GetNActiveChannels(fPayloadCurr[-1]), GetNActiveChannelsFromMask(fPayloadCurr[-1]), channelcountExp);
1735 AliDebug(2, Form("expecting %i active channels, %i timebins", channelcountExp, fCurrNtimebins));
1737 // ----- reading marked ADC channels -----
1738 while (channelcount < channelcountExp && *(fPayloadCurr) != fgkDataEndmarker) {
1741 while (channelno < 20 && (channelmask & 1 << channelno) == 0)
1744 if (fCurrNtimebins > 30) {
1745 currentTimebin = ((*fPayloadCurr >> 2) & 0x3f);
1746 timebins = ((*fPayloadCurr >> 8) & 0xf) * 3;
1753 Int_t nADCwords = (timebins + 2) / 3;
1754 AliDebug(3, Form("Now reading %i words for channel %2i", nADCwords, channelno));
1755 Int_t adccol = adccoloff - channelno;
1756 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));
1761 while ((adcwc < nADCwords) &&
1762 (*(fPayloadCurr) != fgkDataEndmarker) &&
1763 (fPayloadCurr - fPayloadStart < fPayloadSize)) {
1764 int check = 0x3 & *fPayloadCurr;
1765 if (channelno % 2 != 0) { // odd channel
1766 if (check != 0x2 && channelno < 21) {
1767 MCMError(kAdcCheckInvalid,
1768 "%i for %2i. ADC word in odd channel %i",
1769 check, adcwc+1, channelno);
1772 else { // even channel
1773 if (check != 0x3 && channelno < 21) {
1774 MCMError(kAdcCheckInvalid,
1775 "%i for %2i. ADC word in even channel %i",
1776 check, adcwc+1, channelno);
1780 if ((fErrorFlags & kDiscardMCM) == 0) {
1781 // filling the actual timebin data
1782 int tb2 = 0x3ff & (*fPayloadCurr >> 22);
1783 int tb1 = 0x3ff & (*fPayloadCurr >> 12);
1784 int tb0 = 0x3ff & (*fPayloadCurr >> 2);
1785 if (adcwc != 0 || fCurrNtimebins <= 30)
1786 fAdcArray->SetDataByAdcCol(row, adccol, currentTimebin++, tb0);
1789 if (currentTimebin < fCurrNtimebins)
1790 fAdcArray->SetDataByAdcCol(row, adccol, currentTimebin++, tb1);
1791 if (currentTimebin < fCurrNtimebins)
1792 fAdcArray->SetDataByAdcCol(row, adccol, currentTimebin++, tb2);
1799 if (adcwc != nADCwords)
1800 MCMError(kAdcDataAbort);
1803 if (padcol > 0 && padcol < 144) {
1804 fSignalIndex->AddIndexRC(row, padcol);
1810 if (fCurrSm > -1 && fCurrSm < 18) {
1811 fStats.fStatsSector[fCurrSm].fStatsHC[fCurrHC%60].fNChannels += channelcount;
1812 fStats.fStatsSector[fCurrSm].fNChannels += channelcount;
1814 if (channelcount != channelcountExp)
1815 MCMError(kAdcChannelsMiss);
1818 if (fCurrSm > -1 && fCurrSm < 18) {
1819 fStats.fStatsSector[fCurrSm].fStatsHC[fCurrHC%60].fNMCMs++;
1820 fStats.fStatsSector[fCurrSm].fNMCMs++;
1823 if (IsDumping() && DumpingMCM(fCurrHC/2, fCurrRobPos, fCurrMcmPos)) {
1824 AliInfo(DumpRaw(Form("Event %i: Det %3i ROB %i MCM %2i", fRawReader->GetEventIndex(), fCurrHC/2, fCurrRobPos, fCurrMcmPos),
1825 startPosMCM, fPayloadCurr - startPosMCM));
1828 // continue with next MCM
1831 // check for missing MCMs (if header suppression is inactive)
1832 if (((fCurrMajor & 0x1) == 0) && (mcmcount != mcmcountExp)) {
1833 LinkError(kMissMcmHeaders,
1834 "No. of MCM headers %i not as expected: %i",
1835 mcmcount, mcmcountExp);
1838 return (fPayloadCurr - start);
1841 Int_t AliTRDrawStream::ReadNonZSData()
1843 // read the non-zs data from one link from the current reading position
1845 UInt_t *start = fPayloadCurr;
1848 Int_t mcmcountExp = fCurrStack == 2 ? 48 : 64;
1849 Int_t channelcount = 0;
1850 Int_t channelcountExp = 0;
1852 Int_t currentTimebin = 0;
1855 Int_t lastmcmpos = -1;
1856 Int_t lastrobpos = -1;
1858 if (fCurrNtimebins != fNtimebins) {
1860 LinkError(kNtimebinsChanged,
1861 "No. of timebins changed from %i to %i", fNtimebins, fCurrNtimebins);
1862 fNtimebins = fCurrNtimebins;
1865 timebins = fNtimebins;
1867 while (*(fPayloadCurr) != fgkDataEndmarker &&
1868 fPayloadCurr - fPayloadStart < fPayloadSize - 2) {
1870 // ----- Checking MCM Header -----
1871 AliDebug(2, Form("MCM header: 0x%08x", *fPayloadCurr));
1873 // ----- checking for proper readout order - ROB -----
1874 fCurrRobPos = ROB(*fPayloadCurr);
1875 if (GetROBReadoutPos(ROB(*fPayloadCurr) / 2) >= lastrobpos) {
1876 if (GetROBReadoutPos(ROB(*fPayloadCurr) / 2) > lastrobpos)
1878 lastrobpos = GetROBReadoutPos(ROB(*fPayloadCurr) / 2);
1881 ROBError(kPosUnexp, Form("#%i after #%i in readout order", GetROBReadoutPos(ROB(*fPayloadCurr) / 2), lastrobpos));
1884 // ----- checking for proper readout order - MCM -----
1885 fCurrMcmPos = MCM(*fPayloadCurr);
1886 if (GetMCMReadoutPos(MCM(*fPayloadCurr)) > lastmcmpos) {
1887 lastmcmpos = GetMCMReadoutPos(MCM(*fPayloadCurr));
1890 MCMError(kPosUnexp, Form("#%i after #%i in readout order", GetMCMReadoutPos(MCM(*fPayloadCurr)), lastmcmpos));
1893 if (EvNo(*fPayloadCurr) != (evno & 0xfffff)) {
1895 evno = EvNo(*fPayloadCurr);
1898 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];
1912 channelcountExp = 21;
1915 Int_t adccoloff = AdcColOffset(*fPayloadCurr);
1916 Int_t padcoloff = PadColOffset(*fPayloadCurr);
1917 Int_t row = Row(*fPayloadCurr);
1920 if ((row > 11) && (fCurrStack == 2)) {
1921 MCMError(kInvalidPadRow, "Data in padrow > 11 for stack 2");
1924 if (fErrorFlags & (kDiscardHC | kDiscardDDL))
1927 // ----- reading marked ADC channels -----
1928 while (channelcount < channelcountExp &&
1929 *(fPayloadCurr) != fgkDataEndmarker) {
1936 Int_t nADCwords = (timebins + 2) / 3;
1937 AliDebug(2, Form("Now looking %i words", nADCwords));
1938 Int_t adccol = adccoloff - channelno;
1939 Int_t padcol = padcoloff - channelno;
1940 while ((adcwc < nADCwords) &&
1941 (*(fPayloadCurr) != fgkDataEndmarker) &&
1942 (fPayloadCurr - fPayloadStart < fPayloadSize)) {
1943 int check = 0x3 & *fPayloadCurr;
1944 if (channelno % 2 != 0) { // odd channel
1945 if (check != 0x2 && channelno < 21) {
1946 MCMError(kAdcCheckInvalid,
1947 "%i for %2i. ADC word in odd channel %i",
1948 check, adcwc+1, channelno);
1951 else { // even channel
1952 if (check != 0x3 && channelno < 21) {
1953 MCMError(kAdcCheckInvalid,
1954 "%i for %2i. ADC word in even channel %i",
1955 check, adcwc+1, channelno);
1959 if ((fErrorFlags & kDiscardMCM) == 0) {
1960 // filling the actual timebin data
1961 int tb2 = 0x3ff & (*fPayloadCurr >> 22);
1962 int tb1 = 0x3ff & (*fPayloadCurr >> 12);
1963 int tb0 = 0x3ff & (*fPayloadCurr >> 2);
1964 if (adcwc != 0 || fCurrNtimebins <= 30)
1965 fAdcArray->SetDataByAdcCol(row, adccol, currentTimebin++, tb0);
1968 if (currentTimebin < fCurrNtimebins)
1969 fAdcArray->SetDataByAdcCol(row, adccol, currentTimebin++, tb1);
1970 if (currentTimebin < fCurrNtimebins)
1971 fAdcArray->SetDataByAdcCol(row, adccol, currentTimebin++, tb2);
1978 if (adcwc != nADCwords)
1979 MCMError(kAdcDataAbort);
1982 if (padcol > 0 && padcol < 144) {
1983 fSignalIndex->AddIndexRC(row, padcol);
1989 if (channelcount != channelcountExp)
1990 MCMError(kAdcChannelsMiss);
1992 // continue with next MCM
1995 // check for missing MCMs (if header suppression is inactive)
1996 if (mcmcount != mcmcountExp) {
1997 LinkError(kMissMcmHeaders,
1998 "%i not as expected: %i", mcmcount, mcmcountExp);
2001 return (fPayloadCurr - start);
2005 UShort_t AliTRDrawStream::CalcLinkChecksum(UInt_t *data, Int_t size)
2007 // calculate the CRC for the data from this link
2008 // must not change the pointers to the data
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)
2018 size = size - (nEndmarkers-2);
2020 boost::crc_optimal<16, 0x8005, 0, 0, false, false> checksumLink;
2022 checksumLink.reset();
2023 checksumLink.process_bytes(data, size*sizeof(UInt_t));
2024 return checksumLink();
2027 UShort_t AliTRDrawStream::CalcLinkChecksum(UInt_t * /* data */, Int_t /* size */)
2029 // checksum calculation relies on boost,
2030 // we return 0 if we cannot calculate it
2032 AliError("Checksum calculation relies on boost CRC implementation!");
2038 Int_t AliTRDrawStream::SeekNextStack()
2040 // proceed in raw data stream till the next stack
2042 if (!fCurrStackEndmarkerAvail)
2045 UInt_t *start = fPayloadCurr;
2047 // read until data endmarkers
2048 while ((fPayloadCurr - fPayloadStart < fPayloadSize-1) &&
2049 ((fPayloadCurr[0] != fgkStackEndmarker[0]) ||
2050 (fPayloadCurr[1] != fgkStackEndmarker[1])))
2053 if ((fPayloadCurr - start) != 0)
2054 StackError(kUnknown, "skipped %i words to reach stack endmarker", fPayloadCurr - start);
2056 AliDebug(2, Form("stack endmarker: 0x%08x 0x%08x", fPayloadCurr[0], fPayloadCurr[1]));
2062 return (fPayloadCurr-start);
2065 Int_t AliTRDrawStream::SeekNextLink()
2067 // proceed in raw data stream till the next link
2069 UInt_t *start = fPayloadCurr;
2071 // read until data endmarkers
2072 while (fPayloadCurr - fPayloadStart < fPayloadSize &&
2073 ((fPayloadCurr[0] != fgkStackEndmarker[0]) ||
2074 (fPayloadCurr[1] != fgkStackEndmarker[1])) &&
2075 *fPayloadCurr != fgkDataEndmarker)
2078 // read all data endmarkers
2079 while (fPayloadCurr - fPayloadStart < fPayloadSize &&
2080 *fPayloadCurr == fgkDataEndmarker)
2083 return (fPayloadCurr - start);
2087 void AliTRDrawStream::EquipmentError(ErrorCode_t err, const char *const msg, ...)
2089 // register error according to error code on equipment level
2090 // and return the corresponding error message
2092 fLastError.fSector = fCurrEquipmentId - kDDLOffset;
2093 fLastError.fStack = -1;
2094 fLastError.fLink = -1;
2095 fLastError.fRob = -1;
2096 fLastError.fMcm = -1;
2097 fLastError.fError = err;
2098 (this->*fStoreError)();
2101 if (fgErrorDebugLevel[err] > 10)
2102 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) ));
2107 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 fErrorFlags |= fgErrorBehav[err];
2114 void AliTRDrawStream::StackError(ErrorCode_t err, const char *const msg, ...)
2116 // register error according to error code on stack level
2117 // and return the corresponding error message
2119 fLastError.fSector = fCurrEquipmentId - kDDLOffset;
2120 fLastError.fStack = fCurrSlot;
2121 fLastError.fLink = -1;
2122 fLastError.fRob = -1;
2123 fLastError.fMcm = -1;
2124 fLastError.fError = err;
2125 (this->*fStoreError)();
2128 if (fgErrorDebugLevel[err] > 0)
2129 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) ));
2134 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 fErrorFlags |= fgErrorBehav[err];
2141 void AliTRDrawStream::LinkError(ErrorCode_t err, const char *const msg, ...)
2143 // register error according to error code on link level
2144 // and return the corresponding error message
2146 fLastError.fSector = fCurrEquipmentId - kDDLOffset;
2147 fLastError.fStack = fCurrSlot;
2148 fLastError.fLink = fCurrLink;
2149 fLastError.fRob = -1;
2150 fLastError.fMcm = -1;
2151 fLastError.fError = err;
2152 (this->*fStoreError)();
2155 if (fgErrorDebugLevel[err] > 0)
2156 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) ));
2161 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 fErrorFlags |= fgErrorBehav[err];
2168 void AliTRDrawStream::ROBError(ErrorCode_t err, const char *const msg, ...)
2170 // register error according to error code on ROB level
2171 // and return the corresponding error message
2173 fLastError.fSector = fCurrEquipmentId - kDDLOffset;
2174 fLastError.fStack = fCurrSlot;
2175 fLastError.fLink = fCurrLink;
2176 fLastError.fRob = fCurrRobPos;
2177 fLastError.fMcm = -1;
2178 fLastError.fError = err;
2179 (this->*fStoreError)();
2182 if (fgErrorDebugLevel[err] > 0)
2183 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) ));
2188 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 fErrorFlags |= fgErrorBehav[err];
2195 void AliTRDrawStream::MCMError(ErrorCode_t err, const char *const msg, ...)
2197 // register error according to error code on MCM level
2198 // and return the corresponding error message
2200 fLastError.fSector = fCurrEquipmentId - kDDLOffset;
2201 fLastError.fStack = fCurrSlot;
2202 fLastError.fLink = fCurrLink;
2203 fLastError.fRob = fCurrRobPos;
2204 fLastError.fMcm = fCurrMcmPos;
2205 fLastError.fError = err;
2206 (this->*fStoreError)();
2209 if (fgErrorDebugLevel[err] > 0)
2210 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) ));
2215 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 fErrorFlags |= fgErrorBehav[err];
2221 const char* AliTRDrawStream::GetErrorMessage(ErrorCode_t errCode)
2223 // return the error message for the given error code
2225 if (errCode > 0 && errCode < kLastErrorCode)
2226 return fgkErrorMessages[errCode];
2231 void AliTRDrawStream::AliTRDrawStats::ClearStats()
2233 // clear statistics (includes clearing sector-wise statistics)
2236 for (Int_t iSector = 0; iSector < 18; iSector++) {
2237 fStatsSector[iSector].ClearStats();
2242 void AliTRDrawStream::AliTRDrawStats::AliTRDrawStatsSector::ClearStats()
2244 // clear statistics (includes clearing HC-wise statistics)
2252 for (Int_t iHC = 0; iHC < 60; iHC++) {
2253 fStatsHC[iHC].ClearStats();
2257 void AliTRDrawStream::AliTRDrawStats::AliTRDrawStatsSector::AliTRDrawStatsHC::ClearStats()
2268 void AliTRDrawStream::SetDumpMCM(Int_t det, Int_t rob, Int_t mcm, Bool_t dump)
2270 // mark MCM for dumping of raw data
2273 fDumpMCM[fNDumpMCMs++] = (det << 7) | (rob << 4) | mcm;
2277 for (iMCM = 0; iMCM < fNDumpMCMs; iMCM++) {
2278 if (fDumpMCM[iMCM] == ((det << 7) | (rob << 4) | mcm)) {
2283 for ( ; iMCM < fNDumpMCMs; iMCM++) {
2284 fDumpMCM[iMCM] = fDumpMCM[iMCM+1];
2289 Bool_t AliTRDrawStream::DumpingMCM(Int_t det, Int_t rob, Int_t mcm) const
2291 // check if MCM data should be dumped
2293 for (Int_t iMCM = 0; iMCM < fNDumpMCMs; iMCM++) {
2294 if (fDumpMCM[iMCM] == ((det << 7) | (rob << 4) | mcm)) {
2301 TString AliTRDrawStream::DumpRaw(TString title, const UInt_t *start, Int_t length, UInt_t endmarker)
2306 for (Int_t pos = 0; pos < length; pos += 4) {
2307 if ((start[pos+0] != endmarker) && pos+0 < length)
2308 if ((start[pos+1] != endmarker && pos+1 < length))
2309 if ((start[pos+2] != endmarker && pos+2 < length))
2310 if ((start[pos+3] != endmarker && pos+3 < length))
2311 title += Form(" 0x%08x 0x%08x 0x%08x 0x%08x\n",
2312 start[pos+0], start[pos+1], start[pos+2], start[pos+3]);
2314 title += Form(" 0x%08x 0x%08x 0x%08x 0x%08x\n",
2315 start[pos+0], start[pos+1], start[pos+2], start[pos+3]);
2319 title += Form(" 0x%08x 0x%08x 0x%08x\n",
2320 start[pos+0], start[pos+1], start[pos+2]);
2324 title += Form(" 0x%08x 0x%08x\n",
2325 start[pos+0], start[pos+1]);
2329 title += Form(" 0x%08x\n",
2337 TString AliTRDrawStream::DumpMcmHeader(TString title, UInt_t word)
2339 title += Form("0x%08x -> ROB: %i, MCM: %2i",
2340 word, ROB(word), MCM(word));
2344 TString AliTRDrawStream::DumpAdcMask(TString title, UInt_t word)
2346 title += Form("0x%08x -> #ch : %2i, 0x%06x (%2i ch)",
2347 word, GetNActiveChannels(word), GetActiveChannels(word), GetNActiveChannelsFromMask(word));
2351 AliTRDrawStream::AliTRDrawStreamError::AliTRDrawStreamError(Int_t error, Int_t sector, Int_t stack, Int_t link, Int_t rob, Int_t mcm) :
2363 void AliTRDrawStream::SortTracklets(TClonesArray *trklArray, TList &sortedTracklets, Int_t *indices)
2365 // sort tracklets for referencing from GTU tracks
2370 Int_t nTracklets = trklArray->GetEntriesFast();
2373 for (Int_t iTracklet = 0; iTracklet < nTracklets; iTracklet++) {
2374 AliTRDtrackletBase *trkl = (AliTRDtrackletBase*) ((*trklArray)[iTracklet]);
2375 Int_t hc = trkl->GetHCId();
2376 if ((hc < 0) || (hc >= 1080)) {
2377 AliErrorClass(Form("HC for tracklet: 0x%08x out of range: %i", trkl->GetTrackletWord(), trkl->GetHCId()));
2380 AliDebugClass(5, Form("hc: %4i : 0x%08x z: %2i", hc, trkl->GetTrackletWord(), trkl->GetZbin()));
2382 AliDebugClass(2, Form("set tracklet index for HC %i to %i", hc, iTracklet));
2383 indices[hc] = iTracklet + 1;
2388 for (Int_t iDet = 0; iDet < 540; iDet++) {
2389 Int_t trklIndexA = indices[2*iDet + 0] - 1;
2390 Int_t trklIndexB = indices[2*iDet + 1] - 1;
2391 Int_t trklIndex = sortedTracklets.GetEntries();
2392 AliTRDtrackletBase *trklA = trklIndexA > -1 ? (AliTRDtrackletBase*) ((*trklArray)[trklIndexA]) : 0x0;
2393 AliTRDtrackletBase *trklB = trklIndexB > -1 ? (AliTRDtrackletBase*) ((*trklArray)[trklIndexB]) : 0x0;
2394 AliTRDtrackletBase *trklNext = 0x0;
2395 while (trklA != 0x0 || trklB != 0x0) {
2396 AliDebugClass(5, Form("det %i - A: %i/%i -> %p, B: %i/%i -> %p",
2397 iDet, trklIndexA, nTracklets, trklA, trklIndexB, nTracklets, trklB));
2401 trklB = trklIndexB < nTracklets ? (AliTRDtrackletBase*) ((*trklArray)[trklIndexB]) : 0x0;
2402 if (trklB && trklB->GetHCId() != 2*iDet + 1)
2405 else if (trklB == 0x0) {
2408 trklA = trklIndexA < nTracklets ? (AliTRDtrackletBase*) ((*trklArray)[trklIndexA]) : 0x0;
2409 if (trklA && trklA->GetHCId() != 2*iDet)
2413 if (trklA->GetZbin() <= trklB->GetZbin()) {
2416 trklA = trklIndexA < nTracklets ? (AliTRDtrackletBase*) ((*trklArray)[trklIndexA]) : 0x0;
2417 if (trklA && trklA->GetHCId() != 2*iDet)
2423 trklB = trklIndexB < nTracklets ? (AliTRDtrackletBase*) ((*trklArray)[trklIndexB]) : 0x0;
2424 if (trklB && trklB->GetHCId() != 2*iDet + 1)
2429 sortedTracklets.Add(trklNext);
2434 // updating tracklet indices as in output
2435 if (sortedTracklets.GetEntries() != trklIndex) {
2436 indices[2*iDet + 0] = trklIndex;
2437 indices[2*iDet + 1] = sortedTracklets.GetEntries();
2439 indices[2*iDet + 0] = indices[2*iDet + 1] = -1;
2444 void AliTRDrawStream::AssignTracklets(AliESDTrdTrack *trdTrack, Int_t *trackletIndex, Int_t refIndex[6])
2446 UInt_t mask = trdTrack->GetLayerMask();
2447 UInt_t stack = trdTrack->GetStack();
2449 for (Int_t iLayer = 0; iLayer < 6; iLayer++) {
2450 refIndex[iLayer] = -1;
2452 if (mask & (1 << iLayer)) {
2454 Int_t det = trdTrack->GetSector()*30 + stack*6 + iLayer;
2455 Int_t idx = trdTrack->GetTrackletIndex(iLayer);
2457 if ((det < 0) || (det > 539)) {
2458 AliErrorClass(Form("Invalid detector no. from track: %i", 2*det));
2461 if (trackletIndex[2*det] >= 0) {
2462 if ((trackletIndex[2*det] + idx > -1) &&
2463 (trackletIndex[2*det] + idx < trackletIndex[2*det+1])) {
2464 refIndex[iLayer] = trackletIndex[2*det] + idx;
2466 AliErrorClass(Form("Requested tracklet index %i out of range", idx));
2469 AliErrorClass(Form("Non-existing tracklets requested in det %i", det));