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 "AliTRDdigitsManager.h"
34 #include "AliTRDdigitsParam.h"
35 #include "AliTRDtrapConfig.h"
36 #include "AliTRDarrayADC.h"
37 #include "AliTRDarrayDictionary.h"
38 #include "AliTRDSignalIndex.h"
39 #include "AliTRDtrackletWord.h"
40 #include "AliTRDtrackletMCM.h"
41 #include "AliESDTrdTrack.h"
42 #include "AliTreeLoader.h"
43 #include "AliLoader.h"
45 #include "AliTRDrawStream.h"
48 #include "AliRunLoader.h"
50 ClassImp(AliTRDrawStream)
52 // some static information
53 Int_t AliTRDrawStream::fgMcmOrder[] = {12, 13, 14, 15,
57 Int_t AliTRDrawStream::fgRobOrder [] = {0, 1, 2, 3};
58 const Int_t AliTRDrawStream::fgkNlinks = 12;
59 const Int_t AliTRDrawStream::fgkNstacks = 5;
60 const Int_t AliTRDrawStream::fgkNsectors = 18;
61 const Int_t AliTRDrawStream::fgkNtriggers = 12;
62 const UInt_t AliTRDrawStream::fgkDataEndmarker = 0x00000000;
63 const UInt_t AliTRDrawStream::fgkTrackletEndmarker = 0x10001000;
64 const UInt_t AliTRDrawStream::fgkStackEndmarker[] = { 0xe0d01000, 0xe0d10000 };
66 const char* AliTRDrawStream::fgkErrorMessages[] = {
68 "Link monitor active",
69 "Event counter mismatch",
70 "not a TRD equipment (1024-1041)",
71 "Invalid Stack header",
72 "Invalid detector number",
73 "No digits could be retrieved from the digitsmanager",
75 "HC check bits wrong",
76 "Unexpected position in readout stream",
77 "Invalid testpattern mode",
78 "Testpattern mismatch",
79 "Number of timebins changed",
80 "ADC mask inconsistent",
81 "ADC check bits invalid",
83 "Missing expected ADC channels",
84 "Missing MCM headers",
89 Int_t AliTRDrawStream::fgErrorDebugLevel[] = {
112 AliTRDrawStream::ErrorBehav_t AliTRDrawStream::fgErrorBehav[] = {
113 AliTRDrawStream::kTolerate,
114 AliTRDrawStream::kDiscardHC,
115 AliTRDrawStream::kTolerate,
116 AliTRDrawStream::kAbort,
117 AliTRDrawStream::kAbort,
118 AliTRDrawStream::kAbort,
119 AliTRDrawStream::kAbort,
120 AliTRDrawStream::kDiscardHC,
121 AliTRDrawStream::kDiscardHC,
122 AliTRDrawStream::kTolerate,
123 AliTRDrawStream::kTolerate,
124 AliTRDrawStream::kTolerate,
125 AliTRDrawStream::kTolerate,
126 AliTRDrawStream::kTolerate,
127 AliTRDrawStream::kTolerate,
128 AliTRDrawStream::kTolerate,
129 AliTRDrawStream::kTolerate,
130 AliTRDrawStream::kTolerate,
131 AliTRDrawStream::kTolerate,
132 AliTRDrawStream::kTolerate
135 AliTRDrawStream::AliTRDrawStream(AliRawReader *rawReader) :
136 fStoreError(&AliTRDrawStream::ForgetError),
137 fRawReader(rawReader),
154 fCurrSmHeaderSize(0),
155 fCurrSmHeaderVersion(0),
156 fCurrTrailerReadout(0),
157 fCurrTrgHeaderAvail(0),
158 fCurrTrgHeaderReadout(0),
159 fCurrTrkHeaderAvail(0),
160 fCurrStackEndmarkerAvail(0),
162 fCurrTriggerEnable(0),
163 fCurrTriggerFired(0),
165 fCurrTrackletEnable(0),
167 fCurrTrkHeaderIndexWord(0x0),
168 fCurrTrkHeaderSize(0x0),
170 fCurrTrgHeaderIndexWord(0x0),
171 fCurrTrgHeaderSize(0x0),
173 fCurrStackIndexWord(0x0),
174 fCurrStackHeaderSize(0x0),
175 fCurrStackHeaderVersion(0x0),
177 fCurrCleanCheckout(0x0),
181 fCurrLinkMonitorFlags(0x0),
182 fCurrLinkDataTypeFlags(0x0),
183 fCurrLinkDebugFlags(0x0),
184 fCurrMatchFlagsSRAM(0),
185 fCurrMatchFlagsPostBP(0),
186 fCurrChecksumStack(),
211 // default constructor
213 fCurrTrkHeaderIndexWord = new UInt_t[fgkNstacks];
214 fCurrTrkHeaderSize = new UInt_t[fgkNstacks];
215 fCurrTrkFlags = new ULong64_t[fgkNsectors*fgkNstacks];
216 fCurrTrgHeaderIndexWord = new UInt_t[fgkNtriggers];
217 fCurrTrgHeaderSize = new UInt_t[fgkNtriggers];
218 fCurrTrgFlags = new UInt_t[fgkNsectors];
219 fCurrStackIndexWord = new UInt_t[fgkNstacks];
220 fCurrStackHeaderSize = new UInt_t[fgkNstacks];
221 fCurrStackHeaderVersion = new UInt_t[fgkNstacks];
222 fCurrLinkMask = new UInt_t[fgkNstacks];
223 fCurrCleanCheckout = new UInt_t[fgkNstacks];
224 fCurrBoardId = new UInt_t[fgkNstacks];
225 fCurrHwRevTMU = new UInt_t[fgkNstacks];
226 fCurrLinkMonitorFlags = new UInt_t[fgkNstacks * fgkNlinks];
227 fCurrLinkDataTypeFlags = new UInt_t[fgkNstacks * fgkNlinks];
228 fCurrLinkDebugFlags = new UInt_t[fgkNstacks * fgkNlinks];
229 for (Int_t iSector = 0; iSector < fgkNsectors; iSector++)
230 fCurrTrgFlags[iSector] = 0;
231 for (Int_t i = 0; i < 100; i++)
234 // preparing TClonesArray
235 fTrackletArray = new TClonesArray("AliTRDtrackletWord", 256);
237 // setting up the error tree
238 fErrors = new TTree("errorStats", "Error statistics");
239 fErrors->SetDirectory(0x0);
240 fErrors->Branch("error", &fLastError);
241 fErrors->SetCircular(1000);
242 for (Int_t i = 0; i < 100; i++) {
248 AliTRDrawStream::~AliTRDrawStream()
254 delete [] fCurrTrkHeaderIndexWord;
255 delete [] fCurrTrkHeaderSize;
256 delete [] fCurrTrkFlags;
257 delete [] fCurrTrgHeaderIndexWord;
258 delete [] fCurrTrgHeaderSize;
259 delete [] fCurrTrgFlags;
260 delete [] fCurrStackIndexWord;
261 delete [] fCurrStackHeaderSize;
262 delete [] fCurrStackHeaderVersion;
263 delete [] fCurrLinkMask;
264 delete [] fCurrCleanCheckout;
265 delete [] fCurrBoardId;
266 delete [] fCurrHwRevTMU;
267 delete [] fCurrLinkMonitorFlags;
268 delete [] fCurrLinkDataTypeFlags;
269 delete [] fCurrLinkDebugFlags;
272 Bool_t AliTRDrawStream::ReadEvent(TTree *trackletTree)
274 // read the current event from the raw reader and fill it to the digits manager
277 AliError("No raw reader available");
282 ConnectTracklets(trackletTree);
287 // loop over all DDLs
288 // data starts with GTU payload, i.e. SM index word
289 UChar_t *buffer = 0x0;
291 while (fRawReader->ReadNextData(buffer)) {
293 fCurrEquipmentId = fRawReader->GetEquipmentId();
294 AliDebug(2, Form("equipment: %i", fCurrEquipmentId));
296 if (fCurrEquipmentId < kDDLOffset || fCurrEquipmentId > kDDLMax) {
297 EquipmentError(kNonTrdEq, "Skipping");
302 new ((*fMarkers)[fMarkers->GetEntriesFast()])
303 AliTRDrawStreamError(-kSecactive, fCurrEquipmentId - kDDLOffset);
305 ReadGTUHeaders((UInt_t*) buffer);
307 if (fCurrTrailerReadout)
310 // loop over all active links
311 AliDebug(2, Form("Stack mask 0x%02x", fCurrStackMask));
312 for (Int_t iStack = 0; iStack < fgkNstacks; iStack++) {
314 if ((fCurrStackMask & (1 << fCurrSlot)) == 0)
317 AliDebug(2, Form("Stack %i, Link mask: 0x%02x", fCurrSlot, fCurrLinkMask[fCurrSlot]));
318 for (Int_t iLink = 0; iLink < fgkNlinks; iLink++) {
320 fCurrHC = (fCurrEquipmentId - kDDLOffset) * fgkNstacks * fgkNlinks +
321 fCurrSlot * fgkNlinks + iLink;
322 if ((fCurrLinkMask[fCurrSlot] & (1 << fCurrLink)) == 0)
328 // check for link monitor error flag
329 if (fCurrLinkMonitorFlags[fCurrSlot*fgkNlinks + fCurrLink] != 0) {
330 LinkError(kLinkMonitor);
331 if (fgErrorBehav[kLinkMonitor] == kTolerate)
332 size += ReadLinkData();
335 // read the data from one HC
336 size += ReadLinkData();
338 // read all data endmarkers
339 size += SeekNextLink();
342 // continue with next stack
351 Bool_t AliTRDrawStream::NextDDL()
353 // continue reading with the next equipment
358 fCurrEquipmentId = 0;
362 UChar_t *buffer = 0x0;
364 while (fRawReader->ReadNextData(buffer)) {
366 fCurrEquipmentId = fRawReader->GetEquipmentId();
367 AliDebug(2, Form("equipment: %i", fCurrEquipmentId));
369 if (fCurrEquipmentId < kDDLOffset || fCurrEquipmentId > kDDLMax) {
370 EquipmentError(kNonTrdEq, "Skipping");
375 new ((*fMarkers)[fMarkers->GetEntriesFast()])
376 AliTRDrawStreamError(-kSecactive, fCurrEquipmentId - kDDLOffset);
378 ReadGTUHeaders((UInt_t*) buffer);
380 if (fCurrTrailerReadout)
390 Int_t AliTRDrawStream::NextChamber(AliTRDdigitsManager *digMgr)
392 // read the data for the next chamber
393 // in case you only want to read the data of a single chamber
394 // to read all data ReadEvent(...) is recommended
396 fDigitsManager = digMgr;
401 // tracklet output preparation
402 TTree *trklTree = 0x0;
403 AliRunLoader *rl = AliRunLoader::Instance();
404 AliLoader* trdLoader = rl ? rl->GetLoader("TRDLoader") : NULL;
405 AliDataLoader *trklLoader = trdLoader ? trdLoader->GetDataLoader("tracklets") : NULL;
407 AliTreeLoader *trklTreeLoader = (AliTreeLoader*) trklLoader->GetBaseLoader("tracklets-raw");
409 trklTree = trklTreeLoader->Tree();
411 trklTree = trklLoader->Tree();
414 if (fTrackletTree != trklTree)
415 ConnectTracklets(trklTree);
418 AliError("No raw reader available");
422 while (fCurrSlot < 0 || fCurrSlot >= fgkNstacks) {
427 while ((fCurrSlot < fgkNstacks) &&
428 (((fCurrStackMask & (1 << fCurrSlot)) == 0) ||
429 ((fCurrLinkMask[fCurrSlot] & (1 << fCurrLink))) == 0)) {
431 if (fCurrLink >= fgkNlinks) {
438 AliDebug(2, Form("Stack %i, Link %i, mask: 0x%02x", fCurrSlot, fCurrLink, fCurrLinkMask[fCurrSlot]));
439 fCurrHC = (fCurrEquipmentId - kDDLOffset) * fgkNlinks * fgkNstacks +
440 fCurrSlot * fgkNlinks + fCurrLink;
442 if (fCurrLinkMonitorFlags[fCurrSlot*fgkNlinks + fCurrLink] != 0) {
443 LinkError(kLinkMonitor);
444 if (fgErrorBehav[kLinkMonitor] == kTolerate)
448 // read the data from one HC
451 // read all data endmarkers
454 if (fCurrLink % 2 == 0) {
455 // if we just read the A-side HC then also check the B-side
458 if (fCurrLinkMask[fCurrSlot] & (1 << fCurrLink)) {
459 if (fCurrLinkMonitorFlags[fCurrSlot*fgkNlinks + fCurrLink] != 0) {
460 LinkError(kLinkMonitor);
461 if (fgErrorBehav[kLinkMonitor] == kTolerate)
472 if ((fCurrStackMask & (1 << fCurrSlot)) == 0) {
478 if (fCurrLink >= fgkNlinks) {
484 } while ((fCurrSlot < fgkNstacks) &&
485 (((fCurrStackMask & (1 << fCurrSlot)) == 0) ||
486 ((fCurrLinkMask[fCurrSlot] & (1 << fCurrLink))) == 0));
488 // return chamber information from HC if it is valid
489 // otherwise return information from link position
490 if (fCurrSm < 0 || fCurrSm >= fgkNsectors || fCurrStack < 0 || fCurrStack >= fgkNstacks || fCurrLayer < 0 || fCurrLayer >= fgkNlinks/2)
491 return ((fCurrEquipmentId-kDDLOffset) + fCurrSlot * fgkNlinks/2 + fCurrLink/2);
493 return (fCurrSm * fgkNstacks*fgkNlinks/2 + fCurrStack * fgkNlinks/2 + fCurrLayer);
497 Int_t AliTRDrawStream::ReadGTUHeaders(UInt_t *buffer)
499 // check the data source and read the headers
501 if (fCurrEquipmentId >= kDDLOffset && fCurrEquipmentId <= kDDLMax) {
504 // setting the pointer to data and current reading position
505 fPayloadCurr = fPayloadStart = buffer;
506 fPayloadSize = fRawReader->GetDataSize() / sizeof(UInt_t);
507 fStats.fStatsSector[fCurrEquipmentId - kDDLOffset].fBytes = fRawReader->GetDataSize();
508 AliDebug(2, Form("Read buffer of size: %i", fRawReader->GetDataSize()));
510 AliDebug(1, DumpRaw("raw data", fPayloadCurr, TMath::Min(fPayloadSize, 1000)));
513 if (ReadSmHeader() < 0) {
514 AliError(Form("Reading SM header failed, skipping this DDL %i", fCurrEquipmentId));
518 // read tracking headers (if available)
519 if (fCurrTrkHeaderAvail) {
520 for (Int_t iStack = 0; iStack < fgkNstacks; iStack++) {
521 if ((fCurrStackMask & (1 << iStack)) != 0)
522 ReadTrackingHeader(iStack);
526 // read trigger header(s) (if available)
527 if (fCurrTrgHeaderAvail)
528 ReadTriggerHeaders();
531 for (Int_t iStack = 0; iStack < fgkNstacks; iStack++) {
532 if ((fCurrStackMask & (1 << iStack)) != 0)
533 ReadStackHeader(iStack);
542 Int_t AliTRDrawStream::ReadSmHeader()
544 // read the SMU index header at the current reading position
545 // and store the information in the corresponding variables
547 if (fPayloadCurr - fPayloadStart >= fPayloadSize - 1) {
548 EquipmentError(kUnknown, "SM Header incomplete");
552 fCurrTrgFlags[fCurrEquipmentId-kDDLOffset] = 0;
554 fCurrSmHeaderSize = ((*fPayloadCurr) >> 16) & 0xffff;
555 fCurrSmHeaderVersion = ((*fPayloadCurr) >> 12) & 0xf;
556 fCurrTrackEnable = ((*fPayloadCurr) >> 6) & 0x1;
557 fCurrTrackletEnable = ((*fPayloadCurr) >> 5) & 0x1;
558 fCurrStackMask = ((*fPayloadCurr) ) & 0x1f;
559 fCurrHwRev = (fPayloadCurr[1] >> 12) & 0xffff;
560 fCurrStackEndmarkerAvail = 0;
562 switch (fCurrSmHeaderVersion) {
564 fCurrTrailerReadout = 0;
565 fCurrTrgHeaderAvail = 0;
567 fCurrTrkHeaderAvail = 0;
573 fCurrTrailerReadout = ((*fPayloadCurr) >> 10) & 0x1;
574 fCurrTrgHeaderAvail = 1;
575 fCurrTrgHeaderReadout = ((*fPayloadCurr) >> 9) & 0x1;
576 fCurrEvType = ((*fPayloadCurr) >> 7) & 0x3;
577 fCurrTrkHeaderAvail = fCurrTrackEnable;
578 fCurrTriggerEnable = (fPayloadCurr[2] >> 8) & 0xfff;
579 fCurrTriggerFired = (fPayloadCurr[2] >> 20) & 0xfff;
580 fCurrTrgFlags[fCurrEquipmentId-kDDLOffset] = fCurrTriggerFired;
584 fCurrTrailerReadout = ((*fPayloadCurr) >> 10) & 0x1;
585 fCurrTrgHeaderAvail = 1;
586 fCurrTrgHeaderReadout = ((*fPayloadCurr) >> 9) & 0x1;
587 fCurrEvType = ((*fPayloadCurr) >> 7) & 0x3;
588 fCurrTrkHeaderAvail = fCurrTrackEnable;
589 fCurrTriggerEnable = (fPayloadCurr[2] >> 8) & 0xfff;
590 fCurrTriggerFired = (fPayloadCurr[2] >> 20) & 0xfff;
591 fCurrTrgFlags[fCurrEquipmentId-kDDLOffset] = fCurrTriggerFired;
592 fCurrStackEndmarkerAvail = 1;
596 AliError(Form("unknown SM header version: 0x%x", fCurrSmHeaderVersion));
599 AliDebug(5, Form("SM header: size: %i, version: %i, track enable: %i, tracklet enable: %i, stack mask: %2x, trailer: %i, trgheader: %i, trkheader: %i",
601 fCurrSmHeaderVersion,
607 fCurrTrkHeaderAvail ));
609 // jump to the first word after the SM header
610 fPayloadCurr += fCurrSmHeaderSize + 1;
612 return fCurrSmHeaderSize + 1;
615 Int_t AliTRDrawStream::DecodeGTUtracks()
617 // decode GTU track words
618 // this depends on the hardware revision of the SMU
620 Int_t sector = fCurrEquipmentId-kDDLOffset;
622 if ((sector < 0) || (sector > 17)) {
623 AliError(Form("Invalid sector %i for GTU tracks", sector));
627 AliDebug(1, DumpRaw(Form("GTU tracks in sector %2i (hw rev %i)", sector, fCurrHwRev),
628 fPayloadCurr + 4, 10, 0xffe0ffff));
630 fCurrTrgFlags[sector] = 0;
632 if (fCurrHwRev < 1772) {
633 UInt_t fastWord; // fast trigger word
634 ULong64_t trackWord = 0; // extended track word
637 for (UInt_t iWord = 4; iWord < fCurrSmHeaderSize; iWord++) {
638 if (fPayloadCurr[iWord] == 0x10000000) { // stack boundary marker
644 ((fPayloadCurr[iWord] & 0xfffff0f0) == 0x13370000)) {
645 fastWord = fPayloadCurr[iWord];
646 fCurrTrgFlags[sector] |= 1 << (stack+11); // assume tracking done if fast word sent
647 AliDebug(1, Form("stack %i: fast trigger word: 0x%08x", stack, fastWord));
650 else if ((idx & 0x1) == 0x1) {
651 trackWord |= ((ULong64_t) fPayloadCurr[iWord]) << 32;
652 AliDebug(1,Form("track debug word: 0x%016llx", trackWord));
654 AliESDTrdTrack *trk = new ((*fTracks)[fTracks->GetEntriesFast()])
657 trk->SetSector(sector);
658 trk->SetStack((trackWord >> 60) & 0x7);
662 trk->SetLayerMask((trackWord >> 16) & 0x3f);
663 trk->SetTrackletIndex((trackWord >> 22) & 0x3f, 0);
664 trk->SetTrackletIndex((trackWord >> 28) & 0x3f, 1);
665 trk->SetTrackletIndex((trackWord >> 34) & 0x3f, 2);
666 trk->SetTrackletIndex((trackWord >> 40) & 0x3f, 3);
667 trk->SetTrackletIndex((trackWord >> 46) & 0x3f, 4);
668 trk->SetTrackletIndex((trackWord >> 52) & 0x3f, 5);
674 Float_t pt = (((Int_t) (trackWord & 0xffff) ^ 0x8000) - 0x8000)/128.;
675 if (TMath::Abs(pt) > 0.1) {
676 trk->SetA((Int_t) (0.15*51625./100./pt / 160e-4 * 2));
681 trackWord = fPayloadCurr[iWord];
687 else if (fCurrHwRev < 1804) {
688 UInt_t fastWord; // fast trigger word
689 ULong64_t trackWord = 0; // extended track word
692 for (UInt_t iWord = 4; iWord < fCurrSmHeaderSize; iWord++) {
693 if (fPayloadCurr[iWord] == 0xffe0ffff) { // stack boundary marker
699 ((fPayloadCurr[iWord] & 0xfffff0f0) == 0x13370000)) {
700 fastWord = fPayloadCurr[iWord];
701 fCurrTrgFlags[sector] |= 1 << (stack+11); // assume tracking done if fast word sent
702 AliDebug(1, Form("stack %i: fast trigger word: 0x%08x", stack, fastWord));
705 else if ((idx & 0x1) == 0x1) {
706 trackWord |= ((ULong64_t) fPayloadCurr[iWord]) << 32;
707 AliDebug(1, Form("track debug word: 0x%016llx", trackWord));
709 AliESDTrdTrack *trk = new ((*fTracks)[fTracks->GetEntriesFast()])
712 trk->SetSector(fCurrEquipmentId-kDDLOffset);
713 trk->SetStack((trackWord >> 60) & 0x7);
717 trk->SetLayerMask((trackWord >> 16) & 0x3f);
718 trk->SetTrackletIndex((trackWord >> 22) & 0x3f, 0);
719 trk->SetTrackletIndex((trackWord >> 28) & 0x3f, 1);
720 trk->SetTrackletIndex((trackWord >> 34) & 0x3f, 2);
721 trk->SetTrackletIndex((trackWord >> 40) & 0x3f, 3);
722 trk->SetTrackletIndex((trackWord >> 46) & 0x3f, 4);
723 trk->SetTrackletIndex((trackWord >> 52) & 0x3f, 5);
729 Float_t pt = (((Int_t) (trackWord & 0xffff) ^ 0x8000) - 0x8000)/128.;
730 if (TMath::Abs(pt) > 0.1) {
731 trk->SetA((Int_t) (-0.15*51625./100./pt / 160e-4 * 2));
736 trackWord = fPayloadCurr[iWord];
742 else if (fCurrHwRev < 1819) {
743 UInt_t fastWord; // fast trigger word
744 ULong64_t trackWord = 0; // extended track word
747 for (UInt_t iWord = 4; iWord < fCurrSmHeaderSize; iWord++) {
748 if (fPayloadCurr[iWord] == 0xffe0ffff) { // stack boundary marker
754 ((fPayloadCurr[iWord] & 0xfffff0f0) == 0x13370000)) {
755 fastWord = fPayloadCurr[iWord];
756 if (fastWord & (1 << 13))
757 fCurrTrgFlags[sector] |= 1 << (stack+11);
758 AliDebug(1, Form("stack %i: fast trigger word: 0x%08x", stack, fastWord));
761 else if ((idx & 0x1) == 0x1) {
762 trackWord |= ((ULong64_t) fPayloadCurr[iWord]) << 32;
763 AliDebug(1, Form("track debug word: 0x%016llx", trackWord));
766 AliESDTrdTrack *trk = new ((*fTracks)[fTracks->GetEntriesFast()])
769 trk->SetSector(fCurrEquipmentId-kDDLOffset);
770 trk->SetStack((trackWord >> 60) & 0x7);
773 // trk->SetPt(((trackWord & 0xffff) ^ 0x8000) - 0x8000);
775 trk->SetLayerMask((trackWord >> 16) & 0x3f);
776 trk->SetTrackletIndex((trackWord >> 22) & 0x3f, 0);
777 trk->SetTrackletIndex((trackWord >> 28) & 0x3f, 1);
778 trk->SetTrackletIndex((trackWord >> 34) & 0x3f, 2);
779 trk->SetTrackletIndex((trackWord >> 40) & 0x3f, 3);
780 trk->SetTrackletIndex((trackWord >> 46) & 0x3f, 4);
781 trk->SetTrackletIndex((trackWord >> 52) & 0x3f, 5);
787 Float_t pt = (((Int_t) (trackWord & 0xffff) ^ 0x8000) - 0x8000)/128.;
788 if (TMath::Abs(pt) > 0.1) {
789 trk->SetA((Int_t) (0.15*51625./100./trk->Pt() / 160e-4 * 2));
794 trackWord = fPayloadCurr[iWord];
800 else if (fCurrHwRev < 1860) {
801 UInt_t fastWord; // fast trigger word
802 ULong64_t trackWord = 0; // extended track word
805 Bool_t upperWord = kFALSE;
807 for (UInt_t iWord = 4; iWord < fCurrSmHeaderSize; iWord++) {
808 if (fPayloadCurr[iWord] == 0xffe0ffff) { // stack boundary marker
814 // assemble the 32-bit words out of 16-bit blocks
816 word |= (fPayloadCurr[iWord] & 0xffff0000);
820 // lower word is read first
821 word = (fPayloadCurr[iWord] & 0xffff0000) >> 16;
826 if ((word & 0xffff0008) == 0x13370008) {
828 AliDebug(1, Form("stack %i: fast track word: 0x%08x", stack, fastWord));
829 if (fastWord & (1 << 13))
830 fCurrTrgFlags[sector] |= 1 << (stack+11);
833 else if ((idx & 0x1) == 0x1) {
834 trackWord |= ((ULong64_t) word) << 32;
835 AliDebug(1, Form("track debug word: 0x%016llx", trackWord));
837 AliESDTrdTrack *trk = new ((*fTracks)[fTracks->GetEntriesFast()])
840 trk->SetSector(fCurrEquipmentId-kDDLOffset);
841 trk->SetStack((trackWord >> 60) & 0x7);
845 trk->SetLayerMask((trackWord >> 16) & 0x3f);
846 trk->SetTrackletIndex((trackWord >> 22) & 0x3f, 0);
847 trk->SetTrackletIndex((trackWord >> 28) & 0x3f, 1);
848 trk->SetTrackletIndex((trackWord >> 34) & 0x3f, 2);
849 trk->SetTrackletIndex((trackWord >> 40) & 0x3f, 3);
850 trk->SetTrackletIndex((trackWord >> 46) & 0x3f, 4);
851 trk->SetTrackletIndex((trackWord >> 52) & 0x3f, 5);
857 Float_t pt = (((Int_t) (trackWord & 0xffff) ^ 0x8000) - 0x8000)/128.;
858 if (TMath::Abs(pt) > 0.1) {
859 trk->SetA((Int_t) (0.15*51625./100./pt / 160e-4 * 2));
872 ULong64_t trackWord = 0; // this is the debug word
875 Bool_t upperWord = kFALSE;
877 for (UInt_t iWord = 4; iWord < fCurrSmHeaderSize; iWord++) {
878 if (fPayloadCurr[iWord] == 0xffe0ffff) {
884 // assemble the 32-bit words out of 16-bit blocks
886 word |= (fPayloadCurr[iWord] & 0xffff0000);
890 // lower word is read first
891 word = (fPayloadCurr[iWord] & 0xffff0000) >> 16;
896 if ((word & 0xffff0008) == 0x13370008) {
897 AliDebug(1, Form("stack %i: fast track word: 0x%08x", stack, word));
900 else if ((word & 0xffff0010) == 0x13370010) {
901 AliDebug(1, Form("stack %i: tracking done word: 0x%08x", stack, word));
902 fCurrTrgFlags[sector] |= 1 << (stack+11);
905 else if ((idx & 0x1) == 0x1) {
906 trackWord |= ((ULong64_t) word) << 32;
907 AliDebug(1, Form("track debug word: 0x%16llx", trackWord));
909 AliESDTrdTrack *trk = new ((*fTracks)[fTracks->GetEntriesFast()])
911 trk->SetSector(fCurrEquipmentId-kDDLOffset);
912 trk->SetStack((trackWord >> 60) & 0x7);
916 trk->SetLayerMask((trackWord >> 16) & 0x3f);
917 trk->SetTrackletIndex((trackWord >> 22) & 0x3f, 0);
918 trk->SetTrackletIndex((trackWord >> 28) & 0x3f, 1);
919 trk->SetTrackletIndex((trackWord >> 34) & 0x3f, 2);
920 trk->SetTrackletIndex((trackWord >> 40) & 0x3f, 3);
921 trk->SetTrackletIndex((trackWord >> 46) & 0x3f, 4);
922 trk->SetTrackletIndex((trackWord >> 52) & 0x3f, 5);
928 Float_t pt = (((Int_t) (trackWord & 0xffff) ^ 0x8000) - 0x8000)/128.;
929 if (TMath::Abs(pt) > 0.1) {
930 trk->SetA(-(Int_t) (0.15*51625./100./pt / 160e-4 * 2));
944 Int_t AliTRDrawStream::ReadTrackingHeader(Int_t stack)
946 // read the tracking information and store it for the given stack
950 fCurrTrkHeaderIndexWord[stack] = *fPayloadCurr;
951 fCurrTrkHeaderSize[stack] = ((*fPayloadCurr) >> 16) & 0x3ff;
953 AliDebug(1, Form("tracking header index word: 0x%08x, size: %i (hw rev: %i)",
954 fCurrTrkHeaderIndexWord[stack], fCurrTrkHeaderSize[stack], fCurrHwRev));
955 Int_t trackingTime = *fPayloadCurr & 0x3ff;
957 fCurrTrgFlags[fCurrEquipmentId-kDDLOffset] |= ((fCurrTrkHeaderIndexWord[stack] >> 10) & 0x1) << (22 + stack);
961 ULong64_t trackWord = 0;
963 Int_t trackIndex = fTracks ? fTracks->GetEntriesFast() : -1;
965 for (UInt_t iWord = 0; iWord < fCurrTrkHeaderSize[stack]; iWord++) {
968 // first part of 64-bit word
969 trackWord = fPayloadCurr[iWord];
972 trackWord |= ((ULong64_t) fPayloadCurr[iWord]) << 32;
974 if (trackWord & (1ul << 63)) {
975 if ((trackWord & (0x3ful << 56)) != 0) {
977 AliDebug(2, Form("track word: 0x%016llx", trackWord));
980 AliESDTrdTrack *trk = new ((*fTracks)[fTracks->GetEntriesFast()])
983 trk->SetSector(fCurrEquipmentId-kDDLOffset);
984 trk->SetLayerMask((trackWord >> 56) & 0x3f);
985 trk->SetA( (((trackWord >> 38) & 0x3ffff) ^ 0x20000) - 0x20000);
986 trk->SetB( (((trackWord >> 20) & 0x3ffff) ^ 0x20000) - 0x20000);
987 trk->SetC( (((trackWord >> 8) & 0xffff) ^ 0x8000) - 0x8000);
988 trk->SetPID((trackWord >> 0) & 0xff);
989 trk->SetStack(stack);
992 // now compare the track word with the one generated from the ESD information
993 if (trackWord != trk->GetTrackWord(0)) {
994 AliError(Form("track word 0x%016llx does not match the read one 0x%016llx",
995 trk->GetTrackWord(0), trackWord));
1000 // done marker (so far only used to set trigger flag)
1001 fCurrTrgFlags[fCurrEquipmentId-kDDLOffset] |= 1 << (27 + stack);
1002 fCurrTrkFlags[(fCurrEquipmentId-kDDLOffset)*fgkNstacks + stack] = trackWord;
1004 AliDebug(2, Form("tracking done marker: 0x%016llx, trigger flags: 0x%08x",
1005 trackWord, fCurrTrgFlags[fCurrEquipmentId-kDDLOffset]));
1006 AliDebug(2, Form("seg / stack / first / last / done / index : %i %i %lli %lli %lli %i",
1007 fCurrEquipmentId - kDDLOffset, stack,
1008 (trackWord >> 20) & 0x3ff,
1009 (trackWord >> 10) & 0x3ff,
1010 (trackWord >> 0) & 0x3ff,
1015 // extended track word
1016 AliDebug(2, Form("extended track word: 0x%016llx", trackWord));
1019 AliESDTrdTrack *trk = (AliESDTrdTrack*) (*fTracks)[trackIndex];
1021 trk->SetFlags((trackWord >> 52) & 0x7ff);
1022 trk->SetReserved((trackWord >> 49) & 0x7);
1023 trk->SetY((trackWord >> 36) & 0x1fff);
1024 trk->SetTrackletIndex((trackWord >> 0) & 0x3f, 0);
1025 trk->SetTrackletIndex((trackWord >> 6) & 0x3f, 1);
1026 trk->SetTrackletIndex((trackWord >> 12) & 0x3f, 2);
1027 trk->SetTrackletIndex((trackWord >> 18) & 0x3f, 3);
1028 trk->SetTrackletIndex((trackWord >> 24) & 0x3f, 4);
1029 trk->SetTrackletIndex((trackWord >> 30) & 0x3f, 5);
1031 if (trackWord != trk->GetExtendedTrackWord(0)) {
1032 AliError(Form("extended track word 0x%016llx does not match the read one 0x%016llx",
1033 trk->GetExtendedTrackWord(0), trackWord));
1043 fPayloadCurr += fCurrTrkHeaderSize[stack];
1045 return fCurrTrkHeaderSize[stack];
1048 Int_t AliTRDrawStream::ReadTriggerHeaders()
1050 // read all trigger headers present
1052 AliDebug(1, Form("trigger mask: 0x%03x, fired: 0x%03x\n",
1053 fCurrTriggerEnable, fCurrTriggerFired));
1054 // loop over potential trigger blocks
1055 for (Int_t iTrigger = 0; iTrigger < fgkNtriggers; iTrigger++) {
1056 // check for trigger enable
1057 if (fCurrTriggerEnable & (1 << iTrigger)) {
1058 // check for readout mode and trigger fired
1059 if ((fCurrTrgHeaderReadout == 0) || (fCurrTriggerFired & (1 << iTrigger))) {
1061 AliDebug(1, Form("trigger index word %i: 0x%08x\n", iTrigger, *fPayloadCurr));
1062 fCurrTrgHeaderIndexWord[iTrigger] = *fPayloadCurr;
1063 fCurrTrgHeaderSize[iTrigger] = ((*fPayloadCurr) >> 16) & 0x3ff;
1064 if (iTrigger == 7) {
1065 // timeout trigger, use to extract tracking time
1066 fCurrTrgFlags[fCurrEquipmentId-kDDLOffset] |= (*fPayloadCurr & 0x3ff) << 12;
1071 fPayloadCurr += fCurrTrgHeaderSize[iTrigger];
1079 Int_t AliTRDrawStream::ReadStackHeader(Int_t stack)
1081 // read the stack header
1082 // and store the information in the corresponding variables
1084 fCurrStackIndexWord[stack] = *fPayloadCurr;
1085 fCurrStackHeaderSize[stack] = (((*fPayloadCurr) >> 16) & 0xffff) + 1;
1086 fCurrStackHeaderVersion[stack] = ((*fPayloadCurr) >> 12) & 0xf;
1087 fCurrLinkMask[stack] = (*fPayloadCurr) & 0xfff;
1089 // dumping stack header
1090 AliDebug(1, DumpRaw(Form("stack %i header", stack), fPayloadCurr, fCurrStackHeaderSize[stack]));
1092 if (fPayloadCurr - fPayloadStart >= fPayloadSize - (Int_t) fCurrStackHeaderSize[stack]) {
1093 EquipmentError(kStackHeaderInvalid, "Stack index header %i aborted", stack);
1094 // dumping stack header
1095 AliError(DumpRaw(Form("stack %i header", stack), fPayloadCurr, fCurrStackHeaderSize[stack]));
1100 switch (fCurrStackHeaderVersion[stack]) {
1102 if (fCurrStackHeaderSize[stack] < 8) {
1103 LinkError(kStackHeaderInvalid, "Stack header smaller than expected!");
1107 fCurrCleanCheckout[stack] = fPayloadCurr[1] & 0x1;
1108 fCurrBoardId[stack] = (fPayloadCurr[1] >> 8) & 0xff;
1109 fCurrHwRevTMU[stack] = (fPayloadCurr[1] >> 16) & 0xffff;
1111 for (Int_t iLayer = 0; iLayer < 6; iLayer++) {
1113 fCurrLinkMonitorFlags [stack*fgkNlinks + iLayer*2] = fPayloadCurr[iLayer+2] & 0xf;
1114 fCurrLinkDataTypeFlags [stack*fgkNlinks + iLayer*2] = (fPayloadCurr[iLayer+2] >> 4) & 0x3;
1115 fCurrLinkDebugFlags [stack*fgkNlinks + iLayer*2] = (fPayloadCurr[iLayer+2] >> 12) & 0xf;
1117 fCurrLinkMonitorFlags [stack*fgkNlinks + iLayer*2 + 1] = (fPayloadCurr[iLayer+2] >> 16) & 0xf;
1118 fCurrLinkDataTypeFlags [stack*fgkNlinks + iLayer*2 + 1] = (fPayloadCurr[iLayer+2] >> 20) & 0x3;
1119 fCurrLinkDebugFlags [stack*fgkNlinks + iLayer*2 + 1] = (fPayloadCurr[iLayer+2] >> 28) & 0xf;
1124 LinkError(kStackHeaderInvalid, "Invalid Stack Header version %x", fCurrStackHeaderVersion[stack]);
1127 fPayloadCurr += fCurrStackHeaderSize[stack];
1129 return fCurrStackHeaderSize[stack];
1132 Int_t AliTRDrawStream::ReadGTUTrailer()
1134 // read the SM trailer containing CRCs from various stages
1136 UInt_t* trailer = fPayloadStart + fPayloadSize -1;
1138 // look for the trailer index word from the end
1139 for (Int_t iWord = 0; iWord < fPayloadSize; iWord++) {
1140 if ((fPayloadStart[fPayloadSize-1-iWord] & 0xffff) == 0x1f51) {
1141 trailer = fPayloadStart + fPayloadSize - 1 - iWord;
1146 if (((*trailer) & 0xffff) == 0x1f51) {
1147 UInt_t trailerIndexWord = (*trailer);
1148 Int_t trailerSize = (trailerIndexWord >> 16) & 0xffff;
1149 AliDebug(2, DumpRaw("GTU trailer", trailer, trailerSize+1));
1150 // parse the trailer
1151 if (trailerSize >= 4) {
1152 // match flags from GTU
1153 fCurrMatchFlagsSRAM = (trailer[1] >> 0) & 0x1f;
1154 fCurrMatchFlagsPostBP = (trailer[1] >> 5) & 0x1f;
1155 // individual checksums
1156 fCurrChecksumStack[0] = (trailer[1] >> 16) & 0xffff;
1157 fCurrChecksumStack[1] = (trailer[2] >> 0) & 0xffff;
1158 fCurrChecksumStack[2] = (trailer[2] >> 16) & 0xffff;
1159 fCurrChecksumStack[3] = (trailer[3] >> 0) & 0xffff;
1160 fCurrChecksumStack[4] = (trailer[3] >> 16) & 0xffff;
1161 fCurrChecksumSIU = trailer[4];
1163 if ((fCurrMatchFlagsSRAM & fCurrStackMask) != fCurrStackMask)
1164 EquipmentError(kCRCmismatch, "CRC mismatch SRAM: 0x%02x", fCurrMatchFlagsSRAM);
1165 if ((fCurrMatchFlagsPostBP & fCurrStackMask) != fCurrStackMask)
1166 EquipmentError(kCRCmismatch, "CRC mismatch BP: 0x%02x", fCurrMatchFlagsPostBP);
1170 LinkError(kUnknown, "Invalid GTU trailer");
1174 EquipmentError(kUnknown, "trailer index marker mismatch");
1179 Int_t AliTRDrawStream::ReadLinkData()
1181 // read the data in one link (one HC) until the data endmarker is reached
1182 // returns the number of words read!
1185 UInt_t* startPosLink = fPayloadCurr;
1187 AliDebug(1, DumpRaw(Form("link data from seg %2i slot %i link %2i", fCurrEquipmentId-kDDLOffset, fCurrSlot, fCurrLink),
1188 fPayloadCurr, TMath::Min((Int_t) (fPayloadSize - (fPayloadCurr-fPayloadStart)), 100), 0x00000000));
1191 new ((*fMarkers)[fMarkers->GetEntriesFast()])
1192 AliTRDrawStreamError(-kHCactive, fCurrEquipmentId-kDDLOffset, fCurrSlot, fCurrLink);
1194 if (fErrorFlags & kDiscardHC)
1197 if (fCurrTrackletEnable) {
1198 count += ReadTracklets();
1199 if (fErrorFlags & kDiscardHC)
1203 AliDebug(1, DumpRaw("HC header", fPayloadCurr, 4, 0x00000000));
1204 count += ReadHcHeader();
1205 if (fErrorFlags & kDiscardHC)
1208 Int_t det = fCurrSm * 30 + fCurrStack * 6 + fCurrLayer;
1210 if (det > -1 && det < 540) {
1212 // ----- check which kind of data -----
1213 if (fCurrMajor & 0x40) {
1214 if ((fCurrMajor & 0x7) == 0x7) {
1215 AliDebug(1, "This is a config event");
1216 UInt_t *startPos = fPayloadCurr;
1217 while (fPayloadCurr - fPayloadStart < fPayloadSize &&
1218 *fPayloadCurr != fgkDataEndmarker)
1220 count += fPayloadCurr - startPos;
1222 // feeding TRAP config
1223 // AliTRDtrapConfig *trapcfg = AliTRDcalibDB::Instance()->GetTrapConfig();
1224 // trapcfg->ReadPackedConfig(fCurrHC, startPos, fPayloadCurr - startPos);
1227 Int_t tpmode = fCurrMajor & 0x7;
1228 AliDebug(1, Form("Checking testpattern (mode %i) data", tpmode));
1229 count += ReadTPData(tpmode);
1233 // reading real data
1234 if (fDigitsManager) {
1235 if ((fAdcArray = fDigitsManager->GetDigits(det))) {
1236 //fAdcArray->Expand();
1237 if (fAdcArray->GetNtime() != fCurrNtimebins)
1238 fAdcArray->Allocate(16, 144, fCurrNtimebins);
1241 LinkError(kNoDigits);
1244 if (!fDigitsParam) {
1245 fDigitsParam = fDigitsManager->GetDigitsParam();
1248 fDigitsParam->SetPretriggerPhase(det, fCurrPtrgPhase);
1249 fDigitsParam->SetNTimeBins(det, fCurrNtimebins);
1250 fDigitsParam->SetADCbaseline(det, 10);
1253 if (fDigitsManager->UsesDictionaries()) {
1254 fDigitsManager->GetDictionary(det, 0)->Reset();
1255 fDigitsManager->GetDictionary(det, 1)->Reset();
1256 fDigitsManager->GetDictionary(det, 2)->Reset();
1259 if ((fSignalIndex = fDigitsManager->GetIndexes(det))) {
1260 fSignalIndex->SetSM(fCurrSm);
1261 fSignalIndex->SetStack(fCurrStack);
1262 fSignalIndex->SetLayer(fCurrLayer);
1263 fSignalIndex->SetDetNumber(det);
1264 if (!fSignalIndex->IsAllocated())
1265 fSignalIndex->Allocate(16, 144, fCurrNtimebins);
1268 if (fCurrMajor & 0x20) {
1269 AliDebug(1, "This is a zs event");
1270 count += ReadZSData();
1273 AliDebug(1, "This is a nozs event");
1274 count += ReadNonZSData();
1278 // just read until data endmarkers
1279 while (fPayloadCurr - fPayloadStart < fPayloadSize &&
1280 *fPayloadCurr != fgkDataEndmarker)
1286 LinkError(kInvalidDetector, "%i", det);
1287 while (fPayloadCurr - fPayloadStart < fPayloadSize &&
1288 *fPayloadCurr != fgkDataEndmarker)
1292 if (fCurrSm > -1 && fCurrSm < 18) {
1293 fStats.fStatsSector[fCurrSm].fStatsHC[fCurrHC%60].fBytes += (fPayloadCurr - startPosLink) * sizeof(UInt_t);
1294 fStats.fStatsSector[fCurrSm].fStatsHC[fCurrHC%60].fBytesRead += count * sizeof(UInt_t);
1295 fStats.fStatsSector[fCurrSm].fBytesRead += count * sizeof(UInt_t);
1296 fStats.fBytesRead += count * sizeof(UInt_t);
1302 Int_t AliTRDrawStream::ReadTracklets()
1304 // read the tracklets from one HC
1306 fTrackletArray->Clear();
1308 UInt_t *start = fPayloadCurr;
1309 while (*(fPayloadCurr) != fgkTrackletEndmarker &&
1310 fPayloadCurr - fPayloadStart < fPayloadSize) {
1311 new ((*fTrackletArray)[fTrackletArray->GetEntriesFast()]) AliTRDtrackletWord(*(fPayloadCurr), fCurrHC);
1316 if (fTrackletArray->GetEntriesFast() > 0) {
1317 AliDebug(1, Form("Found %i tracklets in %i %i %i (ev. %i)", fTrackletArray->GetEntriesFast(),
1318 (fCurrEquipmentId-kDDLOffset), fCurrSlot, fCurrLink, fRawReader->GetEventIndex()));
1319 if (fCurrSm > -1 && fCurrSm < 18) {
1320 fStats.fStatsSector[fCurrSm].fStatsHC[fCurrHC%60].fNTracklets += fTrackletArray->GetEntriesFast();
1321 fStats.fStatsSector[fCurrSm].fNTracklets += fTrackletArray->GetEntriesFast();
1324 fTrackletTree->Fill();
1326 for (Int_t iTracklet = 0; iTracklet < fTrackletArray->GetEntriesFast(); iTracklet++) {
1327 new ((*fTracklets)[fTracklets->GetEntriesFast()]) AliTRDtrackletWord(*((AliTRDtrackletWord*)(*fTrackletArray)[iTracklet]));
1331 // loop over remaining tracklet endmarkers
1332 while ((*(fPayloadCurr) == fgkTrackletEndmarker &&
1333 fPayloadCurr - fPayloadStart < fPayloadSize))
1336 return fPayloadCurr - start;
1339 Int_t AliTRDrawStream::ReadHcHeader()
1341 // read and parse the HC header of one HC
1342 // and store the information in the corresponding variables
1344 AliDebug(1, Form("HC header: 0x%08x", *fPayloadCurr));
1345 UInt_t *start = fPayloadCurr;
1346 // check not to be at the data endmarker
1347 if (*fPayloadCurr == fgkDataEndmarker)
1350 fCurrSpecial = (*fPayloadCurr >> 31) & 0x1;
1351 fCurrMajor = (*fPayloadCurr >> 24) & 0x7f;
1352 fCurrMinor = (*fPayloadCurr >> 17) & 0x7f;
1353 fCurrAddHcWords = (*fPayloadCurr >> 14) & 0x7;
1354 fCurrSm = (*fPayloadCurr >> 9) & 0x1f;
1355 fCurrLayer = (*fPayloadCurr >> 6) & 0x7;
1356 fCurrStack = (*fPayloadCurr >> 3) & 0x7;
1357 fCurrSide = (*fPayloadCurr >> 2) & 0x1;
1358 fCurrCheck = (*fPayloadCurr) & 0x3;
1360 if ((fCurrSm != (((Int_t) fCurrEquipmentId) - kDDLOffset)) ||
1361 (fCurrStack != fCurrSlot) ||
1362 (fCurrLayer != fCurrLink / 2) ||
1363 (fCurrSide != fCurrLink % 2)) {
1364 LinkError(kHCmismatch,
1365 "HC: %i, %i, %i, %i\n 0x%08x 0x%08x 0x%08x 0x%08x",
1366 fCurrSm, fCurrStack, fCurrLayer, fCurrSide,
1367 fPayloadCurr[0], fPayloadCurr[1], fPayloadCurr[2], fPayloadCurr[3]);
1369 if (fCurrCheck != 0x1) {
1370 LinkError(kHCcheckFailed);
1373 if (fCurrAddHcWords > 0) {
1374 fCurrNtimebins = (fPayloadCurr[1] >> 26) & 0x3f;
1375 fCurrBC = (fPayloadCurr[1] >> 10) & 0xffff;
1376 fCurrPtrgCnt = (fPayloadCurr[1] >> 6) & 0xf;
1377 fCurrPtrgPhase = (fPayloadCurr[1] >> 2) & 0xf;
1380 fPayloadCurr += 1 + fCurrAddHcWords;
1382 return (fPayloadCurr - start);
1385 Int_t AliTRDrawStream::ReadTPData(Int_t mode)
1387 // testing of testpattern 1 to 3 (hardcoded), 0 missing
1388 // evcnt checking missing
1390 Int_t cpufromchannel[] = {0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3};
1394 Int_t mcmcount = -1;
1395 Int_t wordcount = 0;
1396 Int_t channelcount = 0;
1398 UInt_t expadcval = 0;
1400 Int_t lastmcmpos = -1;
1401 Int_t lastrobpos = -1;
1403 UInt_t* start = fPayloadCurr;
1405 while (*(fPayloadCurr) != fgkDataEndmarker &&
1406 fPayloadCurr - fPayloadStart < fPayloadSize - 1) {
1408 // ----- Checking MCM Header -----
1409 AliDebug(2, DumpMcmHeader("MCM header: ", *fPayloadCurr));
1410 UInt_t *startPosMCM = fPayloadCurr;
1413 // ----- checking for proper readout order - ROB -----
1414 fCurrRobPos = ROB(*fPayloadCurr);
1415 if (GetROBReadoutPos(ROB(*fPayloadCurr) / 2) >= lastrobpos) {
1416 if (GetROBReadoutPos(ROB(*fPayloadCurr) / 2) > lastrobpos)
1418 lastrobpos = GetROBReadoutPos(ROB(*fPayloadCurr) / 2);
1421 ROBError(kPosUnexp, Form("#%i after #%i in readout order", GetROBReadoutPos(ROB(*fPayloadCurr) / 2), lastrobpos));
1424 // ----- checking for proper readout order - MCM -----
1425 fCurrMcmPos = MCM(*fPayloadCurr);
1426 if (GetMCMReadoutPos(MCM(*fPayloadCurr)) > lastmcmpos) {
1427 lastmcmpos = GetMCMReadoutPos(MCM(*fPayloadCurr));
1430 MCMError(kPosUnexp, Form("#%i after #%i in readout order", GetMCMReadoutPos(MCM(*fPayloadCurr)), lastmcmpos));
1433 if (EvNo(*fPayloadCurr) != evno) {
1435 evno = EvNo(*fPayloadCurr);
1438 MCMError(kEvCntMismatch, "%i <-> %i", evno, EvNo(*fPayloadCurr));
1444 evcnt = 0x3f & *fPayloadCurr >> 26;
1447 while (channelcount < 21) {
1449 if (cpu != cpufromchannel[channelcount]) {
1450 cpu = cpufromchannel[channelcount];
1451 expadcval = (1 << 9) | (fCurrRobPos << 6) | (fCurrMcmPos << 2) | cpu;
1455 while (count < 10) {
1456 if (*fPayloadCurr == fgkDataEndmarker) {
1457 MCMError(kMissTpData);
1458 return (fPayloadCurr - start);
1461 if (channelcount % 2 == 0)
1468 expword |= expadcval << 2;
1469 expadcval = ( (expadcval << 1) | ( ( (expadcval >> 9) ^ (expadcval >> 6) ) & 1) ) & 0x3FF;
1470 expword |= expadcval << 12;
1471 expadcval = ( (expadcval << 1) | ( ( (expadcval >> 9) ^ (expadcval >> 6) ) & 1) ) & 0x3FF;
1472 expword |= expadcval << 22;
1473 expadcval = ( (expadcval << 1) | ( ( (expadcval >> 9) ^ (expadcval >> 6) ) & 1) ) & 0x3FF;
1475 else if (mode == 2) {
1476 // ----- TP 2 ------
1477 expword = ((0x3f & evcnt) << 26) | ((fCurrSm + 1) << 21) | ((fCurrLayer + 1) << 18) |
1478 ((fCurrStack + 1) << 15) |
1479 (fCurrRobPos << 12) | (fCurrMcmPos << 8) | (cpu << 6) | (wordcount + 1);
1481 else if (mode == 3) {
1483 expword = ((0xfff & evcnt) << 20) | (fCurrSm << 15) | (fCurrLink/2 << 12) | (fCurrStack << 9) |
1484 (fCurrRobPos << 6) | (fCurrMcmPos << 2) | (cpu << 0);
1488 LinkError(kTPmodeInvalid, "Just reading");
1491 diff = *fPayloadCurr ^ expword;
1492 AliDebug(11, Form("Comparing ch %2i, word %2i (cpu %i): 0x%08x <-> 0x%08x",
1493 channelcount, wordcount, cpu, *fPayloadCurr, expword));
1496 MCMError(kTPmismatch,
1497 "Seen 0x%08x, expected 0x%08x, diff: 0x%08x, 0x%04x, 0x%02x - word %2i (cpu %i, ch %i)",
1498 *fPayloadCurr, expword, diff,
1499 0xffff & (diff | diff >> 16),
1500 0xff & (diff | diff >> 8 | diff >> 16 | diff >> 24),
1501 wordcount, cpu, channelcount);;
1506 if (*fPayloadCurr == fgkDataEndmarker)
1507 return (fPayloadCurr - start);
1511 // continue with next MCM
1513 if (IsDumping() && DumpingMCM(fCurrHC/2, fCurrRobPos, fCurrMcmPos)) {
1514 AliInfo(DumpRaw(Form("Event %i: Det %3i ROB %i MCM %2i", fRawReader->GetEventIndex(), fCurrHC/2, fCurrRobPos, fCurrMcmPos),
1515 startPosMCM, fPayloadCurr - startPosMCM));
1519 return fPayloadCurr - start;
1523 Int_t AliTRDrawStream::ReadZSData()
1525 // read the zs data from one link from the current reading position
1527 UInt_t *start = fPayloadCurr;
1530 Int_t mcmcountExp = fCurrStack == 2 ? 48 : 64;
1531 Int_t channelcount = 0;
1532 Int_t channelcountExp = 0;
1533 Int_t channelcountMax = 0;
1535 Int_t currentTimebin = 0;
1538 Int_t lastmcmpos = -1;
1539 Int_t lastrobpos = -1;
1541 if (fCurrNtimebins != fNtimebins) {
1543 LinkError(kNtimebinsChanged,
1544 "No. of timebins changed from %i to %i", fNtimebins, fCurrNtimebins);
1545 fNtimebins = fCurrNtimebins;
1548 timebins = fNtimebins;
1550 while (*(fPayloadCurr) != fgkDataEndmarker &&
1551 fPayloadCurr - fPayloadStart < fPayloadSize) {
1553 // ----- Checking MCM Header -----
1554 AliDebug(2, DumpMcmHeader("MCM header: ", *fPayloadCurr));
1555 UInt_t *startPosMCM = fPayloadCurr;
1557 // ----- checking for proper readout order - ROB -----
1558 fCurrRobPos = ROB(*fPayloadCurr);
1559 if (GetROBReadoutPos(ROB(*fPayloadCurr) / 2) >= lastrobpos) {
1560 if (GetROBReadoutPos(ROB(*fPayloadCurr) / 2) > lastrobpos)
1562 lastrobpos = GetROBReadoutPos(ROB(*fPayloadCurr) / 2);
1565 ROBError(kPosUnexp, Form("#%i after #%i and #%i in readout order",
1566 GetROBReadoutPos(ROB(*fPayloadCurr) / 2), lastrobpos, GetROBReadoutPos(fCurrRobPos)));
1569 // ----- checking for proper readout order - MCM -----
1570 fCurrMcmPos = MCM(*fPayloadCurr);
1571 if (GetMCMReadoutPos(MCM(*fPayloadCurr)) > lastmcmpos) {
1572 lastmcmpos = GetMCMReadoutPos(MCM(*fPayloadCurr));
1575 MCMError(kPosUnexp, Form("#%i after #%i and #%i in readout order",
1576 GetMCMReadoutPos(MCM(*fPayloadCurr)), lastmcmpos, GetMCMReadoutPos(fCurrMcmPos)));
1579 if (EvNo(*fPayloadCurr) != evno) {
1581 evno = EvNo(*fPayloadCurr);
1583 MCMError(kEvCntMismatch, "%i <-> %i", evno, EvNo(*fPayloadCurr));
1586 Int_t adccoloff = AdcColOffset(*fPayloadCurr);
1587 Int_t padcoloff = PadColOffset(*fPayloadCurr);
1588 Int_t row = Row(*fPayloadCurr);
1591 if ((row > 11) && (fCurrStack == 2)) {
1592 MCMError(kUnknown, "Data in padrow > 11 for stack 2");
1595 // ----- Reading ADC channels -----
1596 AliDebug(2, DumpAdcMask("ADC mask: ", *fPayloadCurr));
1598 // ----- analysing the ADC mask -----
1600 channelcountExp = GetNActiveChannelsFromMask(*fPayloadCurr);
1601 channelcountMax = GetNActiveChannels(*fPayloadCurr);
1602 Int_t channelmask = GetActiveChannels(*fPayloadCurr);
1603 Int_t channelno = -1;
1606 if (channelcountExp != channelcountMax) {
1607 if (channelcountExp > channelcountMax) {
1608 Int_t temp = channelcountExp;
1609 channelcountExp = channelcountMax;
1610 channelcountMax = temp;
1612 while (channelcountExp < channelcountMax && channelcountExp < 21 &&
1613 fPayloadCurr - fPayloadStart < fPayloadSize - 10 * channelcountExp - 1) {
1614 MCMError(kAdcMaskInconsistent,
1615 "Possible MCM-H: 0x%08x, possible ADC-mask: 0x%08x",
1616 *(fPayloadCurr + 10 * channelcountExp),
1617 *(fPayloadCurr + 10 * channelcountExp + 1) );
1618 if (!CouldBeMCMhdr( *(fPayloadCurr + 10 * channelcountExp)) && !CouldBeADCmask( *(fPayloadCurr + 10 * channelcountExp + 1)))
1624 MCMError(kAdcMaskInconsistent,
1625 "Inconsistency in no. of active channels: Counter: %i, Mask: %i, chosen: %i!",
1626 GetNActiveChannels(fPayloadCurr[-1]), GetNActiveChannelsFromMask(fPayloadCurr[-1]), channelcountExp);
1628 AliDebug(2, Form("expecting %i active channels, %i timebins", channelcountExp, fCurrNtimebins));
1630 // ----- reading marked ADC channels -----
1631 while (channelcount < channelcountExp && *(fPayloadCurr) != fgkDataEndmarker) {
1634 while (channelno < 20 && (channelmask & 1 << channelno) == 0)
1637 if (fCurrNtimebins > 30) {
1638 currentTimebin = ((*fPayloadCurr >> 2) & 0x3f);
1639 timebins = ((*fPayloadCurr >> 8) & 0xf) * 3;
1646 Int_t nADCwords = (timebins + 2) / 3;
1647 AliDebug(3, Form("Now reading %i words for channel %2i", nADCwords, channelno));
1648 Int_t adccol = adccoloff - channelno;
1649 Int_t padcol = padcoloff - channelno;
1650 // if (adccol < 3 || adccol > 165)
1651 // AliInfo(Form("writing channel %i of det %3i %i:%2i to adcrow/-col: %i/%i padcol: %i",
1652 // channelno, fCurrHC/2, fCurrRobPos, fCurrMcmPos, row, adccol, padcol));
1654 while ((adcwc < nADCwords) &&
1655 (*(fPayloadCurr) != fgkDataEndmarker) &&
1656 (fPayloadCurr - fPayloadStart < fPayloadSize)) {
1657 int check = 0x3 & *fPayloadCurr;
1658 if (channelno % 2 != 0) { // odd channel
1659 if (check != 0x2 && channelno < 21) {
1660 MCMError(kAdcCheckInvalid,
1661 "%i for %2i. ADC word in odd channel %i",
1662 check, adcwc+1, channelno);
1665 else { // even channel
1666 if (check != 0x3 && channelno < 21) {
1667 MCMError(kAdcCheckInvalid,
1668 "%i for %2i. ADC word in even channel %i",
1669 check, adcwc+1, channelno);
1673 // filling the actual timebin data
1674 int tb2 = 0x3ff & *fPayloadCurr >> 22;
1675 int tb1 = 0x3ff & *fPayloadCurr >> 12;
1676 int tb0 = 0x3ff & *fPayloadCurr >> 2;
1677 if (adcwc != 0 || fCurrNtimebins <= 30)
1678 fAdcArray->SetDataByAdcCol(row, adccol, currentTimebin++, tb0);
1681 fAdcArray->SetDataByAdcCol(row, adccol, currentTimebin++, tb1);
1682 fAdcArray->SetDataByAdcCol(row, adccol, currentTimebin++, tb2);
1688 if (adcwc != nADCwords)
1689 MCMError(kAdcDataAbort);
1692 if (padcol > 0 && padcol < 144) {
1693 fSignalIndex->AddIndexRC(row, padcol);
1699 if (fCurrSm > -1 && fCurrSm < 18) {
1700 fStats.fStatsSector[fCurrSm].fStatsHC[fCurrHC%60].fNChannels += channelcount;
1701 fStats.fStatsSector[fCurrSm].fNChannels += channelcount;
1703 if (channelcount != channelcountExp)
1704 MCMError(kAdcChannelsMiss);
1707 if (fCurrSm > -1 && fCurrSm < 18) {
1708 fStats.fStatsSector[fCurrSm].fStatsHC[fCurrHC%60].fNMCMs++;
1709 fStats.fStatsSector[fCurrSm].fNMCMs++;
1712 if (IsDumping() && DumpingMCM(fCurrHC/2, fCurrRobPos, fCurrMcmPos)) {
1713 AliInfo(DumpRaw(Form("Event %i: Det %3i ROB %i MCM %2i", fRawReader->GetEventIndex(), fCurrHC/2, fCurrRobPos, fCurrMcmPos),
1714 startPosMCM, fPayloadCurr - startPosMCM));
1717 // continue with next MCM
1720 // check for missing MCMs (if header suppression is inactive)
1721 if (((fCurrMajor & 0x1) == 0) && (mcmcount != mcmcountExp)) {
1722 LinkError(kMissMcmHeaders,
1723 "No. of MCM headers %i not as expected: %i",
1724 mcmcount, mcmcountExp);
1727 return (fPayloadCurr - start);
1730 Int_t AliTRDrawStream::ReadNonZSData()
1732 // read the non-zs data from one link from the current reading position
1734 UInt_t *start = fPayloadCurr;
1737 Int_t mcmcountExp = fCurrStack == 2 ? 48 : 64;
1738 Int_t channelcount = 0;
1739 Int_t channelcountExp = 0;
1741 Int_t currentTimebin = 0;
1744 Int_t lastmcmpos = -1;
1745 Int_t lastrobpos = -1;
1747 if (fCurrNtimebins != fNtimebins) {
1749 LinkError(kNtimebinsChanged,
1750 "No. of timebins changed from %i to %i", fNtimebins, fCurrNtimebins);
1751 fNtimebins = fCurrNtimebins;
1754 timebins = fNtimebins;
1756 while (*(fPayloadCurr) != fgkDataEndmarker &&
1757 fPayloadCurr - fPayloadStart < fPayloadSize - 2) {
1759 // ----- Checking MCM Header -----
1760 AliDebug(2, Form("MCM header: 0x%08x", *fPayloadCurr));
1762 // ----- checking for proper readout order - ROB -----
1763 fCurrRobPos = ROB(*fPayloadCurr);
1764 if (GetROBReadoutPos(ROB(*fPayloadCurr) / 2) >= lastrobpos) {
1765 if (GetROBReadoutPos(ROB(*fPayloadCurr) / 2) > lastrobpos)
1767 lastrobpos = GetROBReadoutPos(ROB(*fPayloadCurr) / 2);
1770 ROBError(kPosUnexp, Form("#%i after #%i in readout order", GetROBReadoutPos(ROB(*fPayloadCurr) / 2), lastrobpos));
1773 // ----- checking for proper readout order - MCM -----
1774 fCurrMcmPos = MCM(*fPayloadCurr);
1775 if (GetMCMReadoutPos(MCM(*fPayloadCurr)) > lastmcmpos) {
1776 lastmcmpos = GetMCMReadoutPos(MCM(*fPayloadCurr));
1779 MCMError(kPosUnexp, Form("#%i after #%i in readout order", GetMCMReadoutPos(MCM(*fPayloadCurr)), lastmcmpos));
1782 if (EvNo(*fPayloadCurr) != evno) {
1784 evno = EvNo(*fPayloadCurr);
1786 MCMError(kEvCntMismatch, "%i <-> %i", evno, EvNo(*fPayloadCurr));
1791 channelcountExp = 21;
1794 Int_t adccoloff = AdcColOffset(*fPayloadCurr);
1795 Int_t padcoloff = PadColOffset(*fPayloadCurr);
1796 Int_t row = Row(*fPayloadCurr);
1800 // ----- reading marked ADC channels -----
1801 while (channelcount < channelcountExp &&
1802 *(fPayloadCurr) != fgkDataEndmarker) {
1809 Int_t nADCwords = (timebins + 2) / 3;
1810 AliDebug(2, Form("Now looking %i words", nADCwords));
1811 Int_t adccol = adccoloff - channelno;
1812 Int_t padcol = padcoloff - channelno;
1813 while ((adcwc < nADCwords) &&
1814 (*(fPayloadCurr) != fgkDataEndmarker) &&
1815 (fPayloadCurr - fPayloadStart < fPayloadSize)) {
1816 int check = 0x3 & *fPayloadCurr;
1817 if (channelno % 2 != 0) { // odd channel
1818 if (check != 0x2 && channelno < 21) {
1819 MCMError(kAdcCheckInvalid,
1820 "%i for %2i. ADC word in odd channel %i",
1821 check, adcwc+1, channelno);
1824 else { // even channel
1825 if (check != 0x3 && channelno < 21) {
1826 MCMError(kAdcCheckInvalid,
1827 "%i for %2i. ADC word in even channel %i",
1828 check, adcwc+1, channelno);
1832 // filling the actual timebin data
1833 int tb2 = 0x3ff & *fPayloadCurr >> 22;
1834 int tb1 = 0x3ff & *fPayloadCurr >> 12;
1835 int tb0 = 0x3ff & *fPayloadCurr >> 2;
1836 if (adcwc != 0 || fCurrNtimebins <= 30)
1837 fAdcArray->SetDataByAdcCol(row, adccol, currentTimebin++, tb0);
1840 fAdcArray->SetDataByAdcCol(row, adccol, currentTimebin++, tb1);
1841 fAdcArray->SetDataByAdcCol(row, adccol, currentTimebin++, tb2);
1847 if (adcwc != nADCwords)
1848 MCMError(kAdcDataAbort);
1851 if (padcol > 0 && padcol < 144) {
1852 fSignalIndex->AddIndexRC(row, padcol);
1858 if (channelcount != channelcountExp)
1859 MCMError(kAdcChannelsMiss);
1861 // continue with next MCM
1864 // check for missing MCMs (if header suppression is inactive)
1865 if (mcmcount != mcmcountExp) {
1866 LinkError(kMissMcmHeaders,
1867 "%i not as expected: %i", mcmcount, mcmcountExp);
1870 return (fPayloadCurr - start);
1873 Int_t AliTRDrawStream::SeekNextStack()
1875 // proceed in raw data stream till the next stack
1877 if (!fCurrStackEndmarkerAvail)
1880 UInt_t *start = fPayloadCurr;
1882 // read until data endmarkers
1883 while ((fPayloadCurr - fPayloadStart < fPayloadSize-1) &&
1884 ((fPayloadCurr[0] != fgkStackEndmarker[0]) ||
1885 (fPayloadCurr[1] != fgkStackEndmarker[1])))
1888 if ((fPayloadCurr - start) != 0)
1889 StackError(kUnknown, "skipped %i words to reach stack endmarker", fPayloadCurr - start);
1891 AliDebug(2, Form("stack endmarker: 0x%08x 0x%08x", fPayloadCurr[0], fPayloadCurr[1]));
1897 return (fPayloadCurr-start);
1900 Int_t AliTRDrawStream::SeekNextLink()
1902 // proceed in raw data stream till the next link
1904 UInt_t *start = fPayloadCurr;
1906 // read until data endmarkers
1907 while (fPayloadCurr - fPayloadStart < fPayloadSize &&
1908 *fPayloadCurr != fgkDataEndmarker)
1911 // read all data endmarkers
1912 while (fPayloadCurr - fPayloadStart < fPayloadSize &&
1913 *fPayloadCurr == fgkDataEndmarker)
1916 return (fPayloadCurr - start);
1919 Bool_t AliTRDrawStream::ConnectTracklets(TTree *trklTree)
1921 // connect the tracklet tree used to store the tracklet output
1923 fTrackletTree = trklTree;
1927 if (!fTrackletTree->GetBranch("hc"))
1928 fTrackletTree->Branch("hc", &fCurrHC, "hc/I");
1930 fTrackletTree->SetBranchAddress("hc", &fCurrHC);
1932 if (!fTrackletTree->GetBranch("trkl"))
1933 fTrackletTree->Branch("trkl", &fTrackletArray);
1935 fTrackletTree->SetBranchAddress("trkl", &fTrackletArray);
1941 void AliTRDrawStream::EquipmentError(ErrorCode_t err, const char *const msg, ...)
1943 // register error according to error code on equipment level
1944 // and return the corresponding error message
1946 fLastError.fSector = fCurrEquipmentId - kDDLOffset;
1947 fLastError.fStack = -1;
1948 fLastError.fLink = -1;
1949 fLastError.fRob = -1;
1950 fLastError.fMcm = -1;
1951 fLastError.fError = err;
1952 (this->*fStoreError)();
1955 if (fgErrorDebugLevel[err] > 10)
1956 AliDebug(fgErrorDebugLevel[err],
1957 Form("Event %6i: Eq. %2d - %s : %s",
1958 fRawReader->GetEventIndex(), fCurrEquipmentId, fgkErrorMessages[err],
1959 (va_start(ap, msg), vsprintf(fErrorBuffer, msg, ap), va_end(ap), fErrorBuffer) ));
1961 AliError(Form("Event %6i: Eq. %2d - %s : %s",
1962 fRawReader->GetEventIndex(), fCurrEquipmentId, fgkErrorMessages[err],
1963 (va_start(ap, msg), vsprintf(fErrorBuffer, msg, ap), va_end(ap), fErrorBuffer) ));
1964 fErrorFlags |= fgErrorBehav[err];
1968 void AliTRDrawStream::StackError(ErrorCode_t err, const char *const msg, ...)
1970 // register error according to error code on stack level
1971 // and return the corresponding error message
1973 fLastError.fSector = fCurrEquipmentId - kDDLOffset;
1974 fLastError.fStack = fCurrSlot;
1975 fLastError.fLink = -1;
1976 fLastError.fRob = -1;
1977 fLastError.fMcm = -1;
1978 fLastError.fError = err;
1979 (this->*fStoreError)();
1982 if (fgErrorDebugLevel[err] > 0)
1983 AliDebug(fgErrorDebugLevel[err],
1984 Form("Event %6i: Eq. %2d S %i - %s : %s",
1985 fRawReader->GetEventIndex(), fCurrEquipmentId, fCurrSlot, fgkErrorMessages[err],
1986 (va_start(ap, msg), vsprintf(fErrorBuffer, msg, ap), va_end(ap), fErrorBuffer) ));
1988 AliError(Form("Event %6i: Eq. %2d S %i - %s : %s",
1989 fRawReader->GetEventIndex(), fCurrEquipmentId, fCurrSlot, fgkErrorMessages[err],
1990 (va_start(ap, msg), vsprintf(fErrorBuffer, msg, ap), va_end(ap), fErrorBuffer) ));
1991 fErrorFlags |= fgErrorBehav[err];
1995 void AliTRDrawStream::LinkError(ErrorCode_t err, const char *const msg, ...)
1997 // register error according to error code on link level
1998 // and return the corresponding error message
2000 fLastError.fSector = fCurrEquipmentId - kDDLOffset;
2001 fLastError.fStack = fCurrSlot;
2002 fLastError.fLink = fCurrLink;
2003 fLastError.fRob = -1;
2004 fLastError.fMcm = -1;
2005 fLastError.fError = err;
2006 (this->*fStoreError)();
2009 if (fgErrorDebugLevel[err] > 0)
2010 AliDebug(fgErrorDebugLevel[err],
2011 Form("Event %6i: Eq. %2d S %i l %2i - %s : %s",
2012 fRawReader->GetEventIndex(), fCurrEquipmentId, fCurrSlot, fCurrLink, fgkErrorMessages[err],
2013 (va_start(ap, msg), vsprintf(fErrorBuffer, msg, ap), va_end(ap), fErrorBuffer) ));
2015 AliError(Form("Event %6i: Eq. %2d S %i l %2i - %s : %s",
2016 fRawReader->GetEventIndex(), fCurrEquipmentId, fCurrSlot, fCurrLink, fgkErrorMessages[err],
2017 (va_start(ap, msg), vsprintf(fErrorBuffer, msg, ap), va_end(ap), fErrorBuffer) ));
2018 fErrorFlags |= fgErrorBehav[err];
2022 void AliTRDrawStream::ROBError(ErrorCode_t err, const char *const msg, ...)
2024 // register error according to error code on ROB level
2025 // and return the corresponding error message
2027 fLastError.fSector = fCurrEquipmentId - kDDLOffset;
2028 fLastError.fStack = fCurrSlot;
2029 fLastError.fLink = fCurrLink;
2030 fLastError.fRob = fCurrRobPos;
2031 fLastError.fMcm = -1;
2032 fLastError.fError = err;
2033 (this->*fStoreError)();
2036 if (fgErrorDebugLevel[err] > 0)
2037 AliDebug(fgErrorDebugLevel[err],
2038 Form("Event %6i: Eq. %2d S %i l %2i ROB %i - %s : %s",
2039 fRawReader->GetEventIndex(), fCurrEquipmentId, fCurrSlot, fCurrLink, fCurrRobPos, fgkErrorMessages[err],
2040 (va_start(ap, msg), vsprintf(fErrorBuffer, msg, ap), va_end(ap), fErrorBuffer) ));
2042 AliError(Form("Event %6i: Eq. %2d S %i l %2i ROB %i - %s : %s",
2043 fRawReader->GetEventIndex(), fCurrEquipmentId, fCurrSlot, fCurrLink, fCurrRobPos, fgkErrorMessages[err],
2044 (va_start(ap, msg), vsprintf(fErrorBuffer, msg, ap), va_end(ap), fErrorBuffer) ));
2045 fErrorFlags |= fgErrorBehav[err];
2049 void AliTRDrawStream::MCMError(ErrorCode_t err, const char *const msg, ...)
2051 // register error according to error code on MCM level
2052 // and return the corresponding error message
2054 fLastError.fSector = fCurrEquipmentId - kDDLOffset;
2055 fLastError.fStack = fCurrSlot;
2056 fLastError.fLink = fCurrLink;
2057 fLastError.fRob = fCurrRobPos;
2058 fLastError.fMcm = fCurrMcmPos;
2059 fLastError.fError = err;
2060 (this->*fStoreError)();
2063 if (fgErrorDebugLevel[err] > 0)
2064 AliDebug(fgErrorDebugLevel[err],
2065 Form("Event %6i: Eq. %2d S %i l %2i ROB %i MCM %2i - %s : %s",
2066 fRawReader->GetEventIndex(), fCurrEquipmentId, fCurrSlot, fCurrLink, fCurrRobPos, fCurrMcmPos, fgkErrorMessages[err],
2067 (va_start(ap, msg), vsprintf(fErrorBuffer, msg, ap), va_end(ap), fErrorBuffer) ));
2069 AliError(Form("Event %6i: Eq. %2d S %i l %2i ROB %i MCM %2i - %s : %s",
2070 fRawReader->GetEventIndex(), fCurrEquipmentId, fCurrSlot, fCurrLink, fCurrRobPos, fCurrMcmPos, fgkErrorMessages[err],
2071 (va_start(ap, msg), vsprintf(fErrorBuffer, msg, ap), va_end(ap), fErrorBuffer) ));
2072 fErrorFlags |= fgErrorBehav[err];
2075 const char* AliTRDrawStream::GetErrorMessage(ErrorCode_t errCode)
2077 // return the error message for the given error code
2079 if (errCode > 0 && errCode < kLastErrorCode)
2080 return fgkErrorMessages[errCode];
2085 void AliTRDrawStream::AliTRDrawStats::ClearStats()
2087 // clear statistics (includes clearing sector-wise statistics)
2090 for (Int_t iSector = 0; iSector < 18; iSector++) {
2091 fStatsSector[iSector].ClearStats();
2096 void AliTRDrawStream::AliTRDrawStats::AliTRDrawStatsSector::ClearStats()
2098 // clear statistics (includes clearing HC-wise statistics)
2106 for (Int_t iHC = 0; iHC < 60; iHC++) {
2107 fStatsHC[iHC].ClearStats();
2111 void AliTRDrawStream::AliTRDrawStats::AliTRDrawStatsSector::AliTRDrawStatsHC::ClearStats()
2122 void AliTRDrawStream::SetDumpMCM(Int_t det, Int_t rob, Int_t mcm, Bool_t dump)
2124 // mark MCM for dumping of raw data
2127 fDumpMCM[fNDumpMCMs++] = (det << 7) | (rob << 4) | mcm;
2131 for (iMCM = 0; iMCM < fNDumpMCMs; iMCM++) {
2132 if (fDumpMCM[iMCM] == ((det << 7) | (rob << 4) | mcm)) {
2137 for ( ; iMCM < fNDumpMCMs; iMCM++) {
2138 fDumpMCM[iMCM] = fDumpMCM[iMCM+1];
2143 Bool_t AliTRDrawStream::DumpingMCM(Int_t det, Int_t rob, Int_t mcm) const
2145 // check if MCM data should be dumped
2147 for (Int_t iMCM = 0; iMCM < fNDumpMCMs; iMCM++) {
2148 if (fDumpMCM[iMCM] == ((det << 7) | (rob << 4) | mcm)) {
2155 TString AliTRDrawStream::DumpRaw(TString title, UInt_t *start, Int_t length, UInt_t endmarker)
2160 for (Int_t pos = 0; pos < length; pos += 4) {
2161 if ((start[pos+0] != endmarker) && pos+0 < length)
2162 if ((start[pos+1] != endmarker && pos+1 < length))
2163 if ((start[pos+2] != endmarker && pos+2 < length))
2164 if ((start[pos+3] != endmarker && pos+3 < length))
2165 title += Form(" 0x%08x 0x%08x 0x%08x 0x%08x\n",
2166 start[pos+0], start[pos+1], start[pos+2], start[pos+3]);
2168 title += Form(" 0x%08x 0x%08x 0x%08x 0x%08x\n",
2169 start[pos+0], start[pos+1], start[pos+2], start[pos+3]);
2173 title += Form(" 0x%08x 0x%08x 0x%08x\n",
2174 start[pos+0], start[pos+1], start[pos+2]);
2178 title += Form(" 0x%08x 0x%08x\n",
2179 start[pos+0], start[pos+1]);
2183 title += Form(" 0x%08x\n",
2191 TString AliTRDrawStream::DumpMcmHeader(TString title, UInt_t word)
2193 title += Form("0x%08x -> ROB: %i, MCM: %2i",
2194 word, ROB(word), MCM(word));
2198 TString AliTRDrawStream::DumpAdcMask(TString title, UInt_t word)
2200 title += Form("0x%08x -> #ch : %2i, 0x%06x (%2i ch)",
2201 word, GetNActiveChannels(word), GetActiveChannels(word), GetNActiveChannelsFromMask(word));
2205 AliTRDrawStream::AliTRDrawStreamError::AliTRDrawStreamError(Int_t error, Int_t sector, Int_t stack, Int_t link, Int_t rob, Int_t mcm) :
2217 void AliTRDrawStream::SortTracklets(TClonesArray *trklArray, TList &sortedTracklets, Int_t *indices)
2219 // sort tracklets for referencing from GTU tracks
2221 Int_t nTracklets = trklArray->GetEntriesFast();
2224 for (Int_t iTracklet = 0; iTracklet < nTracklets; iTracklet++) {
2225 AliTRDtrackletBase *trkl = (AliTRDtrackletBase*) ((*trklArray)[iTracklet]);
2226 Int_t hc = trkl->GetHCId();
2227 if ((hc < 0) || (hc >= 1080)) {
2228 AliErrorClass(Form("HC for tracklet: 0x%08x out of range: %i", trkl->GetTrackletWord(), trkl->GetHCId()));
2231 AliDebugClass(5, Form("hc: %4i : 0x%08x z: %2i", hc, trkl->GetTrackletWord(), trkl->GetZbin()));
2233 AliDebugClass(2, Form("set tracklet index for HC %i to %i", hc, iTracklet));
2234 indices[hc] = iTracklet + 1;
2239 for (Int_t iDet = 0; iDet < 540; iDet++) {
2240 Int_t trklIndexA = indices[2*iDet + 0] - 1;
2241 Int_t trklIndexB = indices[2*iDet + 1] - 1;
2242 Int_t trklIndex = sortedTracklets.GetEntries();
2243 AliTRDtrackletBase *trklA = trklIndexA > -1 ? (AliTRDtrackletBase*) ((*trklArray)[trklIndexA]) : 0x0;
2244 AliTRDtrackletBase *trklB = trklIndexB > -1 ? (AliTRDtrackletBase*) ((*trklArray)[trklIndexB]) : 0x0;
2245 AliTRDtrackletBase *trklNext = 0x0;
2246 while (trklA != 0x0 || trklB != 0x0) {
2247 AliDebugClass(5, Form("det %i - A: %i/%i -> %p, B: %i/%i -> %p",
2248 iDet, trklIndexA, nTracklets, trklA, trklIndexB, nTracklets, trklB));
2252 trklB = trklIndexB < nTracklets ? (AliTRDtrackletBase*) ((*trklArray)[trklIndexB]) : 0x0;
2253 if (trklB && trklB->GetHCId() != 2*iDet + 1)
2256 else if (trklB == 0x0) {
2259 trklA = trklIndexA < nTracklets ? (AliTRDtrackletBase*) ((*trklArray)[trklIndexA]) : 0x0;
2260 if (trklA && trklA->GetHCId() != 2*iDet)
2264 if ((trklA->GetZbin() < trklB->GetZbin()) ||
2265 ((trklA->GetZbin() == trklB->GetZbin()) && (trklA->GetYbin() < trklB->GetYbin()))) {
2268 trklA = trklIndexA < nTracklets ? (AliTRDtrackletBase*) ((*trklArray)[trklIndexA]) : 0x0;
2269 if (trklA && trklA->GetHCId() != 2*iDet)
2275 trklB = trklIndexB < nTracklets ? (AliTRDtrackletBase*) ((*trklArray)[trklIndexB]) : 0x0;
2276 if (trklB && trklB->GetHCId() != 2*iDet + 1)
2281 Int_t label = -2; // mark raw tracklets with label -2
2282 if (AliTRDtrackletMCM *trklMCM = dynamic_cast<AliTRDtrackletMCM*> (trklNext))
2283 label = trklMCM->GetLabel();
2284 AliESDTrdTracklet *esdTracklet = new AliESDTrdTracklet(trklNext->GetTrackletWord(), trklNext->GetHCId(), label);
2285 sortedTracklets.Add(esdTracklet);
2288 // updating tracklet indices as in output
2289 if (sortedTracklets.GetEntries() != trklIndex) {
2290 indices[2*iDet + 0] = indices[2*iDet + 1] = trklIndex;
2293 indices[2*iDet + 0] = indices[2*iDet + 1] = -1;