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 if (currentTimebin >= fCurrNtimebins)
1704 fAdcArray->SetDataByAdcCol(row, adccol, currentTimebin++, tb1);
1705 if (currentTimebin >= fCurrNtimebins)
1707 fAdcArray->SetDataByAdcCol(row, adccol, currentTimebin++, tb2);
1713 if (adcwc != nADCwords)
1714 MCMError(kAdcDataAbort);
1717 if (padcol > 0 && padcol < 144) {
1718 fSignalIndex->AddIndexRC(row, padcol);
1724 if (fCurrSm > -1 && fCurrSm < 18) {
1725 fStats.fStatsSector[fCurrSm].fStatsHC[fCurrHC%60].fNChannels += channelcount;
1726 fStats.fStatsSector[fCurrSm].fNChannels += channelcount;
1728 if (channelcount != channelcountExp)
1729 MCMError(kAdcChannelsMiss);
1732 if (fCurrSm > -1 && fCurrSm < 18) {
1733 fStats.fStatsSector[fCurrSm].fStatsHC[fCurrHC%60].fNMCMs++;
1734 fStats.fStatsSector[fCurrSm].fNMCMs++;
1737 if (IsDumping() && DumpingMCM(fCurrHC/2, fCurrRobPos, fCurrMcmPos)) {
1738 AliInfo(DumpRaw(Form("Event %i: Det %3i ROB %i MCM %2i", fRawReader->GetEventIndex(), fCurrHC/2, fCurrRobPos, fCurrMcmPos),
1739 startPosMCM, fPayloadCurr - startPosMCM));
1742 // continue with next MCM
1745 // check for missing MCMs (if header suppression is inactive)
1746 if (((fCurrMajor & 0x1) == 0) && (mcmcount != mcmcountExp)) {
1747 LinkError(kMissMcmHeaders,
1748 "No. of MCM headers %i not as expected: %i",
1749 mcmcount, mcmcountExp);
1752 return (fPayloadCurr - start);
1755 Int_t AliTRDrawStream::ReadNonZSData()
1757 // read the non-zs data from one link from the current reading position
1759 UInt_t *start = fPayloadCurr;
1762 Int_t mcmcountExp = fCurrStack == 2 ? 48 : 64;
1763 Int_t channelcount = 0;
1764 Int_t channelcountExp = 0;
1766 Int_t currentTimebin = 0;
1769 Int_t lastmcmpos = -1;
1770 Int_t lastrobpos = -1;
1772 if (fCurrNtimebins != fNtimebins) {
1774 LinkError(kNtimebinsChanged,
1775 "No. of timebins changed from %i to %i", fNtimebins, fCurrNtimebins);
1776 fNtimebins = fCurrNtimebins;
1779 timebins = fNtimebins;
1781 while (*(fPayloadCurr) != fgkDataEndmarker &&
1782 fPayloadCurr - fPayloadStart < fPayloadSize - 2) {
1784 // ----- Checking MCM Header -----
1785 AliDebug(2, Form("MCM header: 0x%08x", *fPayloadCurr));
1787 // ----- checking for proper readout order - ROB -----
1788 fCurrRobPos = ROB(*fPayloadCurr);
1789 if (GetROBReadoutPos(ROB(*fPayloadCurr) / 2) >= lastrobpos) {
1790 if (GetROBReadoutPos(ROB(*fPayloadCurr) / 2) > lastrobpos)
1792 lastrobpos = GetROBReadoutPos(ROB(*fPayloadCurr) / 2);
1795 ROBError(kPosUnexp, Form("#%i after #%i in readout order", GetROBReadoutPos(ROB(*fPayloadCurr) / 2), lastrobpos));
1798 // ----- checking for proper readout order - MCM -----
1799 fCurrMcmPos = MCM(*fPayloadCurr);
1800 if (GetMCMReadoutPos(MCM(*fPayloadCurr)) > lastmcmpos) {
1801 lastmcmpos = GetMCMReadoutPos(MCM(*fPayloadCurr));
1804 MCMError(kPosUnexp, Form("#%i after #%i in readout order", GetMCMReadoutPos(MCM(*fPayloadCurr)), lastmcmpos));
1807 if (EvNo(*fPayloadCurr) != (evno & 0xfffff)) {
1809 evno = EvNo(*fPayloadCurr);
1812 MCMError(kEvCntMismatch, "%i <-> %i", evno, EvNo(*fPayloadCurr));
1817 channelcountExp = 21;
1820 Int_t adccoloff = AdcColOffset(*fPayloadCurr);
1821 Int_t padcoloff = PadColOffset(*fPayloadCurr);
1822 Int_t row = Row(*fPayloadCurr);
1826 // ----- reading marked ADC channels -----
1827 while (channelcount < channelcountExp &&
1828 *(fPayloadCurr) != fgkDataEndmarker) {
1835 Int_t nADCwords = (timebins + 2) / 3;
1836 AliDebug(2, Form("Now looking %i words", nADCwords));
1837 Int_t adccol = adccoloff - channelno;
1838 Int_t padcol = padcoloff - channelno;
1839 while ((adcwc < nADCwords) &&
1840 (*(fPayloadCurr) != fgkDataEndmarker) &&
1841 (fPayloadCurr - fPayloadStart < fPayloadSize)) {
1842 int check = 0x3 & *fPayloadCurr;
1843 if (channelno % 2 != 0) { // odd channel
1844 if (check != 0x2 && channelno < 21) {
1845 MCMError(kAdcCheckInvalid,
1846 "%i for %2i. ADC word in odd channel %i",
1847 check, adcwc+1, channelno);
1850 else { // even channel
1851 if (check != 0x3 && channelno < 21) {
1852 MCMError(kAdcCheckInvalid,
1853 "%i for %2i. ADC word in even channel %i",
1854 check, adcwc+1, channelno);
1858 // filling the actual timebin data
1859 int tb2 = 0x3ff & *fPayloadCurr >> 22;
1860 int tb1 = 0x3ff & *fPayloadCurr >> 12;
1861 int tb0 = 0x3ff & *fPayloadCurr >> 2;
1862 if (adcwc != 0 || fCurrNtimebins <= 30)
1863 fAdcArray->SetDataByAdcCol(row, adccol, currentTimebin++, tb0);
1866 if (currentTimebin >= fCurrNtimebins)
1868 fAdcArray->SetDataByAdcCol(row, adccol, currentTimebin++, tb1);
1869 if (currentTimebin >= fCurrNtimebins)
1871 fAdcArray->SetDataByAdcCol(row, adccol, currentTimebin++, tb2);
1877 if (adcwc != nADCwords)
1878 MCMError(kAdcDataAbort);
1881 if (padcol > 0 && padcol < 144) {
1882 fSignalIndex->AddIndexRC(row, padcol);
1888 if (channelcount != channelcountExp)
1889 MCMError(kAdcChannelsMiss);
1891 // continue with next MCM
1894 // check for missing MCMs (if header suppression is inactive)
1895 if (mcmcount != mcmcountExp) {
1896 LinkError(kMissMcmHeaders,
1897 "%i not as expected: %i", mcmcount, mcmcountExp);
1900 return (fPayloadCurr - start);
1903 Int_t AliTRDrawStream::SeekNextStack()
1905 // proceed in raw data stream till the next stack
1907 if (!fCurrStackEndmarkerAvail)
1910 UInt_t *start = fPayloadCurr;
1912 // read until data endmarkers
1913 while ((fPayloadCurr - fPayloadStart < fPayloadSize-1) &&
1914 ((fPayloadCurr[0] != fgkStackEndmarker[0]) ||
1915 (fPayloadCurr[1] != fgkStackEndmarker[1])))
1918 if ((fPayloadCurr - start) != 0)
1919 StackError(kUnknown, "skipped %i words to reach stack endmarker", fPayloadCurr - start);
1921 AliDebug(2, Form("stack endmarker: 0x%08x 0x%08x", fPayloadCurr[0], fPayloadCurr[1]));
1927 return (fPayloadCurr-start);
1930 Int_t AliTRDrawStream::SeekNextLink()
1932 // proceed in raw data stream till the next link
1934 UInt_t *start = fPayloadCurr;
1936 // read until data endmarkers
1937 while (fPayloadCurr - fPayloadStart < fPayloadSize &&
1938 ((fPayloadCurr[0] != fgkStackEndmarker[0]) ||
1939 (fPayloadCurr[1] != fgkStackEndmarker[1])) &&
1940 *fPayloadCurr != fgkDataEndmarker)
1943 // read all data endmarkers
1944 while (fPayloadCurr - fPayloadStart < fPayloadSize &&
1945 *fPayloadCurr == fgkDataEndmarker)
1948 return (fPayloadCurr - start);
1951 Bool_t AliTRDrawStream::ConnectTracklets(TTree *trklTree)
1953 // connect the tracklet tree used to store the tracklet output
1955 fTrackletTree = trklTree;
1959 if (!fTrackletTree->GetBranch("hc"))
1960 fTrackletTree->Branch("hc", &fCurrHC, "hc/I");
1962 fTrackletTree->SetBranchAddress("hc", &fCurrHC);
1964 if (!fTrackletTree->GetBranch("trkl"))
1965 fTrackletTree->Branch("trkl", &fTrackletArray);
1967 fTrackletTree->SetBranchAddress("trkl", &fTrackletArray);
1973 void AliTRDrawStream::EquipmentError(ErrorCode_t err, const char *const msg, ...)
1975 // register error according to error code on equipment level
1976 // and return the corresponding error message
1978 fLastError.fSector = fCurrEquipmentId - kDDLOffset;
1979 fLastError.fStack = -1;
1980 fLastError.fLink = -1;
1981 fLastError.fRob = -1;
1982 fLastError.fMcm = -1;
1983 fLastError.fError = err;
1984 (this->*fStoreError)();
1987 if (fgErrorDebugLevel[err] > 10)
1988 AliDebug(fgErrorDebugLevel[err],
1989 Form("Event %6i: Eq. %2d - %s : %s",
1990 fRawReader->GetEventIndex(), fCurrEquipmentId, fgkErrorMessages[err],
1991 (va_start(ap, msg), vsprintf(fErrorBuffer, msg, ap), va_end(ap), fErrorBuffer) ));
1993 AliError(Form("Event %6i: Eq. %2d - %s : %s",
1994 fRawReader->GetEventIndex(), fCurrEquipmentId, fgkErrorMessages[err],
1995 (va_start(ap, msg), vsprintf(fErrorBuffer, msg, ap), va_end(ap), fErrorBuffer) ));
1996 fErrorFlags |= fgErrorBehav[err];
2000 void AliTRDrawStream::StackError(ErrorCode_t err, const char *const msg, ...)
2002 // register error according to error code on stack level
2003 // and return the corresponding error message
2005 fLastError.fSector = fCurrEquipmentId - kDDLOffset;
2006 fLastError.fStack = fCurrSlot;
2007 fLastError.fLink = -1;
2008 fLastError.fRob = -1;
2009 fLastError.fMcm = -1;
2010 fLastError.fError = err;
2011 (this->*fStoreError)();
2014 if (fgErrorDebugLevel[err] > 0)
2015 AliDebug(fgErrorDebugLevel[err],
2016 Form("Event %6i: Eq. %2d S %i - %s : %s",
2017 fRawReader->GetEventIndex(), fCurrEquipmentId, fCurrSlot, fgkErrorMessages[err],
2018 (va_start(ap, msg), vsprintf(fErrorBuffer, msg, ap), va_end(ap), fErrorBuffer) ));
2020 AliError(Form("Event %6i: Eq. %2d S %i - %s : %s",
2021 fRawReader->GetEventIndex(), fCurrEquipmentId, fCurrSlot, fgkErrorMessages[err],
2022 (va_start(ap, msg), vsprintf(fErrorBuffer, msg, ap), va_end(ap), fErrorBuffer) ));
2023 fErrorFlags |= fgErrorBehav[err];
2027 void AliTRDrawStream::LinkError(ErrorCode_t err, const char *const msg, ...)
2029 // register error according to error code on link level
2030 // and return the corresponding error message
2032 fLastError.fSector = fCurrEquipmentId - kDDLOffset;
2033 fLastError.fStack = fCurrSlot;
2034 fLastError.fLink = fCurrLink;
2035 fLastError.fRob = -1;
2036 fLastError.fMcm = -1;
2037 fLastError.fError = err;
2038 (this->*fStoreError)();
2041 if (fgErrorDebugLevel[err] > 0)
2042 AliDebug(fgErrorDebugLevel[err],
2043 Form("Event %6i: Eq. %2d S %i l %2i - %s : %s",
2044 fRawReader->GetEventIndex(), fCurrEquipmentId, fCurrSlot, fCurrLink, fgkErrorMessages[err],
2045 (va_start(ap, msg), vsprintf(fErrorBuffer, msg, ap), va_end(ap), fErrorBuffer) ));
2047 AliError(Form("Event %6i: Eq. %2d S %i l %2i - %s : %s",
2048 fRawReader->GetEventIndex(), fCurrEquipmentId, fCurrSlot, fCurrLink, fgkErrorMessages[err],
2049 (va_start(ap, msg), vsprintf(fErrorBuffer, msg, ap), va_end(ap), fErrorBuffer) ));
2050 fErrorFlags |= fgErrorBehav[err];
2054 void AliTRDrawStream::ROBError(ErrorCode_t err, const char *const msg, ...)
2056 // register error according to error code on ROB level
2057 // and return the corresponding error message
2059 fLastError.fSector = fCurrEquipmentId - kDDLOffset;
2060 fLastError.fStack = fCurrSlot;
2061 fLastError.fLink = fCurrLink;
2062 fLastError.fRob = fCurrRobPos;
2063 fLastError.fMcm = -1;
2064 fLastError.fError = err;
2065 (this->*fStoreError)();
2068 if (fgErrorDebugLevel[err] > 0)
2069 AliDebug(fgErrorDebugLevel[err],
2070 Form("Event %6i: Eq. %2d S %i l %2i ROB %i - %s : %s",
2071 fRawReader->GetEventIndex(), fCurrEquipmentId, fCurrSlot, fCurrLink, fCurrRobPos, fgkErrorMessages[err],
2072 (va_start(ap, msg), vsprintf(fErrorBuffer, msg, ap), va_end(ap), fErrorBuffer) ));
2074 AliError(Form("Event %6i: Eq. %2d S %i l %2i ROB %i - %s : %s",
2075 fRawReader->GetEventIndex(), fCurrEquipmentId, fCurrSlot, fCurrLink, fCurrRobPos, fgkErrorMessages[err],
2076 (va_start(ap, msg), vsprintf(fErrorBuffer, msg, ap), va_end(ap), fErrorBuffer) ));
2077 fErrorFlags |= fgErrorBehav[err];
2081 void AliTRDrawStream::MCMError(ErrorCode_t err, const char *const msg, ...)
2083 // register error according to error code on MCM level
2084 // and return the corresponding error message
2086 fLastError.fSector = fCurrEquipmentId - kDDLOffset;
2087 fLastError.fStack = fCurrSlot;
2088 fLastError.fLink = fCurrLink;
2089 fLastError.fRob = fCurrRobPos;
2090 fLastError.fMcm = fCurrMcmPos;
2091 fLastError.fError = err;
2092 (this->*fStoreError)();
2095 if (fgErrorDebugLevel[err] > 0)
2096 AliDebug(fgErrorDebugLevel[err],
2097 Form("Event %6i: Eq. %2d S %i l %2i ROB %i MCM %2i - %s : %s",
2098 fRawReader->GetEventIndex(), fCurrEquipmentId, fCurrSlot, fCurrLink, fCurrRobPos, fCurrMcmPos, fgkErrorMessages[err],
2099 (va_start(ap, msg), vsprintf(fErrorBuffer, msg, ap), va_end(ap), fErrorBuffer) ));
2101 AliError(Form("Event %6i: Eq. %2d S %i l %2i ROB %i MCM %2i - %s : %s",
2102 fRawReader->GetEventIndex(), fCurrEquipmentId, fCurrSlot, fCurrLink, fCurrRobPos, fCurrMcmPos, fgkErrorMessages[err],
2103 (va_start(ap, msg), vsprintf(fErrorBuffer, msg, ap), va_end(ap), fErrorBuffer) ));
2104 fErrorFlags |= fgErrorBehav[err];
2107 const char* AliTRDrawStream::GetErrorMessage(ErrorCode_t errCode)
2109 // return the error message for the given error code
2111 if (errCode > 0 && errCode < kLastErrorCode)
2112 return fgkErrorMessages[errCode];
2117 void AliTRDrawStream::AliTRDrawStats::ClearStats()
2119 // clear statistics (includes clearing sector-wise statistics)
2122 for (Int_t iSector = 0; iSector < 18; iSector++) {
2123 fStatsSector[iSector].ClearStats();
2128 void AliTRDrawStream::AliTRDrawStats::AliTRDrawStatsSector::ClearStats()
2130 // clear statistics (includes clearing HC-wise statistics)
2138 for (Int_t iHC = 0; iHC < 60; iHC++) {
2139 fStatsHC[iHC].ClearStats();
2143 void AliTRDrawStream::AliTRDrawStats::AliTRDrawStatsSector::AliTRDrawStatsHC::ClearStats()
2154 void AliTRDrawStream::SetDumpMCM(Int_t det, Int_t rob, Int_t mcm, Bool_t dump)
2156 // mark MCM for dumping of raw data
2159 fDumpMCM[fNDumpMCMs++] = (det << 7) | (rob << 4) | mcm;
2163 for (iMCM = 0; iMCM < fNDumpMCMs; iMCM++) {
2164 if (fDumpMCM[iMCM] == ((det << 7) | (rob << 4) | mcm)) {
2169 for ( ; iMCM < fNDumpMCMs; iMCM++) {
2170 fDumpMCM[iMCM] = fDumpMCM[iMCM+1];
2175 Bool_t AliTRDrawStream::DumpingMCM(Int_t det, Int_t rob, Int_t mcm) const
2177 // check if MCM data should be dumped
2179 for (Int_t iMCM = 0; iMCM < fNDumpMCMs; iMCM++) {
2180 if (fDumpMCM[iMCM] == ((det << 7) | (rob << 4) | mcm)) {
2187 TString AliTRDrawStream::DumpRaw(TString title, const UInt_t *start, Int_t length, UInt_t endmarker)
2192 for (Int_t pos = 0; pos < length; pos += 4) {
2193 if ((start[pos+0] != endmarker) && pos+0 < length)
2194 if ((start[pos+1] != endmarker && pos+1 < length))
2195 if ((start[pos+2] != endmarker && pos+2 < length))
2196 if ((start[pos+3] != endmarker && pos+3 < length))
2197 title += Form(" 0x%08x 0x%08x 0x%08x 0x%08x\n",
2198 start[pos+0], start[pos+1], start[pos+2], start[pos+3]);
2200 title += Form(" 0x%08x 0x%08x 0x%08x 0x%08x\n",
2201 start[pos+0], start[pos+1], start[pos+2], start[pos+3]);
2205 title += Form(" 0x%08x 0x%08x 0x%08x\n",
2206 start[pos+0], start[pos+1], start[pos+2]);
2210 title += Form(" 0x%08x 0x%08x\n",
2211 start[pos+0], start[pos+1]);
2215 title += Form(" 0x%08x\n",
2223 TString AliTRDrawStream::DumpMcmHeader(TString title, UInt_t word)
2225 title += Form("0x%08x -> ROB: %i, MCM: %2i",
2226 word, ROB(word), MCM(word));
2230 TString AliTRDrawStream::DumpAdcMask(TString title, UInt_t word)
2232 title += Form("0x%08x -> #ch : %2i, 0x%06x (%2i ch)",
2233 word, GetNActiveChannels(word), GetActiveChannels(word), GetNActiveChannelsFromMask(word));
2237 AliTRDrawStream::AliTRDrawStreamError::AliTRDrawStreamError(Int_t error, Int_t sector, Int_t stack, Int_t link, Int_t rob, Int_t mcm) :
2249 void AliTRDrawStream::SortTracklets(TClonesArray *trklArray, TList &sortedTracklets, Int_t *indices)
2251 // sort tracklets for referencing from GTU tracks
2256 Int_t nTracklets = trklArray->GetEntriesFast();
2259 for (Int_t iTracklet = 0; iTracklet < nTracklets; iTracklet++) {
2260 AliTRDtrackletBase *trkl = (AliTRDtrackletBase*) ((*trklArray)[iTracklet]);
2261 Int_t hc = trkl->GetHCId();
2262 if ((hc < 0) || (hc >= 1080)) {
2263 AliErrorClass(Form("HC for tracklet: 0x%08x out of range: %i", trkl->GetTrackletWord(), trkl->GetHCId()));
2266 AliDebugClass(5, Form("hc: %4i : 0x%08x z: %2i", hc, trkl->GetTrackletWord(), trkl->GetZbin()));
2268 AliDebugClass(2, Form("set tracklet index for HC %i to %i", hc, iTracklet));
2269 indices[hc] = iTracklet + 1;
2274 for (Int_t iDet = 0; iDet < 540; iDet++) {
2275 Int_t trklIndexA = indices[2*iDet + 0] - 1;
2276 Int_t trklIndexB = indices[2*iDet + 1] - 1;
2277 Int_t trklIndex = sortedTracklets.GetEntries();
2278 AliTRDtrackletBase *trklA = trklIndexA > -1 ? (AliTRDtrackletBase*) ((*trklArray)[trklIndexA]) : 0x0;
2279 AliTRDtrackletBase *trklB = trklIndexB > -1 ? (AliTRDtrackletBase*) ((*trklArray)[trklIndexB]) : 0x0;
2280 AliTRDtrackletBase *trklNext = 0x0;
2281 while (trklA != 0x0 || trklB != 0x0) {
2282 AliDebugClass(5, Form("det %i - A: %i/%i -> %p, B: %i/%i -> %p",
2283 iDet, trklIndexA, nTracklets, trklA, trklIndexB, nTracklets, trklB));
2287 trklB = trklIndexB < nTracklets ? (AliTRDtrackletBase*) ((*trklArray)[trklIndexB]) : 0x0;
2288 if (trklB && trklB->GetHCId() != 2*iDet + 1)
2291 else if (trklB == 0x0) {
2294 trklA = trklIndexA < nTracklets ? (AliTRDtrackletBase*) ((*trklArray)[trklIndexA]) : 0x0;
2295 if (trklA && trklA->GetHCId() != 2*iDet)
2299 if (trklA->GetZbin() <= trklB->GetZbin()) {
2302 trklA = trklIndexA < nTracklets ? (AliTRDtrackletBase*) ((*trklArray)[trklIndexA]) : 0x0;
2303 if (trklA && trklA->GetHCId() != 2*iDet)
2309 trklB = trklIndexB < nTracklets ? (AliTRDtrackletBase*) ((*trklArray)[trklIndexB]) : 0x0;
2310 if (trklB && trklB->GetHCId() != 2*iDet + 1)
2315 sortedTracklets.Add(trklNext);
2320 // updating tracklet indices as in output
2321 if (sortedTracklets.GetEntries() != trklIndex) {
2322 indices[2*iDet + 0] = trklIndex;
2323 indices[2*iDet + 1] = sortedTracklets.GetEntries();
2325 indices[2*iDet + 0] = indices[2*iDet + 1] = -1;
2330 void AliTRDrawStream::AssignTracklets(AliESDTrdTrack *trdTrack, Int_t *trackletIndex, Int_t refIndex[6])
2332 UInt_t mask = trdTrack->GetLayerMask();
2333 UInt_t stack = trdTrack->GetStack();
2335 for (Int_t iLayer = 0; iLayer < 6; iLayer++) {
2336 refIndex[iLayer] = -1;
2338 if (mask & (1 << iLayer)) {
2340 Int_t det = trdTrack->GetSector()*30 + stack*6 + iLayer;
2341 Int_t idx = trdTrack->GetTrackletIndex(iLayer);
2343 if ((det < 0) || (det > 539)) {
2344 AliErrorClass(Form("Invalid detector no. from track: %i", 2*det));
2347 if (trackletIndex[2*det] >= 0) {
2348 if ((trackletIndex[2*det] + idx > -1) &&
2349 (trackletIndex[2*det] + idx < trackletIndex[2*det+1])) {
2350 refIndex[iLayer] = trackletIndex[2*det] + idx;
2352 AliErrorClass(Form("Requested tracklet index %i out of range", idx));
2355 AliErrorClass(Form("Non-existing tracklets requested in det %i", det));