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)) {
434 if (fCurrLink >= fgkNlinks) {
441 AliDebug(2, Form("Stack %i, Link %i, mask: 0x%02x", fCurrSlot, fCurrLink, fCurrLinkMask[fCurrSlot]));
442 fCurrHC = (fCurrEquipmentId - kDDLOffset) * fgkNlinks * fgkNstacks +
443 fCurrSlot * fgkNlinks + fCurrLink;
445 if (fCurrLinkMonitorFlags[fCurrSlot*fgkNlinks + fCurrLink] != 0) {
446 LinkError(kLinkMonitor);
447 if (fgErrorBehav[kLinkMonitor] == kTolerate)
451 // read the data from one HC
454 // read all data endmarkers
457 if (fCurrLink % 2 == 0) {
458 // if we just read the A-side HC then also check the B-side
461 if (fCurrLinkMask[fCurrSlot] & (1 << fCurrLink)) {
462 if (fCurrLinkMonitorFlags[fCurrSlot*fgkNlinks + fCurrLink] != 0) {
463 LinkError(kLinkMonitor);
464 if (fgErrorBehav[kLinkMonitor] == kTolerate)
475 if ((fCurrStackMask & (1 << fCurrSlot)) == 0) {
481 if (fCurrLink >= fgkNlinks) {
487 } while ((fCurrSlot < fgkNstacks) &&
488 (((fCurrStackMask & (1 << fCurrSlot)) == 0) ||
489 ((fCurrLinkMask[fCurrSlot] & (1 << fCurrLink))) == 0));
491 // return chamber information from HC if it is valid
492 // otherwise return information from link position
493 if (fCurrSm < 0 || fCurrSm >= fgkNsectors || fCurrStack < 0 || fCurrStack >= fgkNstacks || fCurrLayer < 0 || fCurrLayer >= fgkNlinks/2)
494 return ((fCurrEquipmentId-kDDLOffset) + fCurrSlot * fgkNlinks/2 + fCurrLink/2);
496 return (fCurrSm * fgkNstacks*fgkNlinks/2 + fCurrStack * fgkNlinks/2 + fCurrLayer);
500 Int_t AliTRDrawStream::ReadGTUHeaders(UInt_t *buffer)
502 // check the data source and read the headers
504 if (fCurrEquipmentId >= kDDLOffset && fCurrEquipmentId <= kDDLMax) {
507 // setting the pointer to data and current reading position
508 fPayloadCurr = fPayloadStart = buffer;
509 fPayloadSize = fRawReader->GetDataSize() / sizeof(UInt_t);
510 fStats.fStatsSector[fCurrEquipmentId - kDDLOffset].fBytes = fRawReader->GetDataSize();
511 AliDebug(2, Form("Read buffer of size: %i", fRawReader->GetDataSize()));
513 AliDebug(1, DumpRaw("raw data", fPayloadCurr, TMath::Min(fPayloadSize, 1000)));
516 if (ReadSmHeader() < 0) {
517 AliError(Form("Reading SM header failed, skipping this DDL %i", fCurrEquipmentId));
521 // read tracking headers (if available)
522 if (fCurrTrkHeaderAvail) {
523 for (Int_t iStack = 0; iStack < fgkNstacks; iStack++) {
524 if ((fCurrStackMask & (1 << iStack)) != 0)
525 ReadTrackingHeader(iStack);
529 // read trigger header(s) (if available)
530 if (fCurrTrgHeaderAvail)
531 ReadTriggerHeaders();
534 for (Int_t iStack = 0; iStack < fgkNstacks; iStack++) {
535 if ((fCurrStackMask & (1 << iStack)) != 0)
536 ReadStackHeader(iStack);
545 Int_t AliTRDrawStream::ReadSmHeader()
547 // read the SMU index header at the current reading position
548 // and store the information in the corresponding variables
550 if (fPayloadCurr - fPayloadStart >= fPayloadSize - 1) {
551 EquipmentError(kUnknown, "SM Header incomplete");
555 fCurrTrgFlags[fCurrEquipmentId-kDDLOffset] = 0;
557 fCurrSmHeaderSize = ((*fPayloadCurr) >> 16) & 0xffff;
558 fCurrSmHeaderVersion = ((*fPayloadCurr) >> 12) & 0xf;
559 fCurrTrackEnable = ((*fPayloadCurr) >> 6) & 0x1;
560 fCurrTrackletEnable = ((*fPayloadCurr) >> 5) & 0x1;
561 fCurrStackMask = ((*fPayloadCurr) ) & 0x1f;
562 fCurrHwRev = (fPayloadCurr[1] >> 12) & 0xffff;
563 fCurrStackEndmarkerAvail = 0;
565 switch (fCurrSmHeaderVersion) {
567 fCurrTrailerReadout = 0;
568 fCurrTrgHeaderAvail = 0;
570 fCurrTrkHeaderAvail = 0;
576 fCurrTrailerReadout = ((*fPayloadCurr) >> 10) & 0x1;
577 fCurrTrgHeaderAvail = 1;
578 fCurrTrgHeaderReadout = ((*fPayloadCurr) >> 9) & 0x1;
579 fCurrEvType = ((*fPayloadCurr) >> 7) & 0x3;
580 fCurrTrkHeaderAvail = fCurrTrackEnable;
581 fCurrTriggerEnable = (fPayloadCurr[2] >> 8) & 0xfff;
582 fCurrTriggerFired = (fPayloadCurr[2] >> 20) & 0xfff;
583 fCurrTrgFlags[fCurrEquipmentId-kDDLOffset] = fCurrTriggerFired;
587 fCurrTrailerReadout = ((*fPayloadCurr) >> 10) & 0x1;
588 fCurrTrgHeaderAvail = 1;
589 fCurrTrgHeaderReadout = ((*fPayloadCurr) >> 9) & 0x1;
590 fCurrEvType = ((*fPayloadCurr) >> 7) & 0x3;
591 fCurrTrkHeaderAvail = fCurrTrackEnable;
592 fCurrTriggerEnable = (fPayloadCurr[2] >> 8) & 0xfff;
593 fCurrTriggerFired = (fPayloadCurr[2] >> 20) & 0xfff;
594 fCurrTrgFlags[fCurrEquipmentId-kDDLOffset] = fCurrTriggerFired;
595 fCurrStackEndmarkerAvail = 1;
599 AliError(Form("unknown SM header version: 0x%x", fCurrSmHeaderVersion));
602 AliDebug(5, Form("SM header: size: %i, version: %i, track enable: %i, tracklet enable: %i, stack mask: %2x, trailer: %i, trgheader: %i, trkheader: %i",
604 fCurrSmHeaderVersion,
610 fCurrTrkHeaderAvail ));
612 // jump to the first word after the SM header
613 fPayloadCurr += fCurrSmHeaderSize + 1;
615 return fCurrSmHeaderSize + 1;
618 Int_t AliTRDrawStream::DecodeGTUtracks()
620 // decode GTU track words
621 // this depends on the hardware revision of the SMU
623 Int_t sector = fCurrEquipmentId-kDDLOffset;
625 if ((sector < 0) || (sector > 17)) {
626 AliError(Form("Invalid sector %i for GTU tracks", sector));
630 AliDebug(1, DumpRaw(Form("GTU tracks in sector %2i (hw rev %i)", sector, fCurrHwRev),
631 fPayloadCurr + 4, 10, 0xffe0ffff));
633 fCurrTrgFlags[sector] = 0;
635 if (fCurrHwRev < 1772) {
636 UInt_t fastWord; // fast trigger word
637 ULong64_t trackWord = 0; // extended track word
640 for (UInt_t iWord = 4; iWord < fCurrSmHeaderSize; iWord++) {
641 if (fPayloadCurr[iWord] == 0x10000000) { // stack boundary marker
647 ((fPayloadCurr[iWord] & 0xfffff0f0) == 0x13370000)) {
648 fastWord = fPayloadCurr[iWord];
649 fCurrTrgFlags[sector] |= 1 << (stack+11); // assume tracking done if fast word sent
650 AliDebug(1, Form("stack %i: fast trigger word: 0x%08x", stack, fastWord));
653 else if ((idx & 0x1) == 0x1) {
654 trackWord |= ((ULong64_t) fPayloadCurr[iWord]) << 32;
655 AliDebug(1,Form("track debug word: 0x%016llx", trackWord));
657 AliESDTrdTrack *trk = new ((*fTracks)[fTracks->GetEntriesFast()])
660 trk->SetSector(sector);
661 trk->SetStack((trackWord >> 60) & 0x7);
665 trk->SetLayerMask((trackWord >> 16) & 0x3f);
666 trk->SetTrackletIndex((trackWord >> 22) & 0x3f, 0);
667 trk->SetTrackletIndex((trackWord >> 28) & 0x3f, 1);
668 trk->SetTrackletIndex((trackWord >> 34) & 0x3f, 2);
669 trk->SetTrackletIndex((trackWord >> 40) & 0x3f, 3);
670 trk->SetTrackletIndex((trackWord >> 46) & 0x3f, 4);
671 trk->SetTrackletIndex((trackWord >> 52) & 0x3f, 5);
677 Float_t pt = (((Int_t) (trackWord & 0xffff) ^ 0x8000) - 0x8000)/128.;
678 if (TMath::Abs(pt) > 0.1) {
679 trk->SetA((Int_t) (0.15*51625./100./pt / 160e-4 * 2));
684 trackWord = fPayloadCurr[iWord];
690 else if (fCurrHwRev < 1804) {
691 UInt_t fastWord; // fast trigger word
692 ULong64_t trackWord = 0; // extended track word
695 for (UInt_t iWord = 4; iWord < fCurrSmHeaderSize; iWord++) {
696 if (fPayloadCurr[iWord] == 0xffe0ffff) { // stack boundary marker
702 ((fPayloadCurr[iWord] & 0xfffff0f0) == 0x13370000)) {
703 fastWord = fPayloadCurr[iWord];
704 fCurrTrgFlags[sector] |= 1 << (stack+11); // assume tracking done if fast word sent
705 AliDebug(1, Form("stack %i: fast trigger word: 0x%08x", stack, fastWord));
708 else if ((idx & 0x1) == 0x1) {
709 trackWord |= ((ULong64_t) fPayloadCurr[iWord]) << 32;
710 AliDebug(1, Form("track debug word: 0x%016llx", trackWord));
712 AliESDTrdTrack *trk = new ((*fTracks)[fTracks->GetEntriesFast()])
715 trk->SetSector(fCurrEquipmentId-kDDLOffset);
716 trk->SetStack((trackWord >> 60) & 0x7);
720 trk->SetLayerMask((trackWord >> 16) & 0x3f);
721 trk->SetTrackletIndex((trackWord >> 22) & 0x3f, 0);
722 trk->SetTrackletIndex((trackWord >> 28) & 0x3f, 1);
723 trk->SetTrackletIndex((trackWord >> 34) & 0x3f, 2);
724 trk->SetTrackletIndex((trackWord >> 40) & 0x3f, 3);
725 trk->SetTrackletIndex((trackWord >> 46) & 0x3f, 4);
726 trk->SetTrackletIndex((trackWord >> 52) & 0x3f, 5);
732 Float_t pt = (((Int_t) (trackWord & 0xffff) ^ 0x8000) - 0x8000)/128.;
733 if (TMath::Abs(pt) > 0.1) {
734 trk->SetA((Int_t) (-0.15*51625./100./pt / 160e-4 * 2));
739 trackWord = fPayloadCurr[iWord];
745 else if (fCurrHwRev < 1819) {
746 UInt_t fastWord; // fast trigger word
747 ULong64_t trackWord = 0; // extended track word
750 for (UInt_t iWord = 4; iWord < fCurrSmHeaderSize; iWord++) {
751 if (fPayloadCurr[iWord] == 0xffe0ffff) { // stack boundary marker
757 ((fPayloadCurr[iWord] & 0xfffff0f0) == 0x13370000)) {
758 fastWord = fPayloadCurr[iWord];
759 if (fastWord & (1 << 13))
760 fCurrTrgFlags[sector] |= 1 << (stack+11);
761 AliDebug(1, Form("stack %i: fast trigger word: 0x%08x", stack, fastWord));
764 else if ((idx & 0x1) == 0x1) {
765 trackWord |= ((ULong64_t) fPayloadCurr[iWord]) << 32;
766 AliDebug(1, Form("track debug word: 0x%016llx", trackWord));
769 AliESDTrdTrack *trk = new ((*fTracks)[fTracks->GetEntriesFast()])
772 trk->SetSector(fCurrEquipmentId-kDDLOffset);
773 trk->SetStack((trackWord >> 60) & 0x7);
776 // trk->SetPt(((trackWord & 0xffff) ^ 0x8000) - 0x8000);
778 trk->SetLayerMask((trackWord >> 16) & 0x3f);
779 trk->SetTrackletIndex((trackWord >> 22) & 0x3f, 0);
780 trk->SetTrackletIndex((trackWord >> 28) & 0x3f, 1);
781 trk->SetTrackletIndex((trackWord >> 34) & 0x3f, 2);
782 trk->SetTrackletIndex((trackWord >> 40) & 0x3f, 3);
783 trk->SetTrackletIndex((trackWord >> 46) & 0x3f, 4);
784 trk->SetTrackletIndex((trackWord >> 52) & 0x3f, 5);
790 Float_t pt = (((Int_t) (trackWord & 0xffff) ^ 0x8000) - 0x8000)/128.;
791 if (TMath::Abs(pt) > 0.1) {
792 trk->SetA((Int_t) (0.15*51625./100./trk->Pt() / 160e-4 * 2));
797 trackWord = fPayloadCurr[iWord];
803 else if (fCurrHwRev < 1860) {
804 UInt_t fastWord; // fast trigger word
805 ULong64_t trackWord = 0; // extended track word
808 Bool_t upperWord = kFALSE;
810 for (UInt_t iWord = 4; iWord < fCurrSmHeaderSize; iWord++) {
811 if (fPayloadCurr[iWord] == 0xffe0ffff) { // stack boundary marker
817 // assemble the 32-bit words out of 16-bit blocks
819 word |= (fPayloadCurr[iWord] & 0xffff0000);
823 // lower word is read first
824 word = (fPayloadCurr[iWord] & 0xffff0000) >> 16;
829 if ((word & 0xffff0008) == 0x13370008) {
831 AliDebug(1, Form("stack %i: fast track word: 0x%08x", stack, fastWord));
832 if (fastWord & (1 << 13))
833 fCurrTrgFlags[sector] |= 1 << (stack+11);
836 else if ((idx & 0x1) == 0x1) {
837 trackWord |= ((ULong64_t) word) << 32;
838 AliDebug(1, Form("track debug word: 0x%016llx", trackWord));
840 AliESDTrdTrack *trk = new ((*fTracks)[fTracks->GetEntriesFast()])
843 trk->SetSector(fCurrEquipmentId-kDDLOffset);
844 trk->SetStack((trackWord >> 60) & 0x7);
848 trk->SetLayerMask((trackWord >> 16) & 0x3f);
849 trk->SetTrackletIndex((trackWord >> 22) & 0x3f, 0);
850 trk->SetTrackletIndex((trackWord >> 28) & 0x3f, 1);
851 trk->SetTrackletIndex((trackWord >> 34) & 0x3f, 2);
852 trk->SetTrackletIndex((trackWord >> 40) & 0x3f, 3);
853 trk->SetTrackletIndex((trackWord >> 46) & 0x3f, 4);
854 trk->SetTrackletIndex((trackWord >> 52) & 0x3f, 5);
860 Float_t pt = (((Int_t) (trackWord & 0xffff) ^ 0x8000) - 0x8000)/128.;
861 if (TMath::Abs(pt) > 0.1) {
862 trk->SetA((Int_t) (0.15*51625./100./pt / 160e-4 * 2));
875 ULong64_t trackWord = 0; // this is the debug word
878 Bool_t upperWord = kFALSE;
880 for (UInt_t iWord = 4; iWord < fCurrSmHeaderSize; iWord++) {
881 if (fPayloadCurr[iWord] == 0xffe0ffff) {
887 // assemble the 32-bit words out of 16-bit blocks
889 word |= (fPayloadCurr[iWord] & 0xffff0000);
893 // lower word is read first
894 word = (fPayloadCurr[iWord] & 0xffff0000) >> 16;
899 if ((word & 0xffff0008) == 0x13370008) {
900 AliDebug(1, Form("stack %i: fast track word: 0x%08x", stack, word));
903 else if ((word & 0xffff0010) == 0x13370010) {
904 AliDebug(1, Form("stack %i: tracking done word: 0x%08x", stack, word));
905 fCurrTrgFlags[sector] |= 1 << (stack+11);
908 else if ((idx & 0x1) == 0x1) {
909 trackWord |= ((ULong64_t) word) << 32;
910 AliDebug(1, Form("track debug word: 0x%16llx", trackWord));
912 AliESDTrdTrack *trk = new ((*fTracks)[fTracks->GetEntriesFast()])
914 trk->SetSector(fCurrEquipmentId-kDDLOffset);
915 trk->SetStack((trackWord >> 60) & 0x7);
919 trk->SetLayerMask((trackWord >> 16) & 0x3f);
920 trk->SetTrackletIndex((trackWord >> 22) & 0x3f, 0);
921 trk->SetTrackletIndex((trackWord >> 28) & 0x3f, 1);
922 trk->SetTrackletIndex((trackWord >> 34) & 0x3f, 2);
923 trk->SetTrackletIndex((trackWord >> 40) & 0x3f, 3);
924 trk->SetTrackletIndex((trackWord >> 46) & 0x3f, 4);
925 trk->SetTrackletIndex((trackWord >> 52) & 0x3f, 5);
931 Float_t pt = (((Int_t) (trackWord & 0xffff) ^ 0x8000) - 0x8000)/128.;
932 if (TMath::Abs(pt) > 0.1) {
933 trk->SetA(-(Int_t) (0.15*51625./100./pt / 160e-4 * 2));
947 Int_t AliTRDrawStream::ReadTrackingHeader(Int_t stack)
949 // read the tracking information and store it for the given stack
953 fCurrTrkHeaderIndexWord[stack] = *fPayloadCurr;
954 fCurrTrkHeaderSize[stack] = ((*fPayloadCurr) >> 16) & 0x3ff;
956 AliDebug(1, Form("tracking header index word: 0x%08x, size: %i (hw rev: %i)",
957 fCurrTrkHeaderIndexWord[stack], fCurrTrkHeaderSize[stack], fCurrHwRev));
958 Int_t trackingTime = *fPayloadCurr & 0x3ff;
960 fCurrTrgFlags[fCurrEquipmentId-kDDLOffset] |= ((fCurrTrkHeaderIndexWord[stack] >> 10) & 0x1) << (22 + stack);
964 ULong64_t trackWord = 0;
966 Int_t trackIndex = fTracks ? fTracks->GetEntriesFast() : -1;
968 for (UInt_t iWord = 0; iWord < fCurrTrkHeaderSize[stack]; iWord++) {
971 // first part of 64-bit word
972 trackWord = fPayloadCurr[iWord];
975 trackWord |= ((ULong64_t) fPayloadCurr[iWord]) << 32;
977 if (trackWord & (1ul << 63)) {
978 if ((trackWord & (0x3ful << 56)) != 0) {
980 AliDebug(2, Form("track word: 0x%016llx", trackWord));
983 AliESDTrdTrack *trk = new ((*fTracks)[fTracks->GetEntriesFast()])
986 trk->SetSector(fCurrEquipmentId-kDDLOffset);
987 trk->SetLayerMask((trackWord >> 56) & 0x3f);
988 trk->SetA( (((trackWord >> 38) & 0x3ffff) ^ 0x20000) - 0x20000);
989 trk->SetB( (((trackWord >> 20) & 0x3ffff) ^ 0x20000) - 0x20000);
990 trk->SetC( (((trackWord >> 8) & 0xffff) ^ 0x8000) - 0x8000);
991 trk->SetPID((trackWord >> 0) & 0xff);
992 trk->SetStack(stack);
995 // now compare the track word with the one generated from the ESD information
996 if (trackWord != trk->GetTrackWord(0)) {
997 AliError(Form("track word 0x%016llx does not match the read one 0x%016llx",
998 trk->GetTrackWord(0), trackWord));
1003 // done marker (so far only used to set trigger flag)
1004 fCurrTrgFlags[fCurrEquipmentId-kDDLOffset] |= 1 << (27 + stack);
1005 fCurrTrkFlags[(fCurrEquipmentId-kDDLOffset)*fgkNstacks + stack] = trackWord;
1007 AliDebug(2, Form("tracking done marker: 0x%016llx, trigger flags: 0x%08x",
1008 trackWord, fCurrTrgFlags[fCurrEquipmentId-kDDLOffset]));
1009 AliDebug(2, Form("seg / stack / first / last / done / index : %i %i %lli %lli %lli %i",
1010 fCurrEquipmentId - kDDLOffset, stack,
1011 (trackWord >> 20) & 0x3ff,
1012 (trackWord >> 10) & 0x3ff,
1013 (trackWord >> 0) & 0x3ff,
1018 // extended track word
1019 AliDebug(2, Form("extended track word: 0x%016llx", trackWord));
1022 AliESDTrdTrack *trk = (AliESDTrdTrack*) (*fTracks)[trackIndex];
1024 trk->SetFlags((trackWord >> 52) & 0x7ff);
1025 trk->SetReserved((trackWord >> 49) & 0x7);
1026 trk->SetY((trackWord >> 36) & 0x1fff);
1027 trk->SetTrackletIndex((trackWord >> 0) & 0x3f, 0);
1028 trk->SetTrackletIndex((trackWord >> 6) & 0x3f, 1);
1029 trk->SetTrackletIndex((trackWord >> 12) & 0x3f, 2);
1030 trk->SetTrackletIndex((trackWord >> 18) & 0x3f, 3);
1031 trk->SetTrackletIndex((trackWord >> 24) & 0x3f, 4);
1032 trk->SetTrackletIndex((trackWord >> 30) & 0x3f, 5);
1034 if (trackWord != trk->GetExtendedTrackWord(0)) {
1035 AliError(Form("extended track word 0x%016llx does not match the read one 0x%016llx",
1036 trk->GetExtendedTrackWord(0), trackWord));
1046 fPayloadCurr += fCurrTrkHeaderSize[stack];
1048 return fCurrTrkHeaderSize[stack];
1051 Int_t AliTRDrawStream::ReadTriggerHeaders()
1053 // read all trigger headers present
1055 AliDebug(1, Form("trigger mask: 0x%03x, fired: 0x%03x\n",
1056 fCurrTriggerEnable, fCurrTriggerFired));
1057 // loop over potential trigger blocks
1058 for (Int_t iTrigger = 0; iTrigger < fgkNtriggers; iTrigger++) {
1059 // check for trigger enable
1060 if (fCurrTriggerEnable & (1 << iTrigger)) {
1061 // check for readout mode and trigger fired
1062 if ((fCurrTrgHeaderReadout == 0) || (fCurrTriggerFired & (1 << iTrigger))) {
1064 AliDebug(1, Form("trigger index word %i: 0x%08x\n", iTrigger, *fPayloadCurr));
1065 fCurrTrgHeaderIndexWord[iTrigger] = *fPayloadCurr;
1066 fCurrTrgHeaderSize[iTrigger] = ((*fPayloadCurr) >> 16) & 0x3ff;
1067 if (iTrigger == 7) {
1068 // timeout trigger, use to extract tracking time
1069 fCurrTrgFlags[fCurrEquipmentId-kDDLOffset] |= (*fPayloadCurr & 0x3ff) << 12;
1074 fPayloadCurr += fCurrTrgHeaderSize[iTrigger];
1082 Int_t AliTRDrawStream::ReadStackHeader(Int_t stack)
1084 // read the stack header
1085 // and store the information in the corresponding variables
1087 fCurrStackIndexWord[stack] = *fPayloadCurr;
1088 fCurrStackHeaderSize[stack] = (((*fPayloadCurr) >> 16) & 0xffff) + 1;
1089 fCurrStackHeaderVersion[stack] = ((*fPayloadCurr) >> 12) & 0xf;
1090 fCurrLinkMask[stack] = (*fPayloadCurr) & 0xfff;
1092 // dumping stack header
1093 AliDebug(1, DumpRaw(Form("stack %i header", stack), fPayloadCurr, fCurrStackHeaderSize[stack]));
1095 if (fPayloadCurr - fPayloadStart >= fPayloadSize - (Int_t) fCurrStackHeaderSize[stack]) {
1096 EquipmentError(kStackHeaderInvalid, "Stack index header %i incomplete", stack);
1097 // dumping stack header
1098 AliError(DumpRaw(Form("stack %i header", stack), fPayloadCurr, fCurrStackHeaderSize[stack]));
1103 switch (fCurrStackHeaderVersion[stack]) {
1105 if (fCurrStackHeaderSize[stack] < 8) {
1106 LinkError(kStackHeaderInvalid, "Stack header smaller than expected!");
1110 fCurrCleanCheckout[stack] = fPayloadCurr[1] & 0x1;
1111 fCurrBoardId[stack] = (fPayloadCurr[1] >> 8) & 0xff;
1112 fCurrHwRevTMU[stack] = (fPayloadCurr[1] >> 16) & 0xffff;
1114 for (Int_t iLayer = 0; iLayer < 6; iLayer++) {
1116 fCurrLinkMonitorFlags [stack*fgkNlinks + iLayer*2] = fPayloadCurr[iLayer+2] & 0xf;
1117 fCurrLinkDataTypeFlags [stack*fgkNlinks + iLayer*2] = (fPayloadCurr[iLayer+2] >> 4) & 0x3;
1118 fCurrLinkDebugFlags [stack*fgkNlinks + iLayer*2] = (fPayloadCurr[iLayer+2] >> 12) & 0xf;
1120 fCurrLinkMonitorFlags [stack*fgkNlinks + iLayer*2 + 1] = (fPayloadCurr[iLayer+2] >> 16) & 0xf;
1121 fCurrLinkDataTypeFlags [stack*fgkNlinks + iLayer*2 + 1] = (fPayloadCurr[iLayer+2] >> 20) & 0x3;
1122 fCurrLinkDebugFlags [stack*fgkNlinks + iLayer*2 + 1] = (fPayloadCurr[iLayer+2] >> 28) & 0xf;
1127 LinkError(kStackHeaderInvalid, "Invalid Stack Header version %x", fCurrStackHeaderVersion[stack]);
1130 fPayloadCurr += fCurrStackHeaderSize[stack];
1132 return fCurrStackHeaderSize[stack];
1135 Int_t AliTRDrawStream::ReadGTUTrailer()
1137 // read the SM trailer containing CRCs from various stages
1139 UInt_t* trailer = fPayloadStart + fPayloadSize -1;
1141 // look for the trailer index word from the end
1142 for (Int_t iWord = 0; iWord < fPayloadSize; iWord++) {
1143 if ((fPayloadStart[fPayloadSize-1-iWord] & 0xffff) == 0x1f51) {
1144 trailer = fPayloadStart + fPayloadSize - 1 - iWord;
1149 if (((*trailer) & 0xffff) == 0x1f51) {
1150 UInt_t trailerIndexWord = (*trailer);
1151 Int_t trailerSize = (trailerIndexWord >> 16) & 0xffff;
1152 AliDebug(2, DumpRaw("GTU trailer", trailer, trailerSize+1));
1153 // parse the trailer
1154 if (trailerSize >= 4) {
1155 // match flags from GTU
1156 fCurrMatchFlagsSRAM = (trailer[1] >> 0) & 0x1f;
1157 fCurrMatchFlagsPostBP = (trailer[1] >> 5) & 0x1f;
1158 // individual checksums
1159 fCurrChecksumStack[0] = (trailer[1] >> 16) & 0xffff;
1160 fCurrChecksumStack[1] = (trailer[2] >> 0) & 0xffff;
1161 fCurrChecksumStack[2] = (trailer[2] >> 16) & 0xffff;
1162 fCurrChecksumStack[3] = (trailer[3] >> 0) & 0xffff;
1163 fCurrChecksumStack[4] = (trailer[3] >> 16) & 0xffff;
1164 fCurrChecksumSIU = trailer[4];
1166 if ((fCurrMatchFlagsSRAM & fCurrStackMask) != fCurrStackMask)
1167 EquipmentError(kCRCmismatch, "CRC mismatch SRAM: 0x%02x", fCurrMatchFlagsSRAM);
1168 if ((fCurrMatchFlagsPostBP & fCurrStackMask) != fCurrStackMask)
1169 EquipmentError(kCRCmismatch, "CRC mismatch BP: 0x%02x", fCurrMatchFlagsPostBP);
1173 LinkError(kUnknown, "Invalid GTU trailer");
1177 EquipmentError(kUnknown, "trailer index marker mismatch");
1182 Int_t AliTRDrawStream::ReadLinkData()
1184 // read the data in one link (one HC) until the data endmarker is reached
1185 // returns the number of words read!
1188 UInt_t* startPosLink = fPayloadCurr;
1190 AliDebug(1, DumpRaw(Form("link data from seg %2i slot %i link %2i", fCurrEquipmentId-kDDLOffset, fCurrSlot, fCurrLink),
1191 fPayloadCurr, TMath::Min((Int_t) (fPayloadSize - (fPayloadCurr-fPayloadStart)), 100), 0x00000000));
1194 new ((*fMarkers)[fMarkers->GetEntriesFast()])
1195 AliTRDrawStreamError(-kHCactive, fCurrEquipmentId-kDDLOffset, fCurrSlot, fCurrLink);
1197 if (fErrorFlags & kDiscardHC)
1200 if (fCurrTrackletEnable) {
1201 count += ReadTracklets();
1202 if (fErrorFlags & kDiscardHC)
1206 AliDebug(1, DumpRaw("HC header", fPayloadCurr, 4, 0x00000000));
1207 count += ReadHcHeader();
1208 if (fErrorFlags & kDiscardHC)
1211 Int_t det = fCurrSm * 30 + fCurrStack * 6 + fCurrLayer;
1213 if (det > -1 && det < 540) {
1215 // ----- check which kind of data -----
1216 if (fCurrMajor & 0x40) {
1217 if ((fCurrMajor & 0x7) == 0x7) {
1218 AliDebug(1, "This is a config event");
1219 UInt_t *startPos = fPayloadCurr;
1220 while (fPayloadCurr - fPayloadStart < fPayloadSize &&
1221 *fPayloadCurr != fgkDataEndmarker)
1223 count += fPayloadCurr - startPos;
1225 // feeding TRAP config
1226 AliTRDtrapConfig *trapcfg = AliTRDcalibDB::Instance()->GetTrapConfig();
1227 AliTRDmcmSim::ReadPackedConfig(trapcfg, fCurrHC, startPos, fPayloadCurr - startPos);
1230 Int_t tpmode = fCurrMajor & 0x7;
1231 AliDebug(1, Form("Checking testpattern (mode %i) data", tpmode));
1232 count += ReadTPData(tpmode);
1236 // reading real data
1237 if (fDigitsManager) {
1238 if ((fAdcArray = fDigitsManager->GetDigits(det))) {
1239 //fAdcArray->Expand();
1240 if (fAdcArray->GetNtime() != fCurrNtimebins)
1241 fAdcArray->Allocate(16, 144, fCurrNtimebins);
1244 LinkError(kNoDigits);
1247 if (!fDigitsParam) {
1248 fDigitsParam = fDigitsManager->GetDigitsParam();
1251 fDigitsParam->SetPretriggerPhase(det, fCurrPtrgPhase);
1252 fDigitsParam->SetNTimeBins(det, fCurrNtimebins);
1253 fDigitsParam->SetADCbaseline(det, 10);
1256 if (fDigitsManager->UsesDictionaries()) {
1257 fDigitsManager->GetDictionary(det, 0)->Reset();
1258 fDigitsManager->GetDictionary(det, 1)->Reset();
1259 fDigitsManager->GetDictionary(det, 2)->Reset();
1262 if ((fSignalIndex = fDigitsManager->GetIndexes(det))) {
1263 fSignalIndex->SetSM(fCurrSm);
1264 fSignalIndex->SetStack(fCurrStack);
1265 fSignalIndex->SetLayer(fCurrLayer);
1266 fSignalIndex->SetDetNumber(det);
1267 if (!fSignalIndex->IsAllocated())
1268 fSignalIndex->Allocate(16, 144, fCurrNtimebins);
1271 if (fCurrMajor & 0x20) {
1272 AliDebug(1, "This is a zs event");
1273 count += ReadZSData();
1276 AliDebug(1, "This is a nozs event");
1277 count += ReadNonZSData();
1281 // just read until data endmarkers
1282 while (fPayloadCurr - fPayloadStart < fPayloadSize &&
1283 *fPayloadCurr != fgkDataEndmarker)
1289 LinkError(kInvalidDetector, "%i", det);
1290 while (fPayloadCurr - fPayloadStart < fPayloadSize &&
1291 *fPayloadCurr != fgkDataEndmarker)
1295 if (fCurrSm > -1 && fCurrSm < 18) {
1296 fStats.fStatsSector[fCurrSm].fStatsHC[fCurrHC%60].fBytes += (fPayloadCurr - startPosLink) * sizeof(UInt_t);
1297 fStats.fStatsSector[fCurrSm].fStatsHC[fCurrHC%60].fBytesRead += count * sizeof(UInt_t);
1298 fStats.fStatsSector[fCurrSm].fBytesRead += count * sizeof(UInt_t);
1299 fStats.fBytesRead += count * sizeof(UInt_t);
1305 Int_t AliTRDrawStream::ReadTracklets()
1307 // read the tracklets from one HC
1309 fTrackletArray->Clear();
1311 UInt_t *start = fPayloadCurr;
1312 while (*(fPayloadCurr) != fgkTrackletEndmarker &&
1313 fPayloadCurr - fPayloadStart < fPayloadSize) {
1314 new ((*fTrackletArray)[fTrackletArray->GetEntriesFast()]) AliTRDtrackletWord(*(fPayloadCurr), fCurrHC);
1319 if (fTrackletArray->GetEntriesFast() > 0) {
1320 AliDebug(1, Form("Found %i tracklets in %i %i %i (ev. %i)", fTrackletArray->GetEntriesFast(),
1321 (fCurrEquipmentId-kDDLOffset), fCurrSlot, fCurrLink, fRawReader->GetEventIndex()));
1322 if (fCurrSm > -1 && fCurrSm < 18) {
1323 fStats.fStatsSector[fCurrSm].fStatsHC[fCurrHC%60].fNTracklets += fTrackletArray->GetEntriesFast();
1324 fStats.fStatsSector[fCurrSm].fNTracklets += fTrackletArray->GetEntriesFast();
1327 fTrackletTree->Fill();
1329 for (Int_t iTracklet = 0; iTracklet < fTrackletArray->GetEntriesFast(); iTracklet++) {
1330 new ((*fTracklets)[fTracklets->GetEntriesFast()]) AliTRDtrackletWord(*((AliTRDtrackletWord*)(*fTrackletArray)[iTracklet]));
1334 // loop over remaining tracklet endmarkers
1335 while ((*(fPayloadCurr) == fgkTrackletEndmarker &&
1336 fPayloadCurr - fPayloadStart < fPayloadSize))
1339 return fPayloadCurr - start;
1342 Int_t AliTRDrawStream::ReadHcHeader()
1344 // read and parse the HC header of one HC
1345 // and store the information in the corresponding variables
1347 AliDebug(1, Form("HC header: 0x%08x", *fPayloadCurr));
1348 UInt_t *start = fPayloadCurr;
1349 // check not to be at the data endmarker
1350 if (*fPayloadCurr == fgkDataEndmarker)
1353 fCurrSpecial = (*fPayloadCurr >> 31) & 0x1;
1354 fCurrMajor = (*fPayloadCurr >> 24) & 0x7f;
1355 fCurrMinor = (*fPayloadCurr >> 17) & 0x7f;
1356 fCurrAddHcWords = (*fPayloadCurr >> 14) & 0x7;
1357 fCurrSm = (*fPayloadCurr >> 9) & 0x1f;
1358 fCurrLayer = (*fPayloadCurr >> 6) & 0x7;
1359 fCurrStack = (*fPayloadCurr >> 3) & 0x7;
1360 fCurrSide = (*fPayloadCurr >> 2) & 0x1;
1361 fCurrCheck = (*fPayloadCurr) & 0x3;
1363 if ((fCurrSm != (((Int_t) fCurrEquipmentId) - kDDLOffset)) ||
1364 (fCurrStack != fCurrSlot) ||
1365 (fCurrLayer != fCurrLink / 2) ||
1366 (fCurrSide != fCurrLink % 2)) {
1367 LinkError(kHCmismatch,
1368 "HC: %i, %i, %i, %i\n 0x%08x 0x%08x 0x%08x 0x%08x",
1369 fCurrSm, fCurrStack, fCurrLayer, fCurrSide,
1370 fPayloadCurr[0], fPayloadCurr[1], fPayloadCurr[2], fPayloadCurr[3]);
1372 if (fCurrCheck != 0x1) {
1373 LinkError(kHCcheckFailed);
1376 if (fCurrAddHcWords > 0) {
1377 fCurrNtimebins = (fPayloadCurr[1] >> 26) & 0x3f;
1378 fCurrBC = (fPayloadCurr[1] >> 10) & 0xffff;
1379 fCurrPtrgCnt = (fPayloadCurr[1] >> 6) & 0xf;
1380 fCurrPtrgPhase = (fPayloadCurr[1] >> 2) & 0xf;
1383 fPayloadCurr += 1 + fCurrAddHcWords;
1385 return (fPayloadCurr - start);
1388 Int_t AliTRDrawStream::ReadTPData(Int_t mode)
1390 // testing of testpattern 1 to 3 (hardcoded), 0 missing
1391 // evcnt checking missing
1393 Int_t cpufromchannel[] = {0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3};
1397 Int_t mcmcount = -1;
1398 Int_t wordcount = 0;
1399 Int_t channelcount = 0;
1401 UInt_t expadcval = 0;
1403 Int_t lastmcmpos = -1;
1404 Int_t lastrobpos = -1;
1406 UInt_t* start = fPayloadCurr;
1408 while (*(fPayloadCurr) != fgkDataEndmarker &&
1409 fPayloadCurr - fPayloadStart < fPayloadSize - 1) {
1411 // ----- Checking MCM Header -----
1412 AliDebug(2, DumpMcmHeader("MCM header: ", *fPayloadCurr));
1413 UInt_t *startPosMCM = fPayloadCurr;
1416 // ----- checking for proper readout order - ROB -----
1417 fCurrRobPos = ROB(*fPayloadCurr);
1418 if (GetROBReadoutPos(ROB(*fPayloadCurr) / 2) >= lastrobpos) {
1419 if (GetROBReadoutPos(ROB(*fPayloadCurr) / 2) > lastrobpos)
1421 lastrobpos = GetROBReadoutPos(ROB(*fPayloadCurr) / 2);
1424 ROBError(kPosUnexp, Form("#%i after #%i in readout order", GetROBReadoutPos(ROB(*fPayloadCurr) / 2), lastrobpos));
1427 // ----- checking for proper readout order - MCM -----
1428 fCurrMcmPos = MCM(*fPayloadCurr);
1429 if (GetMCMReadoutPos(MCM(*fPayloadCurr)) > lastmcmpos) {
1430 lastmcmpos = GetMCMReadoutPos(MCM(*fPayloadCurr));
1433 MCMError(kPosUnexp, Form("#%i after #%i in readout order", GetMCMReadoutPos(MCM(*fPayloadCurr)), lastmcmpos));
1436 if (EvNo(*fPayloadCurr) != (evno & 0xfffff)) {
1438 evno = EvNo(*fPayloadCurr);
1441 MCMError(kEvCntMismatch, "%i <-> %i", evno, EvNo(*fPayloadCurr));
1447 evcnt = 0x3f & *fPayloadCurr >> 26;
1450 while (channelcount < 21) {
1452 if (cpu != cpufromchannel[channelcount]) {
1453 cpu = cpufromchannel[channelcount];
1454 expadcval = (1 << 9) | (fCurrRobPos << 6) | (fCurrMcmPos << 2) | cpu;
1458 while (count < 10) {
1459 if (*fPayloadCurr == fgkDataEndmarker) {
1460 MCMError(kMissTpData);
1461 return (fPayloadCurr - start);
1464 if (channelcount % 2 == 0)
1471 expword |= expadcval << 2;
1472 expadcval = ( (expadcval << 1) | ( ( (expadcval >> 9) ^ (expadcval >> 6) ) & 1) ) & 0x3FF;
1473 expword |= expadcval << 12;
1474 expadcval = ( (expadcval << 1) | ( ( (expadcval >> 9) ^ (expadcval >> 6) ) & 1) ) & 0x3FF;
1475 expword |= expadcval << 22;
1476 expadcval = ( (expadcval << 1) | ( ( (expadcval >> 9) ^ (expadcval >> 6) ) & 1) ) & 0x3FF;
1478 else if (mode == 2) {
1479 // ----- TP 2 ------
1480 expword = ((0x3f & evcnt) << 26) | ((fCurrSm + 1) << 21) | ((fCurrLayer + 1) << 18) |
1481 ((fCurrStack + 1) << 15) |
1482 (fCurrRobPos << 12) | (fCurrMcmPos << 8) | (cpu << 6) | (wordcount + 1);
1484 else if (mode == 3) {
1486 expword = ((0xfff & evcnt) << 20) | (fCurrSm << 15) | (fCurrLink/2 << 12) | (fCurrStack << 9) |
1487 (fCurrRobPos << 6) | (fCurrMcmPos << 2) | (cpu << 0);
1491 LinkError(kTPmodeInvalid, "Just reading");
1494 diff = *fPayloadCurr ^ expword;
1495 AliDebug(11, Form("Comparing ch %2i, word %2i (cpu %i): 0x%08x <-> 0x%08x",
1496 channelcount, wordcount, cpu, *fPayloadCurr, expword));
1499 MCMError(kTPmismatch,
1500 "Seen 0x%08x, expected 0x%08x, diff: 0x%08x, 0x%04x, 0x%02x - word %2i (cpu %i, ch %i)",
1501 *fPayloadCurr, expword, diff,
1502 0xffff & (diff | diff >> 16),
1503 0xff & (diff | diff >> 8 | diff >> 16 | diff >> 24),
1504 wordcount, cpu, channelcount);;
1509 if (*fPayloadCurr == fgkDataEndmarker)
1510 return (fPayloadCurr - start);
1514 // continue with next MCM
1516 if (IsDumping() && DumpingMCM(fCurrHC/2, fCurrRobPos, fCurrMcmPos)) {
1517 AliInfo(DumpRaw(Form("Event %i: Det %3i ROB %i MCM %2i", fRawReader->GetEventIndex(), fCurrHC/2, fCurrRobPos, fCurrMcmPos),
1518 startPosMCM, fPayloadCurr - startPosMCM));
1522 return fPayloadCurr - start;
1526 Int_t AliTRDrawStream::ReadZSData()
1528 // read the zs data from one link from the current reading position
1530 UInt_t *start = fPayloadCurr;
1533 Int_t mcmcountExp = fCurrStack == 2 ? 48 : 64;
1534 Int_t channelcount = 0;
1535 Int_t channelcountExp = 0;
1536 Int_t channelcountMax = 0;
1538 Int_t currentTimebin = 0;
1541 Int_t lastmcmpos = -1;
1542 Int_t lastrobpos = -1;
1544 if (fCurrNtimebins != fNtimebins) {
1546 LinkError(kNtimebinsChanged,
1547 "No. of timebins changed from %i to %i", fNtimebins, fCurrNtimebins);
1548 fNtimebins = fCurrNtimebins;
1551 timebins = fNtimebins;
1553 while (*(fPayloadCurr) != fgkDataEndmarker &&
1554 fPayloadCurr - fPayloadStart < fPayloadSize) {
1556 // ----- Checking MCM Header -----
1557 AliDebug(2, DumpMcmHeader("MCM header: ", *fPayloadCurr));
1558 UInt_t *startPosMCM = fPayloadCurr;
1560 // ----- checking for proper readout order - ROB -----
1561 fCurrRobPos = ROB(*fPayloadCurr);
1562 if (GetROBReadoutPos(ROB(*fPayloadCurr) / 2) >= lastrobpos) {
1563 if (GetROBReadoutPos(ROB(*fPayloadCurr) / 2) > lastrobpos)
1565 lastrobpos = GetROBReadoutPos(ROB(*fPayloadCurr) / 2);
1568 ROBError(kPosUnexp, Form("#%i after #%i and #%i in readout order",
1569 GetROBReadoutPos(ROB(*fPayloadCurr) / 2), lastrobpos, GetROBReadoutPos(fCurrRobPos)));
1572 // ----- checking for proper readout order - MCM -----
1573 fCurrMcmPos = MCM(*fPayloadCurr);
1574 if (GetMCMReadoutPos(MCM(*fPayloadCurr)) > lastmcmpos) {
1575 lastmcmpos = GetMCMReadoutPos(MCM(*fPayloadCurr));
1578 MCMError(kPosUnexp, Form("#%i after #%i and #%i in readout order",
1579 GetMCMReadoutPos(MCM(*fPayloadCurr)), lastmcmpos, GetMCMReadoutPos(fCurrMcmPos)));
1582 if (EvNo(*fPayloadCurr) != (evno & 0xfffff)) {
1584 evno = EvNo(*fPayloadCurr);
1587 MCMError(kEvCntMismatch, "%i <-> %i", evno, EvNo(*fPayloadCurr));
1590 Int_t adccoloff = AdcColOffset(*fPayloadCurr);
1591 Int_t padcoloff = PadColOffset(*fPayloadCurr);
1592 Int_t row = Row(*fPayloadCurr);
1595 if ((row > 11) && (fCurrStack == 2)) {
1596 MCMError(kUnknown, "Data in padrow > 11 for stack 2");
1599 if (fErrorFlags & (kDiscardMCM | kDiscardHC | kDiscardDDL))
1602 // ----- Reading ADC channels -----
1603 AliDebug(2, DumpAdcMask("ADC mask: ", *fPayloadCurr));
1605 // ----- analysing the ADC mask -----
1607 channelcountExp = GetNActiveChannelsFromMask(*fPayloadCurr);
1608 channelcountMax = GetNActiveChannels(*fPayloadCurr);
1609 Int_t channelmask = GetActiveChannels(*fPayloadCurr);
1610 Int_t channelno = -1;
1613 if (channelcountExp != channelcountMax) {
1614 if (channelcountExp > channelcountMax) {
1615 Int_t temp = channelcountExp;
1616 channelcountExp = channelcountMax;
1617 channelcountMax = temp;
1619 while (channelcountExp < channelcountMax && channelcountExp < 21 &&
1620 fPayloadCurr - fPayloadStart < fPayloadSize - 10 * channelcountExp - 1) {
1621 MCMError(kAdcMaskInconsistent,
1622 "Possible MCM-H: 0x%08x, possible ADC-mask: 0x%08x",
1623 *(fPayloadCurr + 10 * channelcountExp),
1624 *(fPayloadCurr + 10 * channelcountExp + 1) );
1625 if (!CouldBeMCMhdr( *(fPayloadCurr + 10 * channelcountExp)) && !CouldBeADCmask( *(fPayloadCurr + 10 * channelcountExp + 1)))
1631 MCMError(kAdcMaskInconsistent,
1632 "Inconsistency in no. of active channels: Counter: %i, Mask: %i, chosen: %i!",
1633 GetNActiveChannels(fPayloadCurr[-1]), GetNActiveChannelsFromMask(fPayloadCurr[-1]), channelcountExp);
1635 AliDebug(2, Form("expecting %i active channels, %i timebins", channelcountExp, fCurrNtimebins));
1637 // ----- reading marked ADC channels -----
1638 while (channelcount < channelcountExp && *(fPayloadCurr) != fgkDataEndmarker) {
1641 while (channelno < 20 && (channelmask & 1 << channelno) == 0)
1644 if (fCurrNtimebins > 30) {
1645 currentTimebin = ((*fPayloadCurr >> 2) & 0x3f);
1646 timebins = ((*fPayloadCurr >> 8) & 0xf) * 3;
1653 Int_t nADCwords = (timebins + 2) / 3;
1654 AliDebug(3, Form("Now reading %i words for channel %2i", nADCwords, channelno));
1655 Int_t adccol = adccoloff - channelno;
1656 Int_t padcol = padcoloff - channelno;
1657 // if (adccol < 3 || adccol > 165)
1658 // AliInfo(Form("writing channel %i of det %3i %i:%2i to adcrow/-col: %i/%i padcol: %i",
1659 // channelno, fCurrHC/2, fCurrRobPos, fCurrMcmPos, row, adccol, padcol));
1661 while ((adcwc < nADCwords) &&
1662 (*(fPayloadCurr) != fgkDataEndmarker) &&
1663 (fPayloadCurr - fPayloadStart < fPayloadSize)) {
1664 int check = 0x3 & *fPayloadCurr;
1665 if (channelno % 2 != 0) { // odd channel
1666 if (check != 0x2 && channelno < 21) {
1667 MCMError(kAdcCheckInvalid,
1668 "%i for %2i. ADC word in odd channel %i",
1669 check, adcwc+1, channelno);
1672 else { // even channel
1673 if (check != 0x3 && channelno < 21) {
1674 MCMError(kAdcCheckInvalid,
1675 "%i for %2i. ADC word in even channel %i",
1676 check, adcwc+1, channelno);
1680 // filling the actual timebin data
1681 int tb2 = 0x3ff & *fPayloadCurr >> 22;
1682 int tb1 = 0x3ff & *fPayloadCurr >> 12;
1683 int tb0 = 0x3ff & *fPayloadCurr >> 2;
1684 if (adcwc != 0 || fCurrNtimebins <= 30)
1685 fAdcArray->SetDataByAdcCol(row, adccol, currentTimebin++, tb0);
1688 fAdcArray->SetDataByAdcCol(row, adccol, currentTimebin++, tb1);
1689 fAdcArray->SetDataByAdcCol(row, adccol, currentTimebin++, tb2);
1695 if (adcwc != nADCwords)
1696 MCMError(kAdcDataAbort);
1699 if (padcol > 0 && padcol < 144) {
1700 fSignalIndex->AddIndexRC(row, padcol);
1706 if (fCurrSm > -1 && fCurrSm < 18) {
1707 fStats.fStatsSector[fCurrSm].fStatsHC[fCurrHC%60].fNChannels += channelcount;
1708 fStats.fStatsSector[fCurrSm].fNChannels += channelcount;
1710 if (channelcount != channelcountExp)
1711 MCMError(kAdcChannelsMiss);
1714 if (fCurrSm > -1 && fCurrSm < 18) {
1715 fStats.fStatsSector[fCurrSm].fStatsHC[fCurrHC%60].fNMCMs++;
1716 fStats.fStatsSector[fCurrSm].fNMCMs++;
1719 if (IsDumping() && DumpingMCM(fCurrHC/2, fCurrRobPos, fCurrMcmPos)) {
1720 AliInfo(DumpRaw(Form("Event %i: Det %3i ROB %i MCM %2i", fRawReader->GetEventIndex(), fCurrHC/2, fCurrRobPos, fCurrMcmPos),
1721 startPosMCM, fPayloadCurr - startPosMCM));
1724 // continue with next MCM
1727 // check for missing MCMs (if header suppression is inactive)
1728 if (((fCurrMajor & 0x1) == 0) && (mcmcount != mcmcountExp)) {
1729 LinkError(kMissMcmHeaders,
1730 "No. of MCM headers %i not as expected: %i",
1731 mcmcount, mcmcountExp);
1734 return (fPayloadCurr - start);
1737 Int_t AliTRDrawStream::ReadNonZSData()
1739 // read the non-zs data from one link from the current reading position
1741 UInt_t *start = fPayloadCurr;
1744 Int_t mcmcountExp = fCurrStack == 2 ? 48 : 64;
1745 Int_t channelcount = 0;
1746 Int_t channelcountExp = 0;
1748 Int_t currentTimebin = 0;
1751 Int_t lastmcmpos = -1;
1752 Int_t lastrobpos = -1;
1754 if (fCurrNtimebins != fNtimebins) {
1756 LinkError(kNtimebinsChanged,
1757 "No. of timebins changed from %i to %i", fNtimebins, fCurrNtimebins);
1758 fNtimebins = fCurrNtimebins;
1761 timebins = fNtimebins;
1763 while (*(fPayloadCurr) != fgkDataEndmarker &&
1764 fPayloadCurr - fPayloadStart < fPayloadSize - 2) {
1766 // ----- Checking MCM Header -----
1767 AliDebug(2, Form("MCM header: 0x%08x", *fPayloadCurr));
1769 // ----- checking for proper readout order - ROB -----
1770 fCurrRobPos = ROB(*fPayloadCurr);
1771 if (GetROBReadoutPos(ROB(*fPayloadCurr) / 2) >= lastrobpos) {
1772 if (GetROBReadoutPos(ROB(*fPayloadCurr) / 2) > lastrobpos)
1774 lastrobpos = GetROBReadoutPos(ROB(*fPayloadCurr) / 2);
1777 ROBError(kPosUnexp, Form("#%i after #%i in readout order", GetROBReadoutPos(ROB(*fPayloadCurr) / 2), lastrobpos));
1780 // ----- checking for proper readout order - MCM -----
1781 fCurrMcmPos = MCM(*fPayloadCurr);
1782 if (GetMCMReadoutPos(MCM(*fPayloadCurr)) > lastmcmpos) {
1783 lastmcmpos = GetMCMReadoutPos(MCM(*fPayloadCurr));
1786 MCMError(kPosUnexp, Form("#%i after #%i in readout order", GetMCMReadoutPos(MCM(*fPayloadCurr)), lastmcmpos));
1789 if (EvNo(*fPayloadCurr) != (evno & 0xfffff)) {
1791 evno = EvNo(*fPayloadCurr);
1794 MCMError(kEvCntMismatch, "%i <-> %i", evno, EvNo(*fPayloadCurr));
1799 channelcountExp = 21;
1802 Int_t adccoloff = AdcColOffset(*fPayloadCurr);
1803 Int_t padcoloff = PadColOffset(*fPayloadCurr);
1804 Int_t row = Row(*fPayloadCurr);
1808 // ----- reading marked ADC channels -----
1809 while (channelcount < channelcountExp &&
1810 *(fPayloadCurr) != fgkDataEndmarker) {
1817 Int_t nADCwords = (timebins + 2) / 3;
1818 AliDebug(2, Form("Now looking %i words", nADCwords));
1819 Int_t adccol = adccoloff - channelno;
1820 Int_t padcol = padcoloff - channelno;
1821 while ((adcwc < nADCwords) &&
1822 (*(fPayloadCurr) != fgkDataEndmarker) &&
1823 (fPayloadCurr - fPayloadStart < fPayloadSize)) {
1824 int check = 0x3 & *fPayloadCurr;
1825 if (channelno % 2 != 0) { // odd channel
1826 if (check != 0x2 && channelno < 21) {
1827 MCMError(kAdcCheckInvalid,
1828 "%i for %2i. ADC word in odd channel %i",
1829 check, adcwc+1, channelno);
1832 else { // even channel
1833 if (check != 0x3 && channelno < 21) {
1834 MCMError(kAdcCheckInvalid,
1835 "%i for %2i. ADC word in even channel %i",
1836 check, adcwc+1, channelno);
1840 // filling the actual timebin data
1841 int tb2 = 0x3ff & *fPayloadCurr >> 22;
1842 int tb1 = 0x3ff & *fPayloadCurr >> 12;
1843 int tb0 = 0x3ff & *fPayloadCurr >> 2;
1844 if (adcwc != 0 || fCurrNtimebins <= 30)
1845 fAdcArray->SetDataByAdcCol(row, adccol, currentTimebin++, tb0);
1848 fAdcArray->SetDataByAdcCol(row, adccol, currentTimebin++, tb1);
1849 fAdcArray->SetDataByAdcCol(row, adccol, currentTimebin++, tb2);
1855 if (adcwc != nADCwords)
1856 MCMError(kAdcDataAbort);
1859 if (padcol > 0 && padcol < 144) {
1860 fSignalIndex->AddIndexRC(row, padcol);
1866 if (channelcount != channelcountExp)
1867 MCMError(kAdcChannelsMiss);
1869 // continue with next MCM
1872 // check for missing MCMs (if header suppression is inactive)
1873 if (mcmcount != mcmcountExp) {
1874 LinkError(kMissMcmHeaders,
1875 "%i not as expected: %i", mcmcount, mcmcountExp);
1878 return (fPayloadCurr - start);
1881 Int_t AliTRDrawStream::SeekNextStack()
1883 // proceed in raw data stream till the next stack
1885 if (!fCurrStackEndmarkerAvail)
1888 UInt_t *start = fPayloadCurr;
1890 // read until data endmarkers
1891 while ((fPayloadCurr - fPayloadStart < fPayloadSize-1) &&
1892 ((fPayloadCurr[0] != fgkStackEndmarker[0]) ||
1893 (fPayloadCurr[1] != fgkStackEndmarker[1])))
1896 if ((fPayloadCurr - start) != 0)
1897 StackError(kUnknown, "skipped %i words to reach stack endmarker", fPayloadCurr - start);
1899 AliDebug(2, Form("stack endmarker: 0x%08x 0x%08x", fPayloadCurr[0], fPayloadCurr[1]));
1905 return (fPayloadCurr-start);
1908 Int_t AliTRDrawStream::SeekNextLink()
1910 // proceed in raw data stream till the next link
1912 UInt_t *start = fPayloadCurr;
1914 // read until data endmarkers
1915 while (fPayloadCurr - fPayloadStart < fPayloadSize &&
1916 *fPayloadCurr != fgkDataEndmarker)
1919 // read all data endmarkers
1920 while (fPayloadCurr - fPayloadStart < fPayloadSize &&
1921 *fPayloadCurr == fgkDataEndmarker)
1924 return (fPayloadCurr - start);
1927 Bool_t AliTRDrawStream::ConnectTracklets(TTree *trklTree)
1929 // connect the tracklet tree used to store the tracklet output
1931 fTrackletTree = trklTree;
1935 if (!fTrackletTree->GetBranch("hc"))
1936 fTrackletTree->Branch("hc", &fCurrHC, "hc/I");
1938 fTrackletTree->SetBranchAddress("hc", &fCurrHC);
1940 if (!fTrackletTree->GetBranch("trkl"))
1941 fTrackletTree->Branch("trkl", &fTrackletArray);
1943 fTrackletTree->SetBranchAddress("trkl", &fTrackletArray);
1949 void AliTRDrawStream::EquipmentError(ErrorCode_t err, const char *const msg, ...)
1951 // register error according to error code on equipment level
1952 // and return the corresponding error message
1954 fLastError.fSector = fCurrEquipmentId - kDDLOffset;
1955 fLastError.fStack = -1;
1956 fLastError.fLink = -1;
1957 fLastError.fRob = -1;
1958 fLastError.fMcm = -1;
1959 fLastError.fError = err;
1960 (this->*fStoreError)();
1963 if (fgErrorDebugLevel[err] > 10)
1964 AliDebug(fgErrorDebugLevel[err],
1965 Form("Event %6i: Eq. %2d - %s : %s",
1966 fRawReader->GetEventIndex(), fCurrEquipmentId, fgkErrorMessages[err],
1967 (va_start(ap, msg), vsprintf(fErrorBuffer, msg, ap), va_end(ap), fErrorBuffer) ));
1969 AliError(Form("Event %6i: Eq. %2d - %s : %s",
1970 fRawReader->GetEventIndex(), fCurrEquipmentId, fgkErrorMessages[err],
1971 (va_start(ap, msg), vsprintf(fErrorBuffer, msg, ap), va_end(ap), fErrorBuffer) ));
1972 fErrorFlags |= fgErrorBehav[err];
1976 void AliTRDrawStream::StackError(ErrorCode_t err, const char *const msg, ...)
1978 // register error according to error code on stack level
1979 // and return the corresponding error message
1981 fLastError.fSector = fCurrEquipmentId - kDDLOffset;
1982 fLastError.fStack = fCurrSlot;
1983 fLastError.fLink = -1;
1984 fLastError.fRob = -1;
1985 fLastError.fMcm = -1;
1986 fLastError.fError = err;
1987 (this->*fStoreError)();
1990 if (fgErrorDebugLevel[err] > 0)
1991 AliDebug(fgErrorDebugLevel[err],
1992 Form("Event %6i: Eq. %2d S %i - %s : %s",
1993 fRawReader->GetEventIndex(), fCurrEquipmentId, fCurrSlot, fgkErrorMessages[err],
1994 (va_start(ap, msg), vsprintf(fErrorBuffer, msg, ap), va_end(ap), fErrorBuffer) ));
1996 AliError(Form("Event %6i: Eq. %2d S %i - %s : %s",
1997 fRawReader->GetEventIndex(), fCurrEquipmentId, fCurrSlot, fgkErrorMessages[err],
1998 (va_start(ap, msg), vsprintf(fErrorBuffer, msg, ap), va_end(ap), fErrorBuffer) ));
1999 fErrorFlags |= fgErrorBehav[err];
2003 void AliTRDrawStream::LinkError(ErrorCode_t err, const char *const msg, ...)
2005 // register error according to error code on link level
2006 // and return the corresponding error message
2008 fLastError.fSector = fCurrEquipmentId - kDDLOffset;
2009 fLastError.fStack = fCurrSlot;
2010 fLastError.fLink = fCurrLink;
2011 fLastError.fRob = -1;
2012 fLastError.fMcm = -1;
2013 fLastError.fError = err;
2014 (this->*fStoreError)();
2017 if (fgErrorDebugLevel[err] > 0)
2018 AliDebug(fgErrorDebugLevel[err],
2019 Form("Event %6i: Eq. %2d S %i l %2i - %s : %s",
2020 fRawReader->GetEventIndex(), fCurrEquipmentId, fCurrSlot, fCurrLink, fgkErrorMessages[err],
2021 (va_start(ap, msg), vsprintf(fErrorBuffer, msg, ap), va_end(ap), fErrorBuffer) ));
2023 AliError(Form("Event %6i: Eq. %2d S %i l %2i - %s : %s",
2024 fRawReader->GetEventIndex(), fCurrEquipmentId, fCurrSlot, fCurrLink, fgkErrorMessages[err],
2025 (va_start(ap, msg), vsprintf(fErrorBuffer, msg, ap), va_end(ap), fErrorBuffer) ));
2026 fErrorFlags |= fgErrorBehav[err];
2030 void AliTRDrawStream::ROBError(ErrorCode_t err, const char *const msg, ...)
2032 // register error according to error code on ROB level
2033 // and return the corresponding error message
2035 fLastError.fSector = fCurrEquipmentId - kDDLOffset;
2036 fLastError.fStack = fCurrSlot;
2037 fLastError.fLink = fCurrLink;
2038 fLastError.fRob = fCurrRobPos;
2039 fLastError.fMcm = -1;
2040 fLastError.fError = err;
2041 (this->*fStoreError)();
2044 if (fgErrorDebugLevel[err] > 0)
2045 AliDebug(fgErrorDebugLevel[err],
2046 Form("Event %6i: Eq. %2d S %i l %2i ROB %i - %s : %s",
2047 fRawReader->GetEventIndex(), fCurrEquipmentId, fCurrSlot, fCurrLink, fCurrRobPos, fgkErrorMessages[err],
2048 (va_start(ap, msg), vsprintf(fErrorBuffer, msg, ap), va_end(ap), fErrorBuffer) ));
2050 AliError(Form("Event %6i: Eq. %2d S %i l %2i ROB %i - %s : %s",
2051 fRawReader->GetEventIndex(), fCurrEquipmentId, fCurrSlot, fCurrLink, fCurrRobPos, fgkErrorMessages[err],
2052 (va_start(ap, msg), vsprintf(fErrorBuffer, msg, ap), va_end(ap), fErrorBuffer) ));
2053 fErrorFlags |= fgErrorBehav[err];
2057 void AliTRDrawStream::MCMError(ErrorCode_t err, const char *const msg, ...)
2059 // register error according to error code on MCM level
2060 // and return the corresponding error message
2062 fLastError.fSector = fCurrEquipmentId - kDDLOffset;
2063 fLastError.fStack = fCurrSlot;
2064 fLastError.fLink = fCurrLink;
2065 fLastError.fRob = fCurrRobPos;
2066 fLastError.fMcm = fCurrMcmPos;
2067 fLastError.fError = err;
2068 (this->*fStoreError)();
2071 if (fgErrorDebugLevel[err] > 0)
2072 AliDebug(fgErrorDebugLevel[err],
2073 Form("Event %6i: Eq. %2d S %i l %2i ROB %i MCM %2i - %s : %s",
2074 fRawReader->GetEventIndex(), fCurrEquipmentId, fCurrSlot, fCurrLink, fCurrRobPos, fCurrMcmPos, fgkErrorMessages[err],
2075 (va_start(ap, msg), vsprintf(fErrorBuffer, msg, ap), va_end(ap), fErrorBuffer) ));
2077 AliError(Form("Event %6i: Eq. %2d S %i l %2i ROB %i MCM %2i - %s : %s",
2078 fRawReader->GetEventIndex(), fCurrEquipmentId, fCurrSlot, fCurrLink, fCurrRobPos, fCurrMcmPos, fgkErrorMessages[err],
2079 (va_start(ap, msg), vsprintf(fErrorBuffer, msg, ap), va_end(ap), fErrorBuffer) ));
2080 fErrorFlags |= fgErrorBehav[err];
2083 const char* AliTRDrawStream::GetErrorMessage(ErrorCode_t errCode)
2085 // return the error message for the given error code
2087 if (errCode > 0 && errCode < kLastErrorCode)
2088 return fgkErrorMessages[errCode];
2093 void AliTRDrawStream::AliTRDrawStats::ClearStats()
2095 // clear statistics (includes clearing sector-wise statistics)
2098 for (Int_t iSector = 0; iSector < 18; iSector++) {
2099 fStatsSector[iSector].ClearStats();
2104 void AliTRDrawStream::AliTRDrawStats::AliTRDrawStatsSector::ClearStats()
2106 // clear statistics (includes clearing HC-wise statistics)
2114 for (Int_t iHC = 0; iHC < 60; iHC++) {
2115 fStatsHC[iHC].ClearStats();
2119 void AliTRDrawStream::AliTRDrawStats::AliTRDrawStatsSector::AliTRDrawStatsHC::ClearStats()
2130 void AliTRDrawStream::SetDumpMCM(Int_t det, Int_t rob, Int_t mcm, Bool_t dump)
2132 // mark MCM for dumping of raw data
2135 fDumpMCM[fNDumpMCMs++] = (det << 7) | (rob << 4) | mcm;
2139 for (iMCM = 0; iMCM < fNDumpMCMs; iMCM++) {
2140 if (fDumpMCM[iMCM] == ((det << 7) | (rob << 4) | mcm)) {
2145 for ( ; iMCM < fNDumpMCMs; iMCM++) {
2146 fDumpMCM[iMCM] = fDumpMCM[iMCM+1];
2151 Bool_t AliTRDrawStream::DumpingMCM(Int_t det, Int_t rob, Int_t mcm) const
2153 // check if MCM data should be dumped
2155 for (Int_t iMCM = 0; iMCM < fNDumpMCMs; iMCM++) {
2156 if (fDumpMCM[iMCM] == ((det << 7) | (rob << 4) | mcm)) {
2163 TString AliTRDrawStream::DumpRaw(TString title, const UInt_t *start, Int_t length, UInt_t endmarker)
2168 for (Int_t pos = 0; pos < length; pos += 4) {
2169 if ((start[pos+0] != endmarker) && pos+0 < length)
2170 if ((start[pos+1] != endmarker && pos+1 < length))
2171 if ((start[pos+2] != endmarker && pos+2 < length))
2172 if ((start[pos+3] != endmarker && pos+3 < length))
2173 title += Form(" 0x%08x 0x%08x 0x%08x 0x%08x\n",
2174 start[pos+0], start[pos+1], start[pos+2], start[pos+3]);
2176 title += Form(" 0x%08x 0x%08x 0x%08x 0x%08x\n",
2177 start[pos+0], start[pos+1], start[pos+2], start[pos+3]);
2181 title += Form(" 0x%08x 0x%08x 0x%08x\n",
2182 start[pos+0], start[pos+1], start[pos+2]);
2186 title += Form(" 0x%08x 0x%08x\n",
2187 start[pos+0], start[pos+1]);
2191 title += Form(" 0x%08x\n",
2199 TString AliTRDrawStream::DumpMcmHeader(TString title, UInt_t word)
2201 title += Form("0x%08x -> ROB: %i, MCM: %2i",
2202 word, ROB(word), MCM(word));
2206 TString AliTRDrawStream::DumpAdcMask(TString title, UInt_t word)
2208 title += Form("0x%08x -> #ch : %2i, 0x%06x (%2i ch)",
2209 word, GetNActiveChannels(word), GetActiveChannels(word), GetNActiveChannelsFromMask(word));
2213 AliTRDrawStream::AliTRDrawStreamError::AliTRDrawStreamError(Int_t error, Int_t sector, Int_t stack, Int_t link, Int_t rob, Int_t mcm) :
2225 void AliTRDrawStream::SortTracklets(TClonesArray *trklArray, TList &sortedTracklets, Int_t *indices)
2227 // sort tracklets for referencing from GTU tracks
2232 Int_t nTracklets = trklArray->GetEntriesFast();
2235 for (Int_t iTracklet = 0; iTracklet < nTracklets; iTracklet++) {
2236 AliTRDtrackletBase *trkl = (AliTRDtrackletBase*) ((*trklArray)[iTracklet]);
2237 Int_t hc = trkl->GetHCId();
2238 if ((hc < 0) || (hc >= 1080)) {
2239 AliErrorClass(Form("HC for tracklet: 0x%08x out of range: %i", trkl->GetTrackletWord(), trkl->GetHCId()));
2242 AliDebugClass(5, Form("hc: %4i : 0x%08x z: %2i", hc, trkl->GetTrackletWord(), trkl->GetZbin()));
2244 AliDebugClass(2, Form("set tracklet index for HC %i to %i", hc, iTracklet));
2245 indices[hc] = iTracklet + 1;
2250 for (Int_t iDet = 0; iDet < 540; iDet++) {
2251 Int_t trklIndexA = indices[2*iDet + 0] - 1;
2252 Int_t trklIndexB = indices[2*iDet + 1] - 1;
2253 Int_t trklIndex = sortedTracklets.GetEntries();
2254 AliTRDtrackletBase *trklA = trklIndexA > -1 ? (AliTRDtrackletBase*) ((*trklArray)[trklIndexA]) : 0x0;
2255 AliTRDtrackletBase *trklB = trklIndexB > -1 ? (AliTRDtrackletBase*) ((*trklArray)[trklIndexB]) : 0x0;
2256 AliTRDtrackletBase *trklNext = 0x0;
2257 while (trklA != 0x0 || trklB != 0x0) {
2258 AliDebugClass(5, Form("det %i - A: %i/%i -> %p, B: %i/%i -> %p",
2259 iDet, trklIndexA, nTracklets, trklA, trklIndexB, nTracklets, trklB));
2263 trklB = trklIndexB < nTracklets ? (AliTRDtrackletBase*) ((*trklArray)[trklIndexB]) : 0x0;
2264 if (trklB && trklB->GetHCId() != 2*iDet + 1)
2267 else if (trklB == 0x0) {
2270 trklA = trklIndexA < nTracklets ? (AliTRDtrackletBase*) ((*trklArray)[trklIndexA]) : 0x0;
2271 if (trklA && trklA->GetHCId() != 2*iDet)
2275 if (trklA->GetZbin() <= trklB->GetZbin()) {
2278 trklA = trklIndexA < nTracklets ? (AliTRDtrackletBase*) ((*trklArray)[trklIndexA]) : 0x0;
2279 if (trklA && trklA->GetHCId() != 2*iDet)
2285 trklB = trklIndexB < nTracklets ? (AliTRDtrackletBase*) ((*trklArray)[trklIndexB]) : 0x0;
2286 if (trklB && trklB->GetHCId() != 2*iDet + 1)
2291 Int_t label = -2; // mark raw tracklets with label -2
2292 if (AliTRDtrackletMCM *trklMCM = dynamic_cast<AliTRDtrackletMCM*> (trklNext))
2293 label = trklMCM->GetLabel();
2294 AliESDTrdTracklet *esdTracklet = new AliESDTrdTracklet(trklNext->GetTrackletWord(), trklNext->GetHCId(), label);
2295 sortedTracklets.Add(esdTracklet);
2298 // updating tracklet indices as in output
2299 if (sortedTracklets.GetEntries() != trklIndex) {
2300 indices[2*iDet + 0] = indices[2*iDet + 1] = trklIndex;
2303 indices[2*iDet + 0] = indices[2*iDet + 1] = -1;