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 "AliESDTrdTrack.h"
41 #include "AliTreeLoader.h"
43 #include "AliTRDrawStream.h"
46 #include "AliRunLoader.h"
48 ClassImp(AliTRDrawStream)
50 // some static information
51 Int_t AliTRDrawStream::fgMcmOrder[] = {12, 13, 14, 15,
55 Int_t AliTRDrawStream::fgRobOrder [] = {0, 1, 2, 3};
56 const Int_t AliTRDrawStream::fgkNlinks = 12;
57 const Int_t AliTRDrawStream::fgkNstacks = 5;
58 const Int_t AliTRDrawStream::fgkNsectors = 18;
59 const Int_t AliTRDrawStream::fgkNtriggers = 12;
60 const UInt_t AliTRDrawStream::fgkDataEndmarker = 0x00000000;
61 const UInt_t AliTRDrawStream::fgkTrackletEndmarker = 0x10001000;
63 const char* AliTRDrawStream::fgkErrorMessages[] = {
65 "Link monitor active",
66 "Pretrigger counter mismatch",
67 "not a TRD equipment (1024-1041)",
68 "Invalid Stack header",
69 "Invalid detector number",
70 "No digits could be retrieved from the digitsmanager",
72 "HC check bits wrong",
73 "Unexpected position in readout stream",
74 "Invalid testpattern mode",
75 "Testpattern mismatch",
76 "Number of timebins changed",
77 "ADC mask inconsistent",
78 "ADC check bits invalid",
80 "Missing expected ADC channels",
84 Int_t AliTRDrawStream::fgErrorDebugLevel[] = {
105 AliTRDrawStream::ErrorBehav_t AliTRDrawStream::fgErrorBehav[] = {
106 AliTRDrawStream::kTolerate,
107 AliTRDrawStream::kDiscardHC,
108 AliTRDrawStream::kTolerate,
109 AliTRDrawStream::kAbort,
110 AliTRDrawStream::kAbort,
111 AliTRDrawStream::kAbort,
112 AliTRDrawStream::kAbort,
113 AliTRDrawStream::kDiscardHC,
114 AliTRDrawStream::kDiscardHC,
115 AliTRDrawStream::kTolerate,
116 AliTRDrawStream::kTolerate,
117 AliTRDrawStream::kTolerate,
118 AliTRDrawStream::kTolerate,
119 AliTRDrawStream::kTolerate,
120 AliTRDrawStream::kTolerate,
121 AliTRDrawStream::kTolerate,
122 AliTRDrawStream::kTolerate,
123 AliTRDrawStream::kTolerate
126 AliTRDrawStream::AliTRDrawStream(AliRawReader *rawReader) :
128 fStoreError(&AliTRDrawStream::ForgetError),
129 fRawReader(rawReader),
145 fCurrSmHeaderSize(0),
146 fCurrSmHeaderVersion(0),
147 fCurrTrailerReadout(0),
148 fCurrTrgHeaderAvail(0),
149 fCurrTrgHeaderReadout(0),
150 fCurrTrkHeaderAvail(0),
152 fCurrTriggerEnable(0),
153 fCurrTriggerFired(0),
155 fCurrTrackletEnable(0),
157 fCurrTrkHeaderIndexWord(0x0),
158 fCurrTrkHeaderSize(0x0),
159 fCurrTrgHeaderIndexWord(0x0),
160 fCurrTrgHeaderSize(0x0),
161 fCurrStackIndexWord(0x0),
162 fCurrStackHeaderSize(0x0),
163 fCurrStackHeaderVersion(0x0),
165 fCurrCleanCheckout(0x0),
169 fCurrLinkMonitorFlags(0x0),
170 fCurrLinkDataTypeFlags(0x0),
171 fCurrLinkDebugFlags(0x0),
195 // default constructor
197 fCurrTrkHeaderIndexWord = new UInt_t[fgkNstacks];
198 fCurrTrkHeaderSize = new UInt_t[fgkNstacks];
199 fCurrTrgHeaderIndexWord = new UInt_t[fgkNtriggers];
200 fCurrTrgHeaderSize = new UInt_t[fgkNtriggers];
201 fCurrStackIndexWord = new UInt_t[fgkNstacks];
202 fCurrStackHeaderSize = new UInt_t[fgkNstacks];
203 fCurrStackHeaderVersion = new UInt_t[fgkNstacks];
204 fCurrLinkMask = new UInt_t[fgkNstacks];
205 fCurrCleanCheckout = new UInt_t[fgkNstacks];
206 fCurrBoardId = new UInt_t[fgkNstacks];
207 fCurrHwRevTMU = new UInt_t[fgkNstacks];
208 fCurrLinkMonitorFlags = new UInt_t[fgkNstacks * fgkNlinks];
209 fCurrLinkDataTypeFlags = new UInt_t[fgkNstacks * fgkNlinks];
210 fCurrLinkDebugFlags = new UInt_t[fgkNstacks * fgkNlinks];
211 for (Int_t i = 0; i < 100; i++)
214 // preparing TClonesArray
215 fTrackletArray = new TClonesArray("AliTRDtrackletWord", 256);
217 // setting up the error tree
218 fErrors = new TTree("errorStats", "Error statistics");
219 fErrors->SetDirectory(0x0);
220 fErrors->Branch("error", &fLastError);
221 fErrors->SetCircular(1000);
222 for (Int_t i = 0; i < 100; i++) {
228 AliTRDrawStream::~AliTRDrawStream()
234 delete [] fCurrTrkHeaderIndexWord;
235 delete [] fCurrTrkHeaderSize;
236 delete [] fCurrTrgHeaderIndexWord;
237 delete [] fCurrTrgHeaderSize;
238 delete [] fCurrStackIndexWord;
239 delete [] fCurrStackHeaderSize;
240 delete [] fCurrStackHeaderVersion;
241 delete [] fCurrLinkMask;
242 delete [] fCurrCleanCheckout;
243 delete [] fCurrBoardId;
244 delete [] fCurrHwRevTMU;
245 delete [] fCurrLinkMonitorFlags;
246 delete [] fCurrLinkDataTypeFlags;
247 delete [] fCurrLinkDebugFlags;
250 Bool_t AliTRDrawStream::ReadEvent(TTree *trackletTree)
252 // read the current event from the raw reader and fill it to the digits manager
255 AliError("No raw reader available");
260 ConnectTracklets(trackletTree);
265 // loop over all DDLs
266 // data starts with GTU payload, i.e. SM index word
267 UChar_t *buffer = 0x0;
269 while (fRawReader->ReadNextData(buffer)) {
271 fCurrEquipmentId = fRawReader->GetEquipmentId();
272 AliDebug(2, Form("equipment: %i", fCurrEquipmentId));
274 if (fCurrEquipmentId < kDDLOffset || fCurrEquipmentId > kDDLMax) {
275 EquipmentError(kNonTrdEq, "Skipping");
280 new ((*fMarkers)[fMarkers->GetEntriesFast()])
281 AliTRDrawStreamError(-kSecactive, fCurrEquipmentId - kDDLOffset);
283 ReadGTUHeaders((UInt_t*) buffer);
285 if (fCurrTrailerReadout)
288 // loop over all active links
289 AliDebug(2, Form("Stack mask 0x%02x", fCurrStackMask));
290 for (Int_t iStack = 0; iStack < fgkNstacks; iStack++) {
292 if ((fCurrStackMask & (1 << fCurrSlot)) == 0)
295 AliDebug(2, Form("Stack %i, Link mask: 0x%02x", fCurrSlot, fCurrLinkMask[fCurrSlot]));
296 for (Int_t iLink = 0; iLink < fgkNlinks; iLink++) {
298 fCurrHC = (fCurrEquipmentId - kDDLOffset) * fgkNstacks * fgkNlinks +
299 fCurrSlot * fgkNlinks + iLink;
300 if ((fCurrLinkMask[fCurrSlot] & (1 << fCurrLink)) == 0)
304 // check for link monitor error flag
305 if (fCurrLinkMonitorFlags[fCurrSlot*fgkNlinks + fCurrLink] != 0)
306 LinkError(kLinkMonitor);
308 // read the data from one HC
311 // read all data endmarkers
321 Bool_t AliTRDrawStream::NextDDL()
323 // continue reading with the next equipment
328 fCurrEquipmentId = 0;
332 UChar_t *buffer = 0x0;
334 while (fRawReader->ReadNextData(buffer)) {
336 fCurrEquipmentId = fRawReader->GetEquipmentId();
337 AliDebug(2, Form("equipment: %i", fCurrEquipmentId));
339 if (fCurrEquipmentId < kDDLOffset || fCurrEquipmentId > kDDLMax) {
340 EquipmentError(kNonTrdEq, "Skipping");
345 new ((*fMarkers)[fMarkers->GetEntriesFast()])
346 AliTRDrawStreamError(-kSecactive, fCurrEquipmentId - kDDLOffset);
348 ReadGTUHeaders((UInt_t*) buffer);
350 if (fCurrTrailerReadout)
360 Int_t AliTRDrawStream::NextChamber(AliTRDdigitsManager *digMgr)
362 // read the data for the next chamber
363 // in case you only want to read the data of a single chamber
364 // to read all data ReadEvent(...) is recommended
366 fDigitsManager = digMgr;
371 // tracklet output preparation
372 TTree *trklTree = 0x0;
373 AliRunLoader *rl = AliRunLoader::Instance();
374 AliLoader* trdLoader = rl ? rl->GetLoader("TRDLoader") : NULL;
375 AliDataLoader *trklLoader = trdLoader ? trdLoader->GetDataLoader("tracklets") : NULL;
377 AliTreeLoader *trklTreeLoader = (AliTreeLoader*) trklLoader->GetBaseLoader("tracklets-raw");
379 trklTree = trklTreeLoader->Tree();
381 trklTree = trklLoader->Tree();
384 if (fTrackletTree != trklTree)
385 ConnectTracklets(trklTree);
388 AliError("No raw reader available");
392 while (fCurrSlot < 0 || fCurrSlot >= fgkNstacks) {
397 while ((fCurrSlot < fgkNstacks) &&
398 (((fCurrStackMask & (1 << fCurrSlot)) == 0) ||
399 ((fCurrLinkMask[fCurrSlot] & (1 << fCurrLink))) == 0)) {
401 if (fCurrLink >= fgkNlinks) {
408 AliDebug(2, Form("Stack %i, Link %i, mask: 0x%02x", fCurrSlot, fCurrLink, fCurrLinkMask[fCurrSlot]));
409 fCurrHC = (fCurrEquipmentId - kDDLOffset) * fgkNlinks * fgkNstacks +
410 fCurrSlot * fgkNlinks + fCurrLink;
412 if (fCurrLinkMonitorFlags[fCurrSlot*fgkNlinks + fCurrLink] != 0)
413 LinkError(kLinkMonitor);
415 // read the data from one HC
418 // read all data endmarkers
421 if (fCurrLink % 2 == 0) {
422 // if we just read the A-side HC then also check the B-side
425 if (fCurrLinkMask[fCurrSlot] & (1 << fCurrLink)) {
434 if (fCurrLink >= fgkNlinks) {
438 } while ((fCurrSlot < fgkNstacks) &&
439 (((fCurrStackMask & (1 << fCurrSlot)) == 0) ||
440 ((fCurrLinkMask[fCurrSlot] & (1 << fCurrLink))) == 0));
442 // return chamber information from HC if it is valid
443 // otherwise return information from link position
444 if (fCurrSm < 0 || fCurrSm >= fgkNsectors || fCurrStack < 0 || fCurrStack >= fgkNstacks || fCurrLayer < 0 || fCurrLayer >= fgkNlinks/2)
445 return ((fCurrEquipmentId-kDDLOffset) + fCurrSlot * fgkNlinks/2 + fCurrLink/2);
447 return (fCurrSm * fgkNstacks*fgkNlinks/2 + fCurrStack * fgkNlinks/2 + fCurrLayer);
451 Int_t AliTRDrawStream::ReadGTUHeaders(UInt_t *buffer)
453 // check the data source and read the headers
455 if (fCurrEquipmentId >= kDDLOffset && fCurrEquipmentId <= kDDLMax) {
458 // setting the pointer to data and current reading position
459 fPayloadCurr = fPayloadStart = buffer;
460 fPayloadSize = fRawReader->GetDataSize() / sizeof(UInt_t);
461 fStats.fStatsSector[fCurrEquipmentId - kDDLOffset].fBytes = fRawReader->GetDataSize();
462 AliDebug(2, Form("Read buffer of size: %i", fRawReader->GetDataSize()));
464 AliDebug(1, DumpRaw("raw data", fPayloadCurr, TMath::Min(fPayloadSize, 1000)));
467 if (ReadSmHeader() < 0) {
468 AliError(Form("Reading SM header failed, skipping this DDL %i", fCurrEquipmentId));
472 // read tracking headers (if available)
473 if (fCurrTrkHeaderAvail) {
474 for (Int_t iStack = 0; iStack < fgkNstacks; iStack++) {
475 if ((fCurrStackMask & (1 << iStack)) != 0)
476 ReadTrackingHeader(iStack);
480 // read trigger header(s) (if available)
481 if (fCurrTrgHeaderAvail)
482 ReadTriggerHeaders();
485 for (Int_t iStack = 0; iStack < fgkNstacks; iStack++) {
486 if ((fCurrStackMask & (1 << iStack)) != 0)
487 ReadStackHeader(iStack);
496 Int_t AliTRDrawStream::ReadSmHeader()
498 // read the SMU index header at the current reading position
499 // and store the information in the corresponding variables
501 if (fPayloadCurr - fPayloadStart >= fPayloadSize - 1) {
502 EquipmentError(kUnknown, "SM Header incomplete");
506 fCurrSmHeaderSize = ((*fPayloadCurr) >> 16) & 0xffff;
507 fCurrSmHeaderVersion = ((*fPayloadCurr) >> 12) & 0xf;
508 fCurrTrackEnable = ((*fPayloadCurr) >> 6) & 0x1;
509 fCurrTrackletEnable = ((*fPayloadCurr) >> 5) & 0x1;
510 fCurrStackMask = ((*fPayloadCurr) ) & 0x1f;
511 fCurrHwRev = (fPayloadCurr[1] >> 12) & 0xffff;
513 switch (fCurrSmHeaderVersion) {
515 fCurrTrailerReadout = 0;
516 fCurrTrgHeaderAvail = 0;
518 fCurrTrkHeaderAvail = 0;
524 fCurrTrailerReadout = ((*fPayloadCurr) >> 10) & 0x1;
525 fCurrTrgHeaderAvail = 1;
526 fCurrTrgHeaderReadout = ((*fPayloadCurr) >> 9) & 0x1;
527 fCurrEvType = ((*fPayloadCurr) >> 7) & 0x3;
528 fCurrTrkHeaderAvail = fCurrTrackEnable;
529 fCurrTriggerEnable = (fPayloadCurr[2] >> 8) & 0xfff;
530 fCurrTriggerFired = (fPayloadCurr[2] >> 20) & 0xfff;
534 AliError(Form("unknown SM header version: 0x%x", fCurrSmHeaderVersion));
537 AliDebug(5, Form("SM header: size: %i, version: %i, track enable: %i, tracklet enable: %i, stack mask: %2x, trailer: %i, trgheader: %i, trkheader: %i",
539 fCurrSmHeaderVersion,
545 fCurrTrkHeaderAvail ));
547 // jump to the first word after the SM header
548 fPayloadCurr += fCurrSmHeaderSize + 1;
550 return fCurrSmHeaderSize + 1;
553 Int_t AliTRDrawStream::DecodeGTUtracks()
555 // decode GTU track words
556 // this depends on the hardware revision of the SMU
558 AliDebug(1, DumpRaw(Form("GTU tracks (hw rev %i)", fCurrHwRev),
559 fPayloadCurr + 4, 10, 0xffe0ffff));
561 if (fCurrHwRev < 1772) {
562 UInt_t trackWord[2] = { 0, 0 };
565 for (UInt_t iWord = 4; iWord < fCurrSmHeaderSize; iWord++) {
566 if (fPayloadCurr[iWord] == 0x10000000) {
572 ((fPayloadCurr[iWord] & 0xfffff0f0) == 0x13370000)) {
573 AliDebug(1, Form("stack %i: fast trigger word: 0x%08x", stack, fPayloadCurr[iWord]));
576 else if ((idx & 0x1) == 0x1) {
577 trackWord[1] = fPayloadCurr[iWord];
578 AliDebug(1,Form("track debug word: 0x%08x%08x", trackWord[1], trackWord[0]));
580 // new ((*fTracks)[fTracks->GetEntriesFast()]) AliESDTrdTrack(0, 0, trackWord[0], trackWord[1], fCurrEquipmentId-kDDLOffset);
583 trackWord[0] = fPayloadCurr[iWord];
589 else if (fCurrHwRev < 1804) {
590 UInt_t trackWord[2] = { 0, 0 };
593 for (UInt_t iWord = 4; iWord < fCurrSmHeaderSize; iWord++) {
594 if (fPayloadCurr[iWord] == 0xffe0ffff) {
600 ((fPayloadCurr[iWord] & 0xfffff0f0) == 0x13370000)) {
601 AliDebug(1, Form("stack %i: fast trigger word: 0x%08x", stack, fPayloadCurr[iWord]));
604 else if ((idx & 0x1) == 0x1) {
605 trackWord[1] = fPayloadCurr[iWord];
606 AliDebug(1, Form("track debug word: 0x%08x%08x", trackWord[1], trackWord[0]));
607 Float_t pt = (trackWord[0] & 0x8000) ? -1. * ((~(trackWord[0] & 0xffff)&0xffff) + 1)/128. : (trackWord[0] & 0xffff)/128.;
608 AliDebug(1, Form("pt = %f", pt));
610 // AliESDTrdTrack *trk = new ((*fTracks)[fTracks->GetEntriesFast()]) AliESDTrdTrack(0, 0, trackWord[0], trackWord[1], fCurrEquipmentId-kDDLOffset);
611 // if (TMath::Abs(pt) > 0.1) {
612 // trk->SetA((Int_t) (0.15*51625./100./pt / 160e-4 * 2));
614 // trk->SetStack((trackWord[1] >> 28) & 0x7);
618 trackWord[0] = fPayloadCurr[iWord];
624 else if (fCurrHwRev < 1819) {
628 for (UInt_t iWord = 4; iWord < fCurrSmHeaderSize; iWord++) {
629 if (fPayloadCurr[iWord] == 0xffe0ffff) {
635 ((fPayloadCurr[iWord] & 0xfffff0f0) == 0x13370000)) {
636 AliDebug(1, Form("stack %i: fast trigger word: 0x%08x", stack, fPayloadCurr[iWord]));
639 else if ((idx & 0x1) == 0x1) {
640 trackWord[idx&0x1] = fPayloadCurr[iWord];
641 AliDebug(1, Form("track debug word: 0x%08x%08x", trackWord[1], trackWord[0]));
642 printf("%4i %2i %i ",
643 fRawReader->GetEventIndex(),
644 fCurrEquipmentId-kDDLOffset, (trackWord[1] >> 28) & 0x7);
645 Float_t pt = (trackWord[0] & 0x8000) ? -1. * ((~(trackWord[0] & 0xffff)&0xffff) + 1)/128. : (trackWord[0] & 0xffff)/128.;
646 printf("%+7.2f ", pt);
647 printf("%i%i%i%i%i%i ", ((trackWord[0] >> 21) & 0x1),
648 ((trackWord[0] >> 20) & 0x1),
649 ((trackWord[0] >> 19) & 0x1),
650 ((trackWord[0] >> 18) & 0x1),
651 ((trackWord[0] >> 17) & 0x1),
652 ((trackWord[0] >> 16) & 0x1));
653 printf("0x%08x%08x\n", trackWord[1], trackWord[0]);
655 // AliESDTrdTrack *trk = new ((*fTracks)[fTracks->GetEntriesFast()]) AliESDTrdTrack(0, 0, trackWord[0], trackWord[1], fCurrEquipmentId-kDDLOffset);
656 // if (TMath::Abs(pt) > 0.1) {
657 // trk->SetA((Int_t) (0.15*51625./100./pt / 160e-4 * 2));
659 // trk->SetStack((trackWord[1] >> 28) & 0x7);
663 trackWord[idx&0x1] = fPayloadCurr[iWord];
669 else if (fCurrHwRev < 1860) {
670 AliError(Form("unsupported hardware rev %i", fCurrHwRev));
673 UInt_t trackWord[2] = { 0, 0 };
676 Bool_t upperWord = kFALSE;
678 for (UInt_t iWord = 4; iWord < fCurrSmHeaderSize; iWord++) {
679 if (fPayloadCurr[iWord] == 0xffe0ffff) {
685 // assemble the 32-bit words out of 16-bit blocks
687 word |= (fPayloadCurr[iWord] & 0xffff0000);
691 // lower word is read first
692 word = (fPayloadCurr[iWord] & 0xffff0000) >> 16;
697 if ((word & 0xffff0008) == 0x13370008) {
698 AliDebug(1, Form("stack %i: fast track word: 0x%08x", stack, word));
701 else if ((word & 0xffff0010) == 0x13370010) {
702 AliDebug(1, Form("stack %i: tracking done word: 0x%08x", stack, word));
705 else if ((idx & 0x1) == 0x1) {
707 AliDebug(1, Form("track debug word: 0x%08x%08x", trackWord[1], trackWord[0]));
709 // AliESDTrdTrack *trk = new ((*fTracks)[fTracks->GetEntriesFast()]) AliESDTrdTrack(0, 0, trackWord[0], trackWord[1], fCurrEquipmentId-kDDLOffset);
710 // if (TMath::Abs(trk->GetPt()) > 0.1) {
711 // trk->SetA((Int_t) (0.15*51625./100./trk->GetPt() / 160e-4 * 2));
713 // trk->SetStack((trackWord[1] >> 28) & 0x7);
726 Int_t AliTRDrawStream::ReadTrackingHeader(Int_t stack)
728 // read the tracking information and store it for the given stack
732 fCurrTrkHeaderIndexWord[stack] = *fPayloadCurr;
733 fCurrTrkHeaderSize[stack] = ((*fPayloadCurr) >> 16) & 0x3ff;
736 AliDebug(1, Form("tracking header index word: 0x%08x, size: %i\n",
737 fCurrTrkHeaderIndexWord[stack], fCurrTrkHeaderSize[stack]));
740 UInt_t trackWord[2] = { 0, 0 };
742 Bool_t upperWord = kFALSE;
744 for (UInt_t iWord = 0; iWord < fCurrTrkHeaderSize[stack]; iWord++) {
745 // assemble the 32-bit words out of 16-bit blocks
747 word |= (fPayloadCurr[iWord] & 0xffff0000);
751 // lower word is read first
752 word = (fPayloadCurr[iWord] & 0xffff0000) >> 16;
757 if ((word & 0xffff0008) == 0x13370008) {
758 AliDebug(1, Form("stack %i: fast track word: 0x%08x", stack, word));
761 else if ((word & 0xffff0010) == 0x13370010) {
762 AliDebug(1, Form("stack %i: tracking done word: 0x%08x", stack, word));
765 else if ((idx & 0x1) == 0x1) {
767 AliDebug(1, Form("track debug word: 0x%08x%08x", trackWord[1], trackWord[0]));
769 // AliESDTrdTrack *trk = new ((*fTracks)[fTracks->GetEntriesFast()]) AliESDTrdTrack(0, 0, trackWord[0], trackWord[1], fCurrEquipmentId-kDDLOffset);
770 // if (TMath::Abs(trk->GetPt()) > 0.1) {
771 // trk->SetA((Int_t) (0.15*51625./100./trk->GetPt() / 160e-4 * 2));
773 // trk->SetStack((trackWord[1] >> 28) & 0x7);
782 fPayloadCurr += fCurrTrkHeaderSize[stack];
784 return fCurrTrkHeaderSize[stack];
787 Int_t AliTRDrawStream::ReadTriggerHeaders()
789 // read all trigger headers present
791 AliDebug(1, Form("trigger mask: 0x%03x, fired: 0x%03x\n",
792 fCurrTriggerEnable, fCurrTriggerFired));
793 // loop over potential trigger blocks
794 for (Int_t iTrigger = 0; iTrigger < fgkNtriggers; iTrigger++) {
795 // check for trigger enable
796 if (fCurrTriggerEnable & (1 << iTrigger)) {
797 // check for readout mode and trigger fired
798 if ((fCurrTrgHeaderReadout == 0) || (fCurrTriggerFired & (1 << iTrigger))) {
800 AliDebug(1, Form("trigger index word %i: 0x%08x\n", iTrigger, *fPayloadCurr));
801 fCurrTrgHeaderIndexWord[iTrigger] = *fPayloadCurr;
802 fCurrTrgHeaderSize[iTrigger] = ((*fPayloadCurr) >> 16) & 0xffff;
805 fPayloadCurr += fCurrTrgHeaderSize[iTrigger];
813 Int_t AliTRDrawStream::ReadStackHeader(Int_t stack)
815 // read the stack header
816 // and store the information in the corresponding variables
818 fCurrStackIndexWord[stack] = *fPayloadCurr;
819 fCurrStackHeaderSize[stack] = (((*fPayloadCurr) >> 16) & 0xffff) + 1;
820 fCurrStackHeaderVersion[stack] = ((*fPayloadCurr) >> 12) & 0xf;
821 fCurrLinkMask[stack] = (*fPayloadCurr) & 0xfff;
823 // dumping stack header
824 AliDebug(1, DumpRaw(Form("stack %i header", stack), fPayloadCurr, fCurrStackHeaderSize[stack]));
826 if (fPayloadCurr - fPayloadStart >= fPayloadSize - (Int_t) fCurrStackHeaderSize[stack]) {
827 LinkError(kStackHeaderInvalid, "Stack index header aborted");
831 switch (fCurrStackHeaderVersion[stack]) {
833 if (fCurrStackHeaderSize[stack] < 8) {
834 LinkError(kStackHeaderInvalid, "Stack header smaller than expected!");
838 fCurrCleanCheckout[stack] = fPayloadCurr[1] & 0x1;
839 fCurrBoardId[stack] = (fPayloadCurr[1] >> 8) & 0xff;
840 fCurrHwRevTMU[stack] = (fPayloadCurr[1] >> 16) & 0xffff;
842 for (Int_t iLayer = 0; iLayer < 6; iLayer++) {
844 fCurrLinkMonitorFlags [stack*fgkNlinks + iLayer*2] = fPayloadCurr[iLayer+2] & 0xf;
845 fCurrLinkDataTypeFlags [stack*fgkNlinks + iLayer*2] = (fPayloadCurr[iLayer+2] >> 4) & 0x3;
846 fCurrLinkDebugFlags [stack*fgkNlinks + iLayer*2] = (fPayloadCurr[iLayer+2] >> 12) & 0xf;
848 fCurrLinkMonitorFlags [stack*fgkNlinks + iLayer*2 + 1] = (fPayloadCurr[iLayer+2] >> 16) & 0xf;
849 fCurrLinkDataTypeFlags [stack*fgkNlinks + iLayer*2 + 1] = (fPayloadCurr[iLayer+2] >> 20) & 0x3;
850 fCurrLinkDebugFlags [stack*fgkNlinks + iLayer*2 + 1] = (fPayloadCurr[iLayer+2] >> 28) & 0xf;
855 LinkError(kStackHeaderInvalid, "Invalid Stack Header version %x", fCurrStackHeaderVersion[stack]);
858 fPayloadCurr += fCurrStackHeaderSize[stack];
860 return fCurrStackHeaderSize[stack];
863 Int_t AliTRDrawStream::ReadGTUTrailer()
865 // read the SM trailer containing CRCs from various stages
867 UInt_t* trailer = fPayloadStart + fPayloadSize -1;
869 // look for the trailer index word from the end
870 for (Int_t iWord = 0; iWord < fPayloadSize; iWord++) {
871 if ((fPayloadStart[fPayloadSize-1-iWord] & 0xffff) == 0x1f51) {
872 trailer = fPayloadStart + fPayloadSize - 1 - iWord;
877 if (((*trailer) & 0xffff) == 0x1f51) {
878 UInt_t trailerIndexWord = (*trailer);
879 Int_t trailerSize = (trailerIndexWord >> 16) & 0xffff;
880 AliDebug(2, DumpRaw("GTU trailer", trailer, trailerSize+1));
884 EquipmentError(kUnknown, "trailer index marker mismatch");
889 Int_t AliTRDrawStream::ReadLinkData()
891 // read the data in one link (one HC) until the data endmarker is reached
892 // returns the number of words read!
895 UInt_t* startPosLink = fPayloadCurr;
897 AliDebug(1, DumpRaw(Form("link data from seg %2i slot %i link %2i", fCurrEquipmentId-kDDLOffset, fCurrSlot, fCurrLink),
898 fPayloadCurr, TMath::Min((Int_t) (fPayloadSize - (fPayloadCurr-fPayloadStart)), 100), 0x00000000));
901 new ((*fMarkers)[fMarkers->GetEntriesFast()])
902 AliTRDrawStreamError(-kHCactive, fCurrEquipmentId-kDDLOffset, fCurrStack, fCurrLink);
904 if (fErrorFlags & kDiscardHC)
907 //??? add check whether tracklets are enabled
908 count += ReadTracklets();
909 if (fErrorFlags & kDiscardHC)
912 AliDebug(1, DumpRaw("HC header", fPayloadCurr, 4, 0x00000000));
913 count += ReadHcHeader();
914 if (fErrorFlags & kDiscardHC)
917 Int_t det = fCurrSm * 30 + fCurrStack * 6 + fCurrLayer;
919 if (det > -1 && det < 540) {
921 if ((fAdcArray = fDigitsManager->GetDigits(det))) {
922 //fAdcArray->Expand();
923 if (fAdcArray->GetNtime() != fCurrNtimebins)
924 fAdcArray->Allocate(16, 144, fCurrNtimebins);
927 LinkError(kNoDigits);
931 fDigitsParam = fDigitsManager->GetDigitsParam();
934 fDigitsParam->SetPretriggerPhase(det, fCurrPtrgPhase);
935 fDigitsParam->SetNTimeBins(det, fCurrNtimebins);
936 fDigitsParam->SetADCbaseline(det, 10);
939 if (fDigitsManager->UsesDictionaries()) {
940 fDigitsManager->GetDictionary(det, 0)->Reset();
941 fDigitsManager->GetDictionary(det, 1)->Reset();
942 fDigitsManager->GetDictionary(det, 2)->Reset();
945 if ((fSignalIndex = fDigitsManager->GetIndexes(det))) {
946 fSignalIndex->SetSM(fCurrSm);
947 fSignalIndex->SetStack(fCurrStack);
948 fSignalIndex->SetLayer(fCurrLayer);
949 fSignalIndex->SetDetNumber(det);
950 if (!fSignalIndex->IsAllocated())
951 fSignalIndex->Allocate(16, 144, fCurrNtimebins);
954 // ----- check which kind of data -----
955 if (fCurrMajor & 0x40) {
956 if ((fCurrMajor & 0x7) == 0x7) {
957 AliDebug(1, "This is a config event");
958 UInt_t *startPos = fPayloadCurr;
959 while (fPayloadCurr - fPayloadStart < fPayloadSize &&
960 *fPayloadCurr != fgkDataEndmarker)
962 count += fPayloadCurr - startPos;
964 // feeding TRAP config
965 AliTRDtrapConfig *trapcfg = AliTRDtrapConfig::Instance();
966 trapcfg->ReadPackedConfig(fCurrHC, startPos, fPayloadCurr - startPos);
969 Int_t tpmode = fCurrMajor & 0x7;
970 AliDebug(1, Form("Checking testpattern (mode %i) data", tpmode));
974 else if (fCurrMajor & 0x20) {
975 AliDebug(1, "This is a zs event");
976 count += ReadZSData();
979 AliDebug(1, "This is a nozs event");
980 count += ReadNonZSData();
984 LinkError(kInvalidDetector, "%i", det);
985 while (fPayloadCurr - fPayloadStart < fPayloadSize &&
986 *fPayloadCurr != fgkDataEndmarker)
990 if (fCurrSm > -1 && fCurrSm < 18) {
991 fStats.fStatsSector[fCurrSm].fStatsHC[fCurrHC%60].fBytes += (fPayloadCurr - startPosLink) * sizeof(UInt_t);
992 fStats.fStatsSector[fCurrSm].fStatsHC[fCurrHC%60].fBytesRead += count * sizeof(UInt_t);
993 fStats.fStatsSector[fCurrSm].fBytesRead += count * sizeof(UInt_t);
994 fStats.fBytesRead += count * sizeof(UInt_t);
1000 Int_t AliTRDrawStream::ReadTracklets()
1002 // read the tracklets from one HC
1004 fTrackletArray->Clear();
1006 UInt_t *start = fPayloadCurr;
1007 while (*(fPayloadCurr) != fgkTrackletEndmarker &&
1008 fPayloadCurr - fPayloadStart < fPayloadSize) {
1009 new ((*fTrackletArray)[fTrackletArray->GetEntriesFast()]) AliTRDtrackletWord(*(fPayloadCurr), fCurrHC);
1014 if (fTrackletArray->GetEntriesFast() > 0) {
1015 AliDebug(1, Form("Found %i tracklets in %i %i %i (ev. %i)", fTrackletArray->GetEntriesFast(),
1016 (fCurrEquipmentId-kDDLOffset), fCurrSlot, fCurrLink, fRawReader->GetEventIndex()));
1017 if (fCurrSm > -1 && fCurrSm < 18) {
1018 fStats.fStatsSector[fCurrSm].fStatsHC[fCurrHC%60].fNTracklets += fTrackletArray->GetEntriesFast();
1019 fStats.fStatsSector[fCurrSm].fNTracklets += fTrackletArray->GetEntriesFast();
1022 fTrackletTree->Fill();
1024 for (Int_t iTracklet = 0; iTracklet < fTrackletArray->GetEntriesFast(); iTracklet++) {
1025 new ((*fTracklets)[fTracklets->GetEntriesFast()]) AliTRDtrackletWord(*((AliTRDtrackletWord*)(*fTrackletArray)[iTracklet]));
1029 // loop over remaining tracklet endmarkers
1030 while ((*(fPayloadCurr) == fgkTrackletEndmarker &&
1031 fPayloadCurr - fPayloadStart < fPayloadSize))
1034 return fPayloadCurr - start;
1037 Int_t AliTRDrawStream::ReadHcHeader()
1039 // read and parse the HC header of one HC
1040 // and store the information in the corresponding variables
1042 AliDebug(1, Form("HC header: 0x%08x", *fPayloadCurr));
1043 UInt_t *start = fPayloadCurr;
1044 // check not to be at the data endmarker
1045 if (*fPayloadCurr == fgkDataEndmarker)
1048 fCurrSpecial = (*fPayloadCurr >> 31) & 0x1;
1049 fCurrMajor = (*fPayloadCurr >> 24) & 0x7f;
1050 fCurrMinor = (*fPayloadCurr >> 17) & 0x7f;
1051 fCurrAddHcWords = (*fPayloadCurr >> 14) & 0x7;
1052 fCurrSm = (*fPayloadCurr >> 9) & 0x1f;
1053 fCurrLayer = (*fPayloadCurr >> 6) & 0x7;
1054 fCurrStack = (*fPayloadCurr >> 3) & 0x7;
1055 fCurrSide = (*fPayloadCurr >> 2) & 0x1;
1056 fCurrCheck = (*fPayloadCurr) & 0x3;
1058 if ((fCurrSm != (((Int_t) fCurrEquipmentId) - kDDLOffset)) ||
1059 (fCurrStack != fCurrSlot) ||
1060 (fCurrLayer != fCurrLink / 2) ||
1061 (fCurrSide != fCurrLink % 2)) {
1062 LinkError(kHCmismatch,
1063 "HC: %i, %i, %i, %i\n 0x%08x 0x%08x 0x%08x 0x%08x",
1064 fCurrSm, fCurrStack, fCurrLayer, fCurrSide,
1065 fPayloadCurr[0], fPayloadCurr[1], fPayloadCurr[2], fPayloadCurr[3]);
1067 if (fCurrCheck != 0x1) {
1068 LinkError(kHCcheckFailed);
1071 if (fCurrAddHcWords > 0) {
1072 fCurrNtimebins = (fPayloadCurr[1] >> 26) & 0x3f;
1073 fCurrBC = (fPayloadCurr[1] >> 10) & 0xffff;
1074 fCurrPtrgCnt = (fPayloadCurr[1] >> 6) & 0xf;
1075 fCurrPtrgPhase = (fPayloadCurr[1] >> 2) & 0xf;
1078 fPayloadCurr += 1 + fCurrAddHcWords;
1080 return (fPayloadCurr - start);
1083 Int_t AliTRDrawStream::ReadTPData(Int_t mode)
1085 // testing of testpattern 1 to 3 (hardcoded), 0 missing
1086 // evcnt checking missing
1088 Int_t cpufromchannel[] = {0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3};
1091 Int_t mcmcount = -1;
1092 Int_t wordcount = 0;
1093 Int_t channelcount = 0;
1095 UInt_t expadcval = 0;
1097 Int_t lastmcmpos = -1;
1098 Int_t lastrobpos = -1;
1100 UInt_t* start = fPayloadCurr;
1102 while (*(fPayloadCurr) != fgkDataEndmarker &&
1103 fPayloadCurr - fPayloadStart < fPayloadSize - 1) {
1105 // ----- Checking MCM Header -----
1106 AliDebug(2, Form("MCM header: 0x%08x", *fPayloadCurr));
1109 // ----- checking for proper readout order - ROB -----
1110 if (GetROBReadoutPos(ROB(*fPayloadCurr) / 2) >= lastrobpos) {
1111 lastrobpos = GetROBReadoutPos(ROB(*fPayloadCurr) / 2);
1114 ROBError(kPosUnexp, Form("#%i after #%i in readout order", GetROBReadoutPos(ROB(*fPayloadCurr) / 2), lastrobpos));
1116 fCurrRobPos = ROB(*fPayloadCurr);
1118 // ----- checking for proper readout order - MCM -----
1119 if (GetMCMReadoutPos(MCM(*fPayloadCurr)) >= (lastmcmpos + 1) % 16) {
1120 lastmcmpos = GetMCMReadoutPos(MCM(*fPayloadCurr));
1123 MCMError(kPosUnexp, Form("#%i after #%i in readout order", GetMCMReadoutPos(MCM(*fPayloadCurr)), lastmcmpos));
1125 fCurrMcmPos = MCM(*fPayloadCurr);
1130 evcnt = 0x3f & *fPayloadCurr >> 26;
1133 while (channelcount < 21) {
1135 if (cpu != cpufromchannel[channelcount]) {
1136 cpu = cpufromchannel[channelcount];
1137 expadcval = (1 << 9) | (fCurrRobPos << 6) | (fCurrMcmPos << 2) | cpu;
1141 while (count < 10) {
1142 if (channelcount % 2 == 0)
1149 expword |= expadcval << 2;
1150 expadcval = ( (expadcval << 1) | ( ( (expadcval >> 9) ^ (expadcval >> 6) ) & 1) ) & 0x3FF;
1151 expword |= expadcval << 12;
1152 expadcval = ( (expadcval << 1) | ( ( (expadcval >> 9) ^ (expadcval >> 6) ) & 1) ) & 0x3FF;
1153 expword |= expadcval << 22;
1154 expadcval = ( (expadcval << 1) | ( ( (expadcval >> 9) ^ (expadcval >> 6) ) & 1) ) & 0x3FF;
1156 else if (mode == 2) {
1157 // ----- TP 2 ------
1158 expword = ((0x3f & evcnt) << 26) | ((fCurrSm + 1) << 21) | ((fCurrLayer + 1) << 18) |
1159 ((fCurrStack + 1) << 15) |
1160 (fCurrRobPos << 12) | (fCurrMcmPos << 8) | (cpu << 6) | (wordcount + 1);
1162 else if (mode == 3) {
1164 expword = ((0xfff & evcnt) << 20) | (fCurrSm << 15) | (fCurrLink/2 << 12) | (fCurrStack << 9) |
1165 (fCurrRobPos << 6) | (fCurrMcmPos << 2) | (cpu << 0);
1169 LinkError(kTPmodeInvalid, "Just reading");
1172 diff = *fPayloadCurr ^ expword;
1174 MCMError(kTPmismatch,
1175 "Seen 0x%08x, expected 0x%08x, diff: 0x%08x (0x%02x)",
1176 *fPayloadCurr, expword, diff, 0xff & (diff | diff >> 8 | diff >> 16 | diff >> 24));;
1184 // continue with next MCM
1186 return fPayloadCurr - start;
1190 Int_t AliTRDrawStream::ReadZSData()
1192 // read the zs data from one link from the current reading position
1194 UInt_t *start = fPayloadCurr;
1197 Int_t mcmcountExp = fCurrStack == 2 ? 48 : 64;
1198 Int_t channelcount = 0;
1199 Int_t channelcountExp = 0;
1200 Int_t channelcountMax = 0;
1202 Int_t currentTimebin = 0;
1205 Int_t lastmcmpos = -1;
1206 Int_t lastrobpos = -1;
1208 if (fCurrNtimebins != fNtimebins) {
1210 LinkError(kNtimebinsChanged,
1211 "No. of timebins changed from %i to %i", fNtimebins, fCurrNtimebins);
1212 fNtimebins = fCurrNtimebins;
1215 timebins = fNtimebins;
1217 while (*(fPayloadCurr) != fgkDataEndmarker &&
1218 fPayloadCurr - fPayloadStart < fPayloadSize) {
1220 // ----- Checking MCM Header -----
1221 AliDebug(2, DumpMcmHeader("MCM header: ", *fPayloadCurr));
1222 UInt_t *startPosMCM = fPayloadCurr;
1224 // ----- checking for proper readout order - ROB -----
1225 if (GetROBReadoutPos(ROB(*fPayloadCurr) / 2) >= lastrobpos) {
1226 if (GetROBReadoutPos(ROB(*fPayloadCurr) / 2) > lastrobpos)
1228 lastrobpos = GetROBReadoutPos(ROB(*fPayloadCurr) / 2);
1231 ROBError(kPosUnexp, Form("#%i after #%i and #%i in readout order",
1232 GetROBReadoutPos(ROB(*fPayloadCurr) / 2), lastrobpos, GetROBReadoutPos(fCurrRobPos)));
1234 fCurrRobPos = ROB(*fPayloadCurr);
1236 // ----- checking for proper readout order - MCM -----
1237 if (GetMCMReadoutPos(MCM(*fPayloadCurr)) > lastmcmpos) {
1238 lastmcmpos = GetMCMReadoutPos(MCM(*fPayloadCurr));
1241 MCMError(kPosUnexp, Form("#%i after #%i and #%i in readout order",
1242 GetMCMReadoutPos(MCM(*fPayloadCurr)), lastmcmpos, GetMCMReadoutPos(fCurrMcmPos)));
1244 fCurrMcmPos = MCM(*fPayloadCurr);
1246 if (EvNo(*fPayloadCurr) != evno) {
1248 evno = EvNo(*fPayloadCurr);
1250 MCMError(kPtrgCntMismatch, "%i <-> %i", evno, EvNo(*fPayloadCurr));
1253 Int_t adccoloff = AdcColOffset(*fPayloadCurr);
1254 Int_t padcoloff = PadColOffset(*fPayloadCurr);
1255 Int_t row = Row(*fPayloadCurr);
1258 // ----- Reading ADC channels -----
1259 AliDebug(2, DumpAdcMask("ADC mask: ", *fPayloadCurr));
1261 // ----- analysing the ADC mask -----
1263 channelcountExp = GetNActiveChannelsFromMask(*fPayloadCurr);
1264 channelcountMax = GetNActiveChannels(*fPayloadCurr);
1265 Int_t channelmask = GetActiveChannels(*fPayloadCurr);
1266 Int_t channelno = -1;
1269 if (channelcountExp != channelcountMax) {
1270 if (channelcountExp > channelcountMax) {
1271 Int_t temp = channelcountExp;
1272 channelcountExp = channelcountMax;
1273 channelcountMax = temp;
1275 while (channelcountExp < channelcountMax && channelcountExp < 21 &&
1276 fPayloadCurr - fPayloadStart < fPayloadSize - 10 * channelcountExp - 1) {
1277 MCMError(kAdcMaskInconsistent,
1278 "Possible MCM-H: 0x%08x, possible ADC-mask: 0x%08x",
1279 *(fPayloadCurr + 10 * channelcountExp),
1280 *(fPayloadCurr + 10 * channelcountExp + 1) );
1281 if (!CouldBeMCMhdr( *(fPayloadCurr + 10 * channelcountExp)) && !CouldBeADCmask( *(fPayloadCurr + 10 * channelcountExp + 1)))
1287 MCMError(kAdcMaskInconsistent,
1288 "Inconsistency in no. of active channels: Counter: %i, Mask: %i, chosen: %i!",
1289 GetNActiveChannels(fPayloadCurr[-1]), GetNActiveChannelsFromMask(fPayloadCurr[-1]), channelcountExp);
1291 AliDebug(2, Form("expecting %i active channels, %i timebins", channelcountExp, fCurrNtimebins));
1293 // ----- reading marked ADC channels -----
1294 while (channelcount < channelcountExp && *(fPayloadCurr) != fgkDataEndmarker) {
1297 while (channelno < 20 && (channelmask & 1 << channelno) == 0)
1300 if (fCurrNtimebins > 30) {
1301 currentTimebin = ((*fPayloadCurr >> 2) & 0x3f);
1302 timebins = ((*fPayloadCurr >> 8) & 0xf) * 3;
1309 AliDebug(3, Form("Now reading %i words for channel %2i", timebins / 3, channelno));
1310 Int_t adccol = adccoloff - channelno;
1311 Int_t padcol = padcoloff - channelno;
1312 // if (adccol < 3 || adccol > 165)
1313 // AliInfo(Form("writing channel %i of det %3i %i:%2i to adcrow/-col: %i/%i padcol: %i",
1314 // channelno, fCurrHC/2, fCurrRobPos, fCurrMcmPos, row, adccol, padcol));
1316 while (adcwc < timebins / 3 &&
1317 *(fPayloadCurr) != fgkDataEndmarker &&
1318 fPayloadCurr - fPayloadStart < fPayloadSize) {
1319 int check = 0x3 & *fPayloadCurr;
1320 if (channelno % 2 != 0) { // odd channel
1321 if (check != 0x2 && channelno < 21) {
1322 MCMError(kAdcCheckInvalid,
1323 "%i for %2i. ADC word in odd channel %i",
1324 check, adcwc+1, channelno);
1327 else { // even channel
1328 if (check != 0x3 && channelno < 21) {
1329 MCMError(kAdcCheckInvalid,
1330 "%i for %2i. ADC word in even channel %i",
1331 check, adcwc+1, channelno);
1335 // filling the actual timebin data
1336 int tb2 = 0x3ff & *fPayloadCurr >> 22;
1337 int tb1 = 0x3ff & *fPayloadCurr >> 12;
1338 int tb0 = 0x3ff & *fPayloadCurr >> 2;
1339 if (adcwc != 0 || fCurrNtimebins <= 30)
1340 fAdcArray->SetDataByAdcCol(row, adccol, currentTimebin++, tb0);
1343 fAdcArray->SetDataByAdcCol(row, adccol, currentTimebin++, tb1);
1344 fAdcArray->SetDataByAdcCol(row, adccol, currentTimebin++, tb2);
1350 if (adcwc != timebins / 3)
1351 MCMError(kAdcDataAbort);
1354 if (padcol > 0 && padcol < 144) {
1355 fSignalIndex->AddIndexRC(row, padcol);
1361 if (fCurrSm > -1 && fCurrSm < 18) {
1362 fStats.fStatsSector[fCurrSm].fStatsHC[fCurrHC%60].fNChannels += channelcount;
1363 fStats.fStatsSector[fCurrSm].fNChannels += channelcount;
1365 if (channelcount != channelcountExp)
1366 MCMError(kAdcChannelsMiss);
1369 if (fCurrSm > -1 && fCurrSm < 18) {
1370 fStats.fStatsSector[fCurrSm].fStatsHC[fCurrHC%60].fNMCMs++;
1371 fStats.fStatsSector[fCurrSm].fNMCMs++;
1374 if (IsDumping() && DumpingMCM(fCurrHC/2, fCurrRobPos, fCurrMcmPos)) {
1375 AliInfo(DumpRaw(Form("Event %i: Det %3i ROB %i MCM %2i", fRawReader->GetEventIndex(), fCurrHC/2, fCurrRobPos, fCurrMcmPos),
1376 startPosMCM, fPayloadCurr - startPosMCM));
1379 // continue with next MCM
1382 // check for missing MCMs (if header suppression is inactive)
1383 if (((fCurrMajor & 0x1) == 0) && (mcmcount != mcmcountExp)) {
1384 LinkError(kMissMcmHeaders,
1385 "No. of MCM headers %i not as expected: %i",
1386 mcmcount, mcmcountExp);
1389 return (fPayloadCurr - start);
1392 Int_t AliTRDrawStream::ReadNonZSData()
1394 // read the non-zs data from one link from the current reading position
1396 UInt_t *start = fPayloadCurr;
1399 Int_t mcmcountExp = fCurrStack == 2 ? 48 : 64;
1400 Int_t channelcount = 0;
1401 Int_t channelcountExp = 0;
1403 Int_t currentTimebin = 0;
1406 Int_t lastmcmpos = -1;
1407 Int_t lastrobpos = -1;
1409 if (fCurrNtimebins != fNtimebins) {
1411 LinkError(kNtimebinsChanged,
1412 "No. of timebins changed from %i to %i", fNtimebins, fCurrNtimebins);
1413 fNtimebins = fCurrNtimebins;
1416 timebins = fNtimebins;
1418 while (*(fPayloadCurr) != fgkDataEndmarker &&
1419 fPayloadCurr - fPayloadStart < fPayloadSize - 2) {
1421 // ----- Checking MCM Header -----
1422 AliDebug(2, Form("MCM header: 0x%08x", *fPayloadCurr));
1424 // ----- checking for proper readout order - ROB -----
1425 if (GetROBReadoutPos(ROB(*fPayloadCurr) / 2) >= lastrobpos) {
1426 lastrobpos = GetROBReadoutPos(ROB(*fPayloadCurr) / 2);
1429 ROBError(kPosUnexp, Form("#%i after #%i in readout order", GetROBReadoutPos(ROB(*fPayloadCurr) / 2), lastrobpos));
1431 fCurrRobPos = ROB(*fPayloadCurr);
1433 // ----- checking for proper readout order - MCM -----
1434 if (GetMCMReadoutPos(MCM(*fPayloadCurr)) >= (lastmcmpos + 1) % 16) {
1435 lastmcmpos = GetMCMReadoutPos(MCM(*fPayloadCurr));
1438 MCMError(kPosUnexp, Form("#%i after #%i in readout order", GetMCMReadoutPos(MCM(*fPayloadCurr)), lastmcmpos));
1440 fCurrMcmPos = MCM(*fPayloadCurr);
1442 if (EvNo(*fPayloadCurr) != evno) {
1444 evno = EvNo(*fPayloadCurr);
1446 MCMError(kPtrgCntMismatch, "%i <-> %i", evno, EvNo(*fPayloadCurr));
1451 channelcountExp = 21;
1454 Int_t adccoloff = AdcColOffset(*fPayloadCurr);
1455 Int_t padcoloff = PadColOffset(*fPayloadCurr);
1456 Int_t row = Row(*fPayloadCurr);
1460 // ----- reading marked ADC channels -----
1461 while (channelcount < channelcountExp &&
1462 *(fPayloadCurr) != fgkDataEndmarker) {
1469 AliDebug(2, Form("Now looking %i words", timebins / 3));
1470 Int_t adccol = adccoloff - channelno;
1471 Int_t padcol = padcoloff - channelno;
1472 while (adcwc < timebins / 3 &&
1473 *(fPayloadCurr) != fgkDataEndmarker &&
1474 fPayloadCurr - fPayloadStart < fPayloadSize) {
1475 int check = 0x3 & *fPayloadCurr;
1476 if (channelno % 2 != 0) { // odd channel
1477 if (check != 0x2 && channelno < 21) {
1478 MCMError(kAdcCheckInvalid,
1479 "%i for %2i. ADC word in odd channel %i",
1480 check, adcwc+1, channelno);
1483 else { // even channel
1484 if (check != 0x3 && channelno < 21) {
1485 MCMError(kAdcCheckInvalid,
1486 "%i for %2i. ADC word in even channel %i",
1487 check, adcwc+1, channelno);
1491 // filling the actual timebin data
1492 int tb2 = 0x3ff & *fPayloadCurr >> 22;
1493 int tb1 = 0x3ff & *fPayloadCurr >> 12;
1494 int tb0 = 0x3ff & *fPayloadCurr >> 2;
1495 if (adcwc != 0 || fCurrNtimebins <= 30)
1496 fAdcArray->SetDataByAdcCol(row, adccol, currentTimebin++, tb0);
1499 fAdcArray->SetDataByAdcCol(row, adccol, currentTimebin++, tb1);
1500 fAdcArray->SetDataByAdcCol(row, adccol, currentTimebin++, tb2);
1506 if (adcwc != timebins / 3)
1507 MCMError(kAdcDataAbort);
1510 if (padcol > 0 && padcol < 144) {
1511 fSignalIndex->AddIndexRC(row, padcol);
1517 if (channelcount != channelcountExp)
1518 MCMError(kAdcChannelsMiss);
1520 // continue with next MCM
1523 // check for missing MCMs (if header suppression is inactive)
1524 if (mcmcount != mcmcountExp) {
1525 LinkError(kMissMcmHeaders,
1526 "%i not as expected: %i", mcmcount, mcmcountExp);
1529 return (fPayloadCurr - start);
1532 Int_t AliTRDrawStream::SeekNextLink()
1534 // proceed in raw data stream till the next link
1536 UInt_t *start = fPayloadCurr;
1538 // read until data endmarkers
1539 while (fPayloadCurr - fPayloadStart < fPayloadSize &&
1540 *fPayloadCurr != fgkDataEndmarker)
1543 // read all data endmarkers
1544 while (fPayloadCurr - fPayloadStart < fPayloadSize &&
1545 *fPayloadCurr == fgkDataEndmarker)
1548 return (fPayloadCurr - start);
1551 Bool_t AliTRDrawStream::ConnectTracklets(TTree *trklTree)
1553 // connect the tracklet tree used to store the tracklet output
1555 fTrackletTree = trklTree;
1559 if (!fTrackletTree->GetBranch("hc"))
1560 fTrackletTree->Branch("hc", &fCurrHC, "hc/I");
1562 fTrackletTree->SetBranchAddress("hc", &fCurrHC);
1564 if (!fTrackletTree->GetBranch("trkl"))
1565 fTrackletTree->Branch("trkl", &fTrackletArray);
1567 fTrackletTree->SetBranchAddress("trkl", &fTrackletArray);
1573 void AliTRDrawStream::EquipmentError(ErrorCode_t err, const char *const msg, ...)
1575 // register error according to error code on equipment level
1576 // and return the corresponding error message
1578 fLastError.fSector = fCurrEquipmentId - kDDLOffset;
1579 fLastError.fStack = -1;
1580 fLastError.fLink = -1;
1581 fLastError.fRob = -1;
1582 fLastError.fMcm = -1;
1583 fLastError.fError = err;
1584 (this->*fStoreError)();
1587 if (fgErrorDebugLevel[err] > 10)
1588 AliDebug(fgErrorDebugLevel[err],
1589 Form("Event %6i: Eq. %2d - %s : %s",
1590 fRawReader->GetEventIndex(), fCurrEquipmentId, fgkErrorMessages[err],
1591 (va_start(ap, msg), vsprintf(fErrorBuffer, msg, ap), va_end(ap), fErrorBuffer) ));
1593 AliError(Form("Event %6i: Eq. %2d - %s : %s",
1594 fRawReader->GetEventIndex(), fCurrEquipmentId, fgkErrorMessages[err],
1595 (va_start(ap, msg), vsprintf(fErrorBuffer, msg, ap), va_end(ap), fErrorBuffer) ));
1596 fErrorFlags |= fgErrorBehav[err];
1600 void AliTRDrawStream::StackError(ErrorCode_t err, const char *const msg, ...)
1602 // register error according to error code on stack level
1603 // and return the corresponding error message
1605 fLastError.fSector = fCurrEquipmentId - kDDLOffset;
1606 fLastError.fStack = fCurrSlot;
1607 fLastError.fLink = -1;
1608 fLastError.fRob = -1;
1609 fLastError.fMcm = -1;
1610 fLastError.fError = err;
1611 (this->*fStoreError)();
1614 if (fgErrorDebugLevel[err] > 0)
1615 AliDebug(fgErrorDebugLevel[err],
1616 Form("Event %6i: Eq. %2d S %i - %s : %s",
1617 fRawReader->GetEventIndex(), fCurrEquipmentId, fCurrSlot, fgkErrorMessages[err],
1618 (va_start(ap, msg), vsprintf(fErrorBuffer, msg, ap), va_end(ap), fErrorBuffer) ));
1620 AliError(Form("Event %6i: Eq. %2d S %i - %s : %s",
1621 fRawReader->GetEventIndex(), fCurrEquipmentId, fCurrSlot, fgkErrorMessages[err],
1622 (va_start(ap, msg), vsprintf(fErrorBuffer, msg, ap), va_end(ap), fErrorBuffer) ));
1623 fErrorFlags |= fgErrorBehav[err];
1627 void AliTRDrawStream::LinkError(ErrorCode_t err, const char *const msg, ...)
1629 // register error according to error code on link level
1630 // and return the corresponding error message
1632 fLastError.fSector = fCurrEquipmentId - kDDLOffset;
1633 fLastError.fStack = fCurrSlot;
1634 fLastError.fLink = fCurrLink;
1635 fLastError.fRob = -1;
1636 fLastError.fMcm = -1;
1637 fLastError.fError = err;
1638 (this->*fStoreError)();
1641 if (fgErrorDebugLevel[err] > 0)
1642 AliDebug(fgErrorDebugLevel[err],
1643 Form("Event %6i: Eq. %2d S %i l %2i - %s : %s",
1644 fRawReader->GetEventIndex(), fCurrEquipmentId, fCurrSlot, fCurrLink, fgkErrorMessages[err],
1645 (va_start(ap, msg), vsprintf(fErrorBuffer, msg, ap), va_end(ap), fErrorBuffer) ));
1647 AliError(Form("Event %6i: Eq. %2d S %i l %2i - %s : %s",
1648 fRawReader->GetEventIndex(), fCurrEquipmentId, fCurrSlot, fCurrLink, fgkErrorMessages[err],
1649 (va_start(ap, msg), vsprintf(fErrorBuffer, msg, ap), va_end(ap), fErrorBuffer) ));
1650 fErrorFlags |= fgErrorBehav[err];
1654 void AliTRDrawStream::ROBError(ErrorCode_t err, const char *const msg, ...)
1656 // register error according to error code on ROB level
1657 // and return the corresponding error message
1659 fLastError.fSector = fCurrEquipmentId - kDDLOffset;
1660 fLastError.fStack = fCurrSlot;
1661 fLastError.fLink = fCurrLink;
1662 fLastError.fRob = fCurrRobPos;
1663 fLastError.fMcm = -1;
1664 fLastError.fError = err;
1665 (this->*fStoreError)();
1668 if (fgErrorDebugLevel[err] > 0)
1669 AliDebug(fgErrorDebugLevel[err],
1670 Form("Event %6i: Eq. %2d S %i l %2i ROB %i - %s : %s",
1671 fRawReader->GetEventIndex(), fCurrEquipmentId, fCurrSlot, fCurrLink, fCurrRobPos, fgkErrorMessages[err],
1672 (va_start(ap, msg), vsprintf(fErrorBuffer, msg, ap), va_end(ap), fErrorBuffer) ));
1674 AliError(Form("Event %6i: Eq. %2d S %i l %2i ROB %i - %s : %s",
1675 fRawReader->GetEventIndex(), fCurrEquipmentId, fCurrSlot, fCurrLink, fCurrRobPos, fgkErrorMessages[err],
1676 (va_start(ap, msg), vsprintf(fErrorBuffer, msg, ap), va_end(ap), fErrorBuffer) ));
1677 fErrorFlags |= fgErrorBehav[err];
1681 void AliTRDrawStream::MCMError(ErrorCode_t err, const char *const msg, ...)
1683 // register error according to error code on MCM level
1684 // and return the corresponding error message
1686 fLastError.fSector = fCurrEquipmentId - kDDLOffset;
1687 fLastError.fStack = fCurrSlot;
1688 fLastError.fLink = fCurrLink;
1689 fLastError.fRob = fCurrRobPos;
1690 fLastError.fMcm = fCurrMcmPos;
1691 fLastError.fError = err;
1692 (this->*fStoreError)();
1695 if (fgErrorDebugLevel[err] > 0)
1696 AliDebug(fgErrorDebugLevel[err],
1697 Form("Event %6i: Eq. %2d S %i l %2i ROB %i MCM %2i - %s : %s",
1698 fRawReader->GetEventIndex(), fCurrEquipmentId, fCurrSlot, fCurrLink, fCurrRobPos, fCurrMcmPos, fgkErrorMessages[err],
1699 (va_start(ap, msg), vsprintf(fErrorBuffer, msg, ap), va_end(ap), fErrorBuffer) ));
1701 AliError(Form("Event %6i: Eq. %2d S %i l %2i ROB %i MCM %2i - %s : %s",
1702 fRawReader->GetEventIndex(), fCurrEquipmentId, fCurrSlot, fCurrLink, fCurrRobPos, fCurrMcmPos, fgkErrorMessages[err],
1703 (va_start(ap, msg), vsprintf(fErrorBuffer, msg, ap), va_end(ap), fErrorBuffer) ));
1704 fErrorFlags |= fgErrorBehav[err];
1707 const char* AliTRDrawStream::GetErrorMessage(ErrorCode_t errCode)
1709 // return the error message for the given error code
1711 if (errCode > 0 && errCode < kLastErrorCode)
1712 return fgkErrorMessages[errCode];
1717 void AliTRDrawStream::AliTRDrawStats::ClearStats()
1719 // clear statistics (includes clearing sector-wise statistics)
1722 for (Int_t iSector = 0; iSector < 18; iSector++) {
1723 fStatsSector[iSector].ClearStats();
1728 void AliTRDrawStream::AliTRDrawStats::AliTRDrawStatsSector::ClearStats()
1730 // clear statistics (includes clearing HC-wise statistics)
1738 for (Int_t iHC = 0; iHC < 60; iHC++) {
1739 fStatsHC[iHC].ClearStats();
1743 void AliTRDrawStream::AliTRDrawStats::AliTRDrawStatsSector::AliTRDrawStatsHC::ClearStats()
1754 void AliTRDrawStream::SetDumpMCM(Int_t det, Int_t rob, Int_t mcm, Bool_t dump)
1756 // mark MCM for dumping of raw data
1759 fDumpMCM[fNDumpMCMs++] = (det << 7) | (rob << 4) | mcm;
1763 for (iMCM = 0; iMCM < fNDumpMCMs; iMCM++) {
1764 if (fDumpMCM[iMCM] == ((det << 7) | (rob << 4) | mcm)) {
1769 for ( ; iMCM < fNDumpMCMs; iMCM++) {
1770 fDumpMCM[iMCM] = fDumpMCM[iMCM+1];
1775 Bool_t AliTRDrawStream::DumpingMCM(Int_t det, Int_t rob, Int_t mcm) const
1777 // check if MCM data should be dumped
1779 for (Int_t iMCM = 0; iMCM < fNDumpMCMs; iMCM++) {
1780 if (fDumpMCM[iMCM] == ((det << 7) | (rob << 4) | mcm)) {
1787 TString AliTRDrawStream::DumpRaw(TString title, UInt_t *start, Int_t length, UInt_t endmarker)
1792 for (Int_t pos = 0; pos < length; pos += 4) {
1793 if ((start[pos+0] != endmarker) && pos+0 < length)
1794 if ((start[pos+1] != endmarker && pos+1 < length))
1795 if ((start[pos+2] != endmarker && pos+2 < length))
1796 if ((start[pos+3] != endmarker && pos+3 < length))
1797 title += Form(" 0x%08x 0x%08x 0x%08x 0x%08x\n",
1798 start[pos+0], start[pos+1], start[pos+2], start[pos+3]);
1800 title += Form(" 0x%08x 0x%08x 0x%08x 0x%08x\n",
1801 start[pos+0], start[pos+1], start[pos+2], start[pos+3]);
1805 title += Form(" 0x%08x 0x%08x 0x%08x\n",
1806 start[pos+0], start[pos+1], start[pos+2]);
1810 title += Form(" 0x%08x 0x%08x\n",
1811 start[pos+0], start[pos+1]);
1815 title += Form(" 0x%08x\n",
1823 TString AliTRDrawStream::DumpMcmHeader(TString title, UInt_t word)
1825 title += Form("0x%08x -> ROB: %i, MCM: %2i",
1826 word, ROB(word), MCM(word));
1830 TString AliTRDrawStream::DumpAdcMask(TString title, UInt_t word)
1832 title += Form("0x%08x -> #ch : %2i, 0x%06x (%2i ch)",
1833 word, GetNActiveChannels(word), GetActiveChannels(word), GetNActiveChannelsFromMask(word));
1837 AliTRDrawStream::AliTRDrawStreamError::AliTRDrawStreamError(Int_t error, Int_t sector, Int_t stack, Int_t link, Int_t rob, Int_t mcm) :