#include <cstdio>
#include <cstdarg>
#if defined(TRD_RAW_CRC)
#include <boost/crc.hpp>
#endif
#include "TClonesArray.h"
#include "TTree.h"
#include "AliLog.h"
#include "AliRawReader.h"
#include "AliTRDcalibDB.h"
#include "AliTRDdigitsManager.h"
#include "AliTRDdigitsParam.h"
#include "AliTRDcalibDB.h"
#include "AliTRDmcmSim.h"
#include "AliTRDtrapConfig.h"
#include "AliTRDarrayADC.h"
#include "AliTRDarrayDictionary.h"
#include "AliTRDSignalIndex.h"
#include "AliTRDtrackletWord.h"
#include "AliTRDtrackletMCM.h"
#include "AliESDTrdTrack.h"
#include "AliTRDrawStream.h"
ClassImp(AliTRDrawStream)
Int_t AliTRDrawStream::fgMcmOrder[] = {12, 13, 14, 15,
8, 9, 10, 11,
4, 5, 6, 7,
0, 1, 2, 3};
Int_t AliTRDrawStream::fgRobOrder [] = {0, 1, 2, 3};
const Int_t AliTRDrawStream::fgkNlinks = 12;
const Int_t AliTRDrawStream::fgkNstacks = 5;
const Int_t AliTRDrawStream::fgkNsectors = 18;
const Int_t AliTRDrawStream::fgkNtriggers = 12;
const UInt_t AliTRDrawStream::fgkDataEndmarker = 0x00000000;
const UInt_t AliTRDrawStream::fgkTrackletEndmarker = 0x10001000;
const UInt_t AliTRDrawStream::fgkStackEndmarker[] = { 0xe0d01000, 0xe0d10000 };
const char* AliTRDrawStream::fgkErrorMessages[] = {
"Unknown error",
"Link monitor active",
"Event counter mismatch",
"not a TRD equipment (1024-1041)",
"Invalid Stack header",
"Invalid detector number",
"Invalid pad row",
"No digits could be retrieved from the digitsmanager",
"HC header mismatch",
"HC check bits wrong",
"Unexpected position in readout stream",
"Invalid testpattern mode",
"Testpattern mismatch",
"Number of timebins changed",
"ADC mask inconsistent",
"ADC check bits invalid",
"Missing ADC data",
"Missing expected ADC channels",
"Missing MCM headers",
"Missing TP data",
"CRC mismatch"
};
Int_t AliTRDrawStream::fgErrorDebugLevel[] = {
0,
0,
2,
1,
0,
1,
0,
1,
0,
1,
2,
1,
0,
1,
1,
2,
1,
1,
1,
0,
0
};
AliTRDrawStream::ErrorBehav_t AliTRDrawStream::fgErrorBehav[] = {
AliTRDrawStream::kTolerate,
AliTRDrawStream::kDiscardHC,
AliTRDrawStream::kTolerate,
AliTRDrawStream::kAbort,
AliTRDrawStream::kAbort,
AliTRDrawStream::kAbort,
AliTRDrawStream::kDiscardMCM,
AliTRDrawStream::kAbort,
AliTRDrawStream::kDiscardHC,
AliTRDrawStream::kDiscardHC,
AliTRDrawStream::kTolerate,
AliTRDrawStream::kTolerate,
AliTRDrawStream::kTolerate,
AliTRDrawStream::kTolerate,
AliTRDrawStream::kTolerate,
AliTRDrawStream::kTolerate,
AliTRDrawStream::kTolerate,
AliTRDrawStream::kTolerate,
AliTRDrawStream::kTolerate,
AliTRDrawStream::kTolerate,
AliTRDrawStream::kTolerate
};
AliTRDrawStream::AliTRDrawStream(AliRawReader *rawReader) :
fStoreError(&AliTRDrawStream::ForgetError),
fRawReader(rawReader),
fDigitsManager(0x0),
fDigitsParam(0x0),
fErrors(0x0),
fLastError(),
fErrorFlags(0),
fStats(),
fPayloadStart(0x0),
fPayloadCurr(0x0),
fPayloadSize(0),
fNtimebins(-1),
fLastEvId(-1),
fCurrSlot(-1),
fCurrLink(-1),
fCurrRobPos(-1),
fCurrMcmPos(-1),
fCurrEquipmentId(0),
fCurrSmHeaderSize(0),
fCurrSmHeaderVersion(0),
fCurrTrailerReadout(0),
fCurrTrgHeaderAvail(0),
fCurrTrgHeaderReadout(0),
fCurrTrkHeaderAvail(0),
fCurrStackEndmarkerAvail(0),
fCurrEvType(0),
fCurrTriggerEnable(0),
fCurrTriggerFired(0),
fCurrTrackEnable(0),
fCurrTrackletEnable(0),
fCurrStackMask(0),
#ifdef TRD_RAW_DEBUG
fCurrL0Count(),
fCurrL1aCount(),
fCurrL1rCount(),
fCurrL2aCount(),
fCurrL2rCount(),
fCurrL0offset(),
#endif
fCurrTrkHeaderIndexWord(0x0),
fCurrTrkHeaderSize(0x0),
fCurrTrkFlags(0x0),
fCurrTrgHeaderIndexWord(0x0),
fCurrTrgHeaderSize(0x0),
fCurrTrgFlags(0x0),
fCurrStackIndexWord(0x0),
fCurrStackHeaderSize(0x0),
fCurrStackHeaderVersion(0x0),
fCurrLinkMask(0x0),
fCurrCleanCheckout(0x0),
fCurrBoardId(0x0),
fCurrHwRev(-1),
fCurrHwRevTMU(0x0),
fCurrLinkMonitorFlags(0x0),
fCurrLinkDataTypeFlags(0x0),
fCurrLinkDebugFlags(0x0),
fCurrMatchFlagsSRAM(),
fCurrMatchFlagsPostBP(),
fCurrChecksumStack(),
fCurrChecksumSIU(0),
fCurrSpecial(-1),
fCurrMajor(-1),
fCurrMinor(-1),
fCurrAddHcWords(-1),
fCurrSm(-1),
fCurrStack(-1),
fCurrLayer(-1),
fCurrSide(-1),
fCurrHC(-1),
fCurrCheck(-1),
fCurrNtimebins(-1),
fCurrPtrgCnt(-1),
fCurrPtrgPhase(-1),
#ifdef TRD_RAW_DEBUG
fCurrBC(),
#endif
fNDumpMCMs(0),
fAdcArray(0x0),
fSignalIndex(0x0),
fTracklets(0x0),
fTracks(0x0),
fMarkers(0x0)
{
fCurrTrkHeaderIndexWord = new UInt_t[fgkNstacks];
fCurrTrkHeaderSize = new UInt_t[fgkNstacks];
fCurrTrkFlags = new ULong64_t[fgkNsectors*fgkNstacks];
fCurrTrgHeaderIndexWord = new UInt_t[fgkNtriggers];
fCurrTrgHeaderSize = new UInt_t[fgkNtriggers];
fCurrTrgFlags = new UInt_t[fgkNsectors];
#ifdef TRD_RAW_DEBUG
fCurrL0Count = new UInt_t[fgkNsectors];
fCurrL1aCount = new UInt_t[fgkNsectors];
fCurrL1rCount = new UInt_t[fgkNsectors];
fCurrL2aCount = new UInt_t[fgkNsectors];
fCurrL2rCount = new UInt_t[fgkNsectors];
#endif
fCurrStackIndexWord = new UInt_t[fgkNstacks];
fCurrStackHeaderSize = new UInt_t[fgkNstacks];
fCurrStackHeaderVersion = new UInt_t[fgkNstacks];
fCurrLinkMask = new UInt_t[fgkNstacks];
fCurrCleanCheckout = new UInt_t[fgkNstacks];
fCurrBoardId = new UInt_t[fgkNstacks];
fCurrHwRevTMU = new UInt_t[fgkNstacks];
fCurrLinkMonitorFlags = new UInt_t[fgkNsectors * fgkNstacks * fgkNlinks];
fCurrLinkDataTypeFlags = new UInt_t[fgkNstacks * fgkNlinks];
fCurrLinkDebugFlags = new UInt_t[fgkNstacks * fgkNlinks];
for (Int_t iSector = 0; iSector < fgkNsectors; iSector++)
fCurrTrgFlags[iSector] = 0;
for (Int_t i = 0; i < 100; i++)
fDumpMCM[i] = 0;
fErrors = new TTree("errorStats", "Error statistics");
fErrors->SetDirectory(0x0);
fErrors->Branch("error", &fLastError);
fErrors->SetCircular(1000);
for (Int_t i = 0; i < 100; i++) {
fErrorBuffer[i] = 0;
}
}
AliTRDrawStream::~AliTRDrawStream()
{
delete fErrors;
delete [] fCurrTrkHeaderIndexWord;
delete [] fCurrTrkHeaderSize;
delete [] fCurrTrkFlags;
delete [] fCurrTrgHeaderIndexWord;
delete [] fCurrTrgHeaderSize;
delete [] fCurrTrgFlags;
delete [] fCurrStackIndexWord;
delete [] fCurrStackHeaderSize;
delete [] fCurrStackHeaderVersion;
delete [] fCurrLinkMask;
delete [] fCurrCleanCheckout;
delete [] fCurrBoardId;
delete [] fCurrHwRevTMU;
delete [] fCurrLinkMonitorFlags;
delete [] fCurrLinkDataTypeFlags;
delete [] fCurrLinkDebugFlags;
}
Bool_t AliTRDrawStream::ReadEvent()
{
if (!fRawReader) {
AliError("No raw reader available");
return kFALSE;
}
fDigitsParam = 0x0;
UChar_t *buffer = 0x0;
while (fRawReader->ReadNextData(buffer)) {
fCurrEquipmentId = fRawReader->GetEquipmentId();
AliDebug(2, Form("equipment: %i", fCurrEquipmentId));
if (fCurrEquipmentId < kDDLOffset || fCurrEquipmentId > kDDLMax) {
EquipmentError(kNonTrdEq, "Skipping");
continue;
}
if (fMarkers)
new ((*fMarkers)[fMarkers->GetEntriesFast()])
AliTRDrawStreamError(-kSecactive, fCurrEquipmentId - kDDLOffset);
ReadGTUHeaders((UInt_t*) buffer);
if (fCurrTrailerReadout)
ReadGTUTrailer();
#ifdef TRD_RAW_CRC
boost::crc_optimal<16, 0x8005, 0, 0, false, false> checksumStack[5];
boost::crc_optimal<32, 0x04C11DB7, 0, 0, false, false> checksumSIU;
checksumSIU.reset();
UInt_t temp = 0xffffffff;
checksumSIU.process_bytes(&temp, sizeof(UInt_t));
UInt_t *data = (UInt_t*) fRawReader->GetDataHeader();
checksumSIU.process_bytes(&data[1], 7*sizeof(UInt_t));
checksumSIU.process_bytes(buffer, fRawReader->GetDataSize()-4);
if (checksumSIU() != fCurrChecksumSIU) {
EquipmentError(kCRCmismatch, "SIU data - recalc: 0x%08x - 0x%08x", fCurrChecksumSIU, checksumSIU());
}
#endif
AliDebug(2, Form("Stack mask 0x%02x", fCurrStackMask));
for (Int_t iStack = 0; iStack < fgkNstacks; iStack++) {
fCurrSlot = iStack;
#ifdef TRD_RAW_CRC
checksumStack[iStack].reset();
#endif
if ((fCurrStackMask & (1 << fCurrSlot)) == 0)
continue;
AliDebug(2, Form("Stack %i, Link mask: 0x%02x", fCurrSlot, fCurrLinkMask[fCurrSlot]));
for (Int_t iLink = 0; iLink < fgkNlinks; iLink++) {
fCurrLink = iLink;
fCurrHC = (fCurrEquipmentId - kDDLOffset) * fgkNstacks * fgkNlinks +
fCurrSlot * fgkNlinks + iLink;
if ((fCurrLinkMask[fCurrSlot] & (1 << fCurrLink)) == 0)
continue;
#ifdef TRD_RAW_CRC
UInt_t *start = fPayloadCurr;
#endif
Int_t size = 0;
fErrorFlags = 0;
if (fCurrLinkMonitorFlags[(((fCurrEquipmentId - kDDLOffset) * fgkNstacks) + fCurrSlot) * fgkNlinks + fCurrLink] != 0) {
LinkError(kLinkMonitor);
if (fgErrorBehav[kLinkMonitor] == kTolerate)
size += ReadLinkData();
}
else
size += ReadLinkData();
size += SeekNextLink();
#ifdef TRD_RAW_CRC
UShort_t crc = CalcLinkChecksum(start, size);
checksumStack[iStack].process_bytes(&crc, sizeof(UShort_t));
#endif
}
#ifdef TRD_RAW_CRC
if (fDigitsManager && (checksumStack[iStack]() != fCurrChecksumStack[fCurrEquipmentId - kDDLOffset][iStack])) {
StackError(kCRCmismatch, "data - recalc: 0x%04x - 0x%04x", fCurrChecksumStack[fCurrEquipmentId - kDDLOffset][iStack], checksumStack[iStack]());
}
#endif
SeekNextStack();
}
}
return kTRUE;
}
Bool_t AliTRDrawStream::NextDDL()
{
if (!fRawReader)
return kFALSE;
fCurrEquipmentId = 0;
fCurrSlot = 0;
fCurrLink = 0;
UChar_t *buffer = 0x0;
while (fRawReader->ReadNextData(buffer)) {
fCurrEquipmentId = fRawReader->GetEquipmentId();
AliDebug(2, Form("equipment: %i", fCurrEquipmentId));
if (fCurrEquipmentId < kDDLOffset || fCurrEquipmentId > kDDLMax) {
EquipmentError(kNonTrdEq, "Skipping");
continue;
}
if (fMarkers)
new ((*fMarkers)[fMarkers->GetEntriesFast()])
AliTRDrawStreamError(-kSecactive, fCurrEquipmentId - kDDLOffset);
ReadGTUHeaders((UInt_t*) buffer);
if (fCurrTrailerReadout)
ReadGTUTrailer();
return kTRUE;
}
return kFALSE;
}
Int_t AliTRDrawStream::NextChamber(AliTRDdigitsManager *digMgr)
{
fDigitsManager = digMgr;
fDigitsParam = 0x0;
fErrorFlags = 0;
if (!fRawReader) {
AliError("No raw reader available");
return -1;
}
while (fCurrSlot < 0 || fCurrSlot >= fgkNstacks) {
if (!NextDDL()) {
fCurrSlot = -1;
return -1;
}
while ((fCurrSlot < fgkNstacks) &&
(((fCurrStackMask & (1 << fCurrSlot)) == 0) ||
((fCurrLinkMask[fCurrSlot] & (1 << fCurrLink))) == 0)) {
if ((fCurrStackMask & (1 << fCurrSlot)) == 0) {
++fCurrSlot;
fCurrSlot = 0;
continue;
}
fCurrLink++;
if (fCurrLink >= fgkNlinks) {
SeekNextStack();
fCurrLink = 0;
fCurrSlot++;
}
}
}
AliDebug(2, Form("Stack %i, Link %i, mask: 0x%02x", fCurrSlot, fCurrLink, fCurrLinkMask[fCurrSlot]));
fCurrHC = (fCurrEquipmentId - kDDLOffset) * fgkNlinks * fgkNstacks +
fCurrSlot * fgkNlinks + fCurrLink;
if (fCurrLinkMonitorFlags[(((fCurrEquipmentId - kDDLOffset) * fgkNstacks) + fCurrSlot) * fgkNlinks + fCurrLink] != 0) {
LinkError(kLinkMonitor);
if (fgErrorBehav[kLinkMonitor] == kTolerate)
ReadLinkData();
}
else
ReadLinkData();
SeekNextLink();
if (fCurrLink % 2 == 0) {
fCurrLink++;
fCurrHC++;
if (fCurrLinkMask[fCurrSlot] & (1 << fCurrLink)) {
if (fCurrLinkMonitorFlags[(((fCurrEquipmentId - kDDLOffset) * fgkNstacks) + fCurrSlot) * fgkNlinks + fCurrLink] != 0) {
LinkError(kLinkMonitor);
if (fgErrorBehav[kLinkMonitor] == kTolerate)
ReadLinkData();
}
else {
ReadLinkData();
}
SeekNextLink();
}
}
do {
if ((fCurrStackMask & (1 << fCurrSlot)) == 0) {
fCurrLink = 0;
fCurrSlot++;
}
else {
fCurrLink++;
if (fCurrLink >= fgkNlinks) {
SeekNextStack();
fCurrLink = 0;
fCurrSlot++;
}
}
} while ((fCurrSlot < fgkNstacks) &&
(((fCurrStackMask & (1 << fCurrSlot)) == 0) ||
((fCurrLinkMask[fCurrSlot] & (1 << fCurrLink))) == 0));
if (fCurrSm < 0 || fCurrSm >= fgkNsectors || fCurrStack < 0 || fCurrStack >= fgkNstacks || fCurrLayer < 0 || fCurrLayer >= fgkNlinks/2)
return ((fCurrEquipmentId-kDDLOffset) + fCurrSlot * fgkNlinks/2 + fCurrLink/2);
else
return (fCurrSm * fgkNstacks*fgkNlinks/2 + fCurrStack * fgkNlinks/2 + fCurrLayer);
}
Int_t AliTRDrawStream::ReadGTUHeaders(UInt_t *buffer)
{
if (fCurrEquipmentId >= kDDLOffset && fCurrEquipmentId <= kDDLMax) {
fPayloadCurr = fPayloadStart = buffer;
fPayloadSize = fRawReader->GetDataSize() / sizeof(UInt_t);
fStats.fStatsSector[fCurrEquipmentId - kDDLOffset].fBytes = fRawReader->GetDataSize();
AliDebug(2, Form("Read buffer of size: %i", fRawReader->GetDataSize()));
AliDebug(1, DumpRaw("raw data", fPayloadCurr, TMath::Min(fPayloadSize, 1000)));
if (ReadSmHeader() < 0) {
AliError(Form("Reading SM header failed, skipping this DDL %i", fCurrEquipmentId));
return -1;
}
if (fCurrTrkHeaderAvail) {
for (Int_t iStack = 0; iStack < fgkNstacks; iStack++) {
if ((fCurrStackMask & (1 << iStack)) != 0)
ReadTrackingHeader(iStack);
}
}
if (fCurrTrgHeaderAvail)
ReadTriggerHeaders();
for (Int_t iStack = 0; iStack < fgkNstacks; iStack++) {
if ((fCurrStackMask & (1 << iStack)) != 0)
ReadStackHeader(iStack);
}
return 0;
}
else
return -1;
}
Int_t AliTRDrawStream::ReadSmHeader()
{
if (fPayloadCurr - fPayloadStart >= fPayloadSize - 1) {
EquipmentError(kUnknown, "SM Header incomplete");
return -1;
}
fCurrTrgFlags[fCurrEquipmentId-kDDLOffset] = 0;
fCurrSmHeaderSize = ((*fPayloadCurr) >> 16) & 0xffff;
fCurrSmHeaderVersion = ((*fPayloadCurr) >> 12) & 0xf;
fCurrTrackEnable = ((*fPayloadCurr) >> 6) & 0x1;
fCurrTrackletEnable = ((*fPayloadCurr) >> 5) & 0x1;
fCurrStackMask = ((*fPayloadCurr) ) & 0x1f;
fCurrHwRev = (fPayloadCurr[1] >> 12) & 0xffff;
fCurrStackEndmarkerAvail = 0;
switch (fCurrSmHeaderVersion) {
case 0xb:
fCurrTrailerReadout = 0;
fCurrTrgHeaderAvail = 0;
fCurrEvType = 0;
fCurrTrkHeaderAvail = 0;
DecodeGTUtracks();
break;
case 0xc:
fCurrTrailerReadout = ((*fPayloadCurr) >> 10) & 0x1;
fCurrTrgHeaderAvail = 1;
fCurrTrgHeaderReadout = ((*fPayloadCurr) >> 9) & 0x1;
fCurrEvType = ((*fPayloadCurr) >> 7) & 0x3;
fCurrTrkHeaderAvail = fCurrTrackEnable;
fCurrTriggerEnable = (fPayloadCurr[2] >> 8) & 0xfff;
fCurrTriggerFired = (fPayloadCurr[2] >> 20) & 0xfff;
fCurrTrgFlags[fCurrEquipmentId-kDDLOffset] = fCurrTriggerFired;
break;
case 0xd:
fCurrTrailerReadout = ((*fPayloadCurr) >> 10) & 0x1;
fCurrTrgHeaderAvail = 1;
fCurrTrgHeaderReadout = ((*fPayloadCurr) >> 9) & 0x1;
fCurrEvType = ((*fPayloadCurr) >> 7) & 0x3;
fCurrTrkHeaderAvail = fCurrTrackEnable;
fCurrTriggerEnable = (fPayloadCurr[2] >> 8) & 0xfff;
fCurrTriggerFired = (fPayloadCurr[2] >> 20) & 0xfff;
fCurrTrgFlags[fCurrEquipmentId-kDDLOffset] = fCurrTriggerFired;
fCurrStackEndmarkerAvail = 1;
#ifdef TRD_RAW_DEBUG
if (fCurrSmHeaderSize > 7) {
fCurrL0Count[fCurrEquipmentId-kDDLOffset] = fPayloadCurr[3];
fCurrL1aCount[fCurrEquipmentId-kDDLOffset] = fPayloadCurr[4];
fCurrL1rCount[fCurrEquipmentId-kDDLOffset] = fPayloadCurr[5];
fCurrL2aCount[fCurrEquipmentId-kDDLOffset] = fPayloadCurr[6];
fCurrL2rCount[fCurrEquipmentId-kDDLOffset] = fPayloadCurr[7];
}
#endif
break;
default:
AliError(Form("unknown SM header version: 0x%x", fCurrSmHeaderVersion));
}
AliDebug(5, Form("SM header: size: %i, version: %i, track enable: %i, tracklet enable: %i, stack mask: %2x, trailer: %i, trgheader: %i, trkheader: %i",
fCurrSmHeaderSize,
fCurrSmHeaderVersion,
fCurrTrackEnable,
fCurrTrackletEnable,
fCurrStackMask,
fCurrTrailerReadout,
fCurrTrgHeaderAvail,
fCurrTrkHeaderAvail ));
fPayloadCurr += fCurrSmHeaderSize + 1;
return fCurrSmHeaderSize + 1;
}
Int_t AliTRDrawStream::DecodeGTUtracks()
{
Int_t sector = fCurrEquipmentId-kDDLOffset;
if ((sector < 0) || (sector > 17)) {
AliError(Form("Invalid sector %i for GTU tracks", sector));
return -1;
}
AliDebug(1, DumpRaw(Form("GTU tracks in sector %2i (hw rev %i)", sector, fCurrHwRev),
fPayloadCurr + 4, 10, 0xffe0ffff));
fCurrTrgFlags[sector] = 0;
if (fCurrHwRev < 1772) {
UInt_t fastWord;
ULong64_t trackWord = 0;
Int_t stack = 0;
Int_t idx = 0;
for (UInt_t iWord = 4; iWord < fCurrSmHeaderSize; iWord++) {
if (fPayloadCurr[iWord] == 0x10000000) {
stack++;
idx = 0;
}
else {
if ((idx == 0) &&
((fPayloadCurr[iWord] & 0xfffff0f0) == 0x13370000)) {
fastWord = fPayloadCurr[iWord];
fCurrTrgFlags[sector] |= 1 << (stack+11);
AliDebug(1, Form("stack %i: fast trigger word: 0x%08x", stack, fastWord));
continue;
}
else if ((idx & 0x1) == 0x1) {
trackWord |= ((ULong64_t) fPayloadCurr[iWord]) << 32;
AliDebug(1,Form("track debug word: 0x%016llx", trackWord));
if (fTracks) {
AliESDTrdTrack *trk = new ((*fTracks)[fTracks->GetEntriesFast()])
AliESDTrdTrack();
trk->SetSector(sector);
trk->SetStack((trackWord >> 60) & 0x7);
trk->SetA(0);
trk->SetB(0);
trk->SetPID(0);
trk->SetLayerMask((trackWord >> 16) & 0x3f);
trk->SetTrackletIndex((trackWord >> 22) & 0x3f, 0);
trk->SetTrackletIndex((trackWord >> 28) & 0x3f, 1);
trk->SetTrackletIndex((trackWord >> 34) & 0x3f, 2);
trk->SetTrackletIndex((trackWord >> 40) & 0x3f, 3);
trk->SetTrackletIndex((trackWord >> 46) & 0x3f, 4);
trk->SetTrackletIndex((trackWord >> 52) & 0x3f, 5);
trk->SetFlags(0);
trk->SetReserved(0);
trk->SetLabel(-3);
Float_t pt = (((Int_t) (trackWord & 0xffff) ^ 0x8000) - 0x8000)/128.;
if (TMath::Abs(pt) > 0.1) {
trk->SetA((Int_t) (0.15*51625./100./pt / 160e-4 * 2));
}
}
}
else {
trackWord = fPayloadCurr[iWord];
}
idx++;
}
}
}
else if (fCurrHwRev < 1804) {
UInt_t fastWord;
ULong64_t trackWord = 0;
Int_t stack = 0;
Int_t idx = 0;
for (UInt_t iWord = 4; iWord < fCurrSmHeaderSize; iWord++) {
if (fPayloadCurr[iWord] == 0xffe0ffff) {
stack++;
idx = 0;
}
else {
if ((idx == 0) &&
((fPayloadCurr[iWord] & 0xfffff0f0) == 0x13370000)) {
fastWord = fPayloadCurr[iWord];
fCurrTrgFlags[sector] |= 1 << (stack+11);
AliDebug(1, Form("stack %i: fast trigger word: 0x%08x", stack, fastWord));
continue;
}
else if ((idx & 0x1) == 0x1) {
trackWord |= ((ULong64_t) fPayloadCurr[iWord]) << 32;
AliDebug(1, Form("track debug word: 0x%016llx", trackWord));
if (fTracks) {
AliESDTrdTrack *trk = new ((*fTracks)[fTracks->GetEntriesFast()])
AliESDTrdTrack();
trk->SetSector(fCurrEquipmentId-kDDLOffset);
trk->SetStack((trackWord >> 60) & 0x7);
trk->SetA(0);
trk->SetB(0);
trk->SetPID(0);
trk->SetLayerMask((trackWord >> 16) & 0x3f);
trk->SetTrackletIndex((trackWord >> 22) & 0x3f, 0);
trk->SetTrackletIndex((trackWord >> 28) & 0x3f, 1);
trk->SetTrackletIndex((trackWord >> 34) & 0x3f, 2);
trk->SetTrackletIndex((trackWord >> 40) & 0x3f, 3);
trk->SetTrackletIndex((trackWord >> 46) & 0x3f, 4);
trk->SetTrackletIndex((trackWord >> 52) & 0x3f, 5);
trk->SetFlags(0);
trk->SetReserved(0);
trk->SetLabel(-3);
Float_t pt = (((Int_t) (trackWord & 0xffff) ^ 0x8000) - 0x8000)/128.;
if (TMath::Abs(pt) > 0.1) {
trk->SetA((Int_t) (-0.15*51625./100./pt / 160e-4 * 2));
}
}
}
else {
trackWord = fPayloadCurr[iWord];
}
idx++;
}
}
}
else if (fCurrHwRev < 1819) {
UInt_t fastWord;
ULong64_t trackWord = 0;
Int_t stack = 0;
Int_t idx = 0;
for (UInt_t iWord = 4; iWord < fCurrSmHeaderSize; iWord++) {
if (fPayloadCurr[iWord] == 0xffe0ffff) {
stack++;
idx = 0;
}
else {
if ((idx == 0) &&
((fPayloadCurr[iWord] & 0xfffff0f0) == 0x13370000)) {
fastWord = fPayloadCurr[iWord];
if (fastWord & (1 << 13))
fCurrTrgFlags[sector] |= 1 << (stack+11);
AliDebug(1, Form("stack %i: fast trigger word: 0x%08x", stack, fastWord));
continue;
}
else if ((idx & 0x1) == 0x1) {
trackWord |= ((ULong64_t) fPayloadCurr[iWord]) << 32;
AliDebug(1, Form("track debug word: 0x%016llx", trackWord));
if (fTracks) {
AliESDTrdTrack *trk = new ((*fTracks)[fTracks->GetEntriesFast()])
AliESDTrdTrack();
trk->SetSector(fCurrEquipmentId-kDDLOffset);
trk->SetStack((trackWord >> 60) & 0x7);
trk->SetA(0);
trk->SetB(0);
trk->SetPID(0);
trk->SetLayerMask((trackWord >> 16) & 0x3f);
trk->SetTrackletIndex((trackWord >> 22) & 0x3f, 0);
trk->SetTrackletIndex((trackWord >> 28) & 0x3f, 1);
trk->SetTrackletIndex((trackWord >> 34) & 0x3f, 2);
trk->SetTrackletIndex((trackWord >> 40) & 0x3f, 3);
trk->SetTrackletIndex((trackWord >> 46) & 0x3f, 4);
trk->SetTrackletIndex((trackWord >> 52) & 0x3f, 5);
trk->SetFlags(0);
trk->SetReserved(0);
trk->SetLabel(-3);
Float_t pt = (((Int_t) (trackWord & 0xffff) ^ 0x8000) - 0x8000)/128.;
if (TMath::Abs(pt) > 0.1) {
trk->SetA((Int_t) (0.15*51625./100./trk->Pt() / 160e-4 * 2));
}
}
}
else {
trackWord = fPayloadCurr[iWord];
}
idx++;
}
}
}
else if (fCurrHwRev < 1860) {
UInt_t fastWord;
ULong64_t trackWord = 0;
Int_t stack = 0;
Int_t idx = 0;
Bool_t upperWord = kFALSE;
Int_t word = 0;
for (UInt_t iWord = 4; iWord < fCurrSmHeaderSize; iWord++) {
if (fPayloadCurr[iWord] == 0xffe0ffff) {
stack++;
idx = 0;
upperWord = kFALSE;
}
else {
if (upperWord) {
word |= (fPayloadCurr[iWord] & 0xffff0000);
upperWord = kFALSE;
}
else {
word = (fPayloadCurr[iWord] & 0xffff0000) >> 16;
upperWord = kTRUE;
continue;
}
if ((word & 0xffff0008) == 0x13370008) {
fastWord = word;
AliDebug(1, Form("stack %i: fast track word: 0x%08x", stack, fastWord));
if (fastWord & (1 << 13))
fCurrTrgFlags[sector] |= 1 << (stack+11);
continue;
}
else if ((idx & 0x1) == 0x1) {
trackWord |= ((ULong64_t) word) << 32;
AliDebug(1, Form("track debug word: 0x%016llx", trackWord));
if (fTracks) {
AliESDTrdTrack *trk = new ((*fTracks)[fTracks->GetEntriesFast()])
AliESDTrdTrack();
trk->SetSector(fCurrEquipmentId-kDDLOffset);
trk->SetStack((trackWord >> 60) & 0x7);
trk->SetA(0);
trk->SetB(0);
trk->SetPID(0);
trk->SetLayerMask((trackWord >> 16) & 0x3f);
trk->SetTrackletIndex((trackWord >> 22) & 0x3f, 0);
trk->SetTrackletIndex((trackWord >> 28) & 0x3f, 1);
trk->SetTrackletIndex((trackWord >> 34) & 0x3f, 2);
trk->SetTrackletIndex((trackWord >> 40) & 0x3f, 3);
trk->SetTrackletIndex((trackWord >> 46) & 0x3f, 4);
trk->SetTrackletIndex((trackWord >> 52) & 0x3f, 5);
trk->SetFlags(0);
trk->SetReserved(0);
trk->SetLabel(-3);
Float_t pt = (((Int_t) (trackWord & 0xffff) ^ 0x8000) - 0x8000)/128.;
if (TMath::Abs(pt) > 0.1) {
trk->SetA((Int_t) (0.15*51625./100./pt / 160e-4 * 2));
}
}
}
else {
trackWord = word;
}
idx++;
}
}
}
else {
ULong64_t trackWord = 0;
Int_t stack = 0;
Int_t idx = 0;
Bool_t upperWord = kFALSE;
Int_t word = 0;
for (UInt_t iWord = 4; iWord < fCurrSmHeaderSize; iWord++) {
if (fPayloadCurr[iWord] == 0xffe0ffff) {
stack++;
idx = 0;
upperWord = kFALSE;
}
else {
if (upperWord) {
word |= (fPayloadCurr[iWord] & 0xffff0000);
upperWord = kFALSE;
}
else {
word = (fPayloadCurr[iWord] & 0xffff0000) >> 16;
upperWord = kTRUE;
continue;
}
if ((word & 0xffff0008) == 0x13370008) {
AliDebug(1, Form("stack %i: fast track word: 0x%08x", stack, word));
continue;
}
else if ((word & 0xffff0010) == 0x13370010) {
AliDebug(1, Form("stack %i: tracking done word: 0x%08x", stack, word));
fCurrTrgFlags[sector] |= 1 << (stack+11);
continue;
}
else if ((idx & 0x1) == 0x1) {
trackWord |= ((ULong64_t) word) << 32;
AliDebug(1, Form("track debug word: 0x%16llx", trackWord));
if (fTracks) {
AliESDTrdTrack *trk = new ((*fTracks)[fTracks->GetEntriesFast()])
AliESDTrdTrack();
trk->SetSector(fCurrEquipmentId-kDDLOffset);
trk->SetStack((trackWord >> 60) & 0x7);
trk->SetA(0);
trk->SetB(0);
trk->SetPID(0);
trk->SetLayerMask((trackWord >> 16) & 0x3f);
trk->SetTrackletIndex((trackWord >> 22) & 0x3f, 0);
trk->SetTrackletIndex((trackWord >> 28) & 0x3f, 1);
trk->SetTrackletIndex((trackWord >> 34) & 0x3f, 2);
trk->SetTrackletIndex((trackWord >> 40) & 0x3f, 3);
trk->SetTrackletIndex((trackWord >> 46) & 0x3f, 4);
trk->SetTrackletIndex((trackWord >> 52) & 0x3f, 5);
trk->SetFlags(0);
trk->SetReserved(0);
trk->SetLabel(-3);
Float_t pt = (((Int_t) (trackWord & 0xffff) ^ 0x8000) - 0x8000)/128.;
if (TMath::Abs(pt) > 0.1) {
trk->SetA(-(Int_t) (0.15*51625./100./pt / 160e-4 * 2));
}
}
}
else {
trackWord = word;
}
idx++;
}
}
}
return 0;
}
Int_t AliTRDrawStream::ReadTrackingHeader(Int_t stack)
{
fCurrTrkHeaderIndexWord[stack] = *fPayloadCurr;
fCurrTrkHeaderSize[stack] = ((*fPayloadCurr) >> 16) & 0x3ff;
AliDebug(1, Form("tracking header index word: 0x%08x, size: %i (hw rev: %i)",
fCurrTrkHeaderIndexWord[stack], fCurrTrkHeaderSize[stack], fCurrHwRev));
Int_t trackingTime = *fPayloadCurr & 0x3ff;
fCurrTrgFlags[fCurrEquipmentId-kDDLOffset] |= ((fCurrTrkHeaderIndexWord[stack] >> 10) & 0x1) << (22 + stack);
fPayloadCurr++;
ULong64_t trackWord = 0;
Int_t idx = 0;
Int_t trackIndex = fTracks ? fTracks->GetEntriesFast() : -1;
for (UInt_t iWord = 0; iWord < fCurrTrkHeaderSize[stack]; iWord++) {
if (!(idx & 0x1)) {
trackWord = fPayloadCurr[iWord];
}
else {
trackWord |= ((ULong64_t) fPayloadCurr[iWord]) << 32;
if (trackWord & (1ul << 63)) {
if ((trackWord & (0x3ful << 56)) != 0) {
AliDebug(2, Form("track word: 0x%016llx", trackWord));
if (fTracks) {
AliESDTrdTrack *trk = new ((*fTracks)[fTracks->GetEntriesFast()])
AliESDTrdTrack();
trk->SetSector(fCurrEquipmentId-kDDLOffset);
trk->SetLayerMask((trackWord >> 56) & 0x3f);
trk->SetA( (((trackWord >> 38) & 0x3ffff) ^ 0x20000) - 0x20000);
trk->SetB( (((trackWord >> 20) & 0x3ffff) ^ 0x20000) - 0x20000);
trk->SetC( (((trackWord >> 8) & 0xffff) ^ 0x8000) - 0x8000);
trk->SetPID((trackWord >> 0) & 0xff);
trk->SetStack(stack);
trk->SetLabel(-3);
if (trackWord != trk->GetTrackWord(0)) {
AliError(Form("track word 0x%016llx does not match the read one 0x%016llx",
trk->GetTrackWord(0), trackWord));
}
}
}
else {
fCurrTrgFlags[fCurrEquipmentId-kDDLOffset] |= 1 << (27 + stack);
fCurrTrkFlags[(fCurrEquipmentId-kDDLOffset)*fgkNstacks + stack] = trackWord;
AliDebug(2, Form("tracking done marker: 0x%016llx, trigger flags: 0x%08x",
trackWord, fCurrTrgFlags[fCurrEquipmentId-kDDLOffset]));
AliDebug(2, Form("seg / stack / first / last / done / index : %i %i %lli %lli %lli %i",
fCurrEquipmentId - kDDLOffset, stack,
(trackWord >> 20) & 0x3ff,
(trackWord >> 10) & 0x3ff,
(trackWord >> 0) & 0x3ff,
trackingTime));
}
}
else {
AliDebug(2, Form("extended track word: 0x%016llx", trackWord));
if (fTracks) {
AliESDTrdTrack *trk = (AliESDTrdTrack*) (*fTracks)[trackIndex];
trk->SetFlags((trackWord >> 52) & 0x7ff);
trk->SetFlagsTiming((trackWord >> 51) & 0x1);
trk->SetReserved((trackWord >> 49) & 0x3);
trk->SetY((trackWord >> 36) & 0x1fff);
trk->SetTrackletIndex((trackWord >> 0) & 0x3f, 0);
trk->SetTrackletIndex((trackWord >> 6) & 0x3f, 1);
trk->SetTrackletIndex((trackWord >> 12) & 0x3f, 2);
trk->SetTrackletIndex((trackWord >> 18) & 0x3f, 3);
trk->SetTrackletIndex((trackWord >> 24) & 0x3f, 4);
trk->SetTrackletIndex((trackWord >> 30) & 0x3f, 5);
if (trk->GetFlagsTiming() == 0) {
AliError(Form("*** track not in time: 0x%016llx", trk->GetExtendedTrackWord(0)));
}
if (trackWord != trk->GetExtendedTrackWord(0)) {
AliError(Form("extended track word 0x%016llx does not match the read one 0x%016llx",
trk->GetExtendedTrackWord(0), trackWord));
}
trackIndex++;
}
}
}
idx++;
}
fPayloadCurr += fCurrTrkHeaderSize[stack];
return fCurrTrkHeaderSize[stack];
}
Int_t AliTRDrawStream::ReadTriggerHeaders()
{
AliDebug(1, Form("trigger mask: 0x%03x, fired: 0x%03x\n",
fCurrTriggerEnable, fCurrTriggerFired));
for (Int_t iTrigger = 0; iTrigger < fgkNtriggers; iTrigger++) {
if (fCurrTriggerEnable & (1 << iTrigger)) {
if ((fCurrTrgHeaderReadout == 0) || (fCurrTriggerFired & (1 << iTrigger))) {
AliDebug(1, Form("trigger index word %i: 0x%08x\n", iTrigger, *fPayloadCurr));
fCurrTrgHeaderIndexWord[iTrigger] = *fPayloadCurr;
fCurrTrgHeaderSize[iTrigger] = ((*fPayloadCurr) >> 16) & 0x3ff;
if (iTrigger == 7) {
fCurrTrgFlags[fCurrEquipmentId-kDDLOffset] |= (*fPayloadCurr & 0x3ff) << 12;
}
fPayloadCurr++;
fPayloadCurr += fCurrTrgHeaderSize[iTrigger];
}
}
}
return 0;
}
Int_t AliTRDrawStream::ReadStackHeader(Int_t stack)
{
fCurrStackIndexWord[stack] = *fPayloadCurr;
fCurrStackHeaderSize[stack] = (((*fPayloadCurr) >> 16) & 0xffff) + 1;
fCurrStackHeaderVersion[stack] = ((*fPayloadCurr) >> 12) & 0xf;
fCurrLinkMask[stack] = (*fPayloadCurr) & 0xfff;
AliDebug(1, DumpRaw(Form("stack %i header", stack), fPayloadCurr, fCurrStackHeaderSize[stack]));
if (fPayloadCurr - fPayloadStart >= fPayloadSize - (Int_t) fCurrStackHeaderSize[stack]) {
EquipmentError(kStackHeaderInvalid, "Stack index header %i incomplete", stack);
AliError(DumpRaw(Form("stack %i header", stack), fPayloadCurr, fCurrStackHeaderSize[stack]));
return -1;
}
switch (fCurrStackHeaderVersion[stack]) {
case 0xa:
case 0xb:
if (fCurrStackHeaderSize[stack] < 8) {
LinkError(kStackHeaderInvalid, "Stack header smaller than expected!");
return -1;
}
fCurrCleanCheckout[stack] = fPayloadCurr[1] & 0x1;
fCurrBoardId[stack] = (fPayloadCurr[1] >> 8) & 0xff;
fCurrHwRevTMU[stack] = (fPayloadCurr[1] >> 16) & 0xffff;
for (Int_t iLayer = 0; iLayer < 6; iLayer++) {
fCurrLinkMonitorFlags [((fCurrEquipmentId - kDDLOffset) * fgkNstacks + stack) *fgkNlinks + iLayer*2] = fPayloadCurr[iLayer+2] & 0xf;
fCurrLinkDataTypeFlags [stack * fgkNlinks + iLayer*2] = (fPayloadCurr[iLayer+2] >> 4) & 0x3;
fCurrLinkDebugFlags [stack * fgkNlinks + iLayer*2] = (fPayloadCurr[iLayer+2] >> 12) & 0xf;
fCurrLinkMonitorFlags [((fCurrEquipmentId - kDDLOffset) * fgkNstacks + stack) *fgkNlinks + iLayer*2 + 1] = (fPayloadCurr[iLayer+2] >> 16) & 0xf;
fCurrLinkDataTypeFlags [stack * fgkNlinks + iLayer*2 + 1] = (fPayloadCurr[iLayer+2] >> 20) & 0x3;
fCurrLinkDebugFlags [stack * fgkNlinks + iLayer*2 + 1] = (fPayloadCurr[iLayer+2] >> 28) & 0xf;
}
break;
default:
EquipmentError(kStackHeaderInvalid, "Invalid Stack Header version %x", fCurrStackHeaderVersion[stack]);
}
fPayloadCurr += fCurrStackHeaderSize[stack];
return fCurrStackHeaderSize[stack];
}
Int_t AliTRDrawStream::ReadGTUTrailer()
{
UInt_t* trailer = fPayloadStart + fPayloadSize -1;
for (Int_t iWord = 0; iWord < fPayloadSize-2; iWord++) {
if ((fPayloadStart[fPayloadSize-3-iWord] == fgkStackEndmarker[0]) &&
(fPayloadStart[fPayloadSize-2-iWord] == fgkStackEndmarker[1]) &&
((fPayloadStart[fPayloadSize-1-iWord] & 0xfff) == 0xf51)) {
trailer = fPayloadStart + fPayloadSize - 1 - iWord;
break;
}
}
if (((*trailer) & 0xfff) == 0xf51) {
UInt_t trailerIndexWord = (*trailer);
Int_t trailerSize = (trailerIndexWord >> 16) & 0xffff;
AliDebug(2, DumpRaw("GTU trailer", trailer, trailerSize+1));
if (trailerSize >= 4) {
fCurrMatchFlagsSRAM[fCurrEquipmentId-kDDLOffset] = (trailer[1] >> 0) & 0x1f;
fCurrMatchFlagsPostBP[fCurrEquipmentId-kDDLOffset] = (trailer[1] >> 5) & 0x1f;
fCurrChecksumStack[fCurrEquipmentId - kDDLOffset][0] = (trailer[1] >> 16) & 0xffff;
fCurrChecksumStack[fCurrEquipmentId - kDDLOffset][1] = (trailer[2] >> 0) & 0xffff;
fCurrChecksumStack[fCurrEquipmentId - kDDLOffset][2] = (trailer[2] >> 16) & 0xffff;
fCurrChecksumStack[fCurrEquipmentId - kDDLOffset][3] = (trailer[3] >> 0) & 0xffff;
fCurrChecksumStack[fCurrEquipmentId - kDDLOffset][4] = (trailer[3] >> 16) & 0xffff;
fCurrChecksumSIU = trailer[trailerSize];
if ((fCurrMatchFlagsSRAM[fCurrEquipmentId-kDDLOffset] & fCurrStackMask) != fCurrStackMask)
EquipmentError(kCRCmismatch, "CRC mismatch SRAM: 0x%02x", fCurrMatchFlagsSRAM[fCurrEquipmentId-kDDLOffset]);
if ((fCurrMatchFlagsPostBP[fCurrEquipmentId-kDDLOffset] & fCurrStackMask) != fCurrStackMask)
EquipmentError(kCRCmismatch, "CRC mismatch BP: 0x%02x", fCurrMatchFlagsPostBP[fCurrEquipmentId-kDDLOffset]);
}
else {
LinkError(kUnknown, "Invalid GTU trailer");
}
}
else
EquipmentError(kUnknown, "trailer index marker mismatch");
return 0;
}
Int_t AliTRDrawStream::ReadLinkData()
{
Int_t count = 0;
UInt_t* startPosLink = fPayloadCurr;
AliDebug(1, DumpRaw(Form("link data from seg %2i slot %i link %2i", fCurrEquipmentId-kDDLOffset, fCurrSlot, fCurrLink),
fPayloadCurr, TMath::Min((Int_t) (fPayloadSize - (fPayloadCurr-fPayloadStart)), 100), 0x00000000));
if (fMarkers)
new ((*fMarkers)[fMarkers->GetEntriesFast()])
AliTRDrawStreamError(-kHCactive, fCurrEquipmentId-kDDLOffset, fCurrSlot, fCurrLink);
if (fErrorFlags & kDiscardHC)
return count;
if (fCurrTrackletEnable) {
count += ReadTracklets();
if (fErrorFlags & kDiscardHC)
return count;
}
AliDebug(1, DumpRaw("HC header", fPayloadCurr, 4, 0x00000000));
count += ReadHcHeader();
if (fErrorFlags & kDiscardHC)
return count;
Int_t det = fCurrSm * 30 + fCurrStack * 6 + fCurrLayer;
if (det > -1 && det < 540) {
if (fCurrMajor & 0x40) {
if ((fCurrMajor & 0x7) == 0x7) {
AliDebug(1, "This is a config event");
UInt_t *startPos = fPayloadCurr;
while (fPayloadCurr - fPayloadStart < fPayloadSize &&
*fPayloadCurr != fgkDataEndmarker)
fPayloadCurr++;
count += fPayloadCurr - startPos;
AliTRDtrapConfig *trapcfg = AliTRDcalibDB::Instance()->GetTrapConfig();
AliTRDmcmSim::ReadPackedConfig(trapcfg, fCurrHC, startPos, fPayloadCurr - startPos);
}
else {
Int_t tpmode = fCurrMajor & 0x7;
AliDebug(1, Form("Checking testpattern (mode %i) data", tpmode));
count += ReadTPData(tpmode);
}
}
else {
if (fDigitsManager) {
if ((fAdcArray = fDigitsManager->GetDigits(det))) {
if (fAdcArray->GetNtime() != fCurrNtimebins)
fAdcArray->Allocate(16, 144, fCurrNtimebins);
}
else {
LinkError(kNoDigits);
}
if (!fDigitsParam) {
fDigitsParam = fDigitsManager->GetDigitsParam();
}
if (fDigitsParam) {
fDigitsParam->SetPretriggerPhase(det, fCurrPtrgPhase);
fDigitsParam->SetNTimeBins(det, fCurrNtimebins);
fDigitsParam->SetADCbaseline(det, 10);
}
if (fDigitsManager->UsesDictionaries()) {
fDigitsManager->GetDictionary(det, 0)->Reset();
fDigitsManager->GetDictionary(det, 1)->Reset();
fDigitsManager->GetDictionary(det, 2)->Reset();
}
if ((fSignalIndex = fDigitsManager->GetIndexes(det))) {
fSignalIndex->SetSM(fCurrSm);
fSignalIndex->SetStack(fCurrStack);
fSignalIndex->SetLayer(fCurrLayer);
fSignalIndex->SetDetNumber(det);
if (!fSignalIndex->IsAllocated())
fSignalIndex->Allocate(16, 144, fCurrNtimebins);
}
if (fCurrMajor & 0x20) {
AliDebug(1, "This is a zs event");
count += ReadZSData();
}
else {
AliDebug(1, "This is a nozs event");
count += ReadNonZSData();
}
}
else {
while (fPayloadCurr - fPayloadStart < fPayloadSize &&
*fPayloadCurr != fgkDataEndmarker)
fPayloadCurr++;
}
}
}
else {
LinkError(kInvalidDetector, "%i", det);
while (fPayloadCurr - fPayloadStart < fPayloadSize &&
*fPayloadCurr != fgkDataEndmarker)
fPayloadCurr++;
}
if (fCurrSm > -1 && fCurrSm < 18) {
fStats.fStatsSector[fCurrSm].fStatsHC[fCurrHC%60].fBytes += (fPayloadCurr - startPosLink) * sizeof(UInt_t);
fStats.fStatsSector[fCurrSm].fStatsHC[fCurrHC%60].fBytesRead += count * sizeof(UInt_t);
fStats.fStatsSector[fCurrSm].fBytesRead += count * sizeof(UInt_t);
fStats.fBytesRead += count * sizeof(UInt_t);
}
if ((fErrorFlags & kDiscardHC) && fAdcArray)
fAdcArray->SetDataInvalid();
return count;
}
Int_t AliTRDrawStream::ReadTracklets()
{
Int_t nTracklets = 0;
UInt_t *start = fPayloadCurr;
while (*(fPayloadCurr) != fgkTrackletEndmarker &&
*(fPayloadCurr) != fgkStackEndmarker[0] &&
*(fPayloadCurr) != fgkStackEndmarker[1] &&
fPayloadCurr - fPayloadStart < (fPayloadSize - 1)) {
++nTracklets;
if (fTracklets)
new ((*fTracklets)[fTracklets->GetEntriesFast()]) AliTRDtrackletWord(*(fPayloadCurr), fCurrHC);
fPayloadCurr++;
}
if (nTracklets > 0) {
AliDebug(1, Form("Found %i tracklets in %i %i %i (ev. %i)", nTracklets,
(fCurrEquipmentId-kDDLOffset), fCurrSlot, fCurrLink, fRawReader->GetEventIndex()));
if (fCurrSm > -1 && fCurrSm < 18) {
fStats.fStatsSector[fCurrSm].fStatsHC[fCurrHC%60].fNTracklets += nTracklets;
fStats.fStatsSector[fCurrSm].fNTracklets += nTracklets;
}
}
while ((*(fPayloadCurr) == fgkTrackletEndmarker &&
fPayloadCurr - fPayloadStart < fPayloadSize))
fPayloadCurr++;
return fPayloadCurr - start;
}
Int_t AliTRDrawStream::ReadHcHeader()
{
AliDebug(1, Form("HC header: 0x%08x", *fPayloadCurr));
UInt_t *start = fPayloadCurr;
if (*fPayloadCurr == fgkDataEndmarker ||
*(fPayloadCurr) == fgkStackEndmarker[0] ||
*(fPayloadCurr) == fgkStackEndmarker[1]) {
LinkError(kHCmismatch, "found endmarker where HC header should be");
return 0;
}
fCurrSpecial = (*fPayloadCurr >> 31) & 0x1;
fCurrMajor = (*fPayloadCurr >> 24) & 0x7f;
fCurrMinor = (*fPayloadCurr >> 17) & 0x7f;
fCurrAddHcWords = (*fPayloadCurr >> 14) & 0x7;
fCurrSm = (*fPayloadCurr >> 9) & 0x1f;
fCurrLayer = (*fPayloadCurr >> 6) & 0x7;
fCurrStack = (*fPayloadCurr >> 3) & 0x7;
fCurrSide = (*fPayloadCurr >> 2) & 0x1;
fCurrCheck = (*fPayloadCurr) & 0x3;
if ((fCurrSm != (((Int_t) fCurrEquipmentId) - kDDLOffset)) ||
(fCurrStack != fCurrSlot) ||
(fCurrLayer != fCurrLink / 2) ||
(fCurrSide != fCurrLink % 2)) {
LinkError(kHCmismatch,
"HC: %i, %i, %i, %i\n 0x%08x 0x%08x 0x%08x 0x%08x",
fCurrSm, fCurrStack, fCurrLayer, fCurrSide,
fPayloadCurr[0], fPayloadCurr[1], fPayloadCurr[2], fPayloadCurr[3]);
}
if (fCurrCheck != 0x1) {
LinkError(kHCcheckFailed);
}
if (fCurrAddHcWords > 0) {
fCurrNtimebins = (fPayloadCurr[1] >> 26) & 0x3f;
#ifdef TRD_RAW_DEBUG
fCurrBC[fCurrHC] = (fPayloadCurr[1] >> 10) & 0xffff;
#endif
fCurrPtrgCnt = (fPayloadCurr[1] >> 6) & 0xf;
fCurrPtrgPhase = (fPayloadCurr[1] >> 2) & 0xf;
}
fPayloadCurr += 1 + fCurrAddHcWords;
return (fPayloadCurr - start);
}
Int_t AliTRDrawStream::ReadTPData(Int_t mode)
{
Int_t cpu = 0;
Int_t cpufromchannel[] = {0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3};
Int_t evno = -1;
Int_t evcnt = 0;
Int_t count = 0;
Int_t mcmcount = -1;
Int_t wordcount = 0;
Int_t channelcount = 0;
UInt_t expword = 0;
UInt_t expadcval = 0;
UInt_t diff = 0;
Int_t lastmcmpos = -1;
Int_t lastrobpos = -1;
UInt_t* start = fPayloadCurr;
while (*(fPayloadCurr) != fgkDataEndmarker &&
fPayloadCurr - fPayloadStart < fPayloadSize - 1) {
AliDebug(2, DumpMcmHeader("MCM header: ", *fPayloadCurr));
UInt_t *startPosMCM = fPayloadCurr;
mcmcount++;
fCurrRobPos = ROB(*fPayloadCurr);
if (GetROBReadoutPos(ROB(*fPayloadCurr) / 2) >= lastrobpos) {
if (GetROBReadoutPos(ROB(*fPayloadCurr) / 2) > lastrobpos)
lastmcmpos = -1;
lastrobpos = GetROBReadoutPos(ROB(*fPayloadCurr) / 2);
}
else {
ROBError(kPosUnexp, Form("#%i after #%i in readout order", GetROBReadoutPos(ROB(*fPayloadCurr) / 2), lastrobpos));
}
fCurrMcmPos = MCM(*fPayloadCurr);
if (GetMCMReadoutPos(MCM(*fPayloadCurr)) > lastmcmpos) {
lastmcmpos = GetMCMReadoutPos(MCM(*fPayloadCurr));
}
else {
MCMError(kPosUnexp, Form("#%i after #%i in readout order", GetMCMReadoutPos(MCM(*fPayloadCurr)), lastmcmpos));
}
if (EvNo(*fPayloadCurr) != (evno & 0xfffff)) {
if (evno == -1) {
evno = EvNo(*fPayloadCurr);
}
else {
MCMError(kEvCntMismatch, "%i <-> %i", evno, EvNo(*fPayloadCurr));
#ifdef TRD_RAW_DEBUG
if (fCurrL0offset[fCurrHC/2] != 0)
LinkError(kEvCntMismatch, "offset for %i %i %i changed from %i to %i = %i - %i",
fCurrEquipmentId, fCurrSlot, fCurrLink/2, fCurrL0offset[fCurrHC/2],
EvNo(*fPayloadCurr) - fCurrL0Count[fCurrEquipmentId-kDDLOffset],
EvNo(*fPayloadCurr), fCurrL0Count[fCurrEquipmentId-kDDLOffset]);
fCurrL0offset[fCurrHC/2] = EvNo(*fPayloadCurr) - fCurrL0Count[fCurrEquipmentId-kDDLOffset];
evno = fCurrL0Count[fCurrEquipmentId-kDDLOffset] + fCurrL0offset[fCurrHC/2];
#endif
}
}
fPayloadCurr++;
evcnt = 0x3f & *fPayloadCurr >> 26;
cpu = -1;
channelcount = 0;
while (channelcount < 21) {
count = 0;
if (cpu != cpufromchannel[channelcount]) {
cpu = cpufromchannel[channelcount];
expadcval = (1 << 9) | (fCurrRobPos << 6) | (fCurrMcmPos << 2) | cpu;
wordcount = 0;
}
while (count < 10) {
if (*fPayloadCurr == fgkDataEndmarker) {
MCMError(kMissTpData);
return (fPayloadCurr - start);
}
if (channelcount % 2 == 0)
expword = 0x3;
else
expword = 0x2;
if (mode == 1) {
expword |= expadcval << 2;
expadcval = ( (expadcval << 1) | ( ( (expadcval >> 9) ^ (expadcval >> 6) ) & 1) ) & 0x3FF;
expword |= expadcval << 12;
expadcval = ( (expadcval << 1) | ( ( (expadcval >> 9) ^ (expadcval >> 6) ) & 1) ) & 0x3FF;
expword |= expadcval << 22;
expadcval = ( (expadcval << 1) | ( ( (expadcval >> 9) ^ (expadcval >> 6) ) & 1) ) & 0x3FF;
}
else if (mode == 2) {
expword = ((0x3f & evcnt) << 26) | ((fCurrSm + 1) << 21) | ((fCurrLayer + 1) << 18) |
((fCurrStack + 1) << 15) |
(fCurrRobPos << 12) | (fCurrMcmPos << 8) | (cpu << 6) | (wordcount + 1);
}
else if (mode == 3) {
expword = ((0xfff & evcnt) << 20) | (fCurrSm << 15) | (fCurrLink/2 << 12) | (fCurrStack << 9) |
(fCurrRobPos << 6) | (fCurrMcmPos << 2) | (cpu << 0);
}
else {
expword = 0;
LinkError(kTPmodeInvalid, "Just reading");
}
diff = *fPayloadCurr ^ expword;
AliDebug(11, Form("Comparing ch %2i, word %2i (cpu %i): 0x%08x <-> 0x%08x",
channelcount, wordcount, cpu, *fPayloadCurr, expword));
if (diff != 0) {
MCMError(kTPmismatch,
"Seen 0x%08x, expected 0x%08x, diff: 0x%08x, 0x%04x, 0x%02x - word %2i (cpu %i, ch %i)",
*fPayloadCurr, expword, diff,
0xffff & (diff | diff >> 16),
0xff & (diff | diff >> 8 | diff >> 16 | diff >> 24),
wordcount, cpu, channelcount);;
}
fPayloadCurr++;
count++;
wordcount++;
if (*fPayloadCurr == fgkDataEndmarker)
return (fPayloadCurr - start);
}
channelcount++;
}
if (IsDumping() && DumpingMCM(fCurrHC/2, fCurrRobPos, fCurrMcmPos)) {
AliInfo(DumpRaw(Form("Event %i: Det %3i ROB %i MCM %2i", fRawReader->GetEventIndex(), fCurrHC/2, fCurrRobPos, fCurrMcmPos),
startPosMCM, fPayloadCurr - startPosMCM));
}
}
return fPayloadCurr - start;
}
Int_t AliTRDrawStream::ReadZSData()
{
UInt_t *start = fPayloadCurr;
Int_t mcmcount = 0;
Int_t mcmcountExp = fCurrStack == 2 ? 48 : 64;
Int_t channelcount = 0;
Int_t channelcountExp = 0;
Int_t channelcountMax = 0;
Int_t timebins;
Int_t currentTimebin = 0;
Int_t adcwc = 0;
Int_t evno = -1;
Int_t lastmcmpos = -1;
Int_t lastrobpos = -1;
if (fCurrNtimebins != fNtimebins) {
if (fNtimebins > 0)
LinkError(kNtimebinsChanged,
"No. of timebins changed from %i to %i", fNtimebins, fCurrNtimebins);
fNtimebins = fCurrNtimebins;
}
timebins = fNtimebins;
while (*(fPayloadCurr) != fgkDataEndmarker &&
*(fPayloadCurr) != fgkStackEndmarker[0] &&
*(fPayloadCurr) != fgkStackEndmarker[1] &&
fPayloadCurr - fPayloadStart < fPayloadSize) {
AliDebug(2, DumpMcmHeader("MCM header: ", *fPayloadCurr));
UInt_t *startPosMCM = fPayloadCurr;
fCurrRobPos = ROB(*fPayloadCurr);
if (GetROBReadoutPos(ROB(*fPayloadCurr) / 2) >= lastrobpos) {
if (GetROBReadoutPos(ROB(*fPayloadCurr) / 2) > lastrobpos)
lastmcmpos = -1;
lastrobpos = GetROBReadoutPos(ROB(*fPayloadCurr) / 2);
}
else {
ROBError(kPosUnexp, Form("#%i after #%i and #%i in readout order",
GetROBReadoutPos(ROB(*fPayloadCurr) / 2), lastrobpos, GetROBReadoutPos(fCurrRobPos)));
}
fCurrMcmPos = MCM(*fPayloadCurr);
if (GetMCMReadoutPos(MCM(*fPayloadCurr)) > lastmcmpos) {
lastmcmpos = GetMCMReadoutPos(MCM(*fPayloadCurr));
}
else {
MCMError(kPosUnexp, Form("#%i after #%i and #%i in readout order",
GetMCMReadoutPos(MCM(*fPayloadCurr)), lastmcmpos, GetMCMReadoutPos(fCurrMcmPos)));
}
#ifdef TRD_RAW_DEBUG
if (fCurrL0Count[fCurrEquipmentId-kDDLOffset] > 0) {
evno = fCurrL0Count[fCurrEquipmentId-kDDLOffset] + fCurrL0offset[fCurrHC/2];
}
fCurrEvCount[fCurrEquipmentId-kDDLOffset] = EvNo(*fPayloadCurr);
#endif
if (EvNo(*fPayloadCurr) != (evno & 0xfffff)) {
if (evno == -1) {
evno = EvNo(*fPayloadCurr);
}
else {
MCMError(kEvCntMismatch, "exp <-> SM: %i <-> %i", evno & 0xfffff, EvNo(*fPayloadCurr));
#ifdef TRD_RAW_DEBUG
Int_t prevOffset = fCurrL0offset[fCurrHC/2];
fCurrL0offset[fCurrHC/2] = (- fCurrL0Count[fCurrEquipmentId-kDDLOffset] + EvNo(*fPayloadCurr)) % (1 << 20);
if (fCurrL0offset[fCurrHC/2] < 0)
fCurrL0offset[fCurrHC/2] += 0xfffff;
evno = (fCurrL0Count[fCurrEquipmentId-kDDLOffset] + fCurrL0offset[fCurrHC/2]) & 0xfffff;
if (prevOffset != 0)
LinkError(kEvCntMismatch, "offset for %i %i %i changed from %i to %i = %i - %i",
fCurrEquipmentId, fCurrSlot, fCurrLink/2,
prevOffset,
fCurrL0offset[fCurrHC/2],
fCurrL0Count[fCurrEquipmentId-kDDLOffset],
EvNo(*fPayloadCurr));
#endif
}
}
Int_t adccoloff = AdcColOffset(*fPayloadCurr);
Int_t padcoloff = PadColOffset(*fPayloadCurr);
Int_t row = Row(*fPayloadCurr);
fPayloadCurr++;
if ((row > 11) && (fCurrStack == 2)) {
MCMError(kInvalidPadRow, "Data in padrow > 11 for stack 2");
}
if (fErrorFlags & (kDiscardHC | kDiscardDDL))
break;
AliDebug(2, DumpAdcMask("ADC mask: ", *fPayloadCurr));
channelcount = 0;
channelcountExp = GetNActiveChannelsFromMask(*fPayloadCurr);
channelcountMax = GetNActiveChannels(*fPayloadCurr);
Int_t channelmask = GetActiveChannels(*fPayloadCurr);
Int_t channelno = -1;
fPayloadCurr++;
if (channelcountExp != channelcountMax) {
if (channelcountExp > channelcountMax) {
Int_t temp = channelcountExp;
channelcountExp = channelcountMax;
channelcountMax = temp;
}
while (channelcountExp < channelcountMax && channelcountExp < 21 &&
fPayloadCurr - fPayloadStart < fPayloadSize - 10 * channelcountExp - 1) {
MCMError(kAdcMaskInconsistent,
"Possible MCM-H: 0x%08x, possible ADC-mask: 0x%08x",
*(fPayloadCurr + 10 * channelcountExp),
*(fPayloadCurr + 10 * channelcountExp + 1) );
if (!CouldBeMCMhdr( *(fPayloadCurr + 10 * channelcountExp)) && !CouldBeADCmask( *(fPayloadCurr + 10 * channelcountExp + 1)))
channelcountExp++;
else {
break;
}
}
MCMError(kAdcMaskInconsistent,
"Inconsistency in no. of active channels: Counter: %i, Mask: %i, chosen: %i!",
GetNActiveChannels(fPayloadCurr[-1]), GetNActiveChannelsFromMask(fPayloadCurr[-1]), channelcountExp);
}
AliDebug(2, Form("expecting %i active channels, %i timebins", channelcountExp, fCurrNtimebins));
while (channelcount < channelcountExp && *(fPayloadCurr) != fgkDataEndmarker) {
if (channelno < 20)
channelno++;
while (channelno < 20 && (channelmask & 1 << channelno) == 0)
channelno++;
if (fCurrNtimebins > 30) {
currentTimebin = ((*fPayloadCurr >> 2) & 0x3f);
timebins = ((*fPayloadCurr >> 8) & 0xf) * 3;
}
else {
currentTimebin = 0;
}
adcwc = 0;
Int_t nADCwords = (timebins + 2) / 3;
AliDebug(3, Form("Now reading %i words for channel %2i", nADCwords, channelno));
Int_t adccol = adccoloff - channelno;
Int_t padcol = padcoloff - channelno;
while ((adcwc < nADCwords) &&
(*(fPayloadCurr) != fgkDataEndmarker) &&
(fPayloadCurr - fPayloadStart < fPayloadSize)) {
int check = 0x3 & *fPayloadCurr;
if (channelno % 2 != 0) {
if (check != 0x2 && channelno < 21) {
MCMError(kAdcCheckInvalid,
"%i for %2i. ADC word in odd channel %i",
check, adcwc+1, channelno);
}
}
else {
if (check != 0x3 && channelno < 21) {
MCMError(kAdcCheckInvalid,
"%i for %2i. ADC word in even channel %i",
check, adcwc+1, channelno);
}
}
if ((fErrorFlags & kDiscardMCM) == 0) {
int tb2 = 0x3ff & (*fPayloadCurr >> 22);
int tb1 = 0x3ff & (*fPayloadCurr >> 12);
int tb0 = 0x3ff & (*fPayloadCurr >> 2);
if (adcwc != 0 || fCurrNtimebins <= 30)
fAdcArray->SetDataByAdcCol(row, adccol, currentTimebin++, tb0);
else
tb0 = -1;
if (currentTimebin < fCurrNtimebins)
fAdcArray->SetDataByAdcCol(row, adccol, currentTimebin++, tb1);
if (currentTimebin < fCurrNtimebins)
fAdcArray->SetDataByAdcCol(row, adccol, currentTimebin++, tb2);
}
adcwc++;
fPayloadCurr++;
}
if (adcwc != nADCwords)
MCMError(kAdcDataAbort);
if (padcol > 0 && padcol < 144) {
fSignalIndex->AddIndexRC(row, padcol);
}
channelcount++;
}
if (fCurrSm > -1 && fCurrSm < 18) {
fStats.fStatsSector[fCurrSm].fStatsHC[fCurrHC%60].fNChannels += channelcount;
fStats.fStatsSector[fCurrSm].fNChannels += channelcount;
}
if (channelcount != channelcountExp)
MCMError(kAdcChannelsMiss);
mcmcount++;
if (fCurrSm > -1 && fCurrSm < 18) {
fStats.fStatsSector[fCurrSm].fStatsHC[fCurrHC%60].fNMCMs++;
fStats.fStatsSector[fCurrSm].fNMCMs++;
}
if (IsDumping() && DumpingMCM(fCurrHC/2, fCurrRobPos, fCurrMcmPos)) {
AliInfo(DumpRaw(Form("Event %i: Det %3i ROB %i MCM %2i", fRawReader->GetEventIndex(), fCurrHC/2, fCurrRobPos, fCurrMcmPos),
startPosMCM, fPayloadCurr - startPosMCM));
}
}
if (((fCurrMajor & 0x1) == 0) && (mcmcount != mcmcountExp)) {
LinkError(kMissMcmHeaders,
"No. of MCM headers %i not as expected: %i",
mcmcount, mcmcountExp);
}
return (fPayloadCurr - start);
}
Int_t AliTRDrawStream::ReadNonZSData()
{
UInt_t *start = fPayloadCurr;
Int_t mcmcount = 0;
Int_t mcmcountExp = fCurrStack == 2 ? 48 : 64;
Int_t channelcount = 0;
Int_t channelcountExp = 0;
Int_t timebins;
Int_t currentTimebin = 0;
Int_t adcwc = 0;
Int_t evno = -1;
Int_t lastmcmpos = -1;
Int_t lastrobpos = -1;
if (fCurrNtimebins != fNtimebins) {
if (fNtimebins > 0)
LinkError(kNtimebinsChanged,
"No. of timebins changed from %i to %i", fNtimebins, fCurrNtimebins);
fNtimebins = fCurrNtimebins;
}
timebins = fNtimebins;
while (*(fPayloadCurr) != fgkDataEndmarker &&
fPayloadCurr - fPayloadStart < fPayloadSize - 2) {
AliDebug(2, Form("MCM header: 0x%08x", *fPayloadCurr));
fCurrRobPos = ROB(*fPayloadCurr);
if (GetROBReadoutPos(ROB(*fPayloadCurr) / 2) >= lastrobpos) {
if (GetROBReadoutPos(ROB(*fPayloadCurr) / 2) > lastrobpos)
lastmcmpos = -1;
lastrobpos = GetROBReadoutPos(ROB(*fPayloadCurr) / 2);
}
else {
ROBError(kPosUnexp, Form("#%i after #%i in readout order", GetROBReadoutPos(ROB(*fPayloadCurr) / 2), lastrobpos));
}
fCurrMcmPos = MCM(*fPayloadCurr);
if (GetMCMReadoutPos(MCM(*fPayloadCurr)) > lastmcmpos) {
lastmcmpos = GetMCMReadoutPos(MCM(*fPayloadCurr));
}
else {
MCMError(kPosUnexp, Form("#%i after #%i in readout order", GetMCMReadoutPos(MCM(*fPayloadCurr)), lastmcmpos));
}
if (EvNo(*fPayloadCurr) != (evno & 0xfffff)) {
if (evno == -1) {
evno = EvNo(*fPayloadCurr);
}
else {
MCMError(kEvCntMismatch, "%i <-> %i", evno, EvNo(*fPayloadCurr));
#ifdef TRD_RAW_DEBUG
if (fCurrL0offset[fCurrHC/2] != 0)
LinkError(kEvCntMismatch, "offset for %i %i %i changed from %i to %i = %i - %i",
fCurrEquipmentId, fCurrSlot, fCurrLink/2, fCurrL0offset[fCurrHC/2],
EvNo(*fPayloadCurr) - fCurrL0Count[fCurrEquipmentId-kDDLOffset],
EvNo(*fPayloadCurr), fCurrL0Count[fCurrEquipmentId-kDDLOffset]);
fCurrL0offset[fCurrHC/2] = EvNo(*fPayloadCurr) - fCurrL0Count[fCurrEquipmentId-kDDLOffset];
evno = fCurrL0Count[fCurrEquipmentId-kDDLOffset] + fCurrL0offset[fCurrHC/2];
#endif
}
}
channelcount = 0;
channelcountExp = 21;
int channelno = -1;
Int_t adccoloff = AdcColOffset(*fPayloadCurr);
Int_t padcoloff = PadColOffset(*fPayloadCurr);
Int_t row = Row(*fPayloadCurr);
fPayloadCurr++;
if ((row > 11) && (fCurrStack == 2)) {
MCMError(kInvalidPadRow, "Data in padrow > 11 for stack 2");
}
if (fErrorFlags & (kDiscardHC | kDiscardDDL))
break;
while (channelcount < channelcountExp &&
*(fPayloadCurr) != fgkDataEndmarker) {
if (channelno < 20)
channelno++;
currentTimebin = 0;
adcwc = 0;
Int_t nADCwords = (timebins + 2) / 3;
AliDebug(2, Form("Now looking %i words", nADCwords));
Int_t adccol = adccoloff - channelno;
Int_t padcol = padcoloff - channelno;
while ((adcwc < nADCwords) &&
(*(fPayloadCurr) != fgkDataEndmarker) &&
(fPayloadCurr - fPayloadStart < fPayloadSize)) {
int check = 0x3 & *fPayloadCurr;
if (channelno % 2 != 0) {
if (check != 0x2 && channelno < 21) {
MCMError(kAdcCheckInvalid,
"%i for %2i. ADC word in odd channel %i",
check, adcwc+1, channelno);
}
}
else {
if (check != 0x3 && channelno < 21) {
MCMError(kAdcCheckInvalid,
"%i for %2i. ADC word in even channel %i",
check, adcwc+1, channelno);
}
}
if ((fErrorFlags & kDiscardMCM) == 0) {
int tb2 = 0x3ff & (*fPayloadCurr >> 22);
int tb1 = 0x3ff & (*fPayloadCurr >> 12);
int tb0 = 0x3ff & (*fPayloadCurr >> 2);
if (adcwc != 0 || fCurrNtimebins <= 30)
fAdcArray->SetDataByAdcCol(row, adccol, currentTimebin++, tb0);
else
tb0 = -1;
if (currentTimebin < fCurrNtimebins)
fAdcArray->SetDataByAdcCol(row, adccol, currentTimebin++, tb1);
if (currentTimebin < fCurrNtimebins)
fAdcArray->SetDataByAdcCol(row, adccol, currentTimebin++, tb2);
}
adcwc++;
fPayloadCurr++;
}
if (adcwc != nADCwords)
MCMError(kAdcDataAbort);
if (padcol > 0 && padcol < 144) {
fSignalIndex->AddIndexRC(row, padcol);
}
channelcount++;
}
if (channelcount != channelcountExp)
MCMError(kAdcChannelsMiss);
mcmcount++;
}
if (mcmcount != mcmcountExp) {
LinkError(kMissMcmHeaders,
"%i not as expected: %i", mcmcount, mcmcountExp);
}
return (fPayloadCurr - start);
}
#ifdef TRD_RAW_CRC
UShort_t AliTRDrawStream::CalcLinkChecksum(UInt_t *data, Int_t size)
{
Int_t nEndmarkers = 0;
for (Int_t i = 0; i < size; i++) {
if (data[size-1 - i] != fgkDataEndmarker)
break;
nEndmarkers++;
}
size = size - (nEndmarkers-2);
boost::crc_optimal<16, 0x8005, 0, 0, false, false> checksumLink;
checksumLink.reset();
checksumLink.process_bytes(data, size*sizeof(UInt_t));
return checksumLink();
}
#else
UShort_t AliTRDrawStream::CalcLinkChecksum(UInt_t * , Int_t )
{
AliError("Checksum calculation relies on boost CRC implementation!");
return 0;
}
#endif
Int_t AliTRDrawStream::SeekNextStack()
{
if (!fCurrStackEndmarkerAvail)
return 0;
UInt_t *start = fPayloadCurr;
while ((fPayloadCurr - fPayloadStart < fPayloadSize-1) &&
((fPayloadCurr[0] != fgkStackEndmarker[0]) ||
(fPayloadCurr[1] != fgkStackEndmarker[1])))
fPayloadCurr++;
if ((fPayloadCurr - start) != 0)
StackError(kUnknown, "skipped %i words to reach stack endmarker", fPayloadCurr - start);
AliDebug(2, Form("stack endmarker: 0x%08x 0x%08x", fPayloadCurr[0], fPayloadCurr[1]));
fPayloadCurr++;
fPayloadCurr++;
return (fPayloadCurr-start);
}
Int_t AliTRDrawStream::SeekNextLink()
{
UInt_t *start = fPayloadCurr;
while (fPayloadCurr - fPayloadStart < fPayloadSize &&
((fPayloadCurr[0] != fgkStackEndmarker[0]) ||
(fPayloadCurr[1] != fgkStackEndmarker[1])) &&
*fPayloadCurr != fgkDataEndmarker)
fPayloadCurr++;
while (fPayloadCurr - fPayloadStart < fPayloadSize &&
*fPayloadCurr == fgkDataEndmarker)
fPayloadCurr++;
return (fPayloadCurr - start);
}
void AliTRDrawStream::EquipmentError(ErrorCode_t err, const char *const msg, ...)
{
fLastError.fSector = fCurrEquipmentId - kDDLOffset;
fLastError.fStack = -1;
fLastError.fLink = -1;
fLastError.fRob = -1;
fLastError.fMcm = -1;
fLastError.fError = err;
(this->*fStoreError)();
va_list ap;
if (fgErrorDebugLevel[err] > 10)
AliDebug(fgErrorDebugLevel[err],
Form("Event %6i: Eq. %2d - %s : %s",
fRawReader->GetEventIndex(), fCurrEquipmentId, fgkErrorMessages[err],
(va_start(ap, msg), vsprintf(fErrorBuffer, msg, ap), va_end(ap), fErrorBuffer) ));
else
AliError(Form("Event %6i: Eq. %2d - %s : %s",
fRawReader->GetEventIndex(), fCurrEquipmentId, fgkErrorMessages[err],
(va_start(ap, msg), vsprintf(fErrorBuffer, msg, ap), va_end(ap), fErrorBuffer) ));
fErrorFlags |= fgErrorBehav[err];
}
void AliTRDrawStream::StackError(ErrorCode_t err, const char *const msg, ...)
{
fLastError.fSector = fCurrEquipmentId - kDDLOffset;
fLastError.fStack = fCurrSlot;
fLastError.fLink = -1;
fLastError.fRob = -1;
fLastError.fMcm = -1;
fLastError.fError = err;
(this->*fStoreError)();
va_list ap;
if (fgErrorDebugLevel[err] > 0)
AliDebug(fgErrorDebugLevel[err],
Form("Event %6i: Eq. %2d S %i - %s : %s",
fRawReader->GetEventIndex(), fCurrEquipmentId, fCurrSlot, fgkErrorMessages[err],
(va_start(ap, msg), vsprintf(fErrorBuffer, msg, ap), va_end(ap), fErrorBuffer) ));
else
AliError(Form("Event %6i: Eq. %2d S %i - %s : %s",
fRawReader->GetEventIndex(), fCurrEquipmentId, fCurrSlot, fgkErrorMessages[err],
(va_start(ap, msg), vsprintf(fErrorBuffer, msg, ap), va_end(ap), fErrorBuffer) ));
fErrorFlags |= fgErrorBehav[err];
}
void AliTRDrawStream::LinkError(ErrorCode_t err, const char *const msg, ...)
{
fLastError.fSector = fCurrEquipmentId - kDDLOffset;
fLastError.fStack = fCurrSlot;
fLastError.fLink = fCurrLink;
fLastError.fRob = -1;
fLastError.fMcm = -1;
fLastError.fError = err;
(this->*fStoreError)();
va_list ap;
if (fgErrorDebugLevel[err] > 0)
AliDebug(fgErrorDebugLevel[err],
Form("Event %6i: Eq. %2d S %i l %2i - %s : %s",
fRawReader->GetEventIndex(), fCurrEquipmentId, fCurrSlot, fCurrLink, fgkErrorMessages[err],
(va_start(ap, msg), vsprintf(fErrorBuffer, msg, ap), va_end(ap), fErrorBuffer) ));
else
AliError(Form("Event %6i: Eq. %2d S %i l %2i - %s : %s",
fRawReader->GetEventIndex(), fCurrEquipmentId, fCurrSlot, fCurrLink, fgkErrorMessages[err],
(va_start(ap, msg), vsprintf(fErrorBuffer, msg, ap), va_end(ap), fErrorBuffer) ));
fErrorFlags |= fgErrorBehav[err];
}
void AliTRDrawStream::ROBError(ErrorCode_t err, const char *const msg, ...)
{
fLastError.fSector = fCurrEquipmentId - kDDLOffset;
fLastError.fStack = fCurrSlot;
fLastError.fLink = fCurrLink;
fLastError.fRob = fCurrRobPos;
fLastError.fMcm = -1;
fLastError.fError = err;
(this->*fStoreError)();
va_list ap;
if (fgErrorDebugLevel[err] > 0)
AliDebug(fgErrorDebugLevel[err],
Form("Event %6i: Eq. %2d S %i l %2i ROB %i - %s : %s",
fRawReader->GetEventIndex(), fCurrEquipmentId, fCurrSlot, fCurrLink, fCurrRobPos, fgkErrorMessages[err],
(va_start(ap, msg), vsprintf(fErrorBuffer, msg, ap), va_end(ap), fErrorBuffer) ));
else
AliError(Form("Event %6i: Eq. %2d S %i l %2i ROB %i - %s : %s",
fRawReader->GetEventIndex(), fCurrEquipmentId, fCurrSlot, fCurrLink, fCurrRobPos, fgkErrorMessages[err],
(va_start(ap, msg), vsprintf(fErrorBuffer, msg, ap), va_end(ap), fErrorBuffer) ));
fErrorFlags |= fgErrorBehav[err];
}
void AliTRDrawStream::MCMError(ErrorCode_t err, const char *const msg, ...)
{
fLastError.fSector = fCurrEquipmentId - kDDLOffset;
fLastError.fStack = fCurrSlot;
fLastError.fLink = fCurrLink;
fLastError.fRob = fCurrRobPos;
fLastError.fMcm = fCurrMcmPos;
fLastError.fError = err;
(this->*fStoreError)();
va_list ap;
if (fgErrorDebugLevel[err] > 0)
AliDebug(fgErrorDebugLevel[err],
Form("Event %6i: Eq. %2d S %i l %2i ROB %i MCM %2i - %s : %s",
fRawReader->GetEventIndex(), fCurrEquipmentId, fCurrSlot, fCurrLink, fCurrRobPos, fCurrMcmPos, fgkErrorMessages[err],
(va_start(ap, msg), vsprintf(fErrorBuffer, msg, ap), va_end(ap), fErrorBuffer) ));
else
AliError(Form("Event %6i: Eq. %2d S %i l %2i ROB %i MCM %2i - %s : %s",
fRawReader->GetEventIndex(), fCurrEquipmentId, fCurrSlot, fCurrLink, fCurrRobPos, fCurrMcmPos, fgkErrorMessages[err],
(va_start(ap, msg), vsprintf(fErrorBuffer, msg, ap), va_end(ap), fErrorBuffer) ));
fErrorFlags |= fgErrorBehav[err];
}
const char* AliTRDrawStream::GetErrorMessage(ErrorCode_t errCode)
{
if (errCode > 0 && errCode < kLastErrorCode)
return fgkErrorMessages[errCode];
else
return "";
}
void AliTRDrawStream::AliTRDrawStats::ClearStats()
{
fBytesRead = 0;
for (Int_t iSector = 0; iSector < 18; iSector++) {
fStatsSector[iSector].ClearStats();
}
}
void AliTRDrawStream::AliTRDrawStats::AliTRDrawStatsSector::ClearStats()
{
fBytes = 0;
fBytesRead = 0;
fNTracklets = 0;
fNMCMs = 0;
fNChannels = 0;
for (Int_t iHC = 0; iHC < 60; iHC++) {
fStatsHC[iHC].ClearStats();
}
}
void AliTRDrawStream::AliTRDrawStats::AliTRDrawStatsSector::AliTRDrawStatsHC::ClearStats()
{
fBytes = 0;
fBytesRead = 0;
fNTracklets = 0;
fNMCMs = 0;
fNChannels = 0;
}
void AliTRDrawStream::SetDumpMCM(Int_t det, Int_t rob, Int_t mcm, Bool_t dump)
{
if (dump) {
fDumpMCM[fNDumpMCMs++] = (det << 7) | (rob << 4) | mcm;
}
else {
Int_t iMCM;
for (iMCM = 0; iMCM < fNDumpMCMs; iMCM++) {
if (fDumpMCM[iMCM] == ((det << 7) | (rob << 4) | mcm)) {
fNDumpMCMs--;
break;
}
}
for ( ; iMCM < fNDumpMCMs; iMCM++) {
fDumpMCM[iMCM] = fDumpMCM[iMCM+1];
}
}
}
Bool_t AliTRDrawStream::DumpingMCM(Int_t det, Int_t rob, Int_t mcm) const
{
for (Int_t iMCM = 0; iMCM < fNDumpMCMs; iMCM++) {
if (fDumpMCM[iMCM] == ((det << 7) | (rob << 4) | mcm)) {
return kTRUE;
}
}
return kFALSE;
}
TString AliTRDrawStream::DumpRaw(TString title, const UInt_t *start, Int_t length, UInt_t endmarker)
{
title += "\n";
for (Int_t pos = 0; pos < length; pos += 4) {
if ((start[pos+0] != endmarker) && pos+0 < length)
if ((start[pos+1] != endmarker && pos+1 < length))
if ((start[pos+2] != endmarker && pos+2 < length))
if ((start[pos+3] != endmarker && pos+3 < length))
title += Form(" 0x%08x 0x%08x 0x%08x 0x%08x\n",
start[pos+0], start[pos+1], start[pos+2], start[pos+3]);
else {
title += Form(" 0x%08x 0x%08x 0x%08x 0x%08x\n",
start[pos+0], start[pos+1], start[pos+2], start[pos+3]);
return title;
}
else {
title += Form(" 0x%08x 0x%08x 0x%08x\n",
start[pos+0], start[pos+1], start[pos+2]);
return title;
}
else {
title += Form(" 0x%08x 0x%08x\n",
start[pos+0], start[pos+1]);
return title;
}
else {
title += Form(" 0x%08x\n",
start[pos+0]);
return title;
}
}
return title;
}
TString AliTRDrawStream::DumpMcmHeader(TString title, UInt_t word)
{
title += Form("0x%08x -> ROB: %i, MCM: %2i",
word, ROB(word), MCM(word));
return title;
}
TString AliTRDrawStream::DumpAdcMask(TString title, UInt_t word)
{
title += Form("0x%08x -> #ch : %2i, 0x%06x (%2i ch)",
word, GetNActiveChannels(word), GetActiveChannels(word), GetNActiveChannelsFromMask(word));
return title;
}
AliTRDrawStream::AliTRDrawStreamError::AliTRDrawStreamError(Int_t error, Int_t sector, Int_t stack, Int_t link, Int_t rob, Int_t mcm) :
fError(error),
fSector(sector),
fStack(stack),
fLink(link),
fRob(rob),
fMcm(mcm)
{
}
void AliTRDrawStream::SortTracklets(TClonesArray *trklArray, TList &sortedTracklets, Int_t *indices)
{
if (!trklArray)
return;
Int_t nTracklets = trklArray->GetEntriesFast();
Int_t lastHC = -1;
for (Int_t iTracklet = 0; iTracklet < nTracklets; iTracklet++) {
AliTRDtrackletBase *trkl = (AliTRDtrackletBase*) ((*trklArray)[iTracklet]);
Int_t hc = trkl->GetHCId();
if ((hc < 0) || (hc >= 1080)) {
AliErrorClass(Form("HC for tracklet: 0x%08x out of range: %i", trkl->GetTrackletWord(), trkl->GetHCId()));
continue;
}
AliDebugClass(5, Form("hc: %4i : 0x%08x z: %2i", hc, trkl->GetTrackletWord(), trkl->GetZbin()));
if (hc != lastHC) {
AliDebugClass(2, Form("set tracklet index for HC %i to %i", hc, iTracklet));
indices[hc] = iTracklet + 1;
lastHC = hc;
}
}
for (Int_t iDet = 0; iDet < 540; iDet++) {
Int_t trklIndexA = indices[2*iDet + 0] - 1;
Int_t trklIndexB = indices[2*iDet + 1] - 1;
Int_t trklIndex = sortedTracklets.GetEntries();
AliTRDtrackletBase *trklA = trklIndexA > -1 ? (AliTRDtrackletBase*) ((*trklArray)[trklIndexA]) : 0x0;
AliTRDtrackletBase *trklB = trklIndexB > -1 ? (AliTRDtrackletBase*) ((*trklArray)[trklIndexB]) : 0x0;
AliTRDtrackletBase *trklNext = 0x0;
while (trklA != 0x0 || trklB != 0x0) {
AliDebugClass(5, Form("det %i - A: %i/%i -> %p, B: %i/%i -> %p",
iDet, trklIndexA, nTracklets, trklA, trklIndexB, nTracklets, trklB));
if (trklA == 0x0) {
trklNext = trklB;
trklIndexB++;
trklB = trklIndexB < nTracklets ? (AliTRDtrackletBase*) ((*trklArray)[trklIndexB]) : 0x0;
if (trklB && trklB->GetHCId() != 2*iDet + 1)
trklB = 0x0;
}
else if (trklB == 0x0) {
trklNext = trklA;
trklIndexA++;
trklA = trklIndexA < nTracklets ? (AliTRDtrackletBase*) ((*trklArray)[trklIndexA]) : 0x0;
if (trklA && trklA->GetHCId() != 2*iDet)
trklA = 0x0;
}
else {
if (trklA->GetZbin() <= trklB->GetZbin()) {
trklNext = trklA;
trklIndexA++;
trklA = trklIndexA < nTracklets ? (AliTRDtrackletBase*) ((*trklArray)[trklIndexA]) : 0x0;
if (trklA && trklA->GetHCId() != 2*iDet)
trklA = 0x0;
}
else {
trklNext = trklB;
trklIndexB++;
trklB = trklIndexB < nTracklets ? (AliTRDtrackletBase*) ((*trklArray)[trklIndexB]) : 0x0;
if (trklB && trklB->GetHCId() != 2*iDet + 1)
trklB = 0x0;
}
}
if (trklNext) {
sortedTracklets.Add(trklNext);
}
}
if (sortedTracklets.GetEntries() != trklIndex) {
indices[2*iDet + 0] = trklIndex;
indices[2*iDet + 1] = sortedTracklets.GetEntries();
} else {
indices[2*iDet + 0] = indices[2*iDet + 1] = -1;
}
}
}
void AliTRDrawStream::AssignTracklets(AliESDTrdTrack *trdTrack, Int_t *trackletIndex, Int_t refIndex[6])
{
UInt_t mask = trdTrack->GetLayerMask();
UInt_t stack = trdTrack->GetStack();
for (Int_t iLayer = 0; iLayer < 6; iLayer++) {
refIndex[iLayer] = -1;
if (mask & (1 << iLayer)) {
Int_t det = trdTrack->GetSector()*30 + stack*6 + iLayer;
Int_t idx = trdTrack->GetTrackletIndex(iLayer);
if ((det < 0) || (det > 539)) {
AliErrorClass(Form("Invalid detector no. from track: %i", 2*det));
continue;
}
if (trackletIndex[2*det] >= 0) {
if ((trackletIndex[2*det] + idx > -1) &&
(trackletIndex[2*det] + idx < trackletIndex[2*det+1])) {
refIndex[iLayer] = trackletIndex[2*det] + idx;
} else {
AliErrorClass(Form("Requested tracklet index %i out of range", idx));
}
} else {
AliErrorClass(Form("Non-existing tracklets requested in det %i", det));
}
}
}
}