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 //
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 "AliTreeLoader.h"
42 #include "AliTRDrawStream.h"
45 #include "AliRunLoader.h"
47 ClassImp(AliTRDrawStream)
49 // some static information
50 const Int_t AliTRDrawStream::fgkMcmOrder[] = {12, 13, 14, 15,
54 const Int_t AliTRDrawStream::fgkRobOrder [] = {0, 1, 2, 3};
55 const Int_t AliTRDrawStream::fgkNlinks = 12;
56 const Int_t AliTRDrawStream::fgkNstacks = 5;
57 const UInt_t AliTRDrawStream::fgkDataEndmarker = 0x00000000;
58 const UInt_t AliTRDrawStream::fgkTrackletEndmarker = 0x10001000;
60 const char* AliTRDrawStream::fgErrorMessages[] = {
62 "Link monitor active",
63 "Pretrigger counter mismatch",
64 "not a TRD equipment (1024-1041)",
65 "Invalid Stack header",
66 "Invalid detector number",
67 "No digits could be retrieved from the digitsmanager",
69 "HC check bits wrong",
70 "Unexpected position in readout stream",
71 "Invalid testpattern mode",
72 "Testpattern mismatch",
73 "Number of timebins changed",
74 "ADC mask inconsistent",
75 "ADC check bits invalid",
77 "Missing expected ADC channels",
81 const Int_t AliTRDrawStream::fgErrorDebugLevel[] = {
102 AliTRDrawStream::ErrorBehav_t AliTRDrawStream::fgErrorBehav[] = {
103 AliTRDrawStream::kTolerate,
104 AliTRDrawStream::kDiscardHC,
105 AliTRDrawStream::kTolerate,
106 AliTRDrawStream::kAbort,
107 AliTRDrawStream::kAbort,
108 AliTRDrawStream::kAbort,
109 AliTRDrawStream::kAbort,
110 AliTRDrawStream::kDiscardHC,
111 AliTRDrawStream::kDiscardHC,
112 AliTRDrawStream::kTolerate,
113 AliTRDrawStream::kTolerate,
114 AliTRDrawStream::kTolerate,
115 AliTRDrawStream::kTolerate,
116 AliTRDrawStream::kTolerate,
117 AliTRDrawStream::kTolerate,
118 AliTRDrawStream::kTolerate,
119 AliTRDrawStream::kTolerate,
120 AliTRDrawStream::kTolerate
123 AliTRDrawStream::AliTRDrawStream(AliRawReader *rawReader) :
125 fStoreError(&AliTRDrawStream::StoreErrorTree),
126 fRawReader(rawReader),
142 fCurrSmuIndexHeaderSize(0),
143 fCurrSmuIndexHeaderVersion(0),
145 fCurrTrackletEnable(0),
147 fCurrStackIndexWord(0x0),
148 fCurrStackHeaderSize(0x0),
149 fCurrStackHeaderVersion(0x0),
151 fCurrCleanCheckout(0x0),
154 fCurrLinkMonitorFlags(0x0),
155 fCurrLinkDataTypeFlags(0x0),
156 fCurrLinkDebugFlags(0x0),
177 // default constructor
179 fCurrStackIndexWord = new UInt_t[fgkNstacks];
180 fCurrStackHeaderSize = new UInt_t[fgkNstacks];
181 fCurrStackHeaderVersion = new UInt_t[fgkNstacks];
182 fCurrLinkMask = new UInt_t[fgkNstacks];
183 fCurrCleanCheckout = new UInt_t[fgkNstacks];
184 fCurrBoardId = new UInt_t[fgkNstacks];
185 fCurrHwRev = new UInt_t[fgkNstacks];
186 fCurrLinkMonitorFlags = new UInt_t[fgkNstacks * fgkNlinks];
187 fCurrLinkDataTypeFlags = new UInt_t[fgkNstacks * fgkNlinks];
188 fCurrLinkDebugFlags = new UInt_t[fgkNstacks * fgkNlinks];
190 // preparing TClonesArray
191 fTrackletArray = new TClonesArray("AliTRDtrackletWord", 256);
193 // setting up the error tree
194 fErrors = new TTree("errorStats", "Error statistics");
195 fErrors->SetDirectory(0x0);
196 fErrors->Branch("error", &fLastError, "sector/I:stack:link:error:rob:mcm");
197 fErrors->SetCircular(1000);
200 AliTRDrawStream::~AliTRDrawStream()
206 delete [] fCurrStackIndexWord;
207 delete [] fCurrStackHeaderSize;
208 delete [] fCurrStackHeaderVersion;
209 delete [] fCurrLinkMask;
210 delete [] fCurrCleanCheckout;
211 delete [] fCurrBoardId;
212 delete [] fCurrHwRev;
213 delete [] fCurrLinkMonitorFlags;
214 delete [] fCurrLinkDataTypeFlags;
215 delete [] fCurrLinkDebugFlags;
218 Bool_t AliTRDrawStream::ReadEvent(TTree *trackletTree)
220 // read the current event from the raw reader and fill it to the digits manager
223 AliError("No raw reader available");
228 ConnectTracklets(trackletTree);
233 // loop over all DDLs
234 // data starts with GTU payload, i.e. SMU index word
235 UChar_t *buffer = 0x0;
237 while (fRawReader->ReadNextData(buffer)) {
239 fCurrEquipmentId = fRawReader->GetEquipmentId();
240 AliDebug(2, Form("equipment: %i", fCurrEquipmentId));
242 if (fCurrEquipmentId < 1024 || fCurrEquipmentId > 1041) {
243 EquipmentError(kNonTrdEq, "Skipping");
247 // setting the pointer to data and current reading position
248 fPayloadCurr = fPayloadStart = (UInt_t*) (buffer);
249 fPayloadSize = fRawReader->GetDataSize() / sizeof(UInt_t);
250 fStats.fStatsSector[fCurrEquipmentId - 1024].fBytes = fRawReader->GetDataSize();
251 AliDebug(2, Form("Read buffer of size: %i", fRawReader->GetDataSize()));
253 // read SMU index header
254 if (ReadSmHeader() < 0) {
255 AliError(Form("Reading SMU header failed, skipping this DDL %i", fCurrEquipmentId));
259 // read stack index header
260 for (Int_t iStack = 0; iStack < 5; iStack++) {
261 if ((fCurrStackMask & (1 << iStack)) != 0)
262 ReadStackIndexHeader(iStack);
265 for (Int_t iStack = 0; iStack < 5; iStack++) {
267 if ((fCurrStackMask & (1 << fCurrSlot)) == 0)
270 AliDebug(2, Form("Stack %i, Link mask: 0x%02x", fCurrSlot, fCurrLinkMask[fCurrSlot]));
271 for (Int_t iLink = 0; iLink < 12; iLink++) {
273 fCurrHC = fCurrSm * 60 + fCurrSlot * 12 + iLink;
274 if ((fCurrLinkMask[fCurrSlot] & (1 << fCurrLink)) == 0)
278 // check for link monitor error flag
279 if (fCurrLinkMonitorFlags[fCurrSlot*fgkNlinks + fCurrLink] != 0)
280 LinkError(kLinkMonitor);
282 // read the data from one HC
285 // read all data endmarkers
294 Bool_t AliTRDrawStream::NextDDL()
296 // continue reading with the next equipment
301 fCurrEquipmentId = 0;
305 UChar_t *buffer = 0x0;
307 while (fRawReader->ReadNextData(buffer)) {
309 fCurrEquipmentId = fRawReader->GetEquipmentId();
310 AliDebug(2, Form("equipment: %i", fCurrEquipmentId));
312 if (fCurrEquipmentId < 1024 || fCurrEquipmentId > 1041) {
313 EquipmentError(kNonTrdEq, "Skipping");
317 // setting the pointer to data and current reading position
318 fPayloadCurr = fPayloadStart = (UInt_t*) (buffer);
319 fPayloadSize = fRawReader->GetDataSize() / sizeof(UInt_t);
320 AliDebug(2, Form("Read buffer of size: %i", fRawReader->GetDataSize()));
322 // read SMU index header
323 if (ReadSmHeader() < 0) {
324 AliError(Form("Reading SMU header failed, skipping this DDL %i", fCurrEquipmentId));
328 // read stack index header
329 for (Int_t iStack = 0; iStack < 5; iStack++) {
330 if ((fCurrStackMask & (1 << iStack)) != 0) {
331 ReadStackIndexHeader(iStack);
341 Int_t AliTRDrawStream::NextChamber(AliTRDdigitsManager *digMgr, UInt_t ** /* trackletContainer */, UShort_t ** /* errorContainer */)
343 // read the data for the next chamber
344 // in case you only want to read the data of a single chamber
345 // to read all data ReadEvent(...) is recommended
347 fDigitsManager = digMgr;
352 // tracklet output preparation
353 TTree *trklTree = 0x0;
354 AliRunLoader *rl = AliRunLoader::Instance();
355 AliLoader* trdLoader = rl ? rl->GetLoader("TRDLoader") : NULL;
356 AliDataLoader *trklLoader = trdLoader ? trdLoader->GetDataLoader("tracklets") : NULL;
358 AliTreeLoader *trklTreeLoader = (AliTreeLoader*) trklLoader->GetBaseLoader("tracklets-raw");
360 trklTree = trklTreeLoader->Tree();
362 trklTree = trklLoader->Tree();
365 if (fTrackletTree != trklTree)
366 ConnectTracklets(trklTree);
369 AliError("No raw reader available");
373 if (fCurrSlot < 0 || fCurrSlot >= 5) {
380 AliDebug(2, Form("Stack %i, Link %i, mask: 0x%02x", fCurrSlot, fCurrLink, fCurrLinkMask[fCurrSlot]));
381 fCurrHC = (fCurrEquipmentId - 1024) * 60 + fCurrSlot * 12 + fCurrLink;
383 if (fCurrLinkMonitorFlags[fCurrSlot*fgkNlinks + fCurrLink] != 0)
384 LinkError(kLinkMonitor);
386 // read the data from one HC
389 // read all data endmarkers
392 if (fCurrLink % 2 == 0) {
393 // if we just read the A-side HC then also check the B-side
396 if (fCurrLinkMask[fCurrSlot] & (1 << fCurrLink)) {
405 if (fCurrLink > 11) {
409 } while ((fCurrSlot < 5) &&
410 (((fCurrStackMask & (1 << fCurrSlot)) == 0) ||
411 ((fCurrLinkMask[fCurrSlot] & (1 << fCurrLink))) == 0));
413 return (fCurrSm * 30 + fCurrStack * 6 + fCurrLayer);
417 Int_t AliTRDrawStream::ReadSmHeader()
419 // read the SMU index header at the current reading position
420 // and store the information in the corresponding variables
422 if (fPayloadCurr - fPayloadStart >= fPayloadSize - 1) {
423 EquipmentError(kUnknown, "SM Header incomplete");
427 fCurrSmuIndexHeaderSize = ((*fPayloadCurr) >> 16) & 0xffff;
428 fCurrSmuIndexHeaderVersion = ((*fPayloadCurr) >> 12) & 0xf;
429 fCurrTrackEnable = ((*fPayloadCurr) >> 6) & 0x1;
430 fCurrTrackletEnable = ((*fPayloadCurr) >> 5) & 0x1;
431 fCurrStackMask = ((*fPayloadCurr) ) & 0x1f;
433 AliDebug(5, Form("SMU header: size: %i, version: %i, track enable: %i, tracklet enable: %i, stack mask: %2x",
434 fCurrSmuIndexHeaderSize,
435 fCurrSmuIndexHeaderVersion,
440 fPayloadCurr += fCurrSmuIndexHeaderSize + 1;
442 return fCurrSmuIndexHeaderSize + 1;
445 Int_t AliTRDrawStream::ReadStackIndexHeader(Int_t stack)
447 // read the stack index header
448 // and store the information in the corresponding variables
450 fCurrStackIndexWord[stack] = *fPayloadCurr;
451 fCurrStackHeaderSize[stack] = (((*fPayloadCurr) >> 16) & 0xffff) + 1;
452 fCurrStackHeaderVersion[stack] = ((*fPayloadCurr) >> 12) & 0xf;
453 fCurrLinkMask[stack] = (*fPayloadCurr) & 0xfff;
455 if (fPayloadCurr - fPayloadStart >= fPayloadSize - (Int_t) fCurrStackHeaderSize[stack]) {
456 StackError(kStackHeaderInvalid, "Stack index header aborted");
460 switch (fCurrStackHeaderVersion[stack]) {
462 if (fCurrStackHeaderSize[stack] < 8) {
463 StackError(kStackHeaderInvalid, "Stack header smaller than expected!");
467 fCurrCleanCheckout[stack] = fPayloadCurr[1] & 0x1;
468 fCurrBoardId[stack] = (fPayloadCurr[1] >> 8) & 0xff;
469 fCurrHwRev[stack] = (fPayloadCurr[1] >> 16) & 0xffff;
471 for (Int_t iLayer = 0; iLayer < 6; iLayer++) {
473 fCurrLinkMonitorFlags [stack*fgkNlinks + iLayer*2] = fPayloadCurr[iLayer+2] & 0xf;
474 fCurrLinkDataTypeFlags [stack*fgkNlinks + iLayer*2] = (fPayloadCurr[iLayer+2] >> 4) & 0x3;
475 fCurrLinkDebugFlags [stack*fgkNlinks + iLayer*2] = (fPayloadCurr[iLayer+2] >> 12) & 0xf;
477 fCurrLinkMonitorFlags [stack*fgkNlinks + iLayer*2 + 1] = (fPayloadCurr[iLayer+2] >> 16) & 0xf;
478 fCurrLinkDataTypeFlags [stack*fgkNlinks + iLayer*2 + 1] = (fPayloadCurr[iLayer+2] >> 20) & 0x3;
479 fCurrLinkDebugFlags [stack*fgkNlinks + iLayer*2 + 1] = (fPayloadCurr[iLayer+2] >> 28) & 0xf;
484 StackError(kStackHeaderInvalid, "Invalid Stack Index Header version %x", fCurrStackHeaderVersion[stack]);
487 fPayloadCurr += fCurrStackHeaderSize[stack];
489 return fCurrStackHeaderSize[stack];
492 Int_t AliTRDrawStream::ReadLinkData()
494 // read the data in one link (one HC) until the data endmarker is reached
495 // returns the number of words read!
498 UInt_t* startPosLink = fPayloadCurr;
500 // printf("----- HC: %i -----\n", fCurrHC);
501 // for (Int_t i = 0; i < 3; i++) {
502 // printf("0x%08x 0x%08x 0x%08x 0x%08x\n",
503 // fPayloadCurr[i*4+0], fPayloadCurr[i*4+1], fPayloadCurr[i*4+2], fPayloadCurr[i*4+3]);
506 if (fErrorFlags & kDiscardHC)
509 count += ReadTracklets();
510 if (fErrorFlags & kDiscardHC)
513 count += ReadHcHeader();
514 if (fErrorFlags & kDiscardHC)
517 Int_t det = fCurrSm * 30 + fCurrStack * 6 + fCurrLayer;
519 if (det > -1 && det < 540) {
521 if ((fAdcArray = fDigitsManager->GetDigits(det))) {
522 //fAdcArray->Expand();
523 if (fAdcArray->GetNtime() != fCurrNtimebins)
524 fAdcArray->Allocate(16, 144, fCurrNtimebins);
527 LinkError(kNoDigits);
531 fDigitsParam = fDigitsManager->GetDigitsParam();
534 fDigitsParam->SetPretriggerPhase(det, fCurrPtrgPhase);
535 fDigitsParam->SetNTimeBins(det, fCurrNtimebins);
536 fDigitsParam->SetADCbaseline(det, 10);
539 if (fDigitsManager->UsesDictionaries()) {
540 fDigitsManager->GetDictionary(det, 0)->Reset();
541 fDigitsManager->GetDictionary(det, 1)->Reset();
542 fDigitsManager->GetDictionary(det, 2)->Reset();
545 if ((fSignalIndex = fDigitsManager->GetIndexes(det))) {
546 fSignalIndex->SetSM(fCurrSm);
547 fSignalIndex->SetStack(fCurrStack);
548 fSignalIndex->SetLayer(fCurrLayer);
549 fSignalIndex->SetDetNumber(det);
550 if (!fSignalIndex->IsAllocated())
551 fSignalIndex->Allocate(16, 144, fCurrNtimebins);
554 // ----- check which kind of data -----
555 if (fCurrMajor & 0x40) {
556 if ((fCurrMajor & 0x7) == 0x7) {
557 AliDebug(1, "This is a config event");
558 UInt_t *startPos = fPayloadCurr;
559 while (fPayloadCurr - fPayloadStart < fPayloadSize &&
560 *fPayloadCurr != fgkDataEndmarker)
562 count += fPayloadCurr - startPos;
564 // feeding TRAP config
565 AliTRDtrapConfig *trapcfg = AliTRDtrapConfig::Instance();
566 trapcfg->ReadPackedConfig(fCurrHC, startPos, fPayloadCurr - startPos);
569 Int_t tpmode = fCurrMajor & 0x7;
570 AliDebug(1, Form("Checking testpattern (mode %i) data", tpmode));
574 else if (fCurrMajor & 0x20) {
575 AliDebug(1, "This is a zs event");
576 count += ReadZSData();
579 AliDebug(1, "This is a nozs event");
580 count += ReadNonZSData();
584 LinkError(kInvalidDetector, "%i", det);
585 while (fPayloadCurr - fPayloadStart < fPayloadSize &&
586 *fPayloadCurr != fgkDataEndmarker)
590 fStats.fStatsSector[fCurrSm].fStatsHC[fCurrHC%60].fBytes += (fPayloadCurr - startPosLink) * sizeof(UInt_t);
591 fStats.fStatsSector[fCurrSm].fStatsHC[fCurrHC%60].fBytesRead += count * sizeof(UInt_t);
592 fStats.fStatsSector[fCurrSm].fBytesRead += count * sizeof(UInt_t);
593 fStats.fBytesRead += count * sizeof(UInt_t);
598 Int_t AliTRDrawStream::ReadTracklets()
600 // read the tracklets from one HC
602 fTrackletArray->Clear();
604 UInt_t *start = fPayloadCurr;
605 while (*(fPayloadCurr) != fgkTrackletEndmarker &&
606 fPayloadCurr - fPayloadStart < fPayloadSize) {
608 new ((*fTrackletArray)[fTrackletArray->GetEntriesFast()]) AliTRDtrackletWord(*(fPayloadCurr));
613 if (fTrackletArray->GetEntriesFast() > 0) {
614 AliDebug(1, Form("Found %i tracklets in %i %i %i (ev. %i)", fTrackletArray->GetEntriesFast(),
615 fCurrSm, fCurrSlot, fCurrLink, fRawReader->GetEventIndex()));
616 fStats.fStatsSector[fCurrSm].fStatsHC[fCurrHC%60].fNTracklets += fTrackletArray->GetEntriesFast();
617 fStats.fStatsSector[fCurrSm].fNTracklets += fTrackletArray->GetEntriesFast();
619 fTrackletTree->Fill();
622 // loop over remaining tracklet endmarkers
623 while ((*(fPayloadCurr) == fgkTrackletEndmarker &&
624 fPayloadCurr - fPayloadStart < fPayloadSize))
627 return fPayloadCurr - start;
630 Int_t AliTRDrawStream::ReadHcHeader()
632 // read and parse the HC header of one HC
633 // and store the information in the corresponding variables
635 UInt_t *start = fPayloadCurr;
636 // check not to be at the data endmarker
637 if (*fPayloadCurr == fgkDataEndmarker)
640 fCurrSpecial = (*fPayloadCurr >> 31) & 0x1;
641 fCurrMajor = (*fPayloadCurr >> 24) & 0x7f;
642 fCurrMinor = (*fPayloadCurr >> 17) & 0x7f;
643 fCurrAddHcWords = (*fPayloadCurr >> 14) & 0x7;
644 fCurrSm = (*fPayloadCurr >> 9) & 0x1f;
645 fCurrLayer = (*fPayloadCurr >> 6) & 0x7;
646 fCurrStack = (*fPayloadCurr >> 3) & 0x7;
647 fCurrSide = (*fPayloadCurr >> 2) & 0x1;
648 fCurrCheck = (*fPayloadCurr) & 0x3;
650 if (fCurrSm != (((Int_t) fCurrEquipmentId) - 1024) ||
651 fCurrStack != fCurrSlot ||
652 fCurrLayer != fCurrLink / 2 ||
653 fCurrSide != fCurrLink % 2) {
654 LinkError(kHCmismatch,
655 "HC: %i, %i, %i, %i\n 0x%08x 0x%08x 0x%08x 0x%08x",
656 fCurrSm, fCurrStack, fCurrLayer, fCurrSide,
657 fPayloadCurr[0], fPayloadCurr[1], fPayloadCurr[2], fPayloadCurr[3]);;
659 if (fCurrCheck != 0x1) {
660 LinkError(kHCcheckFailed);
663 if (fCurrAddHcWords > 0) {
664 fCurrNtimebins = (fPayloadCurr[1] >> 26) & 0x3f;
665 fCurrBC = (fPayloadCurr[1] >> 10) & 0xffff;
666 fCurrPtrgCnt = (fPayloadCurr[1] >> 6) & 0xf;
667 fCurrPtrgPhase = (fPayloadCurr[1] >> 2) & 0xf;
670 fPayloadCurr += 1 + fCurrAddHcWords;
672 return (fPayloadCurr - start) / sizeof(UInt_t);
675 Int_t AliTRDrawStream::ReadTPData(Int_t mode)
677 // testing of testpattern 1 to 3 (hardcoded), 0 missing
678 // evcnt checking missing
680 Int_t cpufromchannel[] = {0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3};
685 Int_t channelcount = 0;
687 UInt_t expadcval = 0;
689 Int_t lastmcmpos = -1;
690 Int_t lastrobpos = -1;
692 UInt_t* start = fPayloadCurr;
694 while (*(fPayloadCurr) != fgkDataEndmarker &&
695 fPayloadCurr - fPayloadStart < fPayloadSize - 1) {
697 // ----- Checking MCM Header -----
698 AliDebug(2, Form("MCM header: 0x%08x", *fPayloadCurr));
701 // ----- checking for proper readout order - ROB -----
702 if (GetROBReadoutPos(ROB(*fPayloadCurr) / 2) >= lastrobpos) {
703 lastrobpos = GetROBReadoutPos(ROB(*fPayloadCurr) / 2);
708 fCurrRobPos = ROB(*fPayloadCurr);
710 // ----- checking for proper readout order - MCM -----
711 if (GetMCMReadoutPos(MCM(*fPayloadCurr)) >= (lastmcmpos + 1) % 16) {
712 lastmcmpos = GetMCMReadoutPos(MCM(*fPayloadCurr));
717 fCurrMcmPos = MCM(*fPayloadCurr);
722 evcnt = 0x3f & *fPayloadCurr >> 26;
725 while (channelcount < 21) {
727 if (cpu != cpufromchannel[channelcount]) {
728 cpu = cpufromchannel[channelcount];
729 expadcval = (1 << 9) | (fCurrRobPos << 6) | (fCurrMcmPos << 2) | cpu;
734 if (channelcount % 2 == 0)
741 expword |= expadcval << 2;
742 expadcval = ( (expadcval << 1) | ( ( (expadcval >> 9) ^ (expadcval >> 6) ) & 1) ) & 0x3FF;
743 expword |= expadcval << 12;
744 expadcval = ( (expadcval << 1) | ( ( (expadcval >> 9) ^ (expadcval >> 6) ) & 1) ) & 0x3FF;
745 expword |= expadcval << 22;
746 expadcval = ( (expadcval << 1) | ( ( (expadcval >> 9) ^ (expadcval >> 6) ) & 1) ) & 0x3FF;
748 else if (mode == 2) {
750 expword = ((0x3f & evcnt) << 26) | ((fCurrSm + 1) << 21) | ((fCurrLayer + 1) << 18) |
751 ((fCurrStack + 1) << 15) |
752 (fCurrRobPos << 12) | (fCurrMcmPos << 8) | (cpu << 6) | (wordcount + 1);
754 else if (mode == 3) {
756 expword = ((0xfff & evcnt) << 20) | (fCurrSm << 15) | (fCurrLink/2 << 12) | (fCurrStack << 9) |
757 (fCurrRobPos << 6) | (fCurrMcmPos << 2) | (cpu << 0);
761 LinkError(kTPmodeInvalid, "Just reading");
764 diff = *fPayloadCurr ^ expword;
766 MCMError(kTPmismatch,
767 "Seen 0x%08x, expected 0x%08x, diff: 0x%08x (0x%02x)",
768 *fPayloadCurr, expword, diff, 0xff & (diff | diff >> 8 | diff >> 16 | diff >> 24));;
776 // continue with next MCM
778 return fPayloadCurr - start;
782 Int_t AliTRDrawStream::ReadZSData()
784 // read the zs data from one link from the current reading position
786 UInt_t *start = fPayloadCurr;
789 Int_t mcmcountExp = fCurrStack == 2 ? 48 : 64;
790 Int_t channelcount = 0;
791 Int_t channelcountExp = 0;
792 Int_t channelcountMax = 0;
794 Int_t currentTimebin = 0;
797 Int_t lastmcmpos = -1;
798 Int_t lastrobpos = -1;
800 if (fCurrNtimebins != fNtimebins) {
802 LinkError(kNtimebinsChanged,
803 "No. of timebins changed from %i to %i", fNtimebins, fCurrNtimebins);
804 fNtimebins = fCurrNtimebins;
807 timebins = fNtimebins;
809 while (*(fPayloadCurr) != fgkDataEndmarker &&
810 fPayloadCurr - fPayloadStart < fPayloadSize) {
812 // ----- Checking MCM Header -----
813 AliDebug(2, Form("MCM header: 0x%08x", *fPayloadCurr));
814 UInt_t *startPosMCM = fPayloadCurr;
816 // ----- checking for proper readout order - ROB -----
817 if (GetROBReadoutPos(ROB(*fPayloadCurr) / 2) >= lastrobpos) {
818 lastrobpos = GetROBReadoutPos(ROB(*fPayloadCurr) / 2);
823 fCurrRobPos = ROB(*fPayloadCurr);
825 // ----- checking for proper readout order - MCM -----
826 if (GetMCMReadoutPos(MCM(*fPayloadCurr)) > lastmcmpos) {
827 lastmcmpos = GetMCMReadoutPos(lastmcmpos);
832 fCurrMcmPos = MCM(*fPayloadCurr);
834 if (EvNo(*fPayloadCurr) != evno) {
836 evno = EvNo(*fPayloadCurr);
838 MCMError(kPtrgCntMismatch, "%i <-> %i", evno, EvNo(*fPayloadCurr));
841 Int_t adccoloff = AdcColOffset(*fPayloadCurr);
842 Int_t padcoloff = PadColOffset(*fPayloadCurr);
843 Int_t row = Row(*fPayloadCurr);
846 // ----- Reading ADC channels -----
847 AliDebug(2, Form("ADC mask: 0x%08x", *fPayloadCurr));
849 // ----- analysing the ADC mask -----
851 channelcountExp = GetNActiveChannelsFromMask(*fPayloadCurr);
852 channelcountMax = GetNActiveChannels(*fPayloadCurr);
853 Int_t channelmask = GetActiveChannels(*fPayloadCurr);
854 Int_t channelno = -1;
857 if (channelcountExp != channelcountMax) {
858 if (channelcountExp > channelcountMax) {
859 Int_t temp = channelcountExp;
860 channelcountExp = channelcountMax;
861 channelcountMax = temp;
863 while (channelcountExp < channelcountMax && channelcountExp < 21 &&
864 fPayloadCurr - fPayloadStart < fPayloadSize - 10 * channelcountExp - 1) {
865 MCMError(kAdcMaskInconsistent,
866 "Possible MCM-H: 0x%08x, possible ADC-mask: 0x%08x",
867 *(fPayloadCurr + 10 * channelcountExp),
868 *(fPayloadCurr + 10 * channelcountExp + 1) );
869 if (!CouldBeMCMhdr( *(fPayloadCurr + 10 * channelcountExp)) && !CouldBeADCmask( *(fPayloadCurr + 10 * channelcountExp + 1)))
875 MCMError(kAdcMaskInconsistent,
876 "Inconsistency in no. of active channels: Counter: %i, Mask: %i, chosen: %i!",
877 GetNActiveChannels(fPayloadCurr[-1]), GetNActiveChannelsFromMask(fPayloadCurr[-1]), channelcountExp);
879 AliDebug(2, Form("expecting %i active channels, timebins: %i", channelcountExp, fCurrNtimebins));
881 // ----- reading marked ADC channels -----
882 while (channelcount < channelcountExp && *(fPayloadCurr) != fgkDataEndmarker) {
885 while (channelno < 20 && (channelmask & 1 << channelno) == 0)
888 if (fCurrNtimebins > 30) {
889 currentTimebin = ((*fPayloadCurr >> 2) & 0x3f);
890 timebins = ((*fPayloadCurr >> 8) & 0xf) * 3;
897 AliDebug(2, Form("Now looking %i words", timebins / 3));
898 Int_t adccol = adccoloff - channelno;
899 Int_t padcol = padcoloff - channelno;
900 // if (adccol < 3 || adccol > 165)
901 // AliInfo(Form("writing channel %i of det %3i %i:%2i to adcrow/-col: %i/%i padcol: %i",
902 // channelno, fCurrHC/2, fCurrRobPos, fCurrMcmPos, row, adccol, padcol));
904 while (adcwc < timebins / 3 &&
905 *(fPayloadCurr) != fgkDataEndmarker &&
906 fPayloadCurr - fPayloadStart < fPayloadSize) {
907 int check = 0x3 & *fPayloadCurr;
908 if (channelno % 2 != 0) { // odd channel
909 if (check != 0x2 && channelno < 21) {
910 MCMError(kAdcCheckInvalid,
911 "%i for %2i. ADC word in odd channel %i",
912 check, adcwc+1, channelno);
915 else { // even channel
916 if (check != 0x3 && channelno < 21) {
917 MCMError(kAdcCheckInvalid,
918 "%i for %2i. ADC word in even channel %i",
919 check, adcwc+1, channelno);
923 // filling the actual timebin data
924 int tb2 = 0x3ff & *fPayloadCurr >> 22;
925 int tb1 = 0x3ff & *fPayloadCurr >> 12;
926 int tb0 = 0x3ff & *fPayloadCurr >> 2;
927 if (adcwc != 0 || fCurrNtimebins <= 30)
928 fAdcArray->SetDataByAdcCol(row, adccol, currentTimebin++, tb0);
931 fAdcArray->SetDataByAdcCol(row, adccol, currentTimebin++, tb1);
932 fAdcArray->SetDataByAdcCol(row, adccol, currentTimebin++, tb2);
938 if (adcwc != timebins / 3)
939 MCMError(kAdcDataAbort);
942 if (padcol > 0 && padcol < 144) {
943 fSignalIndex->AddIndexRC(row, padcol);
949 fStats.fStatsSector[fCurrSm].fStatsHC[fCurrHC%60].fNChannels += channelcount;
950 fStats.fStatsSector[fCurrSm].fNChannels += channelcount;
951 if (channelcount != channelcountExp)
952 MCMError(kAdcChannelsMiss);
955 fStats.fStatsSector[fCurrSm].fStatsHC[fCurrHC%60].fNMCMs++;
956 fStats.fStatsSector[fCurrSm].fNMCMs++;
958 if (IsDumping() && DumpingMCM(fCurrHC/2, fCurrRobPos, fCurrMcmPos)) {
959 DumpRaw(Form("Event %i: Det %3i ROB %i MCM %2i", fRawReader->GetEventIndex(), fCurrHC/2, fCurrRobPos, fCurrMcmPos),
960 startPosMCM, fPayloadCurr - startPosMCM);
963 // continue with next MCM
966 // check for missing MCMs (if header suppression is inactive)
967 if (((fCurrMajor & 0x1) == 0) && (mcmcount != mcmcountExp)) {
968 LinkError(kMissMcmHeaders,
969 "No. of MCM headers %i not as expected: %i",
970 mcmcount, mcmcountExp);
973 return (fPayloadCurr - start);
976 Int_t AliTRDrawStream::ReadNonZSData()
978 // read the non-zs data from one link from the current reading position
980 UInt_t *start = fPayloadCurr;
983 Int_t mcmcountExp = fCurrStack == 2 ? 48 : 64;
984 Int_t channelcount = 0;
985 Int_t channelcountExp = 0;
987 Int_t currentTimebin = 0;
990 Int_t lastmcmpos = -1;
991 Int_t lastrobpos = -1;
993 if (fCurrNtimebins != fNtimebins) {
995 LinkError(kNtimebinsChanged,
996 "No. of timebins changed from %i to %i", fNtimebins, fCurrNtimebins);
997 fNtimebins = fCurrNtimebins;
1000 timebins = fNtimebins;
1002 while (*(fPayloadCurr) != fgkDataEndmarker &&
1003 fPayloadCurr - fPayloadStart < fPayloadSize - 2) {
1005 // ----- Checking MCM Header -----
1006 AliDebug(2, Form("MCM header: 0x%08x", *fPayloadCurr));
1008 // ----- checking for proper readout order - ROB -----
1009 if (GetROBReadoutPos(ROB(*fPayloadCurr) / 2) >= lastrobpos) {
1010 lastrobpos = GetROBReadoutPos(ROB(*fPayloadCurr) / 2);
1013 ROBError(kPosUnexp);
1015 fCurrRobPos = ROB(*fPayloadCurr);
1017 // ----- checking for proper readout order - MCM -----
1018 if (GetMCMReadoutPos(MCM(*fPayloadCurr)) >= (lastmcmpos + 1) % 16) {
1019 lastmcmpos = GetMCMReadoutPos(*fPayloadCurr);
1022 MCMError(kPosUnexp);
1024 fCurrMcmPos = MCM(*fPayloadCurr);
1026 if (EvNo(*fPayloadCurr) != evno) {
1028 evno = EvNo(*fPayloadCurr);
1030 MCMError(kPtrgCntMismatch, "%i <-> %i", evno, EvNo(*fPayloadCurr));
1035 channelcountExp = 21;
1038 Int_t adccoloff = AdcColOffset(*fPayloadCurr);
1039 Int_t padcoloff = PadColOffset(*fPayloadCurr);
1040 Int_t row = Row(*fPayloadCurr);
1044 // ----- reading marked ADC channels -----
1045 while (channelcount < channelcountExp &&
1046 *(fPayloadCurr) != fgkDataEndmarker) {
1053 AliDebug(2, Form("Now looking %i words", timebins / 3));
1054 Int_t adccol = adccoloff - channelno;
1055 Int_t padcol = padcoloff - channelno;
1056 while (adcwc < timebins / 3 &&
1057 *(fPayloadCurr) != fgkDataEndmarker &&
1058 fPayloadCurr - fPayloadStart < fPayloadSize) {
1059 int check = 0x3 & *fPayloadCurr;
1060 if (channelno % 2 != 0) { // odd channel
1061 if (check != 0x2 && channelno < 21) {
1062 MCMError(kAdcCheckInvalid,
1063 "%i for %2i. ADC word in odd channel %i",
1064 check, adcwc+1, channelno);
1067 else { // even channel
1068 if (check != 0x3 && channelno < 21) {
1069 MCMError(kAdcCheckInvalid,
1070 "%i for %2i. ADC word in even channel %i",
1071 check, adcwc+1, channelno);
1075 // filling the actual timebin data
1076 int tb2 = 0x3ff & *fPayloadCurr >> 22;
1077 int tb1 = 0x3ff & *fPayloadCurr >> 12;
1078 int tb0 = 0x3ff & *fPayloadCurr >> 2;
1079 if (adcwc != 0 || fCurrNtimebins <= 30)
1080 fAdcArray->SetDataByAdcCol(row, adccol, currentTimebin++, tb0);
1083 fAdcArray->SetDataByAdcCol(row, adccol, currentTimebin++, tb1);
1084 fAdcArray->SetDataByAdcCol(row, adccol, currentTimebin++, tb2);
1090 if (adcwc != timebins / 3)
1091 MCMError(kAdcDataAbort);
1094 if (padcol > 0 && padcol < 144) {
1095 fSignalIndex->AddIndexRC(row, padcol);
1101 if (channelcount != channelcountExp)
1102 MCMError(kAdcChannelsMiss);
1104 // continue with next MCM
1107 // check for missing MCMs (if header suppression is inactive)
1108 if (mcmcount != mcmcountExp) {
1109 LinkError(kMissMcmHeaders,
1110 "%i not as expected: %i", mcmcount, mcmcountExp);
1113 return (fPayloadCurr - start);
1116 Int_t AliTRDrawStream::SeekNextLink()
1118 UInt_t *start = fPayloadCurr;
1120 // read until data endmarkers
1121 while (fPayloadCurr - fPayloadStart < fPayloadSize &&
1122 *fPayloadCurr != fgkDataEndmarker)
1125 // read all data endmarkers
1126 while (fPayloadCurr - fPayloadStart < fPayloadSize &&
1127 *fPayloadCurr == fgkDataEndmarker)
1130 return (fPayloadCurr - start);
1133 Bool_t AliTRDrawStream::ConnectTracklets(TTree *trklTree)
1135 fTrackletTree = trklTree;
1139 if (!fTrackletTree->GetBranch("hc"))
1140 fTrackletTree->Branch("hc", &fCurrHC, "hc/I");
1142 fTrackletTree->SetBranchAddress("hc", &fCurrHC);
1144 if (!fTrackletTree->GetBranch("trkl"))
1145 fTrackletTree->Branch("trkl", &fTrackletArray);
1147 fTrackletTree->SetBranchAddress("trkl", &fTrackletArray);
1153 void AliTRDrawStream::EquipmentError(ErrorCode_t err, const char *const msg, ...)
1155 // register error according to error code on equipment level
1156 // and return the corresponding error message
1158 fLastError.fSector = fCurrEquipmentId - 1024;
1159 fLastError.fStack = -1;
1160 fLastError.fLink = -1;
1161 fLastError.fRob = -1;
1162 fLastError.fMcm = -1;
1163 fLastError.fError = err;
1164 (this->*fStoreError)();
1167 if (fgErrorDebugLevel[err] > 10)
1168 AliDebug(fgErrorDebugLevel[err],
1169 Form("Event %6i: Eq. %2d - %s : %s",
1170 fRawReader->GetEventIndex(), fCurrEquipmentId, fgErrorMessages[err],
1171 (va_start(ap, msg), vsprintf(fErrorBuffer, msg, ap), va_end(ap), fErrorBuffer) ));
1173 AliError(Form("Event %6i: Eq. %2d - %s : %s",
1174 fRawReader->GetEventIndex(), fCurrEquipmentId, fgErrorMessages[err],
1175 (va_start(ap, msg), vsprintf(fErrorBuffer, msg, ap), va_end(ap), fErrorBuffer) ));
1176 fErrorFlags |= fgErrorBehav[err];
1180 void AliTRDrawStream::StackError(ErrorCode_t err, const char *const msg, ...)
1182 // register error according to error code on stack level
1183 // and return the corresponding error message
1185 fLastError.fSector = fCurrEquipmentId - 1024;
1186 fLastError.fStack = fCurrSlot;
1187 fLastError.fLink = -1;
1188 fLastError.fRob = -1;
1189 fLastError.fMcm = -1;
1190 fLastError.fError = err;
1191 (this->*fStoreError)();
1194 if (fgErrorDebugLevel[err] > 0)
1195 AliDebug(fgErrorDebugLevel[err],
1196 Form("Event %6i: Eq. %2d S %i - %s : %s",
1197 fRawReader->GetEventIndex(), fCurrEquipmentId, fCurrSlot, fgErrorMessages[err],
1198 (va_start(ap, msg), vsprintf(fErrorBuffer, msg, ap), va_end(ap), fErrorBuffer) ));
1200 AliError(Form("Event %6i: Eq. %2d S %i - %s : %s",
1201 fRawReader->GetEventIndex(), fCurrEquipmentId, fCurrSlot, fgErrorMessages[err],
1202 (va_start(ap, msg), vsprintf(fErrorBuffer, msg, ap), va_end(ap), fErrorBuffer) ));
1203 fErrorFlags |= fgErrorBehav[err];
1207 void AliTRDrawStream::LinkError(ErrorCode_t err, const char *const msg, ...)
1209 // register error according to error code on link level
1210 // and return the corresponding error message
1212 fLastError.fSector = fCurrEquipmentId - 1024;
1213 fLastError.fStack = fCurrSlot;
1214 fLastError.fLink = fCurrLink;
1215 fLastError.fRob = -1;
1216 fLastError.fMcm = -1;
1217 fLastError.fError = err;
1218 (this->*fStoreError)();
1221 if (fgErrorDebugLevel[err] > 0)
1222 AliDebug(fgErrorDebugLevel[err],
1223 Form("Event %6i: Eq. %2d S %i l %2i - %s : %s",
1224 fRawReader->GetEventIndex(), fCurrEquipmentId, fCurrSlot, fCurrLink, fgErrorMessages[err],
1225 (va_start(ap, msg), vsprintf(fErrorBuffer, msg, ap), va_end(ap), fErrorBuffer) ));
1227 AliError(Form("Event %6i: Eq. %2d S %i l %2i - %s : %s",
1228 fRawReader->GetEventIndex(), fCurrEquipmentId, fCurrSlot, fCurrLink, fgErrorMessages[err],
1229 (va_start(ap, msg), vsprintf(fErrorBuffer, msg, ap), va_end(ap), fErrorBuffer) ));
1230 fErrorFlags |= fgErrorBehav[err];
1234 void AliTRDrawStream::ROBError(ErrorCode_t err, const char *const msg, ...)
1236 // register error according to error code on ROB level
1237 // and return the corresponding error message
1239 fLastError.fSector = fCurrEquipmentId - 1024;
1240 fLastError.fStack = fCurrSlot;
1241 fLastError.fLink = fCurrLink;
1242 fLastError.fRob = fCurrRobPos;
1243 fLastError.fMcm = -1;
1244 fLastError.fError = err;
1245 (this->*fStoreError)();
1248 if (fgErrorDebugLevel[err] > 0)
1249 AliDebug(fgErrorDebugLevel[err],
1250 Form("Event %6i: Eq. %2d S %i l %2i ROB %i - %s : %s",
1251 fRawReader->GetEventIndex(), fCurrEquipmentId, fCurrSlot, fCurrLink, fCurrRobPos, fgErrorMessages[err],
1252 (va_start(ap, msg), vsprintf(fErrorBuffer, msg, ap), va_end(ap), fErrorBuffer) ));
1254 AliError(Form("Event %6i: Eq. %2d S %i l %2i ROB %i - %s : %s",
1255 fRawReader->GetEventIndex(), fCurrEquipmentId, fCurrSlot, fCurrLink, fCurrRobPos, fgErrorMessages[err],
1256 (va_start(ap, msg), vsprintf(fErrorBuffer, msg, ap), va_end(ap), fErrorBuffer) ));
1257 fErrorFlags |= fgErrorBehav[err];
1261 void AliTRDrawStream::MCMError(ErrorCode_t err, const char *const msg, ...)
1263 // register error according to error code on MCM level
1264 // and return the corresponding error message
1266 fLastError.fSector = fCurrEquipmentId - 1024;
1267 fLastError.fStack = fCurrSlot;
1268 fLastError.fLink = fCurrLink;
1269 fLastError.fRob = fCurrRobPos;
1270 fLastError.fMcm = fCurrMcmPos;
1271 fLastError.fError = err;
1272 (this->*fStoreError)();
1275 if (fgErrorDebugLevel[err] > 0)
1276 AliDebug(fgErrorDebugLevel[err],
1277 Form("Event %6i: Eq. %2d S %i l %2i ROB %i MCM %2i - %s : %s",
1278 fRawReader->GetEventIndex(), fCurrEquipmentId, fCurrSlot, fCurrLink, fCurrRobPos, fCurrMcmPos, fgErrorMessages[err],
1279 (va_start(ap, msg), vsprintf(fErrorBuffer, msg, ap), va_end(ap), fErrorBuffer) ));
1281 AliError(Form("Event %6i: Eq. %2d S %i l %2i ROB %i MCM %2i - %s : %s",
1282 fRawReader->GetEventIndex(), fCurrEquipmentId, fCurrSlot, fCurrLink, fCurrRobPos, fCurrMcmPos, fgErrorMessages[err],
1283 (va_start(ap, msg), vsprintf(fErrorBuffer, msg, ap), va_end(ap), fErrorBuffer) ));
1284 fErrorFlags |= fgErrorBehav[err];
1287 const char* AliTRDrawStream::GetErrorMessage(ErrorCode_t errCode)
1289 // return the error message for the given error code
1291 if (errCode > 0 && errCode < kLastErrorCode)
1292 return fgErrorMessages[errCode];
1297 void AliTRDrawStream::AliTRDrawStats::ClearStats()
1299 // clear statistics (includes clearing sector-wise statistics)
1302 for (Int_t iSector = 0; iSector < 18; iSector++) {
1303 fStatsSector[iSector].ClearStats();
1308 void AliTRDrawStream::AliTRDrawStats::AliTRDrawStatsSector::ClearStats()
1310 // clear statistics (includes clearing HC-wise statistics)
1318 for (Int_t iHC = 0; iHC < 60; iHC++) {
1319 fStatsHC[iHC].ClearStats();
1323 void AliTRDrawStream::AliTRDrawStats::AliTRDrawStatsSector::AliTRDrawStatsHC::ClearStats()
1334 void AliTRDrawStream::SetDumpMCM(Int_t det, Int_t rob, Int_t mcm, Bool_t dump)
1336 // mark MCM for dumping of raw data
1339 fDumpMCM[fNDumpMCMs++] = (det << 7) | (rob << 4) | mcm;
1343 for (iMCM = 0; iMCM < fNDumpMCMs; iMCM++) {
1344 if (fDumpMCM[iMCM] == ((det << 7) | (rob << 4) | mcm)) {
1349 for ( ; iMCM < fNDumpMCMs; iMCM++) {
1350 fDumpMCM[iMCM] = fDumpMCM[iMCM+1];
1355 Bool_t AliTRDrawStream::DumpingMCM(Int_t det, Int_t rob, Int_t mcm)
1357 // check if MCM data should be dumped
1359 for (Int_t iMCM = 0; iMCM < fNDumpMCMs; iMCM++) {
1360 if (fDumpMCM[iMCM] == ((det << 7) | (rob << 4) | mcm)) {
1367 void AliTRDrawStream::DumpRaw(TString title, UInt_t *start, Int_t length)
1373 for ( ; pos+3 < length; pos += 4) {
1374 title += Form("0x%08x 0x%08x 0x%08x 0x%08x\n",
1375 start[pos+0], start[pos+1], start[pos+2], start[pos+3]);
1377 for ( ; pos < length; pos++) {
1378 title += Form("0x%08x ", start[pos]);
1383 AliTRDrawStream::AliTRDrawStreamError::AliTRDrawStreamError(Int_t error, Int_t sector, Int_t stack, Int_t link, Int_t rob, Int_t mcm) :