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);
1366 Int_t AliTRDrawStream::ReadTracklets()
1368 // read the tracklets from one HC
1370 Int_t nTracklets = 0;
1372 UInt_t *start = fPayloadCurr;
1373 while (*(fPayloadCurr) != fgkTrackletEndmarker &&
1374 *(fPayloadCurr) != fgkStackEndmarker[0] &&
1375 *(fPayloadCurr) != fgkStackEndmarker[1] &&
1376 fPayloadCurr - fPayloadStart < (fPayloadSize - 1)) {
1379 new ((*fTracklets)[fTracklets->GetEntriesFast()]) AliTRDtrackletWord(*(fPayloadCurr), fCurrHC);
1384 if (nTracklets > 0) {
1385 AliDebug(1, Form("Found %i tracklets in %i %i %i (ev. %i)", nTracklets,
1386 (fCurrEquipmentId-kDDLOffset), fCurrSlot, fCurrLink, fRawReader->GetEventIndex()));
1387 if (fCurrSm > -1 && fCurrSm < 18) {
1388 fStats.fStatsSector[fCurrSm].fStatsHC[fCurrHC%60].fNTracklets += nTracklets;
1389 fStats.fStatsSector[fCurrSm].fNTracklets += nTracklets;
1393 // loop over remaining tracklet endmarkers
1394 while ((*(fPayloadCurr) == fgkTrackletEndmarker &&
1395 fPayloadCurr - fPayloadStart < fPayloadSize))
1398 return fPayloadCurr - start;
1401 Int_t AliTRDrawStream::ReadHcHeader()
1403 // read and parse the HC header of one HC
1404 // and store the information in the corresponding variables
1406 AliDebug(1, Form("HC header: 0x%08x", *fPayloadCurr));
1407 UInt_t *start = fPayloadCurr;
1408 // check not to be at the data endmarker
1409 if (*fPayloadCurr == fgkDataEndmarker ||
1410 *(fPayloadCurr) == fgkStackEndmarker[0] ||
1411 *(fPayloadCurr) == fgkStackEndmarker[1]) {
1412 LinkError(kHCmismatch, "found endmarker where HC header should be");
1416 fCurrSpecial = (*fPayloadCurr >> 31) & 0x1;
1417 fCurrMajor = (*fPayloadCurr >> 24) & 0x7f;
1418 fCurrMinor = (*fPayloadCurr >> 17) & 0x7f;
1419 fCurrAddHcWords = (*fPayloadCurr >> 14) & 0x7;
1420 fCurrSm = (*fPayloadCurr >> 9) & 0x1f;
1421 fCurrLayer = (*fPayloadCurr >> 6) & 0x7;
1422 fCurrStack = (*fPayloadCurr >> 3) & 0x7;
1423 fCurrSide = (*fPayloadCurr >> 2) & 0x1;
1424 fCurrCheck = (*fPayloadCurr) & 0x3;
1426 if ((fCurrSm != (((Int_t) fCurrEquipmentId) - kDDLOffset)) ||
1427 (fCurrStack != fCurrSlot) ||
1428 (fCurrLayer != fCurrLink / 2) ||
1429 (fCurrSide != fCurrLink % 2)) {
1430 LinkError(kHCmismatch,
1431 "HC: %i, %i, %i, %i\n 0x%08x 0x%08x 0x%08x 0x%08x",
1432 fCurrSm, fCurrStack, fCurrLayer, fCurrSide,
1433 fPayloadCurr[0], fPayloadCurr[1], fPayloadCurr[2], fPayloadCurr[3]);
1435 if (fCurrCheck != 0x1) {
1436 LinkError(kHCcheckFailed);
1439 if (fCurrAddHcWords > 0) {
1440 fCurrNtimebins = (fPayloadCurr[1] >> 26) & 0x3f;
1441 #ifdef TRD_RAW_DEBUG
1442 fCurrBC[fCurrHC] = (fPayloadCurr[1] >> 10) & 0xffff;
1444 fCurrPtrgCnt = (fPayloadCurr[1] >> 6) & 0xf;
1445 fCurrPtrgPhase = (fPayloadCurr[1] >> 2) & 0xf;
1448 fPayloadCurr += 1 + fCurrAddHcWords;
1450 return (fPayloadCurr - start);
1453 Int_t AliTRDrawStream::ReadTPData(Int_t mode)
1455 // testing of testpattern 1 to 3 (hardcoded), 0 missing
1456 // evcnt checking missing
1458 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 mcmcount = -1;
1463 Int_t wordcount = 0;
1464 Int_t channelcount = 0;
1466 UInt_t expadcval = 0;
1468 Int_t lastmcmpos = -1;
1469 Int_t lastrobpos = -1;
1471 UInt_t* start = fPayloadCurr;
1473 while (*(fPayloadCurr) != fgkDataEndmarker &&
1474 fPayloadCurr - fPayloadStart < fPayloadSize - 1) {
1476 // ----- Checking MCM Header -----
1477 AliDebug(2, DumpMcmHeader("MCM header: ", *fPayloadCurr));
1478 UInt_t *startPosMCM = fPayloadCurr;
1481 // ----- checking for proper readout order - ROB -----
1482 fCurrRobPos = ROB(*fPayloadCurr);
1483 if (GetROBReadoutPos(ROB(*fPayloadCurr) / 2) >= lastrobpos) {
1484 if (GetROBReadoutPos(ROB(*fPayloadCurr) / 2) > lastrobpos)
1486 lastrobpos = GetROBReadoutPos(ROB(*fPayloadCurr) / 2);
1489 ROBError(kPosUnexp, Form("#%i after #%i in readout order", GetROBReadoutPos(ROB(*fPayloadCurr) / 2), lastrobpos));
1492 // ----- checking for proper readout order - MCM -----
1493 fCurrMcmPos = MCM(*fPayloadCurr);
1494 if (GetMCMReadoutPos(MCM(*fPayloadCurr)) > lastmcmpos) {
1495 lastmcmpos = GetMCMReadoutPos(MCM(*fPayloadCurr));
1498 MCMError(kPosUnexp, Form("#%i after #%i in readout order", GetMCMReadoutPos(MCM(*fPayloadCurr)), lastmcmpos));
1501 if (EvNo(*fPayloadCurr) != (evno & 0xfffff)) {
1503 evno = EvNo(*fPayloadCurr);
1506 MCMError(kEvCntMismatch, "%i <-> %i", evno, EvNo(*fPayloadCurr));
1507 #ifdef TRD_RAW_DEBUG
1508 if (fCurrL0offset[fCurrHC/2] != 0)
1509 LinkError(kEvCntMismatch, "offset for %i %i %i changed from %i to %i = %i - %i",
1510 fCurrEquipmentId, fCurrSlot, fCurrLink/2, fCurrL0offset[fCurrHC/2],
1511 EvNo(*fPayloadCurr) - fCurrL0Count[fCurrEquipmentId-kDDLOffset],
1512 EvNo(*fPayloadCurr), fCurrL0Count[fCurrEquipmentId-kDDLOffset]);
1513 fCurrL0offset[fCurrHC/2] = EvNo(*fPayloadCurr) - fCurrL0Count[fCurrEquipmentId-kDDLOffset];
1514 evno = fCurrL0Count[fCurrEquipmentId-kDDLOffset] + fCurrL0offset[fCurrHC/2];
1521 evcnt = 0x3f & *fPayloadCurr >> 26;
1524 while (channelcount < 21) {
1526 if (cpu != cpufromchannel[channelcount]) {
1527 cpu = cpufromchannel[channelcount];
1528 expadcval = (1 << 9) | (fCurrRobPos << 6) | (fCurrMcmPos << 2) | cpu;
1532 while (count < 10) {
1533 if (*fPayloadCurr == fgkDataEndmarker) {
1534 MCMError(kMissTpData);
1535 return (fPayloadCurr - start);
1538 if (channelcount % 2 == 0)
1545 expword |= expadcval << 2;
1546 expadcval = ( (expadcval << 1) | ( ( (expadcval >> 9) ^ (expadcval >> 6) ) & 1) ) & 0x3FF;
1547 expword |= expadcval << 12;
1548 expadcval = ( (expadcval << 1) | ( ( (expadcval >> 9) ^ (expadcval >> 6) ) & 1) ) & 0x3FF;
1549 expword |= expadcval << 22;
1550 expadcval = ( (expadcval << 1) | ( ( (expadcval >> 9) ^ (expadcval >> 6) ) & 1) ) & 0x3FF;
1552 else if (mode == 2) {
1553 // ----- TP 2 ------
1554 expword = ((0x3f & evcnt) << 26) | ((fCurrSm + 1) << 21) | ((fCurrLayer + 1) << 18) |
1555 ((fCurrStack + 1) << 15) |
1556 (fCurrRobPos << 12) | (fCurrMcmPos << 8) | (cpu << 6) | (wordcount + 1);
1558 else if (mode == 3) {
1560 expword = ((0xfff & evcnt) << 20) | (fCurrSm << 15) | (fCurrLink/2 << 12) | (fCurrStack << 9) |
1561 (fCurrRobPos << 6) | (fCurrMcmPos << 2) | (cpu << 0);
1565 LinkError(kTPmodeInvalid, "Just reading");
1568 diff = *fPayloadCurr ^ expword;
1569 AliDebug(11, Form("Comparing ch %2i, word %2i (cpu %i): 0x%08x <-> 0x%08x",
1570 channelcount, wordcount, cpu, *fPayloadCurr, expword));
1573 MCMError(kTPmismatch,
1574 "Seen 0x%08x, expected 0x%08x, diff: 0x%08x, 0x%04x, 0x%02x - word %2i (cpu %i, ch %i)",
1575 *fPayloadCurr, expword, diff,
1576 0xffff & (diff | diff >> 16),
1577 0xff & (diff | diff >> 8 | diff >> 16 | diff >> 24),
1578 wordcount, cpu, channelcount);;
1583 if (*fPayloadCurr == fgkDataEndmarker)
1584 return (fPayloadCurr - start);
1588 // continue with next MCM
1590 if (IsDumping() && DumpingMCM(fCurrHC/2, fCurrRobPos, fCurrMcmPos)) {
1591 AliInfo(DumpRaw(Form("Event %i: Det %3i ROB %i MCM %2i", fRawReader->GetEventIndex(), fCurrHC/2, fCurrRobPos, fCurrMcmPos),
1592 startPosMCM, fPayloadCurr - startPosMCM));
1596 return fPayloadCurr - start;
1600 Int_t AliTRDrawStream::ReadZSData()
1602 // read the zs data from one link from the current reading position
1604 UInt_t *start = fPayloadCurr;
1607 Int_t mcmcountExp = fCurrStack == 2 ? 48 : 64;
1608 Int_t channelcount = 0;
1609 Int_t channelcountExp = 0;
1610 Int_t channelcountMax = 0;
1612 Int_t currentTimebin = 0;
1615 Int_t lastmcmpos = -1;
1616 Int_t lastrobpos = -1;
1618 if (fCurrNtimebins != fNtimebins) {
1620 LinkError(kNtimebinsChanged,
1621 "No. of timebins changed from %i to %i", fNtimebins, fCurrNtimebins);
1622 fNtimebins = fCurrNtimebins;
1625 timebins = fNtimebins;
1627 while (*(fPayloadCurr) != fgkDataEndmarker &&
1628 *(fPayloadCurr) != fgkStackEndmarker[0] &&
1629 *(fPayloadCurr) != fgkStackEndmarker[1] &&
1630 fPayloadCurr - fPayloadStart < fPayloadSize) {
1632 // ----- Checking MCM Header -----
1633 AliDebug(2, DumpMcmHeader("MCM header: ", *fPayloadCurr));
1634 UInt_t *startPosMCM = fPayloadCurr;
1636 // ----- checking for proper readout order - ROB -----
1637 fCurrRobPos = ROB(*fPayloadCurr);
1638 if (GetROBReadoutPos(ROB(*fPayloadCurr) / 2) >= lastrobpos) {
1639 if (GetROBReadoutPos(ROB(*fPayloadCurr) / 2) > lastrobpos)
1641 lastrobpos = GetROBReadoutPos(ROB(*fPayloadCurr) / 2);
1644 ROBError(kPosUnexp, Form("#%i after #%i and #%i in readout order",
1645 GetROBReadoutPos(ROB(*fPayloadCurr) / 2), lastrobpos, GetROBReadoutPos(fCurrRobPos)));
1648 // ----- checking for proper readout order - MCM -----
1649 fCurrMcmPos = MCM(*fPayloadCurr);
1650 if (GetMCMReadoutPos(MCM(*fPayloadCurr)) > lastmcmpos) {
1651 lastmcmpos = GetMCMReadoutPos(MCM(*fPayloadCurr));
1654 MCMError(kPosUnexp, Form("#%i after #%i and #%i in readout order",
1655 GetMCMReadoutPos(MCM(*fPayloadCurr)), lastmcmpos, GetMCMReadoutPos(fCurrMcmPos)));
1658 #ifdef TRD_RAW_DEBUG
1659 if (fCurrL0Count[fCurrEquipmentId-kDDLOffset] > 0) {
1660 evno = fCurrL0Count[fCurrEquipmentId-kDDLOffset] + fCurrL0offset[fCurrHC/2];
1662 fCurrEvCount[fCurrEquipmentId-kDDLOffset] = EvNo(*fPayloadCurr);
1665 if (EvNo(*fPayloadCurr) != (evno & 0xfffff)) {
1667 evno = EvNo(*fPayloadCurr);
1670 MCMError(kEvCntMismatch, "exp <-> SM: %i <-> %i", evno & 0xfffff, EvNo(*fPayloadCurr));
1671 #ifdef TRD_RAW_DEBUG
1672 Int_t prevOffset = fCurrL0offset[fCurrHC/2];
1673 fCurrL0offset[fCurrHC/2] = (- fCurrL0Count[fCurrEquipmentId-kDDLOffset] + EvNo(*fPayloadCurr)) % (1 << 20);
1674 if (fCurrL0offset[fCurrHC/2] < 0)
1675 fCurrL0offset[fCurrHC/2] += 0xfffff;
1676 evno = (fCurrL0Count[fCurrEquipmentId-kDDLOffset] + fCurrL0offset[fCurrHC/2]) & 0xfffff;
1677 if (prevOffset != 0)
1678 LinkError(kEvCntMismatch, "offset for %i %i %i changed from %i to %i = %i - %i",
1679 fCurrEquipmentId, fCurrSlot, fCurrLink/2,
1681 fCurrL0offset[fCurrHC/2],
1682 fCurrL0Count[fCurrEquipmentId-kDDLOffset],
1683 EvNo(*fPayloadCurr));
1687 Int_t adccoloff = AdcColOffset(*fPayloadCurr);
1688 Int_t padcoloff = PadColOffset(*fPayloadCurr);
1689 Int_t row = Row(*fPayloadCurr);
1692 if ((row > 11) && (fCurrStack == 2)) {
1693 MCMError(kInvalidPadRow, "Data in padrow > 11 for stack 2");
1696 if (fErrorFlags & (kDiscardHC | kDiscardDDL))
1699 // ----- Reading ADC channels -----
1700 AliDebug(2, DumpAdcMask("ADC mask: ", *fPayloadCurr));
1702 // ----- analysing the ADC mask -----
1704 channelcountExp = GetNActiveChannelsFromMask(*fPayloadCurr);
1705 channelcountMax = GetNActiveChannels(*fPayloadCurr);
1706 Int_t channelmask = GetActiveChannels(*fPayloadCurr);
1707 Int_t channelno = -1;
1710 if (channelcountExp != channelcountMax) {
1711 if (channelcountExp > channelcountMax) {
1712 Int_t temp = channelcountExp;
1713 channelcountExp = channelcountMax;
1714 channelcountMax = temp;
1716 while (channelcountExp < channelcountMax && channelcountExp < 21 &&
1717 fPayloadCurr - fPayloadStart < fPayloadSize - 10 * channelcountExp - 1) {
1718 MCMError(kAdcMaskInconsistent,
1719 "Possible MCM-H: 0x%08x, possible ADC-mask: 0x%08x",
1720 *(fPayloadCurr + 10 * channelcountExp),
1721 *(fPayloadCurr + 10 * channelcountExp + 1) );
1722 if (!CouldBeMCMhdr( *(fPayloadCurr + 10 * channelcountExp)) && !CouldBeADCmask( *(fPayloadCurr + 10 * channelcountExp + 1)))
1728 MCMError(kAdcMaskInconsistent,
1729 "Inconsistency in no. of active channels: Counter: %i, Mask: %i, chosen: %i!",
1730 GetNActiveChannels(fPayloadCurr[-1]), GetNActiveChannelsFromMask(fPayloadCurr[-1]), channelcountExp);
1732 AliDebug(2, Form("expecting %i active channels, %i timebins", channelcountExp, fCurrNtimebins));
1734 // ----- reading marked ADC channels -----
1735 while (channelcount < channelcountExp && *(fPayloadCurr) != fgkDataEndmarker) {
1738 while (channelno < 20 && (channelmask & 1 << channelno) == 0)
1741 if (fCurrNtimebins > 30) {
1742 currentTimebin = ((*fPayloadCurr >> 2) & 0x3f);
1743 timebins = ((*fPayloadCurr >> 8) & 0xf) * 3;
1750 Int_t nADCwords = (timebins + 2) / 3;
1751 AliDebug(3, Form("Now reading %i words for channel %2i", nADCwords, channelno));
1752 Int_t adccol = adccoloff - channelno;
1753 Int_t padcol = padcoloff - channelno;
1754 // if (adccol < 3 || adccol > 165)
1755 // AliInfo(Form("writing channel %i of det %3i %i:%2i to adcrow/-col: %i/%i padcol: %i",
1756 // channelno, fCurrHC/2, fCurrRobPos, fCurrMcmPos, row, adccol, padcol));
1758 while ((adcwc < nADCwords) &&
1759 (*(fPayloadCurr) != fgkDataEndmarker) &&
1760 (fPayloadCurr - fPayloadStart < fPayloadSize)) {
1761 int check = 0x3 & *fPayloadCurr;
1762 if (channelno % 2 != 0) { // odd channel
1763 if (check != 0x2 && channelno < 21) {
1764 MCMError(kAdcCheckInvalid,
1765 "%i for %2i. ADC word in odd channel %i",
1766 check, adcwc+1, channelno);
1769 else { // even channel
1770 if (check != 0x3 && channelno < 21) {
1771 MCMError(kAdcCheckInvalid,
1772 "%i for %2i. ADC word in even channel %i",
1773 check, adcwc+1, channelno);
1777 if ((fErrorFlags & kDiscardMCM) == 0) {
1778 // filling the actual timebin data
1779 int tb2 = 0x3ff & (*fPayloadCurr >> 22);
1780 int tb1 = 0x3ff & (*fPayloadCurr >> 12);
1781 int tb0 = 0x3ff & (*fPayloadCurr >> 2);
1782 if (adcwc != 0 || fCurrNtimebins <= 30)
1783 fAdcArray->SetDataByAdcCol(row, adccol, currentTimebin++, tb0);
1786 if (currentTimebin < fCurrNtimebins)
1787 fAdcArray->SetDataByAdcCol(row, adccol, currentTimebin++, tb1);
1788 if (currentTimebin < fCurrNtimebins)
1789 fAdcArray->SetDataByAdcCol(row, adccol, currentTimebin++, tb2);
1796 if (adcwc != nADCwords)
1797 MCMError(kAdcDataAbort);
1800 if (padcol > 0 && padcol < 144) {
1801 fSignalIndex->AddIndexRC(row, padcol);
1807 if (fCurrSm > -1 && fCurrSm < 18) {
1808 fStats.fStatsSector[fCurrSm].fStatsHC[fCurrHC%60].fNChannels += channelcount;
1809 fStats.fStatsSector[fCurrSm].fNChannels += channelcount;
1811 if (channelcount != channelcountExp)
1812 MCMError(kAdcChannelsMiss);
1815 if (fCurrSm > -1 && fCurrSm < 18) {
1816 fStats.fStatsSector[fCurrSm].fStatsHC[fCurrHC%60].fNMCMs++;
1817 fStats.fStatsSector[fCurrSm].fNMCMs++;
1820 if (IsDumping() && DumpingMCM(fCurrHC/2, fCurrRobPos, fCurrMcmPos)) {
1821 AliInfo(DumpRaw(Form("Event %i: Det %3i ROB %i MCM %2i", fRawReader->GetEventIndex(), fCurrHC/2, fCurrRobPos, fCurrMcmPos),
1822 startPosMCM, fPayloadCurr - startPosMCM));
1825 // continue with next MCM
1828 // check for missing MCMs (if header suppression is inactive)
1829 if (((fCurrMajor & 0x1) == 0) && (mcmcount != mcmcountExp)) {
1830 LinkError(kMissMcmHeaders,
1831 "No. of MCM headers %i not as expected: %i",
1832 mcmcount, mcmcountExp);
1835 return (fPayloadCurr - start);
1838 Int_t AliTRDrawStream::ReadNonZSData()
1840 // read the non-zs data from one link from the current reading position
1842 UInt_t *start = fPayloadCurr;
1845 Int_t mcmcountExp = fCurrStack == 2 ? 48 : 64;
1846 Int_t channelcount = 0;
1847 Int_t channelcountExp = 0;
1849 Int_t currentTimebin = 0;
1852 Int_t lastmcmpos = -1;
1853 Int_t lastrobpos = -1;
1855 if (fCurrNtimebins != fNtimebins) {
1857 LinkError(kNtimebinsChanged,
1858 "No. of timebins changed from %i to %i", fNtimebins, fCurrNtimebins);
1859 fNtimebins = fCurrNtimebins;
1862 timebins = fNtimebins;
1864 while (*(fPayloadCurr) != fgkDataEndmarker &&
1865 fPayloadCurr - fPayloadStart < fPayloadSize - 2) {
1867 // ----- Checking MCM Header -----
1868 AliDebug(2, Form("MCM header: 0x%08x", *fPayloadCurr));
1870 // ----- checking for proper readout order - ROB -----
1871 fCurrRobPos = ROB(*fPayloadCurr);
1872 if (GetROBReadoutPos(ROB(*fPayloadCurr) / 2) >= lastrobpos) {
1873 if (GetROBReadoutPos(ROB(*fPayloadCurr) / 2) > lastrobpos)
1875 lastrobpos = GetROBReadoutPos(ROB(*fPayloadCurr) / 2);
1878 ROBError(kPosUnexp, Form("#%i after #%i in readout order", GetROBReadoutPos(ROB(*fPayloadCurr) / 2), lastrobpos));
1881 // ----- checking for proper readout order - MCM -----
1882 fCurrMcmPos = MCM(*fPayloadCurr);
1883 if (GetMCMReadoutPos(MCM(*fPayloadCurr)) > lastmcmpos) {
1884 lastmcmpos = GetMCMReadoutPos(MCM(*fPayloadCurr));
1887 MCMError(kPosUnexp, Form("#%i after #%i in readout order", GetMCMReadoutPos(MCM(*fPayloadCurr)), lastmcmpos));
1890 if (EvNo(*fPayloadCurr) != (evno & 0xfffff)) {
1892 evno = EvNo(*fPayloadCurr);
1895 MCMError(kEvCntMismatch, "%i <-> %i", evno, EvNo(*fPayloadCurr));
1896 #ifdef TRD_RAW_DEBUG
1897 if (fCurrL0offset[fCurrHC/2] != 0)
1898 LinkError(kEvCntMismatch, "offset for %i %i %i changed from %i to %i = %i - %i",
1899 fCurrEquipmentId, fCurrSlot, fCurrLink/2, fCurrL0offset[fCurrHC/2],
1900 EvNo(*fPayloadCurr) - fCurrL0Count[fCurrEquipmentId-kDDLOffset],
1901 EvNo(*fPayloadCurr), fCurrL0Count[fCurrEquipmentId-kDDLOffset]);
1902 fCurrL0offset[fCurrHC/2] = EvNo(*fPayloadCurr) - fCurrL0Count[fCurrEquipmentId-kDDLOffset];
1903 evno = fCurrL0Count[fCurrEquipmentId-kDDLOffset] + fCurrL0offset[fCurrHC/2];
1909 channelcountExp = 21;
1912 Int_t adccoloff = AdcColOffset(*fPayloadCurr);
1913 Int_t padcoloff = PadColOffset(*fPayloadCurr);
1914 Int_t row = Row(*fPayloadCurr);
1917 if ((row > 11) && (fCurrStack == 2)) {
1918 MCMError(kInvalidPadRow, "Data in padrow > 11 for stack 2");
1921 if (fErrorFlags & (kDiscardHC | kDiscardDDL))
1924 // ----- reading marked ADC channels -----
1925 while (channelcount < channelcountExp &&
1926 *(fPayloadCurr) != fgkDataEndmarker) {
1933 Int_t nADCwords = (timebins + 2) / 3;
1934 AliDebug(2, Form("Now looking %i words", nADCwords));
1935 Int_t adccol = adccoloff - channelno;
1936 Int_t padcol = padcoloff - channelno;
1937 while ((adcwc < nADCwords) &&
1938 (*(fPayloadCurr) != fgkDataEndmarker) &&
1939 (fPayloadCurr - fPayloadStart < fPayloadSize)) {
1940 int check = 0x3 & *fPayloadCurr;
1941 if (channelno % 2 != 0) { // odd channel
1942 if (check != 0x2 && channelno < 21) {
1943 MCMError(kAdcCheckInvalid,
1944 "%i for %2i. ADC word in odd channel %i",
1945 check, adcwc+1, channelno);
1948 else { // even channel
1949 if (check != 0x3 && channelno < 21) {
1950 MCMError(kAdcCheckInvalid,
1951 "%i for %2i. ADC word in even channel %i",
1952 check, adcwc+1, channelno);
1956 if ((fErrorFlags & kDiscardMCM) == 0) {
1957 // filling the actual timebin data
1958 int tb2 = 0x3ff & (*fPayloadCurr >> 22);
1959 int tb1 = 0x3ff & (*fPayloadCurr >> 12);
1960 int tb0 = 0x3ff & (*fPayloadCurr >> 2);
1961 if (adcwc != 0 || fCurrNtimebins <= 30)
1962 fAdcArray->SetDataByAdcCol(row, adccol, currentTimebin++, tb0);
1965 if (currentTimebin < fCurrNtimebins)
1966 fAdcArray->SetDataByAdcCol(row, adccol, currentTimebin++, tb1);
1967 if (currentTimebin < fCurrNtimebins)
1968 fAdcArray->SetDataByAdcCol(row, adccol, currentTimebin++, tb2);
1975 if (adcwc != nADCwords)
1976 MCMError(kAdcDataAbort);
1979 if (padcol > 0 && padcol < 144) {
1980 fSignalIndex->AddIndexRC(row, padcol);
1986 if (channelcount != channelcountExp)
1987 MCMError(kAdcChannelsMiss);
1989 // continue with next MCM
1992 // check for missing MCMs (if header suppression is inactive)
1993 if (mcmcount != mcmcountExp) {
1994 LinkError(kMissMcmHeaders,
1995 "%i not as expected: %i", mcmcount, mcmcountExp);
1998 return (fPayloadCurr - start);
2002 UShort_t AliTRDrawStream::CalcLinkChecksum(UInt_t *data, Int_t size)
2004 // calculate the CRC for the data from this link
2005 // must not change the pointers to the data
2007 // always count two endmarkers
2008 Int_t nEndmarkers = 0;
2009 for (Int_t i = 0; i < size; i++) {
2010 if (data[size-1 - i] != fgkDataEndmarker)
2015 size = size - (nEndmarkers-2);
2017 boost::crc_optimal<16, 0x8005, 0, 0, false, false> checksumLink;
2019 checksumLink.reset();
2020 checksumLink.process_bytes(data, size*sizeof(UInt_t));
2021 return checksumLink();
2024 UShort_t AliTRDrawStream::CalcLinkChecksum(UInt_t * /* data */, Int_t /* size */)
2026 // checksum calculation relies on boost,
2027 // we return 0 if we cannot calculate it
2029 AliError("Checksum calculation relies on boost CRC implementation!");
2035 Int_t AliTRDrawStream::SeekNextStack()
2037 // proceed in raw data stream till the next stack
2039 if (!fCurrStackEndmarkerAvail)
2042 UInt_t *start = fPayloadCurr;
2044 // read until data endmarkers
2045 while ((fPayloadCurr - fPayloadStart < fPayloadSize-1) &&
2046 ((fPayloadCurr[0] != fgkStackEndmarker[0]) ||
2047 (fPayloadCurr[1] != fgkStackEndmarker[1])))
2050 if ((fPayloadCurr - start) != 0)
2051 StackError(kUnknown, "skipped %i words to reach stack endmarker", fPayloadCurr - start);
2053 AliDebug(2, Form("stack endmarker: 0x%08x 0x%08x", fPayloadCurr[0], fPayloadCurr[1]));
2059 return (fPayloadCurr-start);
2062 Int_t AliTRDrawStream::SeekNextLink()
2064 // proceed in raw data stream till the next link
2066 UInt_t *start = fPayloadCurr;
2068 // read until data endmarkers
2069 while (fPayloadCurr - fPayloadStart < fPayloadSize &&
2070 ((fPayloadCurr[0] != fgkStackEndmarker[0]) ||
2071 (fPayloadCurr[1] != fgkStackEndmarker[1])) &&
2072 *fPayloadCurr != fgkDataEndmarker)
2075 // read all data endmarkers
2076 while (fPayloadCurr - fPayloadStart < fPayloadSize &&
2077 *fPayloadCurr == fgkDataEndmarker)
2080 return (fPayloadCurr - start);
2084 void AliTRDrawStream::EquipmentError(ErrorCode_t err, const char *const msg, ...)
2086 // register error according to error code on equipment level
2087 // and return the corresponding error message
2089 fLastError.fSector = fCurrEquipmentId - kDDLOffset;
2090 fLastError.fStack = -1;
2091 fLastError.fLink = -1;
2092 fLastError.fRob = -1;
2093 fLastError.fMcm = -1;
2094 fLastError.fError = err;
2095 (this->*fStoreError)();
2098 if (fgErrorDebugLevel[err] > 10)
2099 AliDebug(fgErrorDebugLevel[err],
2100 Form("Event %6i: Eq. %2d - %s : %s",
2101 fRawReader->GetEventIndex(), fCurrEquipmentId, fgkErrorMessages[err],
2102 (va_start(ap, msg), vsprintf(fErrorBuffer, msg, ap), va_end(ap), fErrorBuffer) ));
2104 AliError(Form("Event %6i: Eq. %2d - %s : %s",
2105 fRawReader->GetEventIndex(), fCurrEquipmentId, fgkErrorMessages[err],
2106 (va_start(ap, msg), vsprintf(fErrorBuffer, msg, ap), va_end(ap), fErrorBuffer) ));
2107 fErrorFlags |= fgErrorBehav[err];
2111 void AliTRDrawStream::StackError(ErrorCode_t err, const char *const msg, ...)
2113 // register error according to error code on stack level
2114 // and return the corresponding error message
2116 fLastError.fSector = fCurrEquipmentId - kDDLOffset;
2117 fLastError.fStack = fCurrSlot;
2118 fLastError.fLink = -1;
2119 fLastError.fRob = -1;
2120 fLastError.fMcm = -1;
2121 fLastError.fError = err;
2122 (this->*fStoreError)();
2125 if (fgErrorDebugLevel[err] > 0)
2126 AliDebug(fgErrorDebugLevel[err],
2127 Form("Event %6i: Eq. %2d S %i - %s : %s",
2128 fRawReader->GetEventIndex(), fCurrEquipmentId, fCurrSlot, fgkErrorMessages[err],
2129 (va_start(ap, msg), vsprintf(fErrorBuffer, msg, ap), va_end(ap), fErrorBuffer) ));
2131 AliError(Form("Event %6i: Eq. %2d S %i - %s : %s",
2132 fRawReader->GetEventIndex(), fCurrEquipmentId, fCurrSlot, fgkErrorMessages[err],
2133 (va_start(ap, msg), vsprintf(fErrorBuffer, msg, ap), va_end(ap), fErrorBuffer) ));
2134 fErrorFlags |= fgErrorBehav[err];
2138 void AliTRDrawStream::LinkError(ErrorCode_t err, const char *const msg, ...)
2140 // register error according to error code on link level
2141 // and return the corresponding error message
2143 fLastError.fSector = fCurrEquipmentId - kDDLOffset;
2144 fLastError.fStack = fCurrSlot;
2145 fLastError.fLink = fCurrLink;
2146 fLastError.fRob = -1;
2147 fLastError.fMcm = -1;
2148 fLastError.fError = err;
2149 (this->*fStoreError)();
2152 if (fgErrorDebugLevel[err] > 0)
2153 AliDebug(fgErrorDebugLevel[err],
2154 Form("Event %6i: Eq. %2d S %i l %2i - %s : %s",
2155 fRawReader->GetEventIndex(), fCurrEquipmentId, fCurrSlot, fCurrLink, fgkErrorMessages[err],
2156 (va_start(ap, msg), vsprintf(fErrorBuffer, msg, ap), va_end(ap), fErrorBuffer) ));
2158 AliError(Form("Event %6i: Eq. %2d S %i l %2i - %s : %s",
2159 fRawReader->GetEventIndex(), fCurrEquipmentId, fCurrSlot, fCurrLink, fgkErrorMessages[err],
2160 (va_start(ap, msg), vsprintf(fErrorBuffer, msg, ap), va_end(ap), fErrorBuffer) ));
2161 fErrorFlags |= fgErrorBehav[err];
2165 void AliTRDrawStream::ROBError(ErrorCode_t err, const char *const msg, ...)
2167 // register error according to error code on ROB level
2168 // and return the corresponding error message
2170 fLastError.fSector = fCurrEquipmentId - kDDLOffset;
2171 fLastError.fStack = fCurrSlot;
2172 fLastError.fLink = fCurrLink;
2173 fLastError.fRob = fCurrRobPos;
2174 fLastError.fMcm = -1;
2175 fLastError.fError = err;
2176 (this->*fStoreError)();
2179 if (fgErrorDebugLevel[err] > 0)
2180 AliDebug(fgErrorDebugLevel[err],
2181 Form("Event %6i: Eq. %2d S %i l %2i ROB %i - %s : %s",
2182 fRawReader->GetEventIndex(), fCurrEquipmentId, fCurrSlot, fCurrLink, fCurrRobPos, fgkErrorMessages[err],
2183 (va_start(ap, msg), vsprintf(fErrorBuffer, msg, ap), va_end(ap), fErrorBuffer) ));
2185 AliError(Form("Event %6i: Eq. %2d S %i l %2i ROB %i - %s : %s",
2186 fRawReader->GetEventIndex(), fCurrEquipmentId, fCurrSlot, fCurrLink, fCurrRobPos, fgkErrorMessages[err],
2187 (va_start(ap, msg), vsprintf(fErrorBuffer, msg, ap), va_end(ap), fErrorBuffer) ));
2188 fErrorFlags |= fgErrorBehav[err];
2192 void AliTRDrawStream::MCMError(ErrorCode_t err, const char *const msg, ...)
2194 // register error according to error code on MCM level
2195 // and return the corresponding error message
2197 fLastError.fSector = fCurrEquipmentId - kDDLOffset;
2198 fLastError.fStack = fCurrSlot;
2199 fLastError.fLink = fCurrLink;
2200 fLastError.fRob = fCurrRobPos;
2201 fLastError.fMcm = fCurrMcmPos;
2202 fLastError.fError = err;
2203 (this->*fStoreError)();
2206 if (fgErrorDebugLevel[err] > 0)
2207 AliDebug(fgErrorDebugLevel[err],
2208 Form("Event %6i: Eq. %2d S %i l %2i ROB %i MCM %2i - %s : %s",
2209 fRawReader->GetEventIndex(), fCurrEquipmentId, fCurrSlot, fCurrLink, fCurrRobPos, fCurrMcmPos, fgkErrorMessages[err],
2210 (va_start(ap, msg), vsprintf(fErrorBuffer, msg, ap), va_end(ap), fErrorBuffer) ));
2212 AliError(Form("Event %6i: Eq. %2d S %i l %2i ROB %i MCM %2i - %s : %s",
2213 fRawReader->GetEventIndex(), fCurrEquipmentId, fCurrSlot, fCurrLink, fCurrRobPos, fCurrMcmPos, fgkErrorMessages[err],
2214 (va_start(ap, msg), vsprintf(fErrorBuffer, msg, ap), va_end(ap), fErrorBuffer) ));
2215 fErrorFlags |= fgErrorBehav[err];
2218 const char* AliTRDrawStream::GetErrorMessage(ErrorCode_t errCode)
2220 // return the error message for the given error code
2222 if (errCode > 0 && errCode < kLastErrorCode)
2223 return fgkErrorMessages[errCode];
2228 void AliTRDrawStream::AliTRDrawStats::ClearStats()
2230 // clear statistics (includes clearing sector-wise statistics)
2233 for (Int_t iSector = 0; iSector < 18; iSector++) {
2234 fStatsSector[iSector].ClearStats();
2239 void AliTRDrawStream::AliTRDrawStats::AliTRDrawStatsSector::ClearStats()
2241 // clear statistics (includes clearing HC-wise statistics)
2249 for (Int_t iHC = 0; iHC < 60; iHC++) {
2250 fStatsHC[iHC].ClearStats();
2254 void AliTRDrawStream::AliTRDrawStats::AliTRDrawStatsSector::AliTRDrawStatsHC::ClearStats()
2265 void AliTRDrawStream::SetDumpMCM(Int_t det, Int_t rob, Int_t mcm, Bool_t dump)
2267 // mark MCM for dumping of raw data
2270 fDumpMCM[fNDumpMCMs++] = (det << 7) | (rob << 4) | mcm;
2274 for (iMCM = 0; iMCM < fNDumpMCMs; iMCM++) {
2275 if (fDumpMCM[iMCM] == ((det << 7) | (rob << 4) | mcm)) {
2280 for ( ; iMCM < fNDumpMCMs; iMCM++) {
2281 fDumpMCM[iMCM] = fDumpMCM[iMCM+1];
2286 Bool_t AliTRDrawStream::DumpingMCM(Int_t det, Int_t rob, Int_t mcm) const
2288 // check if MCM data should be dumped
2290 for (Int_t iMCM = 0; iMCM < fNDumpMCMs; iMCM++) {
2291 if (fDumpMCM[iMCM] == ((det << 7) | (rob << 4) | mcm)) {
2298 TString AliTRDrawStream::DumpRaw(TString title, const UInt_t *start, Int_t length, UInt_t endmarker)
2303 for (Int_t pos = 0; pos < length; pos += 4) {
2304 if ((start[pos+0] != endmarker) && pos+0 < length)
2305 if ((start[pos+1] != endmarker && pos+1 < length))
2306 if ((start[pos+2] != endmarker && pos+2 < length))
2307 if ((start[pos+3] != endmarker && pos+3 < length))
2308 title += Form(" 0x%08x 0x%08x 0x%08x 0x%08x\n",
2309 start[pos+0], start[pos+1], start[pos+2], start[pos+3]);
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]);
2316 title += Form(" 0x%08x 0x%08x 0x%08x\n",
2317 start[pos+0], start[pos+1], start[pos+2]);
2321 title += Form(" 0x%08x 0x%08x\n",
2322 start[pos+0], start[pos+1]);
2326 title += Form(" 0x%08x\n",
2334 TString AliTRDrawStream::DumpMcmHeader(TString title, UInt_t word)
2336 title += Form("0x%08x -> ROB: %i, MCM: %2i",
2337 word, ROB(word), MCM(word));
2341 TString AliTRDrawStream::DumpAdcMask(TString title, UInt_t word)
2343 title += Form("0x%08x -> #ch : %2i, 0x%06x (%2i ch)",
2344 word, GetNActiveChannels(word), GetActiveChannels(word), GetNActiveChannelsFromMask(word));
2348 AliTRDrawStream::AliTRDrawStreamError::AliTRDrawStreamError(Int_t error, Int_t sector, Int_t stack, Int_t link, Int_t rob, Int_t mcm) :
2360 void AliTRDrawStream::SortTracklets(TClonesArray *trklArray, TList &sortedTracklets, Int_t *indices)
2362 // sort tracklets for referencing from GTU tracks
2367 Int_t nTracklets = trklArray->GetEntriesFast();
2370 for (Int_t iTracklet = 0; iTracklet < nTracklets; iTracklet++) {
2371 AliTRDtrackletBase *trkl = (AliTRDtrackletBase*) ((*trklArray)[iTracklet]);
2372 Int_t hc = trkl->GetHCId();
2373 if ((hc < 0) || (hc >= 1080)) {
2374 AliErrorClass(Form("HC for tracklet: 0x%08x out of range: %i", trkl->GetTrackletWord(), trkl->GetHCId()));
2377 AliDebugClass(5, Form("hc: %4i : 0x%08x z: %2i", hc, trkl->GetTrackletWord(), trkl->GetZbin()));
2379 AliDebugClass(2, Form("set tracklet index for HC %i to %i", hc, iTracklet));
2380 indices[hc] = iTracklet + 1;
2385 for (Int_t iDet = 0; iDet < 540; iDet++) {
2386 Int_t trklIndexA = indices[2*iDet + 0] - 1;
2387 Int_t trklIndexB = indices[2*iDet + 1] - 1;
2388 Int_t trklIndex = sortedTracklets.GetEntries();
2389 AliTRDtrackletBase *trklA = trklIndexA > -1 ? (AliTRDtrackletBase*) ((*trklArray)[trklIndexA]) : 0x0;
2390 AliTRDtrackletBase *trklB = trklIndexB > -1 ? (AliTRDtrackletBase*) ((*trklArray)[trklIndexB]) : 0x0;
2391 AliTRDtrackletBase *trklNext = 0x0;
2392 while (trklA != 0x0 || trklB != 0x0) {
2393 AliDebugClass(5, Form("det %i - A: %i/%i -> %p, B: %i/%i -> %p",
2394 iDet, trklIndexA, nTracklets, trklA, trklIndexB, nTracklets, trklB));
2398 trklB = trklIndexB < nTracklets ? (AliTRDtrackletBase*) ((*trklArray)[trklIndexB]) : 0x0;
2399 if (trklB && trklB->GetHCId() != 2*iDet + 1)
2402 else if (trklB == 0x0) {
2405 trklA = trklIndexA < nTracklets ? (AliTRDtrackletBase*) ((*trklArray)[trklIndexA]) : 0x0;
2406 if (trklA && trklA->GetHCId() != 2*iDet)
2410 if (trklA->GetZbin() <= trklB->GetZbin()) {
2413 trklA = trklIndexA < nTracklets ? (AliTRDtrackletBase*) ((*trklArray)[trklIndexA]) : 0x0;
2414 if (trklA && trklA->GetHCId() != 2*iDet)
2420 trklB = trklIndexB < nTracklets ? (AliTRDtrackletBase*) ((*trklArray)[trklIndexB]) : 0x0;
2421 if (trklB && trklB->GetHCId() != 2*iDet + 1)
2426 sortedTracklets.Add(trklNext);
2431 // updating tracklet indices as in output
2432 if (sortedTracklets.GetEntries() != trklIndex) {
2433 indices[2*iDet + 0] = trklIndex;
2434 indices[2*iDet + 1] = sortedTracklets.GetEntries();
2436 indices[2*iDet + 0] = indices[2*iDet + 1] = -1;
2441 void AliTRDrawStream::AssignTracklets(AliESDTrdTrack *trdTrack, Int_t *trackletIndex, Int_t refIndex[6])
2443 UInt_t mask = trdTrack->GetLayerMask();
2444 UInt_t stack = trdTrack->GetStack();
2446 for (Int_t iLayer = 0; iLayer < 6; iLayer++) {
2447 refIndex[iLayer] = -1;
2449 if (mask & (1 << iLayer)) {
2451 Int_t det = trdTrack->GetSector()*30 + stack*6 + iLayer;
2452 Int_t idx = trdTrack->GetTrackletIndex(iLayer);
2454 if ((det < 0) || (det > 539)) {
2455 AliErrorClass(Form("Invalid detector no. from track: %i", 2*det));
2458 if (trackletIndex[2*det] >= 0) {
2459 if ((trackletIndex[2*det] + idx > -1) &&
2460 (trackletIndex[2*det] + idx < trackletIndex[2*det+1])) {
2461 refIndex[iLayer] = trackletIndex[2*det] + idx;
2463 AliErrorClass(Form("Requested tracklet index %i out of range", idx));
2466 AliErrorClass(Form("Non-existing tracklets requested in det %i", det));