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->SetFlagsTiming((trackWord >> 51) & 0x1);
1032 trk->SetReserved((trackWord >> 49) & 0x3);
1033 trk->SetY((trackWord >> 36) & 0x1fff);
1034 trk->SetTrackletIndex((trackWord >> 0) & 0x3f, 0);
1035 trk->SetTrackletIndex((trackWord >> 6) & 0x3f, 1);
1036 trk->SetTrackletIndex((trackWord >> 12) & 0x3f, 2);
1037 trk->SetTrackletIndex((trackWord >> 18) & 0x3f, 3);
1038 trk->SetTrackletIndex((trackWord >> 24) & 0x3f, 4);
1039 trk->SetTrackletIndex((trackWord >> 30) & 0x3f, 5);
1041 if (trackWord != trk->GetExtendedTrackWord(0)) {
1042 AliError(Form("extended track word 0x%016llx does not match the read one 0x%016llx",
1043 trk->GetExtendedTrackWord(0), trackWord));
1053 fPayloadCurr += fCurrTrkHeaderSize[stack];
1055 return fCurrTrkHeaderSize[stack];
1058 Int_t AliTRDrawStream::ReadTriggerHeaders()
1060 // read all trigger headers present
1062 AliDebug(1, Form("trigger mask: 0x%03x, fired: 0x%03x\n",
1063 fCurrTriggerEnable, fCurrTriggerFired));
1064 // loop over potential trigger blocks
1065 for (Int_t iTrigger = 0; iTrigger < fgkNtriggers; iTrigger++) {
1066 // check for trigger enable
1067 if (fCurrTriggerEnable & (1 << iTrigger)) {
1068 // check for readout mode and trigger fired
1069 if ((fCurrTrgHeaderReadout == 0) || (fCurrTriggerFired & (1 << iTrigger))) {
1071 AliDebug(1, Form("trigger index word %i: 0x%08x\n", iTrigger, *fPayloadCurr));
1072 fCurrTrgHeaderIndexWord[iTrigger] = *fPayloadCurr;
1073 fCurrTrgHeaderSize[iTrigger] = ((*fPayloadCurr) >> 16) & 0x3ff;
1074 if (iTrigger == 7) {
1075 // timeout trigger, use to extract tracking time
1076 fCurrTrgFlags[fCurrEquipmentId-kDDLOffset] |= (*fPayloadCurr & 0x3ff) << 12;
1081 fPayloadCurr += fCurrTrgHeaderSize[iTrigger];
1089 Int_t AliTRDrawStream::ReadStackHeader(Int_t stack)
1091 // read the stack header
1092 // and store the information in the corresponding variables
1094 fCurrStackIndexWord[stack] = *fPayloadCurr;
1095 fCurrStackHeaderSize[stack] = (((*fPayloadCurr) >> 16) & 0xffff) + 1;
1096 fCurrStackHeaderVersion[stack] = ((*fPayloadCurr) >> 12) & 0xf;
1097 fCurrLinkMask[stack] = (*fPayloadCurr) & 0xfff;
1099 // dumping stack header
1100 AliDebug(1, DumpRaw(Form("stack %i header", stack), fPayloadCurr, fCurrStackHeaderSize[stack]));
1102 if (fPayloadCurr - fPayloadStart >= fPayloadSize - (Int_t) fCurrStackHeaderSize[stack]) {
1103 EquipmentError(kStackHeaderInvalid, "Stack index header %i incomplete", stack);
1104 // dumping stack header
1105 AliError(DumpRaw(Form("stack %i header", stack), fPayloadCurr, fCurrStackHeaderSize[stack]));
1110 switch (fCurrStackHeaderVersion[stack]) {
1112 if (fCurrStackHeaderSize[stack] < 8) {
1113 LinkError(kStackHeaderInvalid, "Stack header smaller than expected!");
1117 fCurrCleanCheckout[stack] = fPayloadCurr[1] & 0x1;
1118 fCurrBoardId[stack] = (fPayloadCurr[1] >> 8) & 0xff;
1119 fCurrHwRevTMU[stack] = (fPayloadCurr[1] >> 16) & 0xffff;
1121 for (Int_t iLayer = 0; iLayer < 6; iLayer++) {
1123 fCurrLinkMonitorFlags [stack*fgkNlinks + iLayer*2] = fPayloadCurr[iLayer+2] & 0xf;
1124 fCurrLinkDataTypeFlags [stack*fgkNlinks + iLayer*2] = (fPayloadCurr[iLayer+2] >> 4) & 0x3;
1125 fCurrLinkDebugFlags [stack*fgkNlinks + iLayer*2] = (fPayloadCurr[iLayer+2] >> 12) & 0xf;
1127 fCurrLinkMonitorFlags [stack*fgkNlinks + iLayer*2 + 1] = (fPayloadCurr[iLayer+2] >> 16) & 0xf;
1128 fCurrLinkDataTypeFlags [stack*fgkNlinks + iLayer*2 + 1] = (fPayloadCurr[iLayer+2] >> 20) & 0x3;
1129 fCurrLinkDebugFlags [stack*fgkNlinks + iLayer*2 + 1] = (fPayloadCurr[iLayer+2] >> 28) & 0xf;
1134 LinkError(kStackHeaderInvalid, "Invalid Stack Header version %x", fCurrStackHeaderVersion[stack]);
1137 fPayloadCurr += fCurrStackHeaderSize[stack];
1139 return fCurrStackHeaderSize[stack];
1142 Int_t AliTRDrawStream::ReadGTUTrailer()
1144 // read the SM trailer containing CRCs from various stages
1146 UInt_t* trailer = fPayloadStart + fPayloadSize -1;
1148 // look for the trailer index word from the end
1149 for (Int_t iWord = 0; iWord < fPayloadSize; iWord++) {
1150 if ((fPayloadStart[fPayloadSize-1-iWord] & 0xffff) == 0x1f51) {
1151 trailer = fPayloadStart + fPayloadSize - 1 - iWord;
1156 if (((*trailer) & 0xffff) == 0x1f51) {
1157 UInt_t trailerIndexWord = (*trailer);
1158 Int_t trailerSize = (trailerIndexWord >> 16) & 0xffff;
1159 AliDebug(2, DumpRaw("GTU trailer", trailer, trailerSize+1));
1160 // parse the trailer
1161 if (trailerSize >= 4) {
1162 // match flags from GTU
1163 fCurrMatchFlagsSRAM = (trailer[1] >> 0) & 0x1f;
1164 fCurrMatchFlagsPostBP = (trailer[1] >> 5) & 0x1f;
1165 // individual checksums
1166 fCurrChecksumStack[0] = (trailer[1] >> 16) & 0xffff;
1167 fCurrChecksumStack[1] = (trailer[2] >> 0) & 0xffff;
1168 fCurrChecksumStack[2] = (trailer[2] >> 16) & 0xffff;
1169 fCurrChecksumStack[3] = (trailer[3] >> 0) & 0xffff;
1170 fCurrChecksumStack[4] = (trailer[3] >> 16) & 0xffff;
1171 fCurrChecksumSIU = trailer[4];
1173 if ((fCurrMatchFlagsSRAM & fCurrStackMask) != fCurrStackMask)
1174 EquipmentError(kCRCmismatch, "CRC mismatch SRAM: 0x%02x", fCurrMatchFlagsSRAM);
1175 if ((fCurrMatchFlagsPostBP & fCurrStackMask) != fCurrStackMask)
1176 EquipmentError(kCRCmismatch, "CRC mismatch BP: 0x%02x", fCurrMatchFlagsPostBP);
1180 LinkError(kUnknown, "Invalid GTU trailer");
1184 EquipmentError(kUnknown, "trailer index marker mismatch");
1189 Int_t AliTRDrawStream::ReadLinkData()
1191 // read the data in one link (one HC) until the data endmarker is reached
1192 // returns the number of words read!
1195 UInt_t* startPosLink = fPayloadCurr;
1197 AliDebug(1, DumpRaw(Form("link data from seg %2i slot %i link %2i", fCurrEquipmentId-kDDLOffset, fCurrSlot, fCurrLink),
1198 fPayloadCurr, TMath::Min((Int_t) (fPayloadSize - (fPayloadCurr-fPayloadStart)), 100), 0x00000000));
1201 new ((*fMarkers)[fMarkers->GetEntriesFast()])
1202 AliTRDrawStreamError(-kHCactive, fCurrEquipmentId-kDDLOffset, fCurrSlot, fCurrLink);
1204 if (fErrorFlags & kDiscardHC)
1207 if (fCurrTrackletEnable) {
1208 count += ReadTracklets();
1209 if (fErrorFlags & kDiscardHC)
1213 AliDebug(1, DumpRaw("HC header", fPayloadCurr, 4, 0x00000000));
1214 count += ReadHcHeader();
1215 if (fErrorFlags & kDiscardHC)
1218 Int_t det = fCurrSm * 30 + fCurrStack * 6 + fCurrLayer;
1220 if (det > -1 && det < 540) {
1222 // ----- check which kind of data -----
1223 if (fCurrMajor & 0x40) {
1224 if ((fCurrMajor & 0x7) == 0x7) {
1225 AliDebug(1, "This is a config event");
1226 UInt_t *startPos = fPayloadCurr;
1227 while (fPayloadCurr - fPayloadStart < fPayloadSize &&
1228 *fPayloadCurr != fgkDataEndmarker)
1230 count += fPayloadCurr - startPos;
1232 // feeding TRAP config
1233 AliTRDtrapConfig *trapcfg = AliTRDcalibDB::Instance()->GetTrapConfig();
1234 AliTRDmcmSim::ReadPackedConfig(trapcfg, fCurrHC, startPos, fPayloadCurr - startPos);
1237 Int_t tpmode = fCurrMajor & 0x7;
1238 AliDebug(1, Form("Checking testpattern (mode %i) data", tpmode));
1239 count += ReadTPData(tpmode);
1243 // reading real data
1244 if (fDigitsManager) {
1245 if ((fAdcArray = fDigitsManager->GetDigits(det))) {
1246 //fAdcArray->Expand();
1247 if (fAdcArray->GetNtime() != fCurrNtimebins)
1248 fAdcArray->Allocate(16, 144, fCurrNtimebins);
1251 LinkError(kNoDigits);
1254 if (!fDigitsParam) {
1255 fDigitsParam = fDigitsManager->GetDigitsParam();
1258 fDigitsParam->SetPretriggerPhase(det, fCurrPtrgPhase);
1259 fDigitsParam->SetNTimeBins(det, fCurrNtimebins);
1260 fDigitsParam->SetADCbaseline(det, 10);
1263 if (fDigitsManager->UsesDictionaries()) {
1264 fDigitsManager->GetDictionary(det, 0)->Reset();
1265 fDigitsManager->GetDictionary(det, 1)->Reset();
1266 fDigitsManager->GetDictionary(det, 2)->Reset();
1269 if ((fSignalIndex = fDigitsManager->GetIndexes(det))) {
1270 fSignalIndex->SetSM(fCurrSm);
1271 fSignalIndex->SetStack(fCurrStack);
1272 fSignalIndex->SetLayer(fCurrLayer);
1273 fSignalIndex->SetDetNumber(det);
1274 if (!fSignalIndex->IsAllocated())
1275 fSignalIndex->Allocate(16, 144, fCurrNtimebins);
1278 if (fCurrMajor & 0x20) {
1279 AliDebug(1, "This is a zs event");
1280 count += ReadZSData();
1283 AliDebug(1, "This is a nozs event");
1284 count += ReadNonZSData();
1288 // just read until data endmarkers
1289 while (fPayloadCurr - fPayloadStart < fPayloadSize &&
1290 *fPayloadCurr != fgkDataEndmarker)
1296 LinkError(kInvalidDetector, "%i", det);
1297 while (fPayloadCurr - fPayloadStart < fPayloadSize &&
1298 *fPayloadCurr != fgkDataEndmarker)
1302 if (fCurrSm > -1 && fCurrSm < 18) {
1303 fStats.fStatsSector[fCurrSm].fStatsHC[fCurrHC%60].fBytes += (fPayloadCurr - startPosLink) * sizeof(UInt_t);
1304 fStats.fStatsSector[fCurrSm].fStatsHC[fCurrHC%60].fBytesRead += count * sizeof(UInt_t);
1305 fStats.fStatsSector[fCurrSm].fBytesRead += count * sizeof(UInt_t);
1306 fStats.fBytesRead += count * sizeof(UInt_t);
1312 Int_t AliTRDrawStream::ReadTracklets()
1314 // read the tracklets from one HC
1316 fTrackletArray->Clear();
1318 UInt_t *start = fPayloadCurr;
1319 while (*(fPayloadCurr) != fgkTrackletEndmarker &&
1320 *(fPayloadCurr) != fgkStackEndmarker[0] &&
1321 *(fPayloadCurr) != fgkStackEndmarker[1] &&
1322 fPayloadCurr - fPayloadStart < (fPayloadSize - 1)) {
1323 new ((*fTrackletArray)[fTrackletArray->GetEntriesFast()]) AliTRDtrackletWord(*(fPayloadCurr), fCurrHC);
1328 if (fTrackletArray->GetEntriesFast() > 0) {
1329 AliDebug(1, Form("Found %i tracklets in %i %i %i (ev. %i)", fTrackletArray->GetEntriesFast(),
1330 (fCurrEquipmentId-kDDLOffset), fCurrSlot, fCurrLink, fRawReader->GetEventIndex()));
1331 if (fCurrSm > -1 && fCurrSm < 18) {
1332 fStats.fStatsSector[fCurrSm].fStatsHC[fCurrHC%60].fNTracklets += fTrackletArray->GetEntriesFast();
1333 fStats.fStatsSector[fCurrSm].fNTracklets += fTrackletArray->GetEntriesFast();
1336 fTrackletTree->Fill();
1338 for (Int_t iTracklet = 0; iTracklet < fTrackletArray->GetEntriesFast(); iTracklet++) {
1339 new ((*fTracklets)[fTracklets->GetEntriesFast()]) AliTRDtrackletWord(*((AliTRDtrackletWord*)(*fTrackletArray)[iTracklet]));
1343 // loop over remaining tracklet endmarkers
1344 while ((*(fPayloadCurr) == fgkTrackletEndmarker &&
1345 fPayloadCurr - fPayloadStart < fPayloadSize))
1348 return fPayloadCurr - start;
1351 Int_t AliTRDrawStream::ReadHcHeader()
1353 // read and parse the HC header of one HC
1354 // and store the information in the corresponding variables
1356 AliDebug(1, Form("HC header: 0x%08x", *fPayloadCurr));
1357 UInt_t *start = fPayloadCurr;
1358 // check not to be at the data endmarker
1359 if (*fPayloadCurr == fgkDataEndmarker ||
1360 *(fPayloadCurr) == fgkStackEndmarker[0] ||
1361 *(fPayloadCurr) == fgkStackEndmarker[1]) {
1362 LinkError(kHCmismatch, "found endmarker where HC header should be");
1366 fCurrSpecial = (*fPayloadCurr >> 31) & 0x1;
1367 fCurrMajor = (*fPayloadCurr >> 24) & 0x7f;
1368 fCurrMinor = (*fPayloadCurr >> 17) & 0x7f;
1369 fCurrAddHcWords = (*fPayloadCurr >> 14) & 0x7;
1370 fCurrSm = (*fPayloadCurr >> 9) & 0x1f;
1371 fCurrLayer = (*fPayloadCurr >> 6) & 0x7;
1372 fCurrStack = (*fPayloadCurr >> 3) & 0x7;
1373 fCurrSide = (*fPayloadCurr >> 2) & 0x1;
1374 fCurrCheck = (*fPayloadCurr) & 0x3;
1376 if ((fCurrSm != (((Int_t) fCurrEquipmentId) - kDDLOffset)) ||
1377 (fCurrStack != fCurrSlot) ||
1378 (fCurrLayer != fCurrLink / 2) ||
1379 (fCurrSide != fCurrLink % 2)) {
1380 LinkError(kHCmismatch,
1381 "HC: %i, %i, %i, %i\n 0x%08x 0x%08x 0x%08x 0x%08x",
1382 fCurrSm, fCurrStack, fCurrLayer, fCurrSide,
1383 fPayloadCurr[0], fPayloadCurr[1], fPayloadCurr[2], fPayloadCurr[3]);
1385 if (fCurrCheck != 0x1) {
1386 LinkError(kHCcheckFailed);
1389 if (fCurrAddHcWords > 0) {
1390 fCurrNtimebins = (fPayloadCurr[1] >> 26) & 0x3f;
1391 fCurrBC = (fPayloadCurr[1] >> 10) & 0xffff;
1392 fCurrPtrgCnt = (fPayloadCurr[1] >> 6) & 0xf;
1393 fCurrPtrgPhase = (fPayloadCurr[1] >> 2) & 0xf;
1396 fPayloadCurr += 1 + fCurrAddHcWords;
1398 return (fPayloadCurr - start);
1401 Int_t AliTRDrawStream::ReadTPData(Int_t mode)
1403 // testing of testpattern 1 to 3 (hardcoded), 0 missing
1404 // evcnt checking missing
1406 Int_t cpufromchannel[] = {0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3};
1410 Int_t mcmcount = -1;
1411 Int_t wordcount = 0;
1412 Int_t channelcount = 0;
1414 UInt_t expadcval = 0;
1416 Int_t lastmcmpos = -1;
1417 Int_t lastrobpos = -1;
1419 UInt_t* start = fPayloadCurr;
1421 while (*(fPayloadCurr) != fgkDataEndmarker &&
1422 fPayloadCurr - fPayloadStart < fPayloadSize - 1) {
1424 // ----- Checking MCM Header -----
1425 AliDebug(2, DumpMcmHeader("MCM header: ", *fPayloadCurr));
1426 UInt_t *startPosMCM = fPayloadCurr;
1429 // ----- checking for proper readout order - ROB -----
1430 fCurrRobPos = ROB(*fPayloadCurr);
1431 if (GetROBReadoutPos(ROB(*fPayloadCurr) / 2) >= lastrobpos) {
1432 if (GetROBReadoutPos(ROB(*fPayloadCurr) / 2) > lastrobpos)
1434 lastrobpos = GetROBReadoutPos(ROB(*fPayloadCurr) / 2);
1437 ROBError(kPosUnexp, Form("#%i after #%i in readout order", GetROBReadoutPos(ROB(*fPayloadCurr) / 2), lastrobpos));
1440 // ----- checking for proper readout order - MCM -----
1441 fCurrMcmPos = MCM(*fPayloadCurr);
1442 if (GetMCMReadoutPos(MCM(*fPayloadCurr)) > lastmcmpos) {
1443 lastmcmpos = GetMCMReadoutPos(MCM(*fPayloadCurr));
1446 MCMError(kPosUnexp, Form("#%i after #%i in readout order", GetMCMReadoutPos(MCM(*fPayloadCurr)), lastmcmpos));
1449 if (EvNo(*fPayloadCurr) != (evno & 0xfffff)) {
1451 evno = EvNo(*fPayloadCurr);
1454 MCMError(kEvCntMismatch, "%i <-> %i", evno, EvNo(*fPayloadCurr));
1460 evcnt = 0x3f & *fPayloadCurr >> 26;
1463 while (channelcount < 21) {
1465 if (cpu != cpufromchannel[channelcount]) {
1466 cpu = cpufromchannel[channelcount];
1467 expadcval = (1 << 9) | (fCurrRobPos << 6) | (fCurrMcmPos << 2) | cpu;
1471 while (count < 10) {
1472 if (*fPayloadCurr == fgkDataEndmarker) {
1473 MCMError(kMissTpData);
1474 return (fPayloadCurr - start);
1477 if (channelcount % 2 == 0)
1484 expword |= expadcval << 2;
1485 expadcval = ( (expadcval << 1) | ( ( (expadcval >> 9) ^ (expadcval >> 6) ) & 1) ) & 0x3FF;
1486 expword |= expadcval << 12;
1487 expadcval = ( (expadcval << 1) | ( ( (expadcval >> 9) ^ (expadcval >> 6) ) & 1) ) & 0x3FF;
1488 expword |= expadcval << 22;
1489 expadcval = ( (expadcval << 1) | ( ( (expadcval >> 9) ^ (expadcval >> 6) ) & 1) ) & 0x3FF;
1491 else if (mode == 2) {
1492 // ----- TP 2 ------
1493 expword = ((0x3f & evcnt) << 26) | ((fCurrSm + 1) << 21) | ((fCurrLayer + 1) << 18) |
1494 ((fCurrStack + 1) << 15) |
1495 (fCurrRobPos << 12) | (fCurrMcmPos << 8) | (cpu << 6) | (wordcount + 1);
1497 else if (mode == 3) {
1499 expword = ((0xfff & evcnt) << 20) | (fCurrSm << 15) | (fCurrLink/2 << 12) | (fCurrStack << 9) |
1500 (fCurrRobPos << 6) | (fCurrMcmPos << 2) | (cpu << 0);
1504 LinkError(kTPmodeInvalid, "Just reading");
1507 diff = *fPayloadCurr ^ expword;
1508 AliDebug(11, Form("Comparing ch %2i, word %2i (cpu %i): 0x%08x <-> 0x%08x",
1509 channelcount, wordcount, cpu, *fPayloadCurr, expword));
1512 MCMError(kTPmismatch,
1513 "Seen 0x%08x, expected 0x%08x, diff: 0x%08x, 0x%04x, 0x%02x - word %2i (cpu %i, ch %i)",
1514 *fPayloadCurr, expword, diff,
1515 0xffff & (diff | diff >> 16),
1516 0xff & (diff | diff >> 8 | diff >> 16 | diff >> 24),
1517 wordcount, cpu, channelcount);;
1522 if (*fPayloadCurr == fgkDataEndmarker)
1523 return (fPayloadCurr - start);
1527 // continue with next MCM
1529 if (IsDumping() && DumpingMCM(fCurrHC/2, fCurrRobPos, fCurrMcmPos)) {
1530 AliInfo(DumpRaw(Form("Event %i: Det %3i ROB %i MCM %2i", fRawReader->GetEventIndex(), fCurrHC/2, fCurrRobPos, fCurrMcmPos),
1531 startPosMCM, fPayloadCurr - startPosMCM));
1535 return fPayloadCurr - start;
1539 Int_t AliTRDrawStream::ReadZSData()
1541 // read the zs data from one link from the current reading position
1543 UInt_t *start = fPayloadCurr;
1546 Int_t mcmcountExp = fCurrStack == 2 ? 48 : 64;
1547 Int_t channelcount = 0;
1548 Int_t channelcountExp = 0;
1549 Int_t channelcountMax = 0;
1551 Int_t currentTimebin = 0;
1554 Int_t lastmcmpos = -1;
1555 Int_t lastrobpos = -1;
1557 if (fCurrNtimebins != fNtimebins) {
1559 LinkError(kNtimebinsChanged,
1560 "No. of timebins changed from %i to %i", fNtimebins, fCurrNtimebins);
1561 fNtimebins = fCurrNtimebins;
1564 timebins = fNtimebins;
1566 while (*(fPayloadCurr) != fgkDataEndmarker &&
1567 *(fPayloadCurr) != fgkStackEndmarker[0] &&
1568 *(fPayloadCurr) != fgkStackEndmarker[1] &&
1569 fPayloadCurr - fPayloadStart < fPayloadSize) {
1571 // ----- Checking MCM Header -----
1572 AliDebug(2, DumpMcmHeader("MCM header: ", *fPayloadCurr));
1573 UInt_t *startPosMCM = fPayloadCurr;
1575 // ----- checking for proper readout order - ROB -----
1576 fCurrRobPos = ROB(*fPayloadCurr);
1577 if (GetROBReadoutPos(ROB(*fPayloadCurr) / 2) >= lastrobpos) {
1578 if (GetROBReadoutPos(ROB(*fPayloadCurr) / 2) > lastrobpos)
1580 lastrobpos = GetROBReadoutPos(ROB(*fPayloadCurr) / 2);
1583 ROBError(kPosUnexp, Form("#%i after #%i and #%i in readout order",
1584 GetROBReadoutPos(ROB(*fPayloadCurr) / 2), lastrobpos, GetROBReadoutPos(fCurrRobPos)));
1587 // ----- checking for proper readout order - MCM -----
1588 fCurrMcmPos = MCM(*fPayloadCurr);
1589 if (GetMCMReadoutPos(MCM(*fPayloadCurr)) > lastmcmpos) {
1590 lastmcmpos = GetMCMReadoutPos(MCM(*fPayloadCurr));
1593 MCMError(kPosUnexp, Form("#%i after #%i and #%i in readout order",
1594 GetMCMReadoutPos(MCM(*fPayloadCurr)), lastmcmpos, GetMCMReadoutPos(fCurrMcmPos)));
1597 if (EvNo(*fPayloadCurr) != (evno & 0xfffff)) {
1599 evno = EvNo(*fPayloadCurr);
1602 MCMError(kEvCntMismatch, "%i <-> %i", evno, EvNo(*fPayloadCurr));
1605 Int_t adccoloff = AdcColOffset(*fPayloadCurr);
1606 Int_t padcoloff = PadColOffset(*fPayloadCurr);
1607 Int_t row = Row(*fPayloadCurr);
1610 if ((row > 11) && (fCurrStack == 2)) {
1611 MCMError(kUnknown, "Data in padrow > 11 for stack 2");
1614 if (fErrorFlags & (kDiscardMCM | kDiscardHC | kDiscardDDL))
1617 // ----- Reading ADC channels -----
1618 AliDebug(2, DumpAdcMask("ADC mask: ", *fPayloadCurr));
1620 // ----- analysing the ADC mask -----
1622 channelcountExp = GetNActiveChannelsFromMask(*fPayloadCurr);
1623 channelcountMax = GetNActiveChannels(*fPayloadCurr);
1624 Int_t channelmask = GetActiveChannels(*fPayloadCurr);
1625 Int_t channelno = -1;
1628 if (channelcountExp != channelcountMax) {
1629 if (channelcountExp > channelcountMax) {
1630 Int_t temp = channelcountExp;
1631 channelcountExp = channelcountMax;
1632 channelcountMax = temp;
1634 while (channelcountExp < channelcountMax && channelcountExp < 21 &&
1635 fPayloadCurr - fPayloadStart < fPayloadSize - 10 * channelcountExp - 1) {
1636 MCMError(kAdcMaskInconsistent,
1637 "Possible MCM-H: 0x%08x, possible ADC-mask: 0x%08x",
1638 *(fPayloadCurr + 10 * channelcountExp),
1639 *(fPayloadCurr + 10 * channelcountExp + 1) );
1640 if (!CouldBeMCMhdr( *(fPayloadCurr + 10 * channelcountExp)) && !CouldBeADCmask( *(fPayloadCurr + 10 * channelcountExp + 1)))
1646 MCMError(kAdcMaskInconsistent,
1647 "Inconsistency in no. of active channels: Counter: %i, Mask: %i, chosen: %i!",
1648 GetNActiveChannels(fPayloadCurr[-1]), GetNActiveChannelsFromMask(fPayloadCurr[-1]), channelcountExp);
1650 AliDebug(2, Form("expecting %i active channels, %i timebins", channelcountExp, fCurrNtimebins));
1652 // ----- reading marked ADC channels -----
1653 while (channelcount < channelcountExp && *(fPayloadCurr) != fgkDataEndmarker) {
1656 while (channelno < 20 && (channelmask & 1 << channelno) == 0)
1659 if (fCurrNtimebins > 30) {
1660 currentTimebin = ((*fPayloadCurr >> 2) & 0x3f);
1661 timebins = ((*fPayloadCurr >> 8) & 0xf) * 3;
1668 Int_t nADCwords = (timebins + 2) / 3;
1669 AliDebug(3, Form("Now reading %i words for channel %2i", nADCwords, channelno));
1670 Int_t adccol = adccoloff - channelno;
1671 Int_t padcol = padcoloff - channelno;
1672 // if (adccol < 3 || adccol > 165)
1673 // AliInfo(Form("writing channel %i of det %3i %i:%2i to adcrow/-col: %i/%i padcol: %i",
1674 // channelno, fCurrHC/2, fCurrRobPos, fCurrMcmPos, row, adccol, padcol));
1676 while ((adcwc < nADCwords) &&
1677 (*(fPayloadCurr) != fgkDataEndmarker) &&
1678 (fPayloadCurr - fPayloadStart < fPayloadSize)) {
1679 int check = 0x3 & *fPayloadCurr;
1680 if (channelno % 2 != 0) { // odd channel
1681 if (check != 0x2 && channelno < 21) {
1682 MCMError(kAdcCheckInvalid,
1683 "%i for %2i. ADC word in odd channel %i",
1684 check, adcwc+1, channelno);
1687 else { // even channel
1688 if (check != 0x3 && channelno < 21) {
1689 MCMError(kAdcCheckInvalid,
1690 "%i for %2i. ADC word in even channel %i",
1691 check, adcwc+1, channelno);
1695 // filling the actual timebin data
1696 int tb2 = 0x3ff & *fPayloadCurr >> 22;
1697 int tb1 = 0x3ff & *fPayloadCurr >> 12;
1698 int tb0 = 0x3ff & *fPayloadCurr >> 2;
1699 if (adcwc != 0 || fCurrNtimebins <= 30)
1700 fAdcArray->SetDataByAdcCol(row, adccol, currentTimebin++, tb0);
1703 if (currentTimebin >= fCurrNtimebins)
1705 fAdcArray->SetDataByAdcCol(row, adccol, currentTimebin++, tb1);
1706 if (currentTimebin >= fCurrNtimebins)
1708 fAdcArray->SetDataByAdcCol(row, adccol, currentTimebin++, tb2);
1714 if (adcwc != nADCwords)
1715 MCMError(kAdcDataAbort);
1718 if (padcol > 0 && padcol < 144) {
1719 fSignalIndex->AddIndexRC(row, padcol);
1725 if (fCurrSm > -1 && fCurrSm < 18) {
1726 fStats.fStatsSector[fCurrSm].fStatsHC[fCurrHC%60].fNChannels += channelcount;
1727 fStats.fStatsSector[fCurrSm].fNChannels += channelcount;
1729 if (channelcount != channelcountExp)
1730 MCMError(kAdcChannelsMiss);
1733 if (fCurrSm > -1 && fCurrSm < 18) {
1734 fStats.fStatsSector[fCurrSm].fStatsHC[fCurrHC%60].fNMCMs++;
1735 fStats.fStatsSector[fCurrSm].fNMCMs++;
1738 if (IsDumping() && DumpingMCM(fCurrHC/2, fCurrRobPos, fCurrMcmPos)) {
1739 AliInfo(DumpRaw(Form("Event %i: Det %3i ROB %i MCM %2i", fRawReader->GetEventIndex(), fCurrHC/2, fCurrRobPos, fCurrMcmPos),
1740 startPosMCM, fPayloadCurr - startPosMCM));
1743 // continue with next MCM
1746 // check for missing MCMs (if header suppression is inactive)
1747 if (((fCurrMajor & 0x1) == 0) && (mcmcount != mcmcountExp)) {
1748 LinkError(kMissMcmHeaders,
1749 "No. of MCM headers %i not as expected: %i",
1750 mcmcount, mcmcountExp);
1753 return (fPayloadCurr - start);
1756 Int_t AliTRDrawStream::ReadNonZSData()
1758 // read the non-zs data from one link from the current reading position
1760 UInt_t *start = fPayloadCurr;
1763 Int_t mcmcountExp = fCurrStack == 2 ? 48 : 64;
1764 Int_t channelcount = 0;
1765 Int_t channelcountExp = 0;
1767 Int_t currentTimebin = 0;
1770 Int_t lastmcmpos = -1;
1771 Int_t lastrobpos = -1;
1773 if (fCurrNtimebins != fNtimebins) {
1775 LinkError(kNtimebinsChanged,
1776 "No. of timebins changed from %i to %i", fNtimebins, fCurrNtimebins);
1777 fNtimebins = fCurrNtimebins;
1780 timebins = fNtimebins;
1782 while (*(fPayloadCurr) != fgkDataEndmarker &&
1783 fPayloadCurr - fPayloadStart < fPayloadSize - 2) {
1785 // ----- Checking MCM Header -----
1786 AliDebug(2, Form("MCM header: 0x%08x", *fPayloadCurr));
1788 // ----- checking for proper readout order - ROB -----
1789 fCurrRobPos = ROB(*fPayloadCurr);
1790 if (GetROBReadoutPos(ROB(*fPayloadCurr) / 2) >= lastrobpos) {
1791 if (GetROBReadoutPos(ROB(*fPayloadCurr) / 2) > lastrobpos)
1793 lastrobpos = GetROBReadoutPos(ROB(*fPayloadCurr) / 2);
1796 ROBError(kPosUnexp, Form("#%i after #%i in readout order", GetROBReadoutPos(ROB(*fPayloadCurr) / 2), lastrobpos));
1799 // ----- checking for proper readout order - MCM -----
1800 fCurrMcmPos = MCM(*fPayloadCurr);
1801 if (GetMCMReadoutPos(MCM(*fPayloadCurr)) > lastmcmpos) {
1802 lastmcmpos = GetMCMReadoutPos(MCM(*fPayloadCurr));
1805 MCMError(kPosUnexp, Form("#%i after #%i in readout order", GetMCMReadoutPos(MCM(*fPayloadCurr)), lastmcmpos));
1808 if (EvNo(*fPayloadCurr) != (evno & 0xfffff)) {
1810 evno = EvNo(*fPayloadCurr);
1813 MCMError(kEvCntMismatch, "%i <-> %i", evno, EvNo(*fPayloadCurr));
1818 channelcountExp = 21;
1821 Int_t adccoloff = AdcColOffset(*fPayloadCurr);
1822 Int_t padcoloff = PadColOffset(*fPayloadCurr);
1823 Int_t row = Row(*fPayloadCurr);
1827 // ----- reading marked ADC channels -----
1828 while (channelcount < channelcountExp &&
1829 *(fPayloadCurr) != fgkDataEndmarker) {
1836 Int_t nADCwords = (timebins + 2) / 3;
1837 AliDebug(2, Form("Now looking %i words", nADCwords));
1838 Int_t adccol = adccoloff - channelno;
1839 Int_t padcol = padcoloff - channelno;
1840 while ((adcwc < nADCwords) &&
1841 (*(fPayloadCurr) != fgkDataEndmarker) &&
1842 (fPayloadCurr - fPayloadStart < fPayloadSize)) {
1843 int check = 0x3 & *fPayloadCurr;
1844 if (channelno % 2 != 0) { // odd channel
1845 if (check != 0x2 && channelno < 21) {
1846 MCMError(kAdcCheckInvalid,
1847 "%i for %2i. ADC word in odd channel %i",
1848 check, adcwc+1, channelno);
1851 else { // even channel
1852 if (check != 0x3 && channelno < 21) {
1853 MCMError(kAdcCheckInvalid,
1854 "%i for %2i. ADC word in even channel %i",
1855 check, adcwc+1, channelno);
1859 // filling the actual timebin data
1860 int tb2 = 0x3ff & *fPayloadCurr >> 22;
1861 int tb1 = 0x3ff & *fPayloadCurr >> 12;
1862 int tb0 = 0x3ff & *fPayloadCurr >> 2;
1863 if (adcwc != 0 || fCurrNtimebins <= 30)
1864 fAdcArray->SetDataByAdcCol(row, adccol, currentTimebin++, tb0);
1867 if (currentTimebin >= fCurrNtimebins)
1869 fAdcArray->SetDataByAdcCol(row, adccol, currentTimebin++, tb1);
1870 if (currentTimebin >= fCurrNtimebins)
1872 fAdcArray->SetDataByAdcCol(row, adccol, currentTimebin++, tb2);
1878 if (adcwc != nADCwords)
1879 MCMError(kAdcDataAbort);
1882 if (padcol > 0 && padcol < 144) {
1883 fSignalIndex->AddIndexRC(row, padcol);
1889 if (channelcount != channelcountExp)
1890 MCMError(kAdcChannelsMiss);
1892 // continue with next MCM
1895 // check for missing MCMs (if header suppression is inactive)
1896 if (mcmcount != mcmcountExp) {
1897 LinkError(kMissMcmHeaders,
1898 "%i not as expected: %i", mcmcount, mcmcountExp);
1901 return (fPayloadCurr - start);
1904 Int_t AliTRDrawStream::SeekNextStack()
1906 // proceed in raw data stream till the next stack
1908 if (!fCurrStackEndmarkerAvail)
1911 UInt_t *start = fPayloadCurr;
1913 // read until data endmarkers
1914 while ((fPayloadCurr - fPayloadStart < fPayloadSize-1) &&
1915 ((fPayloadCurr[0] != fgkStackEndmarker[0]) ||
1916 (fPayloadCurr[1] != fgkStackEndmarker[1])))
1919 if ((fPayloadCurr - start) != 0)
1920 StackError(kUnknown, "skipped %i words to reach stack endmarker", fPayloadCurr - start);
1922 AliDebug(2, Form("stack endmarker: 0x%08x 0x%08x", fPayloadCurr[0], fPayloadCurr[1]));
1928 return (fPayloadCurr-start);
1931 Int_t AliTRDrawStream::SeekNextLink()
1933 // proceed in raw data stream till the next link
1935 UInt_t *start = fPayloadCurr;
1937 // read until data endmarkers
1938 while (fPayloadCurr - fPayloadStart < fPayloadSize &&
1939 ((fPayloadCurr[0] != fgkStackEndmarker[0]) ||
1940 (fPayloadCurr[1] != fgkStackEndmarker[1])) &&
1941 *fPayloadCurr != fgkDataEndmarker)
1944 // read all data endmarkers
1945 while (fPayloadCurr - fPayloadStart < fPayloadSize &&
1946 *fPayloadCurr == fgkDataEndmarker)
1949 return (fPayloadCurr - start);
1952 Bool_t AliTRDrawStream::ConnectTracklets(TTree *trklTree)
1954 // connect the tracklet tree used to store the tracklet output
1956 fTrackletTree = trklTree;
1960 if (!fTrackletTree->GetBranch("hc"))
1961 fTrackletTree->Branch("hc", &fCurrHC, "hc/I");
1963 fTrackletTree->SetBranchAddress("hc", &fCurrHC);
1965 if (!fTrackletTree->GetBranch("trkl"))
1966 fTrackletTree->Branch("trkl", &fTrackletArray);
1968 fTrackletTree->SetBranchAddress("trkl", &fTrackletArray);
1974 void AliTRDrawStream::EquipmentError(ErrorCode_t err, const char *const msg, ...)
1976 // register error according to error code on equipment level
1977 // and return the corresponding error message
1979 fLastError.fSector = fCurrEquipmentId - kDDLOffset;
1980 fLastError.fStack = -1;
1981 fLastError.fLink = -1;
1982 fLastError.fRob = -1;
1983 fLastError.fMcm = -1;
1984 fLastError.fError = err;
1985 (this->*fStoreError)();
1988 if (fgErrorDebugLevel[err] > 10)
1989 AliDebug(fgErrorDebugLevel[err],
1990 Form("Event %6i: Eq. %2d - %s : %s",
1991 fRawReader->GetEventIndex(), fCurrEquipmentId, fgkErrorMessages[err],
1992 (va_start(ap, msg), vsprintf(fErrorBuffer, msg, ap), va_end(ap), fErrorBuffer) ));
1994 AliError(Form("Event %6i: Eq. %2d - %s : %s",
1995 fRawReader->GetEventIndex(), fCurrEquipmentId, fgkErrorMessages[err],
1996 (va_start(ap, msg), vsprintf(fErrorBuffer, msg, ap), va_end(ap), fErrorBuffer) ));
1997 fErrorFlags |= fgErrorBehav[err];
2001 void AliTRDrawStream::StackError(ErrorCode_t err, const char *const msg, ...)
2003 // register error according to error code on stack level
2004 // and return the corresponding error message
2006 fLastError.fSector = fCurrEquipmentId - kDDLOffset;
2007 fLastError.fStack = fCurrSlot;
2008 fLastError.fLink = -1;
2009 fLastError.fRob = -1;
2010 fLastError.fMcm = -1;
2011 fLastError.fError = err;
2012 (this->*fStoreError)();
2015 if (fgErrorDebugLevel[err] > 0)
2016 AliDebug(fgErrorDebugLevel[err],
2017 Form("Event %6i: Eq. %2d S %i - %s : %s",
2018 fRawReader->GetEventIndex(), fCurrEquipmentId, fCurrSlot, fgkErrorMessages[err],
2019 (va_start(ap, msg), vsprintf(fErrorBuffer, msg, ap), va_end(ap), fErrorBuffer) ));
2021 AliError(Form("Event %6i: Eq. %2d S %i - %s : %s",
2022 fRawReader->GetEventIndex(), fCurrEquipmentId, fCurrSlot, fgkErrorMessages[err],
2023 (va_start(ap, msg), vsprintf(fErrorBuffer, msg, ap), va_end(ap), fErrorBuffer) ));
2024 fErrorFlags |= fgErrorBehav[err];
2028 void AliTRDrawStream::LinkError(ErrorCode_t err, const char *const msg, ...)
2030 // register error according to error code on link level
2031 // and return the corresponding error message
2033 fLastError.fSector = fCurrEquipmentId - kDDLOffset;
2034 fLastError.fStack = fCurrSlot;
2035 fLastError.fLink = fCurrLink;
2036 fLastError.fRob = -1;
2037 fLastError.fMcm = -1;
2038 fLastError.fError = err;
2039 (this->*fStoreError)();
2042 if (fgErrorDebugLevel[err] > 0)
2043 AliDebug(fgErrorDebugLevel[err],
2044 Form("Event %6i: Eq. %2d S %i l %2i - %s : %s",
2045 fRawReader->GetEventIndex(), fCurrEquipmentId, fCurrSlot, fCurrLink, fgkErrorMessages[err],
2046 (va_start(ap, msg), vsprintf(fErrorBuffer, msg, ap), va_end(ap), fErrorBuffer) ));
2048 AliError(Form("Event %6i: Eq. %2d S %i l %2i - %s : %s",
2049 fRawReader->GetEventIndex(), fCurrEquipmentId, fCurrSlot, fCurrLink, fgkErrorMessages[err],
2050 (va_start(ap, msg), vsprintf(fErrorBuffer, msg, ap), va_end(ap), fErrorBuffer) ));
2051 fErrorFlags |= fgErrorBehav[err];
2055 void AliTRDrawStream::ROBError(ErrorCode_t err, const char *const msg, ...)
2057 // register error according to error code on ROB level
2058 // and return the corresponding error message
2060 fLastError.fSector = fCurrEquipmentId - kDDLOffset;
2061 fLastError.fStack = fCurrSlot;
2062 fLastError.fLink = fCurrLink;
2063 fLastError.fRob = fCurrRobPos;
2064 fLastError.fMcm = -1;
2065 fLastError.fError = err;
2066 (this->*fStoreError)();
2069 if (fgErrorDebugLevel[err] > 0)
2070 AliDebug(fgErrorDebugLevel[err],
2071 Form("Event %6i: Eq. %2d S %i l %2i ROB %i - %s : %s",
2072 fRawReader->GetEventIndex(), fCurrEquipmentId, fCurrSlot, fCurrLink, fCurrRobPos, fgkErrorMessages[err],
2073 (va_start(ap, msg), vsprintf(fErrorBuffer, msg, ap), va_end(ap), fErrorBuffer) ));
2075 AliError(Form("Event %6i: Eq. %2d S %i l %2i ROB %i - %s : %s",
2076 fRawReader->GetEventIndex(), fCurrEquipmentId, fCurrSlot, fCurrLink, fCurrRobPos, fgkErrorMessages[err],
2077 (va_start(ap, msg), vsprintf(fErrorBuffer, msg, ap), va_end(ap), fErrorBuffer) ));
2078 fErrorFlags |= fgErrorBehav[err];
2082 void AliTRDrawStream::MCMError(ErrorCode_t err, const char *const msg, ...)
2084 // register error according to error code on MCM level
2085 // and return the corresponding error message
2087 fLastError.fSector = fCurrEquipmentId - kDDLOffset;
2088 fLastError.fStack = fCurrSlot;
2089 fLastError.fLink = fCurrLink;
2090 fLastError.fRob = fCurrRobPos;
2091 fLastError.fMcm = fCurrMcmPos;
2092 fLastError.fError = err;
2093 (this->*fStoreError)();
2096 if (fgErrorDebugLevel[err] > 0)
2097 AliDebug(fgErrorDebugLevel[err],
2098 Form("Event %6i: Eq. %2d S %i l %2i ROB %i MCM %2i - %s : %s",
2099 fRawReader->GetEventIndex(), fCurrEquipmentId, fCurrSlot, fCurrLink, fCurrRobPos, fCurrMcmPos, fgkErrorMessages[err],
2100 (va_start(ap, msg), vsprintf(fErrorBuffer, msg, ap), va_end(ap), fErrorBuffer) ));
2102 AliError(Form("Event %6i: Eq. %2d S %i l %2i ROB %i MCM %2i - %s : %s",
2103 fRawReader->GetEventIndex(), fCurrEquipmentId, fCurrSlot, fCurrLink, fCurrRobPos, fCurrMcmPos, fgkErrorMessages[err],
2104 (va_start(ap, msg), vsprintf(fErrorBuffer, msg, ap), va_end(ap), fErrorBuffer) ));
2105 fErrorFlags |= fgErrorBehav[err];
2108 const char* AliTRDrawStream::GetErrorMessage(ErrorCode_t errCode)
2110 // return the error message for the given error code
2112 if (errCode > 0 && errCode < kLastErrorCode)
2113 return fgkErrorMessages[errCode];
2118 void AliTRDrawStream::AliTRDrawStats::ClearStats()
2120 // clear statistics (includes clearing sector-wise statistics)
2123 for (Int_t iSector = 0; iSector < 18; iSector++) {
2124 fStatsSector[iSector].ClearStats();
2129 void AliTRDrawStream::AliTRDrawStats::AliTRDrawStatsSector::ClearStats()
2131 // clear statistics (includes clearing HC-wise statistics)
2139 for (Int_t iHC = 0; iHC < 60; iHC++) {
2140 fStatsHC[iHC].ClearStats();
2144 void AliTRDrawStream::AliTRDrawStats::AliTRDrawStatsSector::AliTRDrawStatsHC::ClearStats()
2155 void AliTRDrawStream::SetDumpMCM(Int_t det, Int_t rob, Int_t mcm, Bool_t dump)
2157 // mark MCM for dumping of raw data
2160 fDumpMCM[fNDumpMCMs++] = (det << 7) | (rob << 4) | mcm;
2164 for (iMCM = 0; iMCM < fNDumpMCMs; iMCM++) {
2165 if (fDumpMCM[iMCM] == ((det << 7) | (rob << 4) | mcm)) {
2170 for ( ; iMCM < fNDumpMCMs; iMCM++) {
2171 fDumpMCM[iMCM] = fDumpMCM[iMCM+1];
2176 Bool_t AliTRDrawStream::DumpingMCM(Int_t det, Int_t rob, Int_t mcm) const
2178 // check if MCM data should be dumped
2180 for (Int_t iMCM = 0; iMCM < fNDumpMCMs; iMCM++) {
2181 if (fDumpMCM[iMCM] == ((det << 7) | (rob << 4) | mcm)) {
2188 TString AliTRDrawStream::DumpRaw(TString title, const UInt_t *start, Int_t length, UInt_t endmarker)
2193 for (Int_t pos = 0; pos < length; pos += 4) {
2194 if ((start[pos+0] != endmarker) && pos+0 < length)
2195 if ((start[pos+1] != endmarker && pos+1 < length))
2196 if ((start[pos+2] != endmarker && pos+2 < length))
2197 if ((start[pos+3] != endmarker && pos+3 < length))
2198 title += Form(" 0x%08x 0x%08x 0x%08x 0x%08x\n",
2199 start[pos+0], start[pos+1], start[pos+2], start[pos+3]);
2201 title += Form(" 0x%08x 0x%08x 0x%08x 0x%08x\n",
2202 start[pos+0], start[pos+1], start[pos+2], start[pos+3]);
2206 title += Form(" 0x%08x 0x%08x 0x%08x\n",
2207 start[pos+0], start[pos+1], start[pos+2]);
2211 title += Form(" 0x%08x 0x%08x\n",
2212 start[pos+0], start[pos+1]);
2216 title += Form(" 0x%08x\n",
2224 TString AliTRDrawStream::DumpMcmHeader(TString title, UInt_t word)
2226 title += Form("0x%08x -> ROB: %i, MCM: %2i",
2227 word, ROB(word), MCM(word));
2231 TString AliTRDrawStream::DumpAdcMask(TString title, UInt_t word)
2233 title += Form("0x%08x -> #ch : %2i, 0x%06x (%2i ch)",
2234 word, GetNActiveChannels(word), GetActiveChannels(word), GetNActiveChannelsFromMask(word));
2238 AliTRDrawStream::AliTRDrawStreamError::AliTRDrawStreamError(Int_t error, Int_t sector, Int_t stack, Int_t link, Int_t rob, Int_t mcm) :
2250 void AliTRDrawStream::SortTracklets(TClonesArray *trklArray, TList &sortedTracklets, Int_t *indices)
2252 // sort tracklets for referencing from GTU tracks
2257 Int_t nTracklets = trklArray->GetEntriesFast();
2260 for (Int_t iTracklet = 0; iTracklet < nTracklets; iTracklet++) {
2261 AliTRDtrackletBase *trkl = (AliTRDtrackletBase*) ((*trklArray)[iTracklet]);
2262 Int_t hc = trkl->GetHCId();
2263 if ((hc < 0) || (hc >= 1080)) {
2264 AliErrorClass(Form("HC for tracklet: 0x%08x out of range: %i", trkl->GetTrackletWord(), trkl->GetHCId()));
2267 AliDebugClass(5, Form("hc: %4i : 0x%08x z: %2i", hc, trkl->GetTrackletWord(), trkl->GetZbin()));
2269 AliDebugClass(2, Form("set tracklet index for HC %i to %i", hc, iTracklet));
2270 indices[hc] = iTracklet + 1;
2275 for (Int_t iDet = 0; iDet < 540; iDet++) {
2276 Int_t trklIndexA = indices[2*iDet + 0] - 1;
2277 Int_t trklIndexB = indices[2*iDet + 1] - 1;
2278 Int_t trklIndex = sortedTracklets.GetEntries();
2279 AliTRDtrackletBase *trklA = trklIndexA > -1 ? (AliTRDtrackletBase*) ((*trklArray)[trklIndexA]) : 0x0;
2280 AliTRDtrackletBase *trklB = trklIndexB > -1 ? (AliTRDtrackletBase*) ((*trklArray)[trklIndexB]) : 0x0;
2281 AliTRDtrackletBase *trklNext = 0x0;
2282 while (trklA != 0x0 || trklB != 0x0) {
2283 AliDebugClass(5, Form("det %i - A: %i/%i -> %p, B: %i/%i -> %p",
2284 iDet, trklIndexA, nTracklets, trklA, trklIndexB, nTracklets, trklB));
2288 trklB = trklIndexB < nTracklets ? (AliTRDtrackletBase*) ((*trklArray)[trklIndexB]) : 0x0;
2289 if (trklB && trklB->GetHCId() != 2*iDet + 1)
2292 else if (trklB == 0x0) {
2295 trklA = trklIndexA < nTracklets ? (AliTRDtrackletBase*) ((*trklArray)[trklIndexA]) : 0x0;
2296 if (trklA && trklA->GetHCId() != 2*iDet)
2300 if (trklA->GetZbin() <= trklB->GetZbin()) {
2303 trklA = trklIndexA < nTracklets ? (AliTRDtrackletBase*) ((*trklArray)[trklIndexA]) : 0x0;
2304 if (trklA && trklA->GetHCId() != 2*iDet)
2310 trklB = trklIndexB < nTracklets ? (AliTRDtrackletBase*) ((*trklArray)[trklIndexB]) : 0x0;
2311 if (trklB && trklB->GetHCId() != 2*iDet + 1)
2316 sortedTracklets.Add(trklNext);
2321 // updating tracklet indices as in output
2322 if (sortedTracklets.GetEntries() != trklIndex) {
2323 indices[2*iDet + 0] = trklIndex;
2324 indices[2*iDet + 1] = sortedTracklets.GetEntries();
2326 indices[2*iDet + 0] = indices[2*iDet + 1] = -1;
2331 void AliTRDrawStream::AssignTracklets(AliESDTrdTrack *trdTrack, Int_t *trackletIndex, Int_t refIndex[6])
2333 UInt_t mask = trdTrack->GetLayerMask();
2334 UInt_t stack = trdTrack->GetStack();
2336 for (Int_t iLayer = 0; iLayer < 6; iLayer++) {
2337 refIndex[iLayer] = -1;
2339 if (mask & (1 << iLayer)) {
2341 Int_t det = trdTrack->GetSector()*30 + stack*6 + iLayer;
2342 Int_t idx = trdTrack->GetTrackletIndex(iLayer);
2344 if ((det < 0) || (det > 539)) {
2345 AliErrorClass(Form("Invalid detector no. from track: %i", 2*det));
2348 if (trackletIndex[2*det] >= 0) {
2349 if ((trackletIndex[2*det] + idx > -1) &&
2350 (trackletIndex[2*det] + idx < trackletIndex[2*det+1])) {
2351 refIndex[iLayer] = trackletIndex[2*det] + idx;
2353 AliErrorClass(Form("Requested tracklet index %i out of range", idx));
2356 AliErrorClass(Form("Non-existing tracklets requested in det %i", det));