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 // Author: J. Klein (jochen.klein@cern.ch) //
23 ////////////////////////////////////////////////////////////////////////////
28 #include "TClonesArray.h"
32 #include "AliRawReader.h"
33 #include "AliTRDcalibDB.h"
34 #include "AliTRDdigitsManager.h"
35 #include "AliTRDdigitsParam.h"
36 #include "AliTRDcalibDB.h"
37 #include "AliTRDmcmSim.h"
38 #include "AliTRDtrapConfig.h"
39 #include "AliTRDarrayADC.h"
40 #include "AliTRDarrayDictionary.h"
41 #include "AliTRDSignalIndex.h"
42 #include "AliTRDtrackletWord.h"
43 #include "AliTRDtrackletMCM.h"
44 #include "AliESDTrdTrack.h"
45 #include "AliTreeLoader.h"
46 #include "AliLoader.h"
48 #include "AliTRDrawStream.h"
51 #include "AliRunLoader.h"
53 ClassImp(AliTRDrawStream)
55 // some static information
56 Int_t AliTRDrawStream::fgMcmOrder[] = {12, 13, 14, 15,
60 Int_t AliTRDrawStream::fgRobOrder [] = {0, 1, 2, 3};
61 const Int_t AliTRDrawStream::fgkNlinks = 12;
62 const Int_t AliTRDrawStream::fgkNstacks = 5;
63 const Int_t AliTRDrawStream::fgkNsectors = 18;
64 const Int_t AliTRDrawStream::fgkNtriggers = 12;
65 const UInt_t AliTRDrawStream::fgkDataEndmarker = 0x00000000;
66 const UInt_t AliTRDrawStream::fgkTrackletEndmarker = 0x10001000;
67 const UInt_t AliTRDrawStream::fgkStackEndmarker[] = { 0xe0d01000, 0xe0d10000 };
69 const char* AliTRDrawStream::fgkErrorMessages[] = {
71 "Link monitor active",
72 "Event counter mismatch",
73 "not a TRD equipment (1024-1041)",
74 "Invalid Stack header",
75 "Invalid detector number",
76 "No digits could be retrieved from the digitsmanager",
78 "HC check bits wrong",
79 "Unexpected position in readout stream",
80 "Invalid testpattern mode",
81 "Testpattern mismatch",
82 "Number of timebins changed",
83 "ADC mask inconsistent",
84 "ADC check bits invalid",
86 "Missing expected ADC channels",
87 "Missing MCM headers",
92 Int_t AliTRDrawStream::fgErrorDebugLevel[] = {
115 AliTRDrawStream::ErrorBehav_t AliTRDrawStream::fgErrorBehav[] = {
116 AliTRDrawStream::kTolerate,
117 AliTRDrawStream::kDiscardHC,
118 AliTRDrawStream::kTolerate,
119 AliTRDrawStream::kAbort,
120 AliTRDrawStream::kAbort,
121 AliTRDrawStream::kAbort,
122 AliTRDrawStream::kAbort,
123 AliTRDrawStream::kDiscardHC,
124 AliTRDrawStream::kDiscardHC,
125 AliTRDrawStream::kTolerate,
126 AliTRDrawStream::kTolerate,
127 AliTRDrawStream::kTolerate,
128 AliTRDrawStream::kTolerate,
129 AliTRDrawStream::kTolerate,
130 AliTRDrawStream::kTolerate,
131 AliTRDrawStream::kTolerate,
132 AliTRDrawStream::kTolerate,
133 AliTRDrawStream::kTolerate,
134 AliTRDrawStream::kTolerate,
135 AliTRDrawStream::kTolerate
138 AliTRDrawStream::AliTRDrawStream(AliRawReader *rawReader) :
139 fStoreError(&AliTRDrawStream::ForgetError),
140 fRawReader(rawReader),
157 fCurrSmHeaderSize(0),
158 fCurrSmHeaderVersion(0),
159 fCurrTrailerReadout(0),
160 fCurrTrgHeaderAvail(0),
161 fCurrTrgHeaderReadout(0),
162 fCurrTrkHeaderAvail(0),
163 fCurrStackEndmarkerAvail(0),
165 fCurrTriggerEnable(0),
166 fCurrTriggerFired(0),
168 fCurrTrackletEnable(0),
170 fCurrTrkHeaderIndexWord(0x0),
171 fCurrTrkHeaderSize(0x0),
173 fCurrTrgHeaderIndexWord(0x0),
174 fCurrTrgHeaderSize(0x0),
176 fCurrStackIndexWord(0x0),
177 fCurrStackHeaderSize(0x0),
178 fCurrStackHeaderVersion(0x0),
180 fCurrCleanCheckout(0x0),
184 fCurrLinkMonitorFlags(0x0),
185 fCurrLinkDataTypeFlags(0x0),
186 fCurrLinkDebugFlags(0x0),
187 fCurrMatchFlagsSRAM(0),
188 fCurrMatchFlagsPostBP(0),
189 fCurrChecksumStack(),
214 // default constructor
216 fCurrTrkHeaderIndexWord = new UInt_t[fgkNstacks];
217 fCurrTrkHeaderSize = new UInt_t[fgkNstacks];
218 fCurrTrkFlags = new ULong64_t[fgkNsectors*fgkNstacks];
219 fCurrTrgHeaderIndexWord = new UInt_t[fgkNtriggers];
220 fCurrTrgHeaderSize = new UInt_t[fgkNtriggers];
221 fCurrTrgFlags = new UInt_t[fgkNsectors];
222 fCurrStackIndexWord = new UInt_t[fgkNstacks];
223 fCurrStackHeaderSize = new UInt_t[fgkNstacks];
224 fCurrStackHeaderVersion = new UInt_t[fgkNstacks];
225 fCurrLinkMask = new UInt_t[fgkNstacks];
226 fCurrCleanCheckout = new UInt_t[fgkNstacks];
227 fCurrBoardId = new UInt_t[fgkNstacks];
228 fCurrHwRevTMU = new UInt_t[fgkNstacks];
229 fCurrLinkMonitorFlags = new UInt_t[fgkNstacks * fgkNlinks];
230 fCurrLinkDataTypeFlags = new UInt_t[fgkNstacks * fgkNlinks];
231 fCurrLinkDebugFlags = new UInt_t[fgkNstacks * fgkNlinks];
232 for (Int_t iSector = 0; iSector < fgkNsectors; iSector++)
233 fCurrTrgFlags[iSector] = 0;
234 for (Int_t i = 0; i < 100; i++)
237 // preparing TClonesArray
238 fTrackletArray = new TClonesArray("AliTRDtrackletWord", 256);
240 // setting up the error tree
241 fErrors = new TTree("errorStats", "Error statistics");
242 fErrors->SetDirectory(0x0);
243 fErrors->Branch("error", &fLastError);
244 fErrors->SetCircular(1000);
245 for (Int_t i = 0; i < 100; i++) {
251 AliTRDrawStream::~AliTRDrawStream()
257 delete [] fCurrTrkHeaderIndexWord;
258 delete [] fCurrTrkHeaderSize;
259 delete [] fCurrTrkFlags;
260 delete [] fCurrTrgHeaderIndexWord;
261 delete [] fCurrTrgHeaderSize;
262 delete [] fCurrTrgFlags;
263 delete [] fCurrStackIndexWord;
264 delete [] fCurrStackHeaderSize;
265 delete [] fCurrStackHeaderVersion;
266 delete [] fCurrLinkMask;
267 delete [] fCurrCleanCheckout;
268 delete [] fCurrBoardId;
269 delete [] fCurrHwRevTMU;
270 delete [] fCurrLinkMonitorFlags;
271 delete [] fCurrLinkDataTypeFlags;
272 delete [] fCurrLinkDebugFlags;
275 Bool_t AliTRDrawStream::ReadEvent(TTree *trackletTree)
277 // read the current event from the raw reader and fill it to the digits manager
280 AliError("No raw reader available");
285 ConnectTracklets(trackletTree);
290 // loop over all DDLs
291 // data starts with GTU payload, i.e. SM index word
292 UChar_t *buffer = 0x0;
294 while (fRawReader->ReadNextData(buffer)) {
296 fCurrEquipmentId = fRawReader->GetEquipmentId();
297 AliDebug(2, Form("equipment: %i", fCurrEquipmentId));
299 if (fCurrEquipmentId < kDDLOffset || fCurrEquipmentId > kDDLMax) {
300 EquipmentError(kNonTrdEq, "Skipping");
305 new ((*fMarkers)[fMarkers->GetEntriesFast()])
306 AliTRDrawStreamError(-kSecactive, fCurrEquipmentId - kDDLOffset);
308 ReadGTUHeaders((UInt_t*) buffer);
310 if (fCurrTrailerReadout)
313 // loop over all active links
314 AliDebug(2, Form("Stack mask 0x%02x", fCurrStackMask));
315 for (Int_t iStack = 0; iStack < fgkNstacks; iStack++) {
317 if ((fCurrStackMask & (1 << fCurrSlot)) == 0)
320 AliDebug(2, Form("Stack %i, Link mask: 0x%02x", fCurrSlot, fCurrLinkMask[fCurrSlot]));
321 for (Int_t iLink = 0; iLink < fgkNlinks; iLink++) {
323 fCurrHC = (fCurrEquipmentId - kDDLOffset) * fgkNstacks * fgkNlinks +
324 fCurrSlot * fgkNlinks + iLink;
325 if ((fCurrLinkMask[fCurrSlot] & (1 << fCurrLink)) == 0)
331 // check for link monitor error flag
332 if (fCurrLinkMonitorFlags[fCurrSlot*fgkNlinks + fCurrLink] != 0) {
333 LinkError(kLinkMonitor);
334 if (fgErrorBehav[kLinkMonitor] == kTolerate)
335 size += ReadLinkData();
338 // read the data from one HC
339 size += ReadLinkData();
341 // read all data endmarkers
342 size += SeekNextLink();
345 // continue with next stack
354 Bool_t AliTRDrawStream::NextDDL()
356 // continue reading with the next equipment
361 fCurrEquipmentId = 0;
365 UChar_t *buffer = 0x0;
367 while (fRawReader->ReadNextData(buffer)) {
369 fCurrEquipmentId = fRawReader->GetEquipmentId();
370 AliDebug(2, Form("equipment: %i", fCurrEquipmentId));
372 if (fCurrEquipmentId < kDDLOffset || fCurrEquipmentId > kDDLMax) {
373 EquipmentError(kNonTrdEq, "Skipping");
378 new ((*fMarkers)[fMarkers->GetEntriesFast()])
379 AliTRDrawStreamError(-kSecactive, fCurrEquipmentId - kDDLOffset);
381 ReadGTUHeaders((UInt_t*) buffer);
383 if (fCurrTrailerReadout)
393 Int_t AliTRDrawStream::NextChamber(AliTRDdigitsManager *digMgr)
395 // read the data for the next chamber
396 // in case you only want to read the data of a single chamber
397 // to read all data ReadEvent(...) is recommended
399 fDigitsManager = digMgr;
404 // tracklet output preparation
405 TTree *trklTree = 0x0;
406 AliRunLoader *rl = AliRunLoader::Instance();
407 AliLoader* trdLoader = rl ? rl->GetLoader("TRDLoader") : NULL;
408 AliDataLoader *trklLoader = trdLoader ? trdLoader->GetDataLoader("tracklets") : NULL;
410 AliTreeLoader *trklTreeLoader = (AliTreeLoader*) trklLoader->GetBaseLoader("tracklets-raw");
412 trklTree = trklTreeLoader->Tree();
414 trklTree = trklLoader->Tree();
417 if (fTrackletTree != trklTree)
418 ConnectTracklets(trklTree);
421 AliError("No raw reader available");
425 while (fCurrSlot < 0 || fCurrSlot >= fgkNstacks) {
430 while ((fCurrSlot < fgkNstacks) &&
431 (((fCurrStackMask & (1 << fCurrSlot)) == 0) ||
432 ((fCurrLinkMask[fCurrSlot] & (1 << fCurrLink))) == 0)) {
433 if ((fCurrStackMask & (1 << fCurrSlot)) == 0) {
439 if (fCurrLink >= fgkNlinks) {
447 AliDebug(2, Form("Stack %i, Link %i, mask: 0x%02x", fCurrSlot, fCurrLink, fCurrLinkMask[fCurrSlot]));
448 fCurrHC = (fCurrEquipmentId - kDDLOffset) * fgkNlinks * fgkNstacks +
449 fCurrSlot * fgkNlinks + fCurrLink;
451 if (fCurrLinkMonitorFlags[fCurrSlot*fgkNlinks + fCurrLink] != 0) {
452 LinkError(kLinkMonitor);
453 if (fgErrorBehav[kLinkMonitor] == kTolerate)
457 // read the data from one HC
460 // read all data endmarkers
463 if (fCurrLink % 2 == 0) {
464 // if we just read the A-side HC then also check the B-side
467 if (fCurrLinkMask[fCurrSlot] & (1 << fCurrLink)) {
468 if (fCurrLinkMonitorFlags[fCurrSlot*fgkNlinks + fCurrLink] != 0) {
469 LinkError(kLinkMonitor);
470 if (fgErrorBehav[kLinkMonitor] == kTolerate)
481 if ((fCurrStackMask & (1 << fCurrSlot)) == 0) {
487 if (fCurrLink >= fgkNlinks) {
493 } while ((fCurrSlot < fgkNstacks) &&
494 (((fCurrStackMask & (1 << fCurrSlot)) == 0) ||
495 ((fCurrLinkMask[fCurrSlot] & (1 << fCurrLink))) == 0));
497 // return chamber information from HC if it is valid
498 // otherwise return information from link position
499 if (fCurrSm < 0 || fCurrSm >= fgkNsectors || fCurrStack < 0 || fCurrStack >= fgkNstacks || fCurrLayer < 0 || fCurrLayer >= fgkNlinks/2)
500 return ((fCurrEquipmentId-kDDLOffset) + fCurrSlot * fgkNlinks/2 + fCurrLink/2);
502 return (fCurrSm * fgkNstacks*fgkNlinks/2 + fCurrStack * fgkNlinks/2 + fCurrLayer);
506 Int_t AliTRDrawStream::ReadGTUHeaders(UInt_t *buffer)
508 // check the data source and read the headers
510 if (fCurrEquipmentId >= kDDLOffset && fCurrEquipmentId <= kDDLMax) {
513 // setting the pointer to data and current reading position
514 fPayloadCurr = fPayloadStart = buffer;
515 fPayloadSize = fRawReader->GetDataSize() / sizeof(UInt_t);
516 fStats.fStatsSector[fCurrEquipmentId - kDDLOffset].fBytes = fRawReader->GetDataSize();
517 AliDebug(2, Form("Read buffer of size: %i", fRawReader->GetDataSize()));
519 AliDebug(1, DumpRaw("raw data", fPayloadCurr, TMath::Min(fPayloadSize, 1000)));
522 if (ReadSmHeader() < 0) {
523 AliError(Form("Reading SM header failed, skipping this DDL %i", fCurrEquipmentId));
527 // read tracking headers (if available)
528 if (fCurrTrkHeaderAvail) {
529 for (Int_t iStack = 0; iStack < fgkNstacks; iStack++) {
530 if ((fCurrStackMask & (1 << iStack)) != 0)
531 ReadTrackingHeader(iStack);
535 // read trigger header(s) (if available)
536 if (fCurrTrgHeaderAvail)
537 ReadTriggerHeaders();
540 for (Int_t iStack = 0; iStack < fgkNstacks; iStack++) {
541 if ((fCurrStackMask & (1 << iStack)) != 0)
542 ReadStackHeader(iStack);
551 Int_t AliTRDrawStream::ReadSmHeader()
553 // read the SMU index header at the current reading position
554 // and store the information in the corresponding variables
556 if (fPayloadCurr - fPayloadStart >= fPayloadSize - 1) {
557 EquipmentError(kUnknown, "SM Header incomplete");
561 fCurrTrgFlags[fCurrEquipmentId-kDDLOffset] = 0;
563 fCurrSmHeaderSize = ((*fPayloadCurr) >> 16) & 0xffff;
564 fCurrSmHeaderVersion = ((*fPayloadCurr) >> 12) & 0xf;
565 fCurrTrackEnable = ((*fPayloadCurr) >> 6) & 0x1;
566 fCurrTrackletEnable = ((*fPayloadCurr) >> 5) & 0x1;
567 fCurrStackMask = ((*fPayloadCurr) ) & 0x1f;
568 fCurrHwRev = (fPayloadCurr[1] >> 12) & 0xffff;
569 fCurrStackEndmarkerAvail = 0;
571 switch (fCurrSmHeaderVersion) {
573 fCurrTrailerReadout = 0;
574 fCurrTrgHeaderAvail = 0;
576 fCurrTrkHeaderAvail = 0;
582 fCurrTrailerReadout = ((*fPayloadCurr) >> 10) & 0x1;
583 fCurrTrgHeaderAvail = 1;
584 fCurrTrgHeaderReadout = ((*fPayloadCurr) >> 9) & 0x1;
585 fCurrEvType = ((*fPayloadCurr) >> 7) & 0x3;
586 fCurrTrkHeaderAvail = fCurrTrackEnable;
587 fCurrTriggerEnable = (fPayloadCurr[2] >> 8) & 0xfff;
588 fCurrTriggerFired = (fPayloadCurr[2] >> 20) & 0xfff;
589 fCurrTrgFlags[fCurrEquipmentId-kDDLOffset] = fCurrTriggerFired;
593 fCurrTrailerReadout = ((*fPayloadCurr) >> 10) & 0x1;
594 fCurrTrgHeaderAvail = 1;
595 fCurrTrgHeaderReadout = ((*fPayloadCurr) >> 9) & 0x1;
596 fCurrEvType = ((*fPayloadCurr) >> 7) & 0x3;
597 fCurrTrkHeaderAvail = fCurrTrackEnable;
598 fCurrTriggerEnable = (fPayloadCurr[2] >> 8) & 0xfff;
599 fCurrTriggerFired = (fPayloadCurr[2] >> 20) & 0xfff;
600 fCurrTrgFlags[fCurrEquipmentId-kDDLOffset] = fCurrTriggerFired;
601 fCurrStackEndmarkerAvail = 1;
605 AliError(Form("unknown SM header version: 0x%x", fCurrSmHeaderVersion));
608 AliDebug(5, Form("SM header: size: %i, version: %i, track enable: %i, tracklet enable: %i, stack mask: %2x, trailer: %i, trgheader: %i, trkheader: %i",
610 fCurrSmHeaderVersion,
616 fCurrTrkHeaderAvail ));
618 // jump to the first word after the SM header
619 fPayloadCurr += fCurrSmHeaderSize + 1;
621 return fCurrSmHeaderSize + 1;
624 Int_t AliTRDrawStream::DecodeGTUtracks()
626 // decode GTU track words
627 // this depends on the hardware revision of the SMU
629 Int_t sector = fCurrEquipmentId-kDDLOffset;
631 if ((sector < 0) || (sector > 17)) {
632 AliError(Form("Invalid sector %i for GTU tracks", sector));
636 AliDebug(1, DumpRaw(Form("GTU tracks in sector %2i (hw rev %i)", sector, fCurrHwRev),
637 fPayloadCurr + 4, 10, 0xffe0ffff));
639 fCurrTrgFlags[sector] = 0;
641 if (fCurrHwRev < 1772) {
642 UInt_t fastWord; // fast trigger word
643 ULong64_t trackWord = 0; // extended track word
646 for (UInt_t iWord = 4; iWord < fCurrSmHeaderSize; iWord++) {
647 if (fPayloadCurr[iWord] == 0x10000000) { // stack boundary marker
653 ((fPayloadCurr[iWord] & 0xfffff0f0) == 0x13370000)) {
654 fastWord = fPayloadCurr[iWord];
655 fCurrTrgFlags[sector] |= 1 << (stack+11); // assume tracking done if fast word sent
656 AliDebug(1, Form("stack %i: fast trigger word: 0x%08x", stack, fastWord));
659 else if ((idx & 0x1) == 0x1) {
660 trackWord |= ((ULong64_t) fPayloadCurr[iWord]) << 32;
661 AliDebug(1,Form("track debug word: 0x%016llx", trackWord));
663 AliESDTrdTrack *trk = new ((*fTracks)[fTracks->GetEntriesFast()])
666 trk->SetSector(sector);
667 trk->SetStack((trackWord >> 60) & 0x7);
671 trk->SetLayerMask((trackWord >> 16) & 0x3f);
672 trk->SetTrackletIndex((trackWord >> 22) & 0x3f, 0);
673 trk->SetTrackletIndex((trackWord >> 28) & 0x3f, 1);
674 trk->SetTrackletIndex((trackWord >> 34) & 0x3f, 2);
675 trk->SetTrackletIndex((trackWord >> 40) & 0x3f, 3);
676 trk->SetTrackletIndex((trackWord >> 46) & 0x3f, 4);
677 trk->SetTrackletIndex((trackWord >> 52) & 0x3f, 5);
683 Float_t pt = (((Int_t) (trackWord & 0xffff) ^ 0x8000) - 0x8000)/128.;
684 if (TMath::Abs(pt) > 0.1) {
685 trk->SetA((Int_t) (0.15*51625./100./pt / 160e-4 * 2));
690 trackWord = fPayloadCurr[iWord];
696 else if (fCurrHwRev < 1804) {
697 UInt_t fastWord; // fast trigger word
698 ULong64_t trackWord = 0; // extended track word
701 for (UInt_t iWord = 4; iWord < fCurrSmHeaderSize; iWord++) {
702 if (fPayloadCurr[iWord] == 0xffe0ffff) { // stack boundary marker
708 ((fPayloadCurr[iWord] & 0xfffff0f0) == 0x13370000)) {
709 fastWord = fPayloadCurr[iWord];
710 fCurrTrgFlags[sector] |= 1 << (stack+11); // assume tracking done if fast word sent
711 AliDebug(1, Form("stack %i: fast trigger word: 0x%08x", stack, fastWord));
714 else if ((idx & 0x1) == 0x1) {
715 trackWord |= ((ULong64_t) fPayloadCurr[iWord]) << 32;
716 AliDebug(1, Form("track debug word: 0x%016llx", trackWord));
718 AliESDTrdTrack *trk = new ((*fTracks)[fTracks->GetEntriesFast()])
721 trk->SetSector(fCurrEquipmentId-kDDLOffset);
722 trk->SetStack((trackWord >> 60) & 0x7);
726 trk->SetLayerMask((trackWord >> 16) & 0x3f);
727 trk->SetTrackletIndex((trackWord >> 22) & 0x3f, 0);
728 trk->SetTrackletIndex((trackWord >> 28) & 0x3f, 1);
729 trk->SetTrackletIndex((trackWord >> 34) & 0x3f, 2);
730 trk->SetTrackletIndex((trackWord >> 40) & 0x3f, 3);
731 trk->SetTrackletIndex((trackWord >> 46) & 0x3f, 4);
732 trk->SetTrackletIndex((trackWord >> 52) & 0x3f, 5);
738 Float_t pt = (((Int_t) (trackWord & 0xffff) ^ 0x8000) - 0x8000)/128.;
739 if (TMath::Abs(pt) > 0.1) {
740 trk->SetA((Int_t) (-0.15*51625./100./pt / 160e-4 * 2));
745 trackWord = fPayloadCurr[iWord];
751 else if (fCurrHwRev < 1819) {
752 UInt_t fastWord; // fast trigger word
753 ULong64_t trackWord = 0; // extended track word
756 for (UInt_t iWord = 4; iWord < fCurrSmHeaderSize; iWord++) {
757 if (fPayloadCurr[iWord] == 0xffe0ffff) { // stack boundary marker
763 ((fPayloadCurr[iWord] & 0xfffff0f0) == 0x13370000)) {
764 fastWord = fPayloadCurr[iWord];
765 if (fastWord & (1 << 13))
766 fCurrTrgFlags[sector] |= 1 << (stack+11);
767 AliDebug(1, Form("stack %i: fast trigger word: 0x%08x", stack, fastWord));
770 else if ((idx & 0x1) == 0x1) {
771 trackWord |= ((ULong64_t) fPayloadCurr[iWord]) << 32;
772 AliDebug(1, Form("track debug word: 0x%016llx", trackWord));
775 AliESDTrdTrack *trk = new ((*fTracks)[fTracks->GetEntriesFast()])
778 trk->SetSector(fCurrEquipmentId-kDDLOffset);
779 trk->SetStack((trackWord >> 60) & 0x7);
782 // trk->SetPt(((trackWord & 0xffff) ^ 0x8000) - 0x8000);
784 trk->SetLayerMask((trackWord >> 16) & 0x3f);
785 trk->SetTrackletIndex((trackWord >> 22) & 0x3f, 0);
786 trk->SetTrackletIndex((trackWord >> 28) & 0x3f, 1);
787 trk->SetTrackletIndex((trackWord >> 34) & 0x3f, 2);
788 trk->SetTrackletIndex((trackWord >> 40) & 0x3f, 3);
789 trk->SetTrackletIndex((trackWord >> 46) & 0x3f, 4);
790 trk->SetTrackletIndex((trackWord >> 52) & 0x3f, 5);
796 Float_t pt = (((Int_t) (trackWord & 0xffff) ^ 0x8000) - 0x8000)/128.;
797 if (TMath::Abs(pt) > 0.1) {
798 trk->SetA((Int_t) (0.15*51625./100./trk->Pt() / 160e-4 * 2));
803 trackWord = fPayloadCurr[iWord];
809 else if (fCurrHwRev < 1860) {
810 UInt_t fastWord; // fast trigger word
811 ULong64_t trackWord = 0; // extended track word
814 Bool_t upperWord = kFALSE;
816 for (UInt_t iWord = 4; iWord < fCurrSmHeaderSize; iWord++) {
817 if (fPayloadCurr[iWord] == 0xffe0ffff) { // stack boundary marker
823 // assemble the 32-bit words out of 16-bit blocks
825 word |= (fPayloadCurr[iWord] & 0xffff0000);
829 // lower word is read first
830 word = (fPayloadCurr[iWord] & 0xffff0000) >> 16;
835 if ((word & 0xffff0008) == 0x13370008) {
837 AliDebug(1, Form("stack %i: fast track word: 0x%08x", stack, fastWord));
838 if (fastWord & (1 << 13))
839 fCurrTrgFlags[sector] |= 1 << (stack+11);
842 else if ((idx & 0x1) == 0x1) {
843 trackWord |= ((ULong64_t) word) << 32;
844 AliDebug(1, Form("track debug word: 0x%016llx", trackWord));
846 AliESDTrdTrack *trk = new ((*fTracks)[fTracks->GetEntriesFast()])
849 trk->SetSector(fCurrEquipmentId-kDDLOffset);
850 trk->SetStack((trackWord >> 60) & 0x7);
854 trk->SetLayerMask((trackWord >> 16) & 0x3f);
855 trk->SetTrackletIndex((trackWord >> 22) & 0x3f, 0);
856 trk->SetTrackletIndex((trackWord >> 28) & 0x3f, 1);
857 trk->SetTrackletIndex((trackWord >> 34) & 0x3f, 2);
858 trk->SetTrackletIndex((trackWord >> 40) & 0x3f, 3);
859 trk->SetTrackletIndex((trackWord >> 46) & 0x3f, 4);
860 trk->SetTrackletIndex((trackWord >> 52) & 0x3f, 5);
866 Float_t pt = (((Int_t) (trackWord & 0xffff) ^ 0x8000) - 0x8000)/128.;
867 if (TMath::Abs(pt) > 0.1) {
868 trk->SetA((Int_t) (0.15*51625./100./pt / 160e-4 * 2));
881 ULong64_t trackWord = 0; // this is the debug word
884 Bool_t upperWord = kFALSE;
886 for (UInt_t iWord = 4; iWord < fCurrSmHeaderSize; iWord++) {
887 if (fPayloadCurr[iWord] == 0xffe0ffff) {
893 // assemble the 32-bit words out of 16-bit blocks
895 word |= (fPayloadCurr[iWord] & 0xffff0000);
899 // lower word is read first
900 word = (fPayloadCurr[iWord] & 0xffff0000) >> 16;
905 if ((word & 0xffff0008) == 0x13370008) {
906 AliDebug(1, Form("stack %i: fast track word: 0x%08x", stack, word));
909 else if ((word & 0xffff0010) == 0x13370010) {
910 AliDebug(1, Form("stack %i: tracking done word: 0x%08x", stack, word));
911 fCurrTrgFlags[sector] |= 1 << (stack+11);
914 else if ((idx & 0x1) == 0x1) {
915 trackWord |= ((ULong64_t) word) << 32;
916 AliDebug(1, Form("track debug word: 0x%16llx", trackWord));
918 AliESDTrdTrack *trk = new ((*fTracks)[fTracks->GetEntriesFast()])
920 trk->SetSector(fCurrEquipmentId-kDDLOffset);
921 trk->SetStack((trackWord >> 60) & 0x7);
925 trk->SetLayerMask((trackWord >> 16) & 0x3f);
926 trk->SetTrackletIndex((trackWord >> 22) & 0x3f, 0);
927 trk->SetTrackletIndex((trackWord >> 28) & 0x3f, 1);
928 trk->SetTrackletIndex((trackWord >> 34) & 0x3f, 2);
929 trk->SetTrackletIndex((trackWord >> 40) & 0x3f, 3);
930 trk->SetTrackletIndex((trackWord >> 46) & 0x3f, 4);
931 trk->SetTrackletIndex((trackWord >> 52) & 0x3f, 5);
937 Float_t pt = (((Int_t) (trackWord & 0xffff) ^ 0x8000) - 0x8000)/128.;
938 if (TMath::Abs(pt) > 0.1) {
939 trk->SetA(-(Int_t) (0.15*51625./100./pt / 160e-4 * 2));
953 Int_t AliTRDrawStream::ReadTrackingHeader(Int_t stack)
955 // read the tracking information and store it for the given stack
959 fCurrTrkHeaderIndexWord[stack] = *fPayloadCurr;
960 fCurrTrkHeaderSize[stack] = ((*fPayloadCurr) >> 16) & 0x3ff;
962 AliDebug(1, Form("tracking header index word: 0x%08x, size: %i (hw rev: %i)",
963 fCurrTrkHeaderIndexWord[stack], fCurrTrkHeaderSize[stack], fCurrHwRev));
964 Int_t trackingTime = *fPayloadCurr & 0x3ff;
966 fCurrTrgFlags[fCurrEquipmentId-kDDLOffset] |= ((fCurrTrkHeaderIndexWord[stack] >> 10) & 0x1) << (22 + stack);
970 ULong64_t trackWord = 0;
972 Int_t trackIndex = fTracks ? fTracks->GetEntriesFast() : -1;
974 for (UInt_t iWord = 0; iWord < fCurrTrkHeaderSize[stack]; iWord++) {
977 // first part of 64-bit word
978 trackWord = fPayloadCurr[iWord];
981 trackWord |= ((ULong64_t) fPayloadCurr[iWord]) << 32;
983 if (trackWord & (1ul << 63)) {
984 if ((trackWord & (0x3ful << 56)) != 0) {
986 AliDebug(2, Form("track word: 0x%016llx", trackWord));
989 AliESDTrdTrack *trk = new ((*fTracks)[fTracks->GetEntriesFast()])
992 trk->SetSector(fCurrEquipmentId-kDDLOffset);
993 trk->SetLayerMask((trackWord >> 56) & 0x3f);
994 trk->SetA( (((trackWord >> 38) & 0x3ffff) ^ 0x20000) - 0x20000);
995 trk->SetB( (((trackWord >> 20) & 0x3ffff) ^ 0x20000) - 0x20000);
996 trk->SetC( (((trackWord >> 8) & 0xffff) ^ 0x8000) - 0x8000);
997 trk->SetPID((trackWord >> 0) & 0xff);
998 trk->SetStack(stack);
1001 // now compare the track word with the one generated from the ESD information
1002 if (trackWord != trk->GetTrackWord(0)) {
1003 AliError(Form("track word 0x%016llx does not match the read one 0x%016llx",
1004 trk->GetTrackWord(0), trackWord));
1009 // done marker (so far only used to set trigger flag)
1010 fCurrTrgFlags[fCurrEquipmentId-kDDLOffset] |= 1 << (27 + stack);
1011 fCurrTrkFlags[(fCurrEquipmentId-kDDLOffset)*fgkNstacks + stack] = trackWord;
1013 AliDebug(2, Form("tracking done marker: 0x%016llx, trigger flags: 0x%08x",
1014 trackWord, fCurrTrgFlags[fCurrEquipmentId-kDDLOffset]));
1015 AliDebug(2, Form("seg / stack / first / last / done / index : %i %i %lli %lli %lli %i",
1016 fCurrEquipmentId - kDDLOffset, stack,
1017 (trackWord >> 20) & 0x3ff,
1018 (trackWord >> 10) & 0x3ff,
1019 (trackWord >> 0) & 0x3ff,
1024 // extended track word
1025 AliDebug(2, Form("extended track word: 0x%016llx", trackWord));
1028 AliESDTrdTrack *trk = (AliESDTrdTrack*) (*fTracks)[trackIndex];
1030 trk->SetFlags((trackWord >> 52) & 0x7ff);
1031 trk->SetReserved((trackWord >> 49) & 0x7);
1032 trk->SetY((trackWord >> 36) & 0x1fff);
1033 trk->SetTrackletIndex((trackWord >> 0) & 0x3f, 0);
1034 trk->SetTrackletIndex((trackWord >> 6) & 0x3f, 1);
1035 trk->SetTrackletIndex((trackWord >> 12) & 0x3f, 2);
1036 trk->SetTrackletIndex((trackWord >> 18) & 0x3f, 3);
1037 trk->SetTrackletIndex((trackWord >> 24) & 0x3f, 4);
1038 trk->SetTrackletIndex((trackWord >> 30) & 0x3f, 5);
1040 if (trackWord != trk->GetExtendedTrackWord(0)) {
1041 AliError(Form("extended track word 0x%016llx does not match the read one 0x%016llx",
1042 trk->GetExtendedTrackWord(0), trackWord));
1052 fPayloadCurr += fCurrTrkHeaderSize[stack];
1054 return fCurrTrkHeaderSize[stack];
1057 Int_t AliTRDrawStream::ReadTriggerHeaders()
1059 // read all trigger headers present
1061 AliDebug(1, Form("trigger mask: 0x%03x, fired: 0x%03x\n",
1062 fCurrTriggerEnable, fCurrTriggerFired));
1063 // loop over potential trigger blocks
1064 for (Int_t iTrigger = 0; iTrigger < fgkNtriggers; iTrigger++) {
1065 // check for trigger enable
1066 if (fCurrTriggerEnable & (1 << iTrigger)) {
1067 // check for readout mode and trigger fired
1068 if ((fCurrTrgHeaderReadout == 0) || (fCurrTriggerFired & (1 << iTrigger))) {
1070 AliDebug(1, Form("trigger index word %i: 0x%08x\n", iTrigger, *fPayloadCurr));
1071 fCurrTrgHeaderIndexWord[iTrigger] = *fPayloadCurr;
1072 fCurrTrgHeaderSize[iTrigger] = ((*fPayloadCurr) >> 16) & 0x3ff;
1073 if (iTrigger == 7) {
1074 // timeout trigger, use to extract tracking time
1075 fCurrTrgFlags[fCurrEquipmentId-kDDLOffset] |= (*fPayloadCurr & 0x3ff) << 12;
1080 fPayloadCurr += fCurrTrgHeaderSize[iTrigger];
1088 Int_t AliTRDrawStream::ReadStackHeader(Int_t stack)
1090 // read the stack header
1091 // and store the information in the corresponding variables
1093 fCurrStackIndexWord[stack] = *fPayloadCurr;
1094 fCurrStackHeaderSize[stack] = (((*fPayloadCurr) >> 16) & 0xffff) + 1;
1095 fCurrStackHeaderVersion[stack] = ((*fPayloadCurr) >> 12) & 0xf;
1096 fCurrLinkMask[stack] = (*fPayloadCurr) & 0xfff;
1098 // dumping stack header
1099 AliDebug(1, DumpRaw(Form("stack %i header", stack), fPayloadCurr, fCurrStackHeaderSize[stack]));
1101 if (fPayloadCurr - fPayloadStart >= fPayloadSize - (Int_t) fCurrStackHeaderSize[stack]) {
1102 EquipmentError(kStackHeaderInvalid, "Stack index header %i incomplete", stack);
1103 // dumping stack header
1104 AliError(DumpRaw(Form("stack %i header", stack), fPayloadCurr, fCurrStackHeaderSize[stack]));
1109 switch (fCurrStackHeaderVersion[stack]) {
1111 if (fCurrStackHeaderSize[stack] < 8) {
1112 LinkError(kStackHeaderInvalid, "Stack header smaller than expected!");
1116 fCurrCleanCheckout[stack] = fPayloadCurr[1] & 0x1;
1117 fCurrBoardId[stack] = (fPayloadCurr[1] >> 8) & 0xff;
1118 fCurrHwRevTMU[stack] = (fPayloadCurr[1] >> 16) & 0xffff;
1120 for (Int_t iLayer = 0; iLayer < 6; iLayer++) {
1122 fCurrLinkMonitorFlags [stack*fgkNlinks + iLayer*2] = fPayloadCurr[iLayer+2] & 0xf;
1123 fCurrLinkDataTypeFlags [stack*fgkNlinks + iLayer*2] = (fPayloadCurr[iLayer+2] >> 4) & 0x3;
1124 fCurrLinkDebugFlags [stack*fgkNlinks + iLayer*2] = (fPayloadCurr[iLayer+2] >> 12) & 0xf;
1126 fCurrLinkMonitorFlags [stack*fgkNlinks + iLayer*2 + 1] = (fPayloadCurr[iLayer+2] >> 16) & 0xf;
1127 fCurrLinkDataTypeFlags [stack*fgkNlinks + iLayer*2 + 1] = (fPayloadCurr[iLayer+2] >> 20) & 0x3;
1128 fCurrLinkDebugFlags [stack*fgkNlinks + iLayer*2 + 1] = (fPayloadCurr[iLayer+2] >> 28) & 0xf;
1133 LinkError(kStackHeaderInvalid, "Invalid Stack Header version %x", fCurrStackHeaderVersion[stack]);
1136 fPayloadCurr += fCurrStackHeaderSize[stack];
1138 return fCurrStackHeaderSize[stack];
1141 Int_t AliTRDrawStream::ReadGTUTrailer()
1143 // read the SM trailer containing CRCs from various stages
1145 UInt_t* trailer = fPayloadStart + fPayloadSize -1;
1147 // look for the trailer index word from the end
1148 for (Int_t iWord = 0; iWord < fPayloadSize; iWord++) {
1149 if ((fPayloadStart[fPayloadSize-1-iWord] & 0xffff) == 0x1f51) {
1150 trailer = fPayloadStart + fPayloadSize - 1 - iWord;
1155 if (((*trailer) & 0xffff) == 0x1f51) {
1156 UInt_t trailerIndexWord = (*trailer);
1157 Int_t trailerSize = (trailerIndexWord >> 16) & 0xffff;
1158 AliDebug(2, DumpRaw("GTU trailer", trailer, trailerSize+1));
1159 // parse the trailer
1160 if (trailerSize >= 4) {
1161 // match flags from GTU
1162 fCurrMatchFlagsSRAM = (trailer[1] >> 0) & 0x1f;
1163 fCurrMatchFlagsPostBP = (trailer[1] >> 5) & 0x1f;
1164 // individual checksums
1165 fCurrChecksumStack[0] = (trailer[1] >> 16) & 0xffff;
1166 fCurrChecksumStack[1] = (trailer[2] >> 0) & 0xffff;
1167 fCurrChecksumStack[2] = (trailer[2] >> 16) & 0xffff;
1168 fCurrChecksumStack[3] = (trailer[3] >> 0) & 0xffff;
1169 fCurrChecksumStack[4] = (trailer[3] >> 16) & 0xffff;
1170 fCurrChecksumSIU = trailer[4];
1172 if ((fCurrMatchFlagsSRAM & fCurrStackMask) != fCurrStackMask)
1173 EquipmentError(kCRCmismatch, "CRC mismatch SRAM: 0x%02x", fCurrMatchFlagsSRAM);
1174 if ((fCurrMatchFlagsPostBP & fCurrStackMask) != fCurrStackMask)
1175 EquipmentError(kCRCmismatch, "CRC mismatch BP: 0x%02x", fCurrMatchFlagsPostBP);
1179 LinkError(kUnknown, "Invalid GTU trailer");
1183 EquipmentError(kUnknown, "trailer index marker mismatch");
1188 Int_t AliTRDrawStream::ReadLinkData()
1190 // read the data in one link (one HC) until the data endmarker is reached
1191 // returns the number of words read!
1194 UInt_t* startPosLink = fPayloadCurr;
1196 AliDebug(1, DumpRaw(Form("link data from seg %2i slot %i link %2i", fCurrEquipmentId-kDDLOffset, fCurrSlot, fCurrLink),
1197 fPayloadCurr, TMath::Min((Int_t) (fPayloadSize - (fPayloadCurr-fPayloadStart)), 100), 0x00000000));
1200 new ((*fMarkers)[fMarkers->GetEntriesFast()])
1201 AliTRDrawStreamError(-kHCactive, fCurrEquipmentId-kDDLOffset, fCurrSlot, fCurrLink);
1203 if (fErrorFlags & kDiscardHC)
1206 if (fCurrTrackletEnable) {
1207 count += ReadTracklets();
1208 if (fErrorFlags & kDiscardHC)
1212 AliDebug(1, DumpRaw("HC header", fPayloadCurr, 4, 0x00000000));
1213 count += ReadHcHeader();
1214 if (fErrorFlags & kDiscardHC)
1217 Int_t det = fCurrSm * 30 + fCurrStack * 6 + fCurrLayer;
1219 if (det > -1 && det < 540) {
1221 // ----- check which kind of data -----
1222 if (fCurrMajor & 0x40) {
1223 if ((fCurrMajor & 0x7) == 0x7) {
1224 AliDebug(1, "This is a config event");
1225 UInt_t *startPos = fPayloadCurr;
1226 while (fPayloadCurr - fPayloadStart < fPayloadSize &&
1227 *fPayloadCurr != fgkDataEndmarker)
1229 count += fPayloadCurr - startPos;
1231 // feeding TRAP config
1232 AliTRDtrapConfig *trapcfg = AliTRDcalibDB::Instance()->GetTrapConfig();
1233 AliTRDmcmSim::ReadPackedConfig(trapcfg, fCurrHC, startPos, fPayloadCurr - startPos);
1236 Int_t tpmode = fCurrMajor & 0x7;
1237 AliDebug(1, Form("Checking testpattern (mode %i) data", tpmode));
1238 count += ReadTPData(tpmode);
1242 // reading real data
1243 if (fDigitsManager) {
1244 if ((fAdcArray = fDigitsManager->GetDigits(det))) {
1245 //fAdcArray->Expand();
1246 if (fAdcArray->GetNtime() != fCurrNtimebins)
1247 fAdcArray->Allocate(16, 144, fCurrNtimebins);
1250 LinkError(kNoDigits);
1253 if (!fDigitsParam) {
1254 fDigitsParam = fDigitsManager->GetDigitsParam();
1257 fDigitsParam->SetPretriggerPhase(det, fCurrPtrgPhase);
1258 fDigitsParam->SetNTimeBins(det, fCurrNtimebins);
1259 fDigitsParam->SetADCbaseline(det, 10);
1262 if (fDigitsManager->UsesDictionaries()) {
1263 fDigitsManager->GetDictionary(det, 0)->Reset();
1264 fDigitsManager->GetDictionary(det, 1)->Reset();
1265 fDigitsManager->GetDictionary(det, 2)->Reset();
1268 if ((fSignalIndex = fDigitsManager->GetIndexes(det))) {
1269 fSignalIndex->SetSM(fCurrSm);
1270 fSignalIndex->SetStack(fCurrStack);
1271 fSignalIndex->SetLayer(fCurrLayer);
1272 fSignalIndex->SetDetNumber(det);
1273 if (!fSignalIndex->IsAllocated())
1274 fSignalIndex->Allocate(16, 144, fCurrNtimebins);
1277 if (fCurrMajor & 0x20) {
1278 AliDebug(1, "This is a zs event");
1279 count += ReadZSData();
1282 AliDebug(1, "This is a nozs event");
1283 count += ReadNonZSData();
1287 // just read until data endmarkers
1288 while (fPayloadCurr - fPayloadStart < fPayloadSize &&
1289 *fPayloadCurr != fgkDataEndmarker)
1295 LinkError(kInvalidDetector, "%i", det);
1296 while (fPayloadCurr - fPayloadStart < fPayloadSize &&
1297 *fPayloadCurr != fgkDataEndmarker)
1301 if (fCurrSm > -1 && fCurrSm < 18) {
1302 fStats.fStatsSector[fCurrSm].fStatsHC[fCurrHC%60].fBytes += (fPayloadCurr - startPosLink) * sizeof(UInt_t);
1303 fStats.fStatsSector[fCurrSm].fStatsHC[fCurrHC%60].fBytesRead += count * sizeof(UInt_t);
1304 fStats.fStatsSector[fCurrSm].fBytesRead += count * sizeof(UInt_t);
1305 fStats.fBytesRead += count * sizeof(UInt_t);
1311 Int_t AliTRDrawStream::ReadTracklets()
1313 // read the tracklets from one HC
1315 fTrackletArray->Clear();
1317 UInt_t *start = fPayloadCurr;
1318 while (*(fPayloadCurr) != fgkTrackletEndmarker &&
1319 *(fPayloadCurr) != fgkStackEndmarker[0] &&
1320 *(fPayloadCurr) != fgkStackEndmarker[1] &&
1321 fPayloadCurr - fPayloadStart < (fPayloadSize - 1)) {
1322 new ((*fTrackletArray)[fTrackletArray->GetEntriesFast()]) AliTRDtrackletWord(*(fPayloadCurr), fCurrHC);
1327 if (fTrackletArray->GetEntriesFast() > 0) {
1328 AliDebug(1, Form("Found %i tracklets in %i %i %i (ev. %i)", fTrackletArray->GetEntriesFast(),
1329 (fCurrEquipmentId-kDDLOffset), fCurrSlot, fCurrLink, fRawReader->GetEventIndex()));
1330 if (fCurrSm > -1 && fCurrSm < 18) {
1331 fStats.fStatsSector[fCurrSm].fStatsHC[fCurrHC%60].fNTracklets += fTrackletArray->GetEntriesFast();
1332 fStats.fStatsSector[fCurrSm].fNTracklets += fTrackletArray->GetEntriesFast();
1335 fTrackletTree->Fill();
1337 for (Int_t iTracklet = 0; iTracklet < fTrackletArray->GetEntriesFast(); iTracklet++) {
1338 new ((*fTracklets)[fTracklets->GetEntriesFast()]) AliTRDtrackletWord(*((AliTRDtrackletWord*)(*fTrackletArray)[iTracklet]));
1342 // loop over remaining tracklet endmarkers
1343 while ((*(fPayloadCurr) == fgkTrackletEndmarker &&
1344 fPayloadCurr - fPayloadStart < fPayloadSize))
1347 return fPayloadCurr - start;
1350 Int_t AliTRDrawStream::ReadHcHeader()
1352 // read and parse the HC header of one HC
1353 // and store the information in the corresponding variables
1355 AliDebug(1, Form("HC header: 0x%08x", *fPayloadCurr));
1356 UInt_t *start = fPayloadCurr;
1357 // check not to be at the data endmarker
1358 if (*fPayloadCurr == fgkDataEndmarker ||
1359 *(fPayloadCurr) == fgkStackEndmarker[0] ||
1360 *(fPayloadCurr) == fgkStackEndmarker[1]) {
1361 LinkError(kHCmismatch, "found endmarker where HC header should be");
1365 fCurrSpecial = (*fPayloadCurr >> 31) & 0x1;
1366 fCurrMajor = (*fPayloadCurr >> 24) & 0x7f;
1367 fCurrMinor = (*fPayloadCurr >> 17) & 0x7f;
1368 fCurrAddHcWords = (*fPayloadCurr >> 14) & 0x7;
1369 fCurrSm = (*fPayloadCurr >> 9) & 0x1f;
1370 fCurrLayer = (*fPayloadCurr >> 6) & 0x7;
1371 fCurrStack = (*fPayloadCurr >> 3) & 0x7;
1372 fCurrSide = (*fPayloadCurr >> 2) & 0x1;
1373 fCurrCheck = (*fPayloadCurr) & 0x3;
1375 if ((fCurrSm != (((Int_t) fCurrEquipmentId) - kDDLOffset)) ||
1376 (fCurrStack != fCurrSlot) ||
1377 (fCurrLayer != fCurrLink / 2) ||
1378 (fCurrSide != fCurrLink % 2)) {
1379 LinkError(kHCmismatch,
1380 "HC: %i, %i, %i, %i\n 0x%08x 0x%08x 0x%08x 0x%08x",
1381 fCurrSm, fCurrStack, fCurrLayer, fCurrSide,
1382 fPayloadCurr[0], fPayloadCurr[1], fPayloadCurr[2], fPayloadCurr[3]);
1384 if (fCurrCheck != 0x1) {
1385 LinkError(kHCcheckFailed);
1388 if (fCurrAddHcWords > 0) {
1389 fCurrNtimebins = (fPayloadCurr[1] >> 26) & 0x3f;
1390 fCurrBC = (fPayloadCurr[1] >> 10) & 0xffff;
1391 fCurrPtrgCnt = (fPayloadCurr[1] >> 6) & 0xf;
1392 fCurrPtrgPhase = (fPayloadCurr[1] >> 2) & 0xf;
1395 fPayloadCurr += 1 + fCurrAddHcWords;
1397 return (fPayloadCurr - start);
1400 Int_t AliTRDrawStream::ReadTPData(Int_t mode)
1402 // testing of testpattern 1 to 3 (hardcoded), 0 missing
1403 // evcnt checking missing
1405 Int_t cpufromchannel[] = {0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3};
1409 Int_t mcmcount = -1;
1410 Int_t wordcount = 0;
1411 Int_t channelcount = 0;
1413 UInt_t expadcval = 0;
1415 Int_t lastmcmpos = -1;
1416 Int_t lastrobpos = -1;
1418 UInt_t* start = fPayloadCurr;
1420 while (*(fPayloadCurr) != fgkDataEndmarker &&
1421 fPayloadCurr - fPayloadStart < fPayloadSize - 1) {
1423 // ----- Checking MCM Header -----
1424 AliDebug(2, DumpMcmHeader("MCM header: ", *fPayloadCurr));
1425 UInt_t *startPosMCM = fPayloadCurr;
1428 // ----- checking for proper readout order - ROB -----
1429 fCurrRobPos = ROB(*fPayloadCurr);
1430 if (GetROBReadoutPos(ROB(*fPayloadCurr) / 2) >= lastrobpos) {
1431 if (GetROBReadoutPos(ROB(*fPayloadCurr) / 2) > lastrobpos)
1433 lastrobpos = GetROBReadoutPos(ROB(*fPayloadCurr) / 2);
1436 ROBError(kPosUnexp, Form("#%i after #%i in readout order", GetROBReadoutPos(ROB(*fPayloadCurr) / 2), lastrobpos));
1439 // ----- checking for proper readout order - MCM -----
1440 fCurrMcmPos = MCM(*fPayloadCurr);
1441 if (GetMCMReadoutPos(MCM(*fPayloadCurr)) > lastmcmpos) {
1442 lastmcmpos = GetMCMReadoutPos(MCM(*fPayloadCurr));
1445 MCMError(kPosUnexp, Form("#%i after #%i in readout order", GetMCMReadoutPos(MCM(*fPayloadCurr)), lastmcmpos));
1448 if (EvNo(*fPayloadCurr) != (evno & 0xfffff)) {
1450 evno = EvNo(*fPayloadCurr);
1453 MCMError(kEvCntMismatch, "%i <-> %i", evno, EvNo(*fPayloadCurr));
1459 evcnt = 0x3f & *fPayloadCurr >> 26;
1462 while (channelcount < 21) {
1464 if (cpu != cpufromchannel[channelcount]) {
1465 cpu = cpufromchannel[channelcount];
1466 expadcval = (1 << 9) | (fCurrRobPos << 6) | (fCurrMcmPos << 2) | cpu;
1470 while (count < 10) {
1471 if (*fPayloadCurr == fgkDataEndmarker) {
1472 MCMError(kMissTpData);
1473 return (fPayloadCurr - start);
1476 if (channelcount % 2 == 0)
1483 expword |= expadcval << 2;
1484 expadcval = ( (expadcval << 1) | ( ( (expadcval >> 9) ^ (expadcval >> 6) ) & 1) ) & 0x3FF;
1485 expword |= expadcval << 12;
1486 expadcval = ( (expadcval << 1) | ( ( (expadcval >> 9) ^ (expadcval >> 6) ) & 1) ) & 0x3FF;
1487 expword |= expadcval << 22;
1488 expadcval = ( (expadcval << 1) | ( ( (expadcval >> 9) ^ (expadcval >> 6) ) & 1) ) & 0x3FF;
1490 else if (mode == 2) {
1491 // ----- TP 2 ------
1492 expword = ((0x3f & evcnt) << 26) | ((fCurrSm + 1) << 21) | ((fCurrLayer + 1) << 18) |
1493 ((fCurrStack + 1) << 15) |
1494 (fCurrRobPos << 12) | (fCurrMcmPos << 8) | (cpu << 6) | (wordcount + 1);
1496 else if (mode == 3) {
1498 expword = ((0xfff & evcnt) << 20) | (fCurrSm << 15) | (fCurrLink/2 << 12) | (fCurrStack << 9) |
1499 (fCurrRobPos << 6) | (fCurrMcmPos << 2) | (cpu << 0);
1503 LinkError(kTPmodeInvalid, "Just reading");
1506 diff = *fPayloadCurr ^ expword;
1507 AliDebug(11, Form("Comparing ch %2i, word %2i (cpu %i): 0x%08x <-> 0x%08x",
1508 channelcount, wordcount, cpu, *fPayloadCurr, expword));
1511 MCMError(kTPmismatch,
1512 "Seen 0x%08x, expected 0x%08x, diff: 0x%08x, 0x%04x, 0x%02x - word %2i (cpu %i, ch %i)",
1513 *fPayloadCurr, expword, diff,
1514 0xffff & (diff | diff >> 16),
1515 0xff & (diff | diff >> 8 | diff >> 16 | diff >> 24),
1516 wordcount, cpu, channelcount);;
1521 if (*fPayloadCurr == fgkDataEndmarker)
1522 return (fPayloadCurr - start);
1526 // continue with next MCM
1528 if (IsDumping() && DumpingMCM(fCurrHC/2, fCurrRobPos, fCurrMcmPos)) {
1529 AliInfo(DumpRaw(Form("Event %i: Det %3i ROB %i MCM %2i", fRawReader->GetEventIndex(), fCurrHC/2, fCurrRobPos, fCurrMcmPos),
1530 startPosMCM, fPayloadCurr - startPosMCM));
1534 return fPayloadCurr - start;
1538 Int_t AliTRDrawStream::ReadZSData()
1540 // read the zs data from one link from the current reading position
1542 UInt_t *start = fPayloadCurr;
1545 Int_t mcmcountExp = fCurrStack == 2 ? 48 : 64;
1546 Int_t channelcount = 0;
1547 Int_t channelcountExp = 0;
1548 Int_t channelcountMax = 0;
1550 Int_t currentTimebin = 0;
1553 Int_t lastmcmpos = -1;
1554 Int_t lastrobpos = -1;
1556 if (fCurrNtimebins != fNtimebins) {
1558 LinkError(kNtimebinsChanged,
1559 "No. of timebins changed from %i to %i", fNtimebins, fCurrNtimebins);
1560 fNtimebins = fCurrNtimebins;
1563 timebins = fNtimebins;
1565 while (*(fPayloadCurr) != fgkDataEndmarker &&
1566 *(fPayloadCurr) != fgkStackEndmarker[0] &&
1567 *(fPayloadCurr) != fgkStackEndmarker[1] &&
1568 fPayloadCurr - fPayloadStart < fPayloadSize) {
1570 // ----- Checking MCM Header -----
1571 AliDebug(2, DumpMcmHeader("MCM header: ", *fPayloadCurr));
1572 UInt_t *startPosMCM = fPayloadCurr;
1574 // ----- checking for proper readout order - ROB -----
1575 fCurrRobPos = ROB(*fPayloadCurr);
1576 if (GetROBReadoutPos(ROB(*fPayloadCurr) / 2) >= lastrobpos) {
1577 if (GetROBReadoutPos(ROB(*fPayloadCurr) / 2) > lastrobpos)
1579 lastrobpos = GetROBReadoutPos(ROB(*fPayloadCurr) / 2);
1582 ROBError(kPosUnexp, Form("#%i after #%i and #%i in readout order",
1583 GetROBReadoutPos(ROB(*fPayloadCurr) / 2), lastrobpos, GetROBReadoutPos(fCurrRobPos)));
1586 // ----- checking for proper readout order - MCM -----
1587 fCurrMcmPos = MCM(*fPayloadCurr);
1588 if (GetMCMReadoutPos(MCM(*fPayloadCurr)) > lastmcmpos) {
1589 lastmcmpos = GetMCMReadoutPos(MCM(*fPayloadCurr));
1592 MCMError(kPosUnexp, Form("#%i after #%i and #%i in readout order",
1593 GetMCMReadoutPos(MCM(*fPayloadCurr)), lastmcmpos, GetMCMReadoutPos(fCurrMcmPos)));
1596 if (EvNo(*fPayloadCurr) != (evno & 0xfffff)) {
1598 evno = EvNo(*fPayloadCurr);
1601 MCMError(kEvCntMismatch, "%i <-> %i", evno, EvNo(*fPayloadCurr));
1604 Int_t adccoloff = AdcColOffset(*fPayloadCurr);
1605 Int_t padcoloff = PadColOffset(*fPayloadCurr);
1606 Int_t row = Row(*fPayloadCurr);
1609 if ((row > 11) && (fCurrStack == 2)) {
1610 MCMError(kUnknown, "Data in padrow > 11 for stack 2");
1613 if (fErrorFlags & (kDiscardMCM | kDiscardHC | kDiscardDDL))
1616 // ----- Reading ADC channels -----
1617 AliDebug(2, DumpAdcMask("ADC mask: ", *fPayloadCurr));
1619 // ----- analysing the ADC mask -----
1621 channelcountExp = GetNActiveChannelsFromMask(*fPayloadCurr);
1622 channelcountMax = GetNActiveChannels(*fPayloadCurr);
1623 Int_t channelmask = GetActiveChannels(*fPayloadCurr);
1624 Int_t channelno = -1;
1627 if (channelcountExp != channelcountMax) {
1628 if (channelcountExp > channelcountMax) {
1629 Int_t temp = channelcountExp;
1630 channelcountExp = channelcountMax;
1631 channelcountMax = temp;
1633 while (channelcountExp < channelcountMax && channelcountExp < 21 &&
1634 fPayloadCurr - fPayloadStart < fPayloadSize - 10 * channelcountExp - 1) {
1635 MCMError(kAdcMaskInconsistent,
1636 "Possible MCM-H: 0x%08x, possible ADC-mask: 0x%08x",
1637 *(fPayloadCurr + 10 * channelcountExp),
1638 *(fPayloadCurr + 10 * channelcountExp + 1) );
1639 if (!CouldBeMCMhdr( *(fPayloadCurr + 10 * channelcountExp)) && !CouldBeADCmask( *(fPayloadCurr + 10 * channelcountExp + 1)))
1645 MCMError(kAdcMaskInconsistent,
1646 "Inconsistency in no. of active channels: Counter: %i, Mask: %i, chosen: %i!",
1647 GetNActiveChannels(fPayloadCurr[-1]), GetNActiveChannelsFromMask(fPayloadCurr[-1]), channelcountExp);
1649 AliDebug(2, Form("expecting %i active channels, %i timebins", channelcountExp, fCurrNtimebins));
1651 // ----- reading marked ADC channels -----
1652 while (channelcount < channelcountExp && *(fPayloadCurr) != fgkDataEndmarker) {
1655 while (channelno < 20 && (channelmask & 1 << channelno) == 0)
1658 if (fCurrNtimebins > 30) {
1659 currentTimebin = ((*fPayloadCurr >> 2) & 0x3f);
1660 timebins = ((*fPayloadCurr >> 8) & 0xf) * 3;
1667 Int_t nADCwords = (timebins + 2) / 3;
1668 AliDebug(3, Form("Now reading %i words for channel %2i", nADCwords, channelno));
1669 Int_t adccol = adccoloff - channelno;
1670 Int_t padcol = padcoloff - channelno;
1671 // if (adccol < 3 || adccol > 165)
1672 // AliInfo(Form("writing channel %i of det %3i %i:%2i to adcrow/-col: %i/%i padcol: %i",
1673 // channelno, fCurrHC/2, fCurrRobPos, fCurrMcmPos, row, adccol, padcol));
1675 while ((adcwc < nADCwords) &&
1676 (*(fPayloadCurr) != fgkDataEndmarker) &&
1677 (fPayloadCurr - fPayloadStart < fPayloadSize)) {
1678 int check = 0x3 & *fPayloadCurr;
1679 if (channelno % 2 != 0) { // odd channel
1680 if (check != 0x2 && channelno < 21) {
1681 MCMError(kAdcCheckInvalid,
1682 "%i for %2i. ADC word in odd channel %i",
1683 check, adcwc+1, channelno);
1686 else { // even channel
1687 if (check != 0x3 && channelno < 21) {
1688 MCMError(kAdcCheckInvalid,
1689 "%i for %2i. ADC word in even channel %i",
1690 check, adcwc+1, channelno);
1694 // filling the actual timebin data
1695 int tb2 = 0x3ff & *fPayloadCurr >> 22;
1696 int tb1 = 0x3ff & *fPayloadCurr >> 12;
1697 int tb0 = 0x3ff & *fPayloadCurr >> 2;
1698 if (adcwc != 0 || fCurrNtimebins <= 30)
1699 fAdcArray->SetDataByAdcCol(row, adccol, currentTimebin++, tb0);
1702 fAdcArray->SetDataByAdcCol(row, adccol, currentTimebin++, tb1);
1703 fAdcArray->SetDataByAdcCol(row, adccol, currentTimebin++, tb2);
1709 if (adcwc != nADCwords)
1710 MCMError(kAdcDataAbort);
1713 if (padcol > 0 && padcol < 144) {
1714 fSignalIndex->AddIndexRC(row, padcol);
1720 if (fCurrSm > -1 && fCurrSm < 18) {
1721 fStats.fStatsSector[fCurrSm].fStatsHC[fCurrHC%60].fNChannels += channelcount;
1722 fStats.fStatsSector[fCurrSm].fNChannels += channelcount;
1724 if (channelcount != channelcountExp)
1725 MCMError(kAdcChannelsMiss);
1728 if (fCurrSm > -1 && fCurrSm < 18) {
1729 fStats.fStatsSector[fCurrSm].fStatsHC[fCurrHC%60].fNMCMs++;
1730 fStats.fStatsSector[fCurrSm].fNMCMs++;
1733 if (IsDumping() && DumpingMCM(fCurrHC/2, fCurrRobPos, fCurrMcmPos)) {
1734 AliInfo(DumpRaw(Form("Event %i: Det %3i ROB %i MCM %2i", fRawReader->GetEventIndex(), fCurrHC/2, fCurrRobPos, fCurrMcmPos),
1735 startPosMCM, fPayloadCurr - startPosMCM));
1738 // continue with next MCM
1741 // check for missing MCMs (if header suppression is inactive)
1742 if (((fCurrMajor & 0x1) == 0) && (mcmcount != mcmcountExp)) {
1743 LinkError(kMissMcmHeaders,
1744 "No. of MCM headers %i not as expected: %i",
1745 mcmcount, mcmcountExp);
1748 return (fPayloadCurr - start);
1751 Int_t AliTRDrawStream::ReadNonZSData()
1753 // read the non-zs data from one link from the current reading position
1755 UInt_t *start = fPayloadCurr;
1758 Int_t mcmcountExp = fCurrStack == 2 ? 48 : 64;
1759 Int_t channelcount = 0;
1760 Int_t channelcountExp = 0;
1762 Int_t currentTimebin = 0;
1765 Int_t lastmcmpos = -1;
1766 Int_t lastrobpos = -1;
1768 if (fCurrNtimebins != fNtimebins) {
1770 LinkError(kNtimebinsChanged,
1771 "No. of timebins changed from %i to %i", fNtimebins, fCurrNtimebins);
1772 fNtimebins = fCurrNtimebins;
1775 timebins = fNtimebins;
1777 while (*(fPayloadCurr) != fgkDataEndmarker &&
1778 fPayloadCurr - fPayloadStart < fPayloadSize - 2) {
1780 // ----- Checking MCM Header -----
1781 AliDebug(2, Form("MCM header: 0x%08x", *fPayloadCurr));
1783 // ----- checking for proper readout order - ROB -----
1784 fCurrRobPos = ROB(*fPayloadCurr);
1785 if (GetROBReadoutPos(ROB(*fPayloadCurr) / 2) >= lastrobpos) {
1786 if (GetROBReadoutPos(ROB(*fPayloadCurr) / 2) > lastrobpos)
1788 lastrobpos = GetROBReadoutPos(ROB(*fPayloadCurr) / 2);
1791 ROBError(kPosUnexp, Form("#%i after #%i in readout order", GetROBReadoutPos(ROB(*fPayloadCurr) / 2), lastrobpos));
1794 // ----- checking for proper readout order - MCM -----
1795 fCurrMcmPos = MCM(*fPayloadCurr);
1796 if (GetMCMReadoutPos(MCM(*fPayloadCurr)) > lastmcmpos) {
1797 lastmcmpos = GetMCMReadoutPos(MCM(*fPayloadCurr));
1800 MCMError(kPosUnexp, Form("#%i after #%i in readout order", GetMCMReadoutPos(MCM(*fPayloadCurr)), lastmcmpos));
1803 if (EvNo(*fPayloadCurr) != (evno & 0xfffff)) {
1805 evno = EvNo(*fPayloadCurr);
1808 MCMError(kEvCntMismatch, "%i <-> %i", evno, EvNo(*fPayloadCurr));
1813 channelcountExp = 21;
1816 Int_t adccoloff = AdcColOffset(*fPayloadCurr);
1817 Int_t padcoloff = PadColOffset(*fPayloadCurr);
1818 Int_t row = Row(*fPayloadCurr);
1822 // ----- reading marked ADC channels -----
1823 while (channelcount < channelcountExp &&
1824 *(fPayloadCurr) != fgkDataEndmarker) {
1831 Int_t nADCwords = (timebins + 2) / 3;
1832 AliDebug(2, Form("Now looking %i words", nADCwords));
1833 Int_t adccol = adccoloff - channelno;
1834 Int_t padcol = padcoloff - channelno;
1835 while ((adcwc < nADCwords) &&
1836 (*(fPayloadCurr) != fgkDataEndmarker) &&
1837 (fPayloadCurr - fPayloadStart < fPayloadSize)) {
1838 int check = 0x3 & *fPayloadCurr;
1839 if (channelno % 2 != 0) { // odd channel
1840 if (check != 0x2 && channelno < 21) {
1841 MCMError(kAdcCheckInvalid,
1842 "%i for %2i. ADC word in odd channel %i",
1843 check, adcwc+1, channelno);
1846 else { // even channel
1847 if (check != 0x3 && channelno < 21) {
1848 MCMError(kAdcCheckInvalid,
1849 "%i for %2i. ADC word in even channel %i",
1850 check, adcwc+1, channelno);
1854 // filling the actual timebin data
1855 int tb2 = 0x3ff & *fPayloadCurr >> 22;
1856 int tb1 = 0x3ff & *fPayloadCurr >> 12;
1857 int tb0 = 0x3ff & *fPayloadCurr >> 2;
1858 if (adcwc != 0 || fCurrNtimebins <= 30)
1859 fAdcArray->SetDataByAdcCol(row, adccol, currentTimebin++, tb0);
1862 fAdcArray->SetDataByAdcCol(row, adccol, currentTimebin++, tb1);
1863 fAdcArray->SetDataByAdcCol(row, adccol, currentTimebin++, tb2);
1869 if (adcwc != nADCwords)
1870 MCMError(kAdcDataAbort);
1873 if (padcol > 0 && padcol < 144) {
1874 fSignalIndex->AddIndexRC(row, padcol);
1880 if (channelcount != channelcountExp)
1881 MCMError(kAdcChannelsMiss);
1883 // continue with next MCM
1886 // check for missing MCMs (if header suppression is inactive)
1887 if (mcmcount != mcmcountExp) {
1888 LinkError(kMissMcmHeaders,
1889 "%i not as expected: %i", mcmcount, mcmcountExp);
1892 return (fPayloadCurr - start);
1895 Int_t AliTRDrawStream::SeekNextStack()
1897 // proceed in raw data stream till the next stack
1899 if (!fCurrStackEndmarkerAvail)
1902 UInt_t *start = fPayloadCurr;
1904 // read until data endmarkers
1905 while ((fPayloadCurr - fPayloadStart < fPayloadSize-1) &&
1906 ((fPayloadCurr[0] != fgkStackEndmarker[0]) ||
1907 (fPayloadCurr[1] != fgkStackEndmarker[1])))
1910 if ((fPayloadCurr - start) != 0)
1911 StackError(kUnknown, "skipped %i words to reach stack endmarker", fPayloadCurr - start);
1913 AliDebug(2, Form("stack endmarker: 0x%08x 0x%08x", fPayloadCurr[0], fPayloadCurr[1]));
1919 return (fPayloadCurr-start);
1922 Int_t AliTRDrawStream::SeekNextLink()
1924 // proceed in raw data stream till the next link
1926 UInt_t *start = fPayloadCurr;
1928 // read until data endmarkers
1929 while (fPayloadCurr - fPayloadStart < fPayloadSize &&
1930 ((fPayloadCurr[0] != fgkStackEndmarker[0]) ||
1931 (fPayloadCurr[1] != fgkStackEndmarker[1])) &&
1932 *fPayloadCurr != fgkDataEndmarker)
1935 // read all data endmarkers
1936 while (fPayloadCurr - fPayloadStart < fPayloadSize &&
1937 *fPayloadCurr == fgkDataEndmarker)
1940 return (fPayloadCurr - start);
1943 Bool_t AliTRDrawStream::ConnectTracklets(TTree *trklTree)
1945 // connect the tracklet tree used to store the tracklet output
1947 fTrackletTree = trklTree;
1951 if (!fTrackletTree->GetBranch("hc"))
1952 fTrackletTree->Branch("hc", &fCurrHC, "hc/I");
1954 fTrackletTree->SetBranchAddress("hc", &fCurrHC);
1956 if (!fTrackletTree->GetBranch("trkl"))
1957 fTrackletTree->Branch("trkl", &fTrackletArray);
1959 fTrackletTree->SetBranchAddress("trkl", &fTrackletArray);
1965 void AliTRDrawStream::EquipmentError(ErrorCode_t err, const char *const msg, ...)
1967 // register error according to error code on equipment level
1968 // and return the corresponding error message
1970 fLastError.fSector = fCurrEquipmentId - kDDLOffset;
1971 fLastError.fStack = -1;
1972 fLastError.fLink = -1;
1973 fLastError.fRob = -1;
1974 fLastError.fMcm = -1;
1975 fLastError.fError = err;
1976 (this->*fStoreError)();
1979 if (fgErrorDebugLevel[err] > 10)
1980 AliDebug(fgErrorDebugLevel[err],
1981 Form("Event %6i: Eq. %2d - %s : %s",
1982 fRawReader->GetEventIndex(), fCurrEquipmentId, fgkErrorMessages[err],
1983 (va_start(ap, msg), vsprintf(fErrorBuffer, msg, ap), va_end(ap), fErrorBuffer) ));
1985 AliError(Form("Event %6i: Eq. %2d - %s : %s",
1986 fRawReader->GetEventIndex(), fCurrEquipmentId, fgkErrorMessages[err],
1987 (va_start(ap, msg), vsprintf(fErrorBuffer, msg, ap), va_end(ap), fErrorBuffer) ));
1988 fErrorFlags |= fgErrorBehav[err];
1992 void AliTRDrawStream::StackError(ErrorCode_t err, const char *const msg, ...)
1994 // register error according to error code on stack level
1995 // and return the corresponding error message
1997 fLastError.fSector = fCurrEquipmentId - kDDLOffset;
1998 fLastError.fStack = fCurrSlot;
1999 fLastError.fLink = -1;
2000 fLastError.fRob = -1;
2001 fLastError.fMcm = -1;
2002 fLastError.fError = err;
2003 (this->*fStoreError)();
2006 if (fgErrorDebugLevel[err] > 0)
2007 AliDebug(fgErrorDebugLevel[err],
2008 Form("Event %6i: Eq. %2d S %i - %s : %s",
2009 fRawReader->GetEventIndex(), fCurrEquipmentId, fCurrSlot, fgkErrorMessages[err],
2010 (va_start(ap, msg), vsprintf(fErrorBuffer, msg, ap), va_end(ap), fErrorBuffer) ));
2012 AliError(Form("Event %6i: Eq. %2d S %i - %s : %s",
2013 fRawReader->GetEventIndex(), fCurrEquipmentId, fCurrSlot, fgkErrorMessages[err],
2014 (va_start(ap, msg), vsprintf(fErrorBuffer, msg, ap), va_end(ap), fErrorBuffer) ));
2015 fErrorFlags |= fgErrorBehav[err];
2019 void AliTRDrawStream::LinkError(ErrorCode_t err, const char *const msg, ...)
2021 // register error according to error code on link level
2022 // and return the corresponding error message
2024 fLastError.fSector = fCurrEquipmentId - kDDLOffset;
2025 fLastError.fStack = fCurrSlot;
2026 fLastError.fLink = fCurrLink;
2027 fLastError.fRob = -1;
2028 fLastError.fMcm = -1;
2029 fLastError.fError = err;
2030 (this->*fStoreError)();
2033 if (fgErrorDebugLevel[err] > 0)
2034 AliDebug(fgErrorDebugLevel[err],
2035 Form("Event %6i: Eq. %2d S %i l %2i - %s : %s",
2036 fRawReader->GetEventIndex(), fCurrEquipmentId, fCurrSlot, fCurrLink, fgkErrorMessages[err],
2037 (va_start(ap, msg), vsprintf(fErrorBuffer, msg, ap), va_end(ap), fErrorBuffer) ));
2039 AliError(Form("Event %6i: Eq. %2d S %i l %2i - %s : %s",
2040 fRawReader->GetEventIndex(), fCurrEquipmentId, fCurrSlot, fCurrLink, fgkErrorMessages[err],
2041 (va_start(ap, msg), vsprintf(fErrorBuffer, msg, ap), va_end(ap), fErrorBuffer) ));
2042 fErrorFlags |= fgErrorBehav[err];
2046 void AliTRDrawStream::ROBError(ErrorCode_t err, const char *const msg, ...)
2048 // register error according to error code on ROB level
2049 // and return the corresponding error message
2051 fLastError.fSector = fCurrEquipmentId - kDDLOffset;
2052 fLastError.fStack = fCurrSlot;
2053 fLastError.fLink = fCurrLink;
2054 fLastError.fRob = fCurrRobPos;
2055 fLastError.fMcm = -1;
2056 fLastError.fError = err;
2057 (this->*fStoreError)();
2060 if (fgErrorDebugLevel[err] > 0)
2061 AliDebug(fgErrorDebugLevel[err],
2062 Form("Event %6i: Eq. %2d S %i l %2i ROB %i - %s : %s",
2063 fRawReader->GetEventIndex(), fCurrEquipmentId, fCurrSlot, fCurrLink, fCurrRobPos, fgkErrorMessages[err],
2064 (va_start(ap, msg), vsprintf(fErrorBuffer, msg, ap), va_end(ap), fErrorBuffer) ));
2066 AliError(Form("Event %6i: Eq. %2d S %i l %2i ROB %i - %s : %s",
2067 fRawReader->GetEventIndex(), fCurrEquipmentId, fCurrSlot, fCurrLink, fCurrRobPos, fgkErrorMessages[err],
2068 (va_start(ap, msg), vsprintf(fErrorBuffer, msg, ap), va_end(ap), fErrorBuffer) ));
2069 fErrorFlags |= fgErrorBehav[err];
2073 void AliTRDrawStream::MCMError(ErrorCode_t err, const char *const msg, ...)
2075 // register error according to error code on MCM level
2076 // and return the corresponding error message
2078 fLastError.fSector = fCurrEquipmentId - kDDLOffset;
2079 fLastError.fStack = fCurrSlot;
2080 fLastError.fLink = fCurrLink;
2081 fLastError.fRob = fCurrRobPos;
2082 fLastError.fMcm = fCurrMcmPos;
2083 fLastError.fError = err;
2084 (this->*fStoreError)();
2087 if (fgErrorDebugLevel[err] > 0)
2088 AliDebug(fgErrorDebugLevel[err],
2089 Form("Event %6i: Eq. %2d S %i l %2i ROB %i MCM %2i - %s : %s",
2090 fRawReader->GetEventIndex(), fCurrEquipmentId, fCurrSlot, fCurrLink, fCurrRobPos, fCurrMcmPos, fgkErrorMessages[err],
2091 (va_start(ap, msg), vsprintf(fErrorBuffer, msg, ap), va_end(ap), fErrorBuffer) ));
2093 AliError(Form("Event %6i: Eq. %2d S %i l %2i ROB %i MCM %2i - %s : %s",
2094 fRawReader->GetEventIndex(), fCurrEquipmentId, fCurrSlot, fCurrLink, fCurrRobPos, fCurrMcmPos, fgkErrorMessages[err],
2095 (va_start(ap, msg), vsprintf(fErrorBuffer, msg, ap), va_end(ap), fErrorBuffer) ));
2096 fErrorFlags |= fgErrorBehav[err];
2099 const char* AliTRDrawStream::GetErrorMessage(ErrorCode_t errCode)
2101 // return the error message for the given error code
2103 if (errCode > 0 && errCode < kLastErrorCode)
2104 return fgkErrorMessages[errCode];
2109 void AliTRDrawStream::AliTRDrawStats::ClearStats()
2111 // clear statistics (includes clearing sector-wise statistics)
2114 for (Int_t iSector = 0; iSector < 18; iSector++) {
2115 fStatsSector[iSector].ClearStats();
2120 void AliTRDrawStream::AliTRDrawStats::AliTRDrawStatsSector::ClearStats()
2122 // clear statistics (includes clearing HC-wise statistics)
2130 for (Int_t iHC = 0; iHC < 60; iHC++) {
2131 fStatsHC[iHC].ClearStats();
2135 void AliTRDrawStream::AliTRDrawStats::AliTRDrawStatsSector::AliTRDrawStatsHC::ClearStats()
2146 void AliTRDrawStream::SetDumpMCM(Int_t det, Int_t rob, Int_t mcm, Bool_t dump)
2148 // mark MCM for dumping of raw data
2151 fDumpMCM[fNDumpMCMs++] = (det << 7) | (rob << 4) | mcm;
2155 for (iMCM = 0; iMCM < fNDumpMCMs; iMCM++) {
2156 if (fDumpMCM[iMCM] == ((det << 7) | (rob << 4) | mcm)) {
2161 for ( ; iMCM < fNDumpMCMs; iMCM++) {
2162 fDumpMCM[iMCM] = fDumpMCM[iMCM+1];
2167 Bool_t AliTRDrawStream::DumpingMCM(Int_t det, Int_t rob, Int_t mcm) const
2169 // check if MCM data should be dumped
2171 for (Int_t iMCM = 0; iMCM < fNDumpMCMs; iMCM++) {
2172 if (fDumpMCM[iMCM] == ((det << 7) | (rob << 4) | mcm)) {
2179 TString AliTRDrawStream::DumpRaw(TString title, const UInt_t *start, Int_t length, UInt_t endmarker)
2184 for (Int_t pos = 0; pos < length; pos += 4) {
2185 if ((start[pos+0] != endmarker) && pos+0 < length)
2186 if ((start[pos+1] != endmarker && pos+1 < length))
2187 if ((start[pos+2] != endmarker && pos+2 < length))
2188 if ((start[pos+3] != endmarker && pos+3 < length))
2189 title += Form(" 0x%08x 0x%08x 0x%08x 0x%08x\n",
2190 start[pos+0], start[pos+1], start[pos+2], start[pos+3]);
2192 title += Form(" 0x%08x 0x%08x 0x%08x 0x%08x\n",
2193 start[pos+0], start[pos+1], start[pos+2], start[pos+3]);
2197 title += Form(" 0x%08x 0x%08x 0x%08x\n",
2198 start[pos+0], start[pos+1], start[pos+2]);
2202 title += Form(" 0x%08x 0x%08x\n",
2203 start[pos+0], start[pos+1]);
2207 title += Form(" 0x%08x\n",
2215 TString AliTRDrawStream::DumpMcmHeader(TString title, UInt_t word)
2217 title += Form("0x%08x -> ROB: %i, MCM: %2i",
2218 word, ROB(word), MCM(word));
2222 TString AliTRDrawStream::DumpAdcMask(TString title, UInt_t word)
2224 title += Form("0x%08x -> #ch : %2i, 0x%06x (%2i ch)",
2225 word, GetNActiveChannels(word), GetActiveChannels(word), GetNActiveChannelsFromMask(word));
2229 AliTRDrawStream::AliTRDrawStreamError::AliTRDrawStreamError(Int_t error, Int_t sector, Int_t stack, Int_t link, Int_t rob, Int_t mcm) :
2241 void AliTRDrawStream::SortTracklets(TClonesArray *trklArray, TList &sortedTracklets, Int_t *indices)
2243 // sort tracklets for referencing from GTU tracks
2248 Int_t nTracklets = trklArray->GetEntriesFast();
2251 for (Int_t iTracklet = 0; iTracklet < nTracklets; iTracklet++) {
2252 AliTRDtrackletBase *trkl = (AliTRDtrackletBase*) ((*trklArray)[iTracklet]);
2253 Int_t hc = trkl->GetHCId();
2254 if ((hc < 0) || (hc >= 1080)) {
2255 AliErrorClass(Form("HC for tracklet: 0x%08x out of range: %i", trkl->GetTrackletWord(), trkl->GetHCId()));
2258 AliDebugClass(5, Form("hc: %4i : 0x%08x z: %2i", hc, trkl->GetTrackletWord(), trkl->GetZbin()));
2260 AliDebugClass(2, Form("set tracklet index for HC %i to %i", hc, iTracklet));
2261 indices[hc] = iTracklet + 1;
2266 for (Int_t iDet = 0; iDet < 540; iDet++) {
2267 Int_t trklIndexA = indices[2*iDet + 0] - 1;
2268 Int_t trklIndexB = indices[2*iDet + 1] - 1;
2269 Int_t trklIndex = sortedTracklets.GetEntries();
2270 AliTRDtrackletBase *trklA = trklIndexA > -1 ? (AliTRDtrackletBase*) ((*trklArray)[trklIndexA]) : 0x0;
2271 AliTRDtrackletBase *trklB = trklIndexB > -1 ? (AliTRDtrackletBase*) ((*trklArray)[trklIndexB]) : 0x0;
2272 AliTRDtrackletBase *trklNext = 0x0;
2273 while (trklA != 0x0 || trklB != 0x0) {
2274 AliDebugClass(5, Form("det %i - A: %i/%i -> %p, B: %i/%i -> %p",
2275 iDet, trklIndexA, nTracklets, trklA, trklIndexB, nTracklets, trklB));
2279 trklB = trklIndexB < nTracklets ? (AliTRDtrackletBase*) ((*trklArray)[trklIndexB]) : 0x0;
2280 if (trklB && trklB->GetHCId() != 2*iDet + 1)
2283 else if (trklB == 0x0) {
2286 trklA = trklIndexA < nTracklets ? (AliTRDtrackletBase*) ((*trklArray)[trklIndexA]) : 0x0;
2287 if (trklA && trklA->GetHCId() != 2*iDet)
2291 if (trklA->GetZbin() <= trklB->GetZbin()) {
2294 trklA = trklIndexA < nTracklets ? (AliTRDtrackletBase*) ((*trklArray)[trklIndexA]) : 0x0;
2295 if (trklA && trklA->GetHCId() != 2*iDet)
2301 trklB = trklIndexB < nTracklets ? (AliTRDtrackletBase*) ((*trklArray)[trklIndexB]) : 0x0;
2302 if (trklB && trklB->GetHCId() != 2*iDet + 1)
2307 Int_t label = -2; // mark raw tracklets with label -2
2308 if (AliTRDtrackletMCM *trklMCM = dynamic_cast<AliTRDtrackletMCM*> (trklNext))
2309 label = trklMCM->GetLabel();
2310 AliESDTrdTracklet *esdTracklet = new AliESDTrdTracklet(trklNext->GetTrackletWord(), trklNext->GetHCId(), label);
2311 sortedTracklets.Add(esdTracklet);
2315 // updating tracklet indices as in output
2316 if (sortedTracklets.GetEntries() != trklIndex) {
2317 indices[2*iDet + 0] = indices[2*iDet + 1] = trklIndex;
2319 indices[2*iDet + 0] = indices[2*iDet + 1] = -1;