--- /dev/null
+/**************************************************************************
+ * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ * *
+ * Author: The ALICE Off-line Project. *
+ * Contributors are mentioned in the code where appropriate. *
+ * *
+ * Permission to use, copy, modify and distribute this software and its *
+ * documentation strictly for non-commercial purposes is hereby granted *
+ * without fee, provided that the above copyright notice appears in all *
+ * copies and that both the copyright notice and this permission notice *
+ * appear in the supporting documentation. The authors make no claims *
+ * about the suitability of this software for any purpose. It is *
+ * provided "as is" without express or implied warranty. *
+ **************************************************************************/
+
+/* $Id$ */
+
+///////////////////////////////////////////////////////////////////////////////
+// //
+// This class provides access to TRD digits in raw data. //
+// //
+// It loops over all TRD digits in the raw data given by the AliRawReader. //
+// The Next method goes to the next digit. If there are no digits left //
+// it returns kFALSE. //
+// Several getters provide information about the current digit. //
+// //
+// Author: C. Lippmann (C.Lippmann@gsi.de) //
+// //
+///////////////////////////////////////////////////////////////////////////////
+
+#include "AliLog.h"
+#include "AliRawReader.h"
+#include "AliTRDRawStreamTB.h"
+#include "AliTRDgeometry.h"
+#include "AliTRDcalibDB.h"
+#include "AliTRDfeeParam.h"
+
+#include "AliTRDdigitsManager.h"
+#include "AliTRDdataArrayI.h"
+#include "AliTRDSignalIndex.h"
+
+#include "TMath.h"
+
+using namespace AliTRDrawDataUtilsTB;
+
+ClassImp(AliTRDRawStreamTB)
+
+Bool_t AliTRDRawStreamTB::fgStackIndexBug=kFALSE;
+Int_t AliTRDRawStreamTB::fgForceRawVersion = -1;
+Bool_t AliTRDRawStreamTB::fgSupressWarnings=kFALSE;
+Bool_t AliTRDRawStreamTB::fgRawDataHack=kFALSE;
+Bool_t AliTRDRawStreamTB::fgExtraDebug=kFALSE;
+
+//_____________________________________________________________________________
+AliTRDRawStreamTB::AliTRDRawStreamTB()
+ :TObject()
+ ,fSig()
+ ,fADC(0)
+ ,fMaxADCgeom(-1)
+ ,fTB(0)
+ ,fEv(0)
+ ,fROB(0)
+ ,fMCM(0)
+ ,fSM(0)
+ ,fLAYER(0)
+ ,fSTACK(0)
+ ,fROC(0)
+ ,fSIDE(0)
+ ,fDCS(0)
+ ,fROW(0)
+ ,fCOL(0)
+ ,fDET(-1)
+ ,fLastDET(-1)
+ ,fBCctr(0)
+ ,fPTctr(0)
+ ,fPTphase(0)
+ ,fRVmajor(0)
+ ,fRVminor(0)
+ ,fHCHWords(0)
+ ,fTBins(0)
+ ,fTCon(0)
+ ,fPEDon(0)
+ ,fGAINon(0)
+ ,fXTon(0)
+ ,fNonLinOn(0)
+ ,fBypass(0)
+ ,fCommonAdditive(0)
+ ,fZeroSuppressed(0)
+ ,fHCHctr1(0)
+ ,fHCHctr2(0)
+ ,fMCMHctr1(0)
+ ,fMCMHctr2(0)
+ ,fGTUctr1(0)
+ ,fGTUctr2(0)
+ ,fHCdataCtr(0)
+ ,fTracklPID(0.)
+ ,fTracklDefL(0.)
+ ,fTracklPadPos(0.)
+ ,fTracklPadRow(0)
+ ,fGTUlinkMask()
+ ,fMCMWordCrt(0)
+ ,fMCMWordsExpected(0)
+ ,fRawReader(NULL)
+ ,fRawVersion(0)
+ ,fRawDigitThreshold(0)
+ ,fNextStatus(0)
+ ,fLastStatus(0)
+ ,fTbSwitch(0)
+ ,fTbSwitchCtr(0)
+ ,fTimeWords(0)
+ ,fWordCtr(0)
+ ,fRowMax(0)
+ ,fColMax(0)
+ ,fADCmask()
+ ,fLastADCmask(0)
+ ,fChamberDone()
+ ,fRetVal(0)
+ ,fEqID(0)
+ ,fDataSize(0)
+ ,fSizeOK(kFALSE)
+ ,fCountBytes(0)
+ ,fBufSize(0)
+ ,fkBufferSet(kFALSE)
+ ,fPos(NULL)
+ ,fDataWord(NULL)
+ ,fTimeBinsCalib(0)
+ ,fADClookup()
+ ,fNActiveADCs(0)
+ ,fEndOfDataFlag(kFALSE)
+ ,fHCInfo()
+ ,fMCMInfo()
+ ,fiSMx(0)
+ ,fSharedPadsOn(kFALSE)
+ ,fIsPadShared(kFALSE)
+ ,fGeo(NULL)
+{
+ //
+ // Default constructor
+ //
+
+ for (Int_t i = 0; i < 540; i++) {
+ fChamberDone[i] = 0;
+ }
+
+}
+
+//_____________________________________________________________________________
+AliTRDRawStreamTB::AliTRDRawStreamTB(AliRawReader *rawReader)
+ :TObject()
+ ,fSig()
+ ,fADC(0)
+ ,fMaxADCgeom(-1)
+ ,fTB(0)
+ ,fEv(0)
+ ,fROB(0)
+ ,fMCM(0)
+ ,fSM(0)
+ ,fLAYER(0)
+ ,fSTACK(0)
+ ,fROC(0)
+ ,fSIDE(0)
+ ,fDCS(0)
+ ,fROW(0)
+ ,fCOL(0)
+ ,fDET(-1)
+ ,fLastDET(-1)
+ ,fBCctr(0)
+ ,fPTctr(0)
+ ,fPTphase(0)
+ ,fRVmajor(0)
+ ,fRVminor(0)
+ ,fHCHWords(0)
+ ,fTBins(0)
+ ,fTCon(0)
+ ,fPEDon(0)
+ ,fGAINon(0)
+ ,fXTon(0)
+ ,fNonLinOn(0)
+ ,fBypass(0)
+ ,fCommonAdditive(0)
+ ,fZeroSuppressed(0)
+ ,fHCHctr1(0)
+ ,fHCHctr2(0)
+ ,fMCMHctr1(0)
+ ,fMCMHctr2(0)
+ ,fGTUctr1(0)
+ ,fGTUctr2(0)
+ ,fHCdataCtr(0)
+ ,fTracklPID(0.)
+ ,fTracklDefL(0.)
+ ,fTracklPadPos(0.)
+ ,fTracklPadRow(0)
+ ,fGTUlinkMask()
+ ,fMCMWordCrt(0)
+ ,fMCMWordsExpected(0)
+ ,fRawReader(rawReader)
+ ,fRawVersion(0)
+ ,fRawDigitThreshold(0)
+ ,fNextStatus(0)
+ ,fLastStatus(0)
+ ,fTbSwitch(0)
+ ,fTbSwitchCtr(0)
+ ,fTimeWords(0)
+ ,fWordCtr(0)
+ ,fRowMax(0)
+ ,fColMax(0)
+ ,fADCmask()
+ ,fLastADCmask(0)
+ ,fChamberDone()
+ ,fRetVal(0)
+ ,fEqID(0)
+ ,fDataSize(0)
+ ,fSizeOK(kFALSE)
+ ,fCountBytes(0)
+ ,fBufSize(0)
+ ,fkBufferSet(kFALSE)
+ ,fPos(NULL)
+ ,fDataWord(NULL)
+ ,fTimeBinsCalib(0)
+ ,fADClookup()
+ ,fNActiveADCs(0)
+ ,fEndOfDataFlag(kFALSE)
+ ,fHCInfo()
+ ,fMCMInfo()
+ ,fiSMx(0)
+ ,fSharedPadsOn(kFALSE)
+ ,fIsPadShared(kFALSE)
+ ,fGeo(NULL)
+{
+ //
+ // Create an object to read TRD raw digits
+ //
+
+ fRawReader->Select("TRD");
+
+ for (Int_t i = 0; i < 540; i++) {
+ fChamberDone[i] = 0;
+ }
+
+}
+
+//_____________________________________________________________________________
+AliTRDRawStreamTB::AliTRDRawStreamTB(const AliTRDRawStreamTB& stream)
+ :TObject(stream)
+ ,fSig()
+ ,fADC(-1)
+ ,fMaxADCgeom(-1)
+ ,fTB(-1)
+ ,fEv(-1)
+ ,fROB(-1)
+ ,fMCM(-1)
+ ,fSM(-1)
+ ,fLAYER(-1)
+ ,fSTACK(-1)
+ ,fROC(-1)
+ ,fSIDE(-1)
+ ,fDCS(-1)
+ ,fROW(-1)
+ ,fCOL(-1)
+ ,fDET(-1)
+ ,fLastDET(-1)
+ ,fBCctr(-1)
+ ,fPTctr(-1)
+ ,fPTphase(-1)
+ ,fRVmajor(-1)
+ ,fRVminor(-1)
+ ,fHCHWords(-1)
+ ,fTBins(-1)
+ ,fTCon(0)
+ ,fPEDon(0)
+ ,fGAINon(0)
+ ,fXTon(0)
+ ,fNonLinOn(-1)
+ ,fBypass(-1)
+ ,fCommonAdditive(-1)
+ ,fZeroSuppressed(0)
+ ,fHCHctr1(-1)
+ ,fHCHctr2(-1)
+ ,fMCMHctr1(-1)
+ ,fMCMHctr2(-1)
+ ,fGTUctr1(-1)
+ ,fGTUctr2(-1)
+ ,fHCdataCtr(-1)
+ ,fTracklPID(-1.)
+ ,fTracklDefL(-1.)
+ ,fTracklPadPos(-1.)
+ ,fTracklPadRow(-1)
+ ,fGTUlinkMask()
+ ,fMCMWordCrt(0)
+ ,fMCMWordsExpected(0)
+ ,fRawReader(NULL)
+ ,fRawVersion(0)
+ ,fRawDigitThreshold(0)
+ ,fNextStatus(0)
+ ,fLastStatus(0)
+ ,fTbSwitch(0)
+ ,fTbSwitchCtr(0)
+ ,fTimeWords(0)
+ ,fWordCtr(0)
+ ,fRowMax(-1)
+ ,fColMax(-1)
+ ,fADCmask()
+ ,fLastADCmask(0)
+ ,fChamberDone()
+ ,fRetVal(0)
+ ,fEqID(0)
+ ,fDataSize(0)
+ ,fSizeOK(kFALSE)
+ ,fCountBytes(0)
+ ,fBufSize(0)
+ ,fkBufferSet(kFALSE)
+ ,fPos(NULL)
+ ,fDataWord(NULL)
+ ,fTimeBinsCalib(0)
+ ,fADClookup()
+ ,fNActiveADCs(0)
+ ,fEndOfDataFlag(kFALSE)
+ ,fHCInfo()
+ ,fMCMInfo()
+ ,fiSMx(0)
+ ,fSharedPadsOn(kFALSE)
+ ,fIsPadShared(kFALSE)
+ ,fGeo(NULL)
+{
+ //
+ // Copy constructor
+ //
+
+ AliFatal("Copy constructor not implemented");
+
+}
+
+//_____________________________________________________________________________
+AliTRDRawStreamTB& AliTRDRawStreamTB::operator = (const AliTRDRawStreamTB&
+ /* stream */)
+{
+ //
+ // Assigment operator
+ //
+
+ Fatal("operator =", "assignment operator not implemented");
+ return *this;
+
+}
+
+//_____________________________________________________________________________
+AliTRDRawStreamTB::~AliTRDRawStreamTB()
+{
+ //
+ // Destructor
+ //
+
+ if (fGeo)
+ {
+ delete fGeo;
+ }
+
+}
+
+//_____________________________________________________________________________
+void AliTRDRawStreamTB::SetRawReader(AliRawReader *rawReader)
+{
+ //
+ // Set the rawreader
+ //
+
+ if (rawReader)
+ {
+ fRawReader = rawReader;
+ }
+}
+
+//_____________________________________________________________________________
+Bool_t AliTRDRawStreamTB::SetRawVersion(Int_t rv)
+{
+ //
+ // Set the raw data version
+ //
+
+ if ( rv >= 0 && rv <= 3 ) {
+ fRawVersion = rv;
+ return kTRUE;
+ }
+
+ return kFALSE;
+
+}
+
+
+//____________________________________________________________________________
+Int_t AliTRDRawStreamTB::Init()
+{
+ //
+ // Initialization
+ //
+
+ if (!AliTRDcalibDB::Instance()) {
+ AliError("Could not get calibration object");
+ return 0;
+ }
+
+ if (!fGeo) {
+ fGeo = new AliTRDgeometry();
+ }
+
+ fMaxADCgeom = (Int_t)fGeo->ADCmax();
+
+ fTimeBinsCalib = AliTRDcalibDB::Instance()->GetNumberOfTimeBins();
+ //AliDebug(2, Form("Number of Timebins read from CDB: %d", fTimeBinsCalib));
+
+ // The number of data words needed for this number of time bins (there
+ // are 3 time bins in one word)
+ fTimeWords = (fTimeBinsCalib-1)/3 + 1;
+
+ fTbSwitch = 3;
+ fTbSwitchCtr = 0;
+
+ fHCHctr1 = fHCHctr2 = 0;
+ fGTUctr1 = fGTUctr2 = -1;
+
+ fHCdataCtr = 0;
+ fWordCtr = 0;
+
+ fDET = -1;
+ fLastDET = -1;
+ fRetVal = 0;
+ fEqID = 0;
+ fDataSize = 0;
+ fSizeOK = kFALSE;
+
+ fLastStatus = fkStart;
+ fNextStatus = fkStart;
+
+ fCountBytes = 0;
+ fBufSize = 0;
+ fDataWord = NULL;
+ fPos = NULL;
+ fWordCtr = 0;
+ fkBufferSet = kFALSE;
+
+ fMCMWordCrt = 0;
+ fMCMWordsExpected = 0;
+
+ fEndOfDataFlag = kFALSE;
+ // set all ADC active
+ fNActiveADCs = ChannelsToRead(0x1fffff); // should be 1111 1111 1111 1111 1111 1 = 21 bits active (0-20)
+
+ fLastADCmask = 0;
+
+ //default value overwritten by HC header word h[2]
+ fCommonAdditive = 10;
+ //fSharedPadsOn = kFALSE;
+ //fSharedPadsOn = kTRUE;
+ fIsPadShared = kFALSE;
+ fZeroSuppressed = kFALSE;
+
+ return kTRUE;
+}
+
+//____________________________________________________________________________
+void AliTRDRawStreamTB::SwapOnEndian()
+{
+ //
+ // Check the endian and swap if needed
+ //
+
+ int itemp = 1;
+ char* ptemp = (char*) &itemp;
+ if (ptemp[0] != 1)
+ {
+ // need to swap...
+ // assume we are at the begining of the buffer!
+ //AliDebug(5, "Swapping.");
+ UInt_t *pbegin = (UInt_t*)fPos;
+ UInt_t iutmp = 0;
+ for (UInt_t i = 0; i < fBufSize / AliTRDrawDataUtilsTB::kSizeWord; i++)
+ {
+ fDataWord = pbegin + i;
+ iutmp = (((*fDataWord & 0x000000ffU) << 24) | ((*fDataWord & 0x0000ff00U) << 8) |
+ ((*fDataWord & 0x00ff0000U) >> 8) | ((*fDataWord & 0xff000000U) >> 24));
+ // here we override the value in the buffer!
+ *fDataWord = iutmp;
+ }
+ fDataWord = pbegin;
+ }
+}
+
+//____________________________________________________________________________
+Int_t AliTRDRawStreamTB::NextData()
+{
+ //
+ // Updates the next data word pointer
+ //
+
+ if (fCountBytes + kSizeWord >= fBufSize)
+ {
+ fkBufferSet = fRawReader->ReadNextData(fPos);
+ if (fkBufferSet == kTRUE)
+ {
+ fBufSize = fRawReader->GetDataSize();
+ fCountBytes = 0;
+ fDataWord = (UInt_t*)fPos;
+ SwapOnEndian();
+ if (fgRawDataHack == kTRUE)
+ {
+ SkipWords(24);
+ fCountBytes += 24 * kSizeWord;
+ //fgRawDataHack = kFALSE;
+ }
+ ChangeStatus(fkNextSM);
+ fWordCtr = 0;
+ AliDebug(3, "NextSM. Buffer is set.");
+ return fkNextSM;
+ }
+ else
+ {
+ //AliDebug(3, "No more data!");
+ ChangeStatus(fkStop);
+ ChangeStatus(fkNoMoreData);
+ return fkNoMoreData;
+ }
+ }
+ else
+ {
+ fPos += kSizeWord;
+ fCountBytes += kSizeWord;
+ fDataWord = (UInt_t*)fPos;
+ fWordCtr++;
+ AliDebug(10, Form("Current word %d : 0x%x at 0x%x. Count bytes %d of %d",
+ fWordCtr, *fDataWord, fPos, fCountBytes, fBufSize));
+ // if (fCountBytes > 3080000)
+ // printf("Current word %d : 0x%x at 0x%x. Count bytes %d of %d\n",
+ // fWordCtr, *fDataWord, fPos, fCountBytes, fBufSize);
+ return fkWordOK;
+ }
+}
+
+//____________________________________________________________________________
+Int_t AliTRDRawStreamTB::RewindWord()
+{
+ //
+ // Updates the next data word pointer
+ //
+
+ if (fkBufferSet == kFALSE)
+ return fkStart;
+
+ if (fCountBytes > 0)
+ {
+ fPos -= kSizeWord;
+ fCountBytes -= kSizeWord;
+ fDataWord = (UInt_t*)fPos;
+ fWordCtr--;
+ }
+ else
+ {
+ AliWarning("Already at the begining of the buffer");
+ }
+
+ return fkWordOK;
+}
+
+//============================================================================
+// Decoding functions
+//============================================================================
+
+//____________________________________________________________________________
+void AliTRDRawStreamTB::DecodeHCheader(Int_t timeBins)
+{
+ //
+ // Decode the HC header (fRawVersion == 2, 3, 4, ???)
+ //
+ //AliDebug(3, "Here");
+
+ // 1st word (h[0])
+ if ( (*fDataWord & 0x3) == 1 )
+ {
+
+ fHCInfo.DecodeH0(fDataWord);
+ if (fgExtraDebug)
+ fHCInfo.Dump();
+
+ fHCHWords = fHCInfo.fNExtraWords;
+ fSM = fHCInfo.fSM;
+ fLAYER = fHCInfo.fLayer;
+ fSTACK = fHCInfo.fStack;
+ fSIDE = fHCInfo.fSide;
+
+ fRVmajor = fHCInfo.fRawVMajor;
+ fRVminor = fHCInfo.fRawVMinor;
+
+ //assuming valid raw version w/o ZS
+ if (fRVmajor <= 0)
+ fRVmajor = 2;
+
+ if ( fRawVersion != fRVmajor )
+ {
+ if (fgSupressWarnings == kTRUE)
+ {
+ if (fgForceRawVersion > 0)
+ {
+ fRawVersion = fgForceRawVersion;
+ }
+ else
+ {
+ fRawVersion = fRVmajor;
+ }
+ }
+ else
+ {
+ AliWarning("===============================================================================");
+ AliWarning(Form("Mismatch between fRawVersion (%d) and fRVmajor from HC header (%d)"
+ ,fRawVersion,fRVmajor));
+ if (fgForceRawVersion > 0)
+ {
+ AliWarning(Form("Forcing fRawVersion to %d", fgForceRawVersion));
+ fRawVersion = fgForceRawVersion;
+ }
+ else
+ {
+ AliWarning(Form("Setting fRawVersion to %d", fRVmajor));
+ fRawVersion = fRVmajor;
+ }
+ AliWarning("===============================================================================");
+ } //warn or not
+ }//if raw version missmatch
+
+ //AliInfo(Form("Raw Version %d", fRawVersion));
+
+ //
+ // check for zero suppression
+ if ( fRawVersion >= 3 || fRawVersion <= 4 ) fZeroSuppressed = kTRUE;
+ else fZeroSuppressed = kFALSE;
+
+ fROC = fGeo->GetDetectorSec(fLAYER, fSTACK);
+
+ AliDebug(3, Form("0x%08x: HC header: sm=%d; roc=%d; side=%x", *fDataWord, fSM, fROC, fSIDE+10));
+ AliDebug(5, Form("0x%08x: HC header: expecting %d HC words", *fDataWord, fHCHWords));
+
+ if ((fSM < 0) ||
+ (fSM > 17) ||
+ (fLAYER < 0) ||
+ (fLAYER > 5) ||
+ (fSTACK < 0) ||
+ (fSTACK > 4) ||
+ (fSIDE < 0) ||
+ (fSIDE > 1))
+ {
+ AliWarning(Form("0x%08x: Strange HC header: dcs=%d; sm=%d; layer=%d; stack=%d.",
+ *fDataWord, fDCS, fSM, fLAYER, fSTACK));
+ fRawReader->AddMajorErrorLog(kHCHeaderCorrupt,Form("0x%08x:dcs=%d; sm=%d; layer=%d; stack=%d.",
+ *fDataWord, fDCS, fSM, fLAYER, fSTACK));
+ }
+ else
+ {
+ fHCHctr1++;
+ fHCHctr2++;
+ }
+ }
+ else
+ {
+ AliWarning(Form("0x%08x: No HC header when it was expected.", *fDataWord));
+ fRawReader->AddMajorErrorLog(kHCHeaderMissing,Form("0x%08x", *fDataWord));
+ }
+
+ // 2nd word (h[1])
+ if ( fHCHWords >= 1 )
+ {
+ // read one more word
+ if (NextData() != fkWordOK)
+ {
+ AliWarning("Next HC ( H[1] ) word missing");
+ fRawReader->AddMajorErrorLog(kHCWordMissing,"Next HC ( H[1] )word missing");
+ ChangeStatus(fkNextHC);
+ return;
+ }
+
+ if ( (*fDataWord & 0x3) == 1 )
+ {
+
+ fHCInfo.DecodeH1(fDataWord);
+
+ fBCctr = fHCInfo.fBunchCrossCounter;
+ fPTctr = fHCInfo.fPreTriggerCounter;
+ fPTphase = fHCInfo.fPreTriggerPhase;
+ fTBins = fHCInfo.fTimeBins;
+
+ fTimeWords = (fTBins - 1)/3 + 1;
+
+ AliDebug(3, Form("0x%08x: HC header [1]: BCctr=%d PTctr=%d PTph=%d TB=%d"
+ , *fDataWord, fBCctr, fPTctr, fPTphase, fTBins));
+
+ if( fTBins != timeBins )
+ {
+ if (fgSupressWarnings == kTRUE)
+ {
+ fTimeWords = (fTBins - 1)/3 + 1;
+ }
+ else
+ {
+ AliWarning("===============================================================================");
+ AliError(Form("Mismatch between nNTB from CDB (%d) and from HC header (%d)"
+ , timeBins, fTBins));
+ AliWarning(Form("We will use the value from the raw data (HC header): %d", fTBins));
+ AliWarning("===============================================================================");
+ fTimeWords = (fTBins - 1)/3 + 1;
+ }
+ }
+ }
+ }
+
+ // 3nd word (h[2])
+ if ( fHCHWords >= 2 )
+ {
+ // read one more word
+ if (NextData() != fkWordOK)
+ {
+ AliWarning("Next HC ( [2] )word missing");
+ fRawReader->AddMajorErrorLog(kHCWordMissing,"Next HC ( [2] ) word missing");
+ ChangeStatus(fkNextHC);
+ return;
+ }
+
+ if ( (*fDataWord & 0x3) == 1 )
+ {
+
+ fTCon = (*fDataWord >> 29) & 0x1;
+ fPEDon = (*fDataWord >> 31) & 0x1;
+ fGAINon = (*fDataWord >> 30) & 0x1;
+ fXTon = (*fDataWord >> 28) & 0x1;
+ fNonLinOn = (*fDataWord >> 27) & 0x1;
+ fBypass = (*fDataWord >> 26) & 0x1;
+
+ fCommonAdditive = (*fDataWord >> 20) & 0x3f;
+
+ AliDebug(3, Form("0x%08x: HC header 3: TC=%d, PED=%d, GAIN=%d, XT=%d, NonLin=%d, Bypass=%d, Add=%d"
+ , fTCon, fPEDon, fGAINon, fXTon, fNonLinOn, fBypass, fCommonAdditive));
+ }
+ }
+
+ if (fTBins <= 0)
+ {
+ fTBins = 30;
+ fTimeWords = (fTBins - 1)/3 + 1;
+ AliDebug(5, Form("Forced tbins %d timewords %d", fTBins, fTimeWords));
+ }
+}
+
+//____________________________________________________________________________
+Int_t AliTRDRawStreamTB::ChannelsToRead(Int_t ADCmask)
+{
+ //AliDebug(3, "Here");
+ memset(fADClookup, -1, 32 * sizeof(Int_t));
+ fADClookup[0] = 0; // count entries
+ fADClookup[1] = 2; // index - data start at 2
+ UInt_t mask = 0;
+ for (Int_t i = 0; i < 30; i++)
+ {
+ mask = 1 << i;
+ if ((ADCmask & mask))
+ {
+ //AliDebug(9, Form("fDataWord=0x%08x mask=0x%08x i=%d", *fDataWord, mask, i));
+ fADClookup[fADClookup[1]] = i;
+ ++fADClookup[0];
+ ++fADClookup[1];
+ }
+ }
+
+ // test the iteration - comment out for production
+ // begin of comment out section
+// char schannels[512];
+// sprintf(schannels, "ADC Channels to read: ");
+// fADClookup[1] = 2;
+// while(fADClookup[1] - 2 < fADClookup[0])
+// {
+// AliDebug(9, Form("max=%d index=%d adc=%d", fADClookup[0], fADClookup[1], fADClookup[fADClookup[1]]));
+// strcat(schannels, Form("%d ", fADClookup[fADClookup[1]]));
+// fADClookup[1]++;
+// }
+ //AliDebug(9, Form("%s", schannels));
+ //AliDebug(9, Form("ADC channels = %d", fADClookup[0]));
+ // end of comment out section
+
+ fADClookup[1] = 2;
+ return fADClookup[0];
+}
+
+//____________________________________________________________________________
+void AliTRDRawStreamTB::DecodeTracklet()
+{
+
+ //
+ // Decode the Tracklet
+ //
+ // this function is not tested yet on real tracklets
+ //
+ //AliDebug(3, "Here");
+// if ( fRawVersion < 1 || fRawVersion > 3 )
+// {
+// AliError(Form(" Unsupported raw version: %d", fRawVersion));
+// }
+
+ fTracklPID = (*fDataWord >> 24) & 0xff;
+ fTracklPadRow = (*fDataWord >> 20) & 0xf; // 0:15
+ fTracklDefL = (*fDataWord >> 13) & 0x7f;
+ fTracklPadPos = (*fDataWord) & 0x1fff;
+
+ fTracklPID /= (Float_t)((1<<8) - 1); // 0:1 (steps of 0.39%)
+ fTracklDefL = (fTracklDefL - ((1<< 7)-1)/2.) * 140.e-4; // -0.889:0.889cm
+ fTracklPadPos = (fTracklPadPos - ((1<<13)-1)/2.) * 160.e-4; // -65.528:65.528 cm
+
+ AliDebug(4, Form("0x%08x: Tracklet found: SM%d L%dS%d side %x: PadRow=%d PadPos=%f DefL=%f PID=%f"
+ , *fDataWord, fSM, fLAYER, fSTACK, fSIDE+10
+ , fTracklPadRow, fTracklPadPos, fTracklDefL, fTracklPID));
+
+ if( (fSTACK == 2) && (fTracklPadRow >= (Int_t) fGeo->RowmaxC0()) ||
+ (fSTACK != 2) && (fTracklPadRow >= (Int_t) fGeo->RowmaxC1()) ) {
+ AliWarning(Form("Strange Row read from Tracklet Word: %d", fTracklPadRow));
+ fRawReader->AddMajorErrorLog(kTrackletRowMismatch,Form("Word: %d", fTracklPadRow));
+ }
+
+}
+
+//____________________________________________________________________________
+void AliTRDRawStreamTB::DecodeMCMheader()
+{
+
+ //
+ // Decode the MCM header
+ //
+ //AliDebug(3, "Here");
+
+ if ( fRawVersion < 0 || fRawVersion > 3 )
+ {
+ AliError(Form(" Unsupported raw version: %d", fRawVersion));
+ }
+
+ fMCMInfo.Decode(fDataWord);
+
+ fMCM = fMCMInfo.fMCM;
+ fROB = fMCMInfo.fROB;
+ fEv = fMCMInfo.fEvCounter;
+ if (fgExtraDebug)
+ fMCMInfo.Dump();
+
+ fROW = AliTRDfeeParam::Instance()->GetPadRowFromMCM(fROB, fMCM);
+
+ AliDebug(4, Form("0x%08x: SM%d L%dS%d. MCM Header: fROB=%d fMCM=%02d fEv=%02d"
+ , *fDataWord, fSM, fLAYER, fSTACK, fROB, fMCM, fEv));
+
+ if ( fROB % 2 == 0 && fSIDE == 1 )
+ {
+ AliWarning(Form("SM%d L%dS%d: Mismatch between fROB (%d) and fSIDE (%d): fMCM=%02d"
+ , fSM, fLAYER, fSTACK, fROB, fSIDE, fMCM ));
+ fRawReader->AddMajorErrorLog(kROBSideMismatch,Form("SM%d L%dS%d: fROB (%d) fSIDE (%d): fMCM=%02d"
+ , fSM, fLAYER, fSTACK, fROB, fSIDE, fMCM ));
+ }
+
+ if ( fROB % 2 != 0 && fSIDE == 0 )
+ {
+ AliWarning(Form("SM%d L%dS%d: Mismatch between fROB (%d) and fSIDE (%d): fMCM=%02d"
+ , fSM, fLAYER, fSTACK, fROB, fSIDE, fMCM ));
+ fRawReader->AddMajorErrorLog(kROBSideMismatch,Form("SM%d L%dS%d: fROB (%d) fSIDE (%d): fMCM=%02d"
+ , fSM, fLAYER, fSTACK, fROB, fSIDE, fMCM ));
+ }
+
+ if ( (fSTACK == 2 && fROW >= fGeo->RowmaxC0()) ||
+ (fSTACK != 2 && fROW >= fGeo->RowmaxC1()) || fROW < 0 )
+ {
+ AliWarning(Form("SM%d L%dS%d: Wrong Padrow (%d) fROB=%d, fSIDE=%d, fMCM=%02d"
+ , fSM, fLAYER, fSTACK, fROW, fROB, fSIDE, fMCM ));
+ fRawReader->AddMajorErrorLog(kWrongPadrow,Form("SM%d L%dS%d: Padrow (%d) fROB=%d, fSIDE=%d, fMCM=%02d"
+ , fSM, fLAYER, fSTACK, fROW, fROB, fSIDE, fMCM ));
+ }
+
+ fMCMHctr1++;
+ fMCMHctr2++;
+
+ fMCMWordCrt = 1; // MCM header
+
+ // AdcMask for Zero supressed data
+ if ( fRawVersion == 3 )
+ {
+ // read one more word
+ if (NextData() != fkWordOK)
+ {
+ AliWarning("MCM ADC mask missing");
+ fRawReader->AddMajorErrorLog(kMCMADCMaskMissing,"Missing");
+ fNextStatus = fkNextHC;
+ return;
+ }
+ else
+ {
+ ++fMCMWordCrt;
+
+ for ( Int_t ctr = 0; ctr < fMaxADCgeom; ctr++ ) {
+ if ( (*fDataWord >> (11+ctr)) == 0x1 ) fADCmask[ctr] = kTRUE;
+ else fADCmask[ctr] = kFALSE;
+ }
+
+ if (*fDataWord & 0xf != 0xc)
+ {
+ AliWarning(Form("ADC mask does not end with 0xc : 0x%x", *fDataWord));
+ }
+
+ //AliDebug(4, Form("0x%08x: ADC mask", *fDataWord));
+ // 7 MSbits are ignored!
+ UInt_t maskWord = (*fDataWord >> 4) & 0x1fffff;
+ fNActiveADCs = ChannelsToRead(maskWord);
+ }
+ }
+
+ if (fRawVersion <= 2)
+ {
+ fNActiveADCs = ChannelsToRead(0x1fffff); // should be 1111 1111 1111 1111 1111 1 = 21 bits active (0-20)
+ //directly get it like that:
+ fMCMWordsExpected = 1 + fNActiveADCs * fTBins / 3;
+ }
+
+ if (fRawVersion >= 3)
+ {
+ // raw version 3:
+ //directly get it like that:
+ fMCMWordsExpected = 1 + 1 + (fTBins * fNActiveADCs) / 3;
+ }
+
+ AliDebug(8, Form("TBins %d fNActiveADCs %d => We expect %d MCM words. We read %d so far.", fTBins, fNActiveADCs, fMCMWordsExpected, fMCMWordCrt));
+}
+
+//____________________________________________________________________________
+Bool_t AliTRDRawStreamTB::DecodeADCWord()
+{
+ // Decode ADC word for any pad
+ // Rearange this function!!!
+ //AliDebug(3, "Here");
+ Bool_t kIsDataOK = kFALSE;
+
+ // Get Pad column
+ // fCOL = fFee->GetPadColFromADC(fROB, fMCM, fADC);
+ if ( fADC >= fMaxADCgeom - 1)
+ {
+ // let us guess the Column
+ // take the one before last ADC and shift by one column
+ // later we check if we are inside the limits of the chamber
+ fCOL = AliTRDfeeParam::Instance()->GetPadColFromADC(fROB, fMCM, fADC - 1);
+ fCOL--;
+ //AliDebug(8, Form("-x fADC %d fCOL %d", fADC, fCOL));
+ if (fCOL >= fColMax || fCOL < 0)
+ {
+ //AliDebug(8, Form("-xx fADC %d fCOL %d", fADC, fCOL));
+ fCOL = -1;
+ kIsDataOK = kFALSE;
+ return kIsDataOK;
+ }
+ }
+ else
+ {
+ //AliDebug(8, Form("-y fADC %d fCOL %d", fADC, fCOL));
+ fCOL = AliTRDfeeParam::Instance()->GetPadColFromADC(fROB, fMCM, fADC);
+ if (fCOL >= fColMax || fCOL < 0)
+ {
+ //AliDebug(8, Form("-xx fADC %d fCOL %d", fADC, fCOL));
+ fCOL = -1;
+ kIsDataOK = kFALSE;
+ return kIsDataOK;
+ }
+ }
+
+ // We have only 144 Pad Columns
+ //if ( fCOL > fColMax-1 || fCOL < 0 )
+ if ( fCOL >= 0 && fCOL < fColMax && fROW >= 0 && fROW < fRowMax )
+ {
+ // Decode 32 bit data words with information from 3 time bins and copy the data
+ fSig[0] = (*fDataWord & 0x00000ffc) >> 2;
+ fSig[1] = (*fDataWord & 0x003ff000) >> 12;
+ fSig[2] = (*fDataWord & 0xffc00000) >> 22;
+
+ // Print data to screen:
+ AliDebug(5, Form("DATA : 0x%x tTbin %d", *fDataWord, fTB));
+ AliDebug(5, Form("SM%d L%dS%d: ROB%d MCM=%d ADC=%d (ROW=%d COL=%d): Data %04d %04d %04d\n",
+ fSM, fLAYER, fSTACK, fROB, fMCM, fADC, fROW, fCOL, fSig[0], fSig[1], fSig[2]));
+ kIsDataOK = kTRUE;
+ }
+ else
+ {
+ AliWarning(Form("SM%d L%dS%d: Wrong Pad column (%d) fROB=%d, fSIDE=%d, fMCM=%02d", fSM,
+ fLAYER, fSTACK, fCOL, fROB, fSIDE, fMCM ));
+ fRawReader->AddMajorErrorLog(kWrongPadcolumn,Form("SM%d L%dS%d: column (%d) fROB=%d, fSIDE=%d, fMCM=%02d", fSM,
+ fLAYER, fSTACK, fCOL, fROB, fSIDE, fMCM ));
+ kIsDataOK = kFALSE;
+ }
+
+ return kIsDataOK;
+}
+
+//____________________________________________________________________________
+Bool_t AliTRDRawStreamTB::DecodeNextRawWord()
+{
+ //AliDebug(8, Form("-----------------------------------------"));
+ //AliDebug(8, Form("DATA IS 0x%x", *fDataWord));
+
+ //AliDebug(3, "Here");
+ if ( *fDataWord == kEndOfRawDataMarker )
+ { // End of half-chamber data, finished
+ AliDebug(3, "We have reached the eof data. Next should be HC header.");
+ fGTUctr1 = -1;
+ ChangeStatus(fkNextHC);
+ fEndOfDataFlag = kTRUE;
+ return kFALSE;
+ }
+
+ if (fADClookup[1] - 2 > fADClookup[0])
+ {
+ AliDebug(8, Form("Overflow Index ADC = %d Max Index = %d Value = %d. Done with ADCs in this MCM. Is this already MCM header 0x%x?",
+ fADClookup[1] - 2, fADClookup[0], fADClookup[fADClookup[1]], *fDataWord));
+ fTB = 0;
+ fTbSwitchCtr = 0;
+ fMCMWordsExpected = 0;
+ AliWarning("Trying to recover. Fall back to DecodeMCM.");
+ RewindWord();
+ ChangeStatus(fkNextMCM);
+ return kFALSE;
+ }
+
+ if ( (*fDataWord & 0x00000003) != 0x2 && (*fDataWord & 0x00000003) != 0x3)
+ {
+ AliWarning(Form("Data %08x : Data Word ends neither with b11 nor b10", (Int_t)*fDataWord));
+ fRawReader->AddMinorErrorLog(kDataMaskError,Form("Data %08x", (Int_t)*fDataWord));
+ fMCMWordsExpected = 0;
+ fTB = 0;
+ fTbSwitchCtr = 0;
+ AliWarning("Trying to recover. Fall back to DecodeMCM.");
+ RewindWord();
+ ChangeStatus(fkNextMCM);
+ return kFALSE;
+ }
+
+ if ( (*fDataWord & 0x3) != fLastADCmask || fTbSwitchCtr >= fTimeWords)
+ {
+ fADC = fADClookup[fADClookup[1]];
+ AliDebug(8, Form("Next fADC = %d at index = %d MCM Word Number: %d Max MCM Words is %d",
+ fADC, fADClookup[1] - 2, fMCMWordCrt, fMCMWordsExpected));
+ AliDebug(10, Form("LastMask 0x%x this data 0x%x OR fTbSwitchCtr %d >= fTimeWords %d",
+ fLastADCmask, (*fDataWord) & 0x3, fTbSwitchCtr, fTimeWords));
+ if ((*fDataWord & 0x3) != fLastADCmask && fTbSwitchCtr < fTimeWords && fTbSwitchCtr > 0)
+ {
+ AliWarning(Form("Change of mask! But not all words read!"));
+ AliWarning(Form("Next fADC = %d at index = %d MCM Word Number: %d Max MCM Words is %d",
+ fADC, fADClookup[1] - 2, fMCMWordCrt, fMCMWordsExpected));
+ AliWarning(Form("LastMask 0x%x this data 0x%x OR fTbSwitchCtr %d >= fTimeWords %d",
+ fLastADCmask, (*fDataWord) & 0x3, fTbSwitchCtr, fTimeWords));
+ }
+ ++fADClookup[1];
+ fTB = 0;
+ fTbSwitchCtr = 0;
+ ChangeStatus(fkNextData);
+ fLastADCmask = (*fDataWord) & 0x3;
+ }
+
+ ++fTbSwitchCtr;
+
+ //decode data here
+ Bool_t kIsDataOK = kFALSE;
+
+ // We have only 21 ADC channels.
+ if ( fADC > fMaxADCgeom - 1 || fADC < 0)
+ {
+ AliWarning(Form("Data 0x%08x : Data is strange. fADC is %d", (Int_t)*fDataWord, (Int_t)fADC));
+ AliWarning(Form("fADClookup[0] %d fADClookup[1] %d", fADClookup[0], fADClookup[1]));
+ fRawReader->AddMinorErrorLog(kADCChannelOverflow,Form("Data %08x : fADC=%d", (Int_t)*fDataWord, (Int_t)fADC));
+ }
+ else
+ {
+ // There are 18 pads connected to each MCM ADC channels 2...19. The other channels cross to other
+ // MCMs and are good for online tracking in the MCM.
+ if (fSharedPadsOn == kTRUE)
+ {
+ kIsDataOK = DecodeADCWord();
+ if (fADC <= 1 || fADC == fMaxADCgeom - 1)
+ {
+ AliDebug(9, Form("Shared Pad fADC == %d", fADC));
+ fIsPadShared = kTRUE;
+ }
+ else
+ {
+ fIsPadShared = kFALSE;
+ }
+ }
+ else
+ {
+ if ( fADC > 1 && fADC < fMaxADCgeom - 1 )
+ {
+ kIsDataOK = DecodeADCWord();
+ }
+ else
+ {
+ AliDebug(9, Form("fADC not accepted - shared pad %d - DATA : 0x%x", fADC, *fDataWord));
+ fCOL = -1;
+ kIsDataOK = kFALSE;
+ }
+ }
+ }// if fADC is ok
+
+ ++fMCMWordCrt;
+ AliDebug(8, Form("We expect %d MCM words. We read %d so far.Current word is 0x%x", fMCMWordsExpected, fMCMWordCrt, *fDataWord));
+
+ // all mcm data processed go to next one
+ if ( fMCMWordCrt >= fMCMWordsExpected)
+ {
+ AliDebug(8, Form("We expect %d MCM words. We read %d so far. Going to next MCM.", fMCMWordsExpected, fMCMWordCrt));
+ ChangeStatus(fkNextMCM);
+ }
+
+ return kIsDataOK;
+}
+
+//____________________________________________________________________________
+Bool_t AliTRDRawStreamTB::DecodeMCM()
+{
+ fTbSwitch = 3; // For first adc channel we expect: (*fDataWord & 3) = 3
+ fTbSwitchCtr = 0; //
+ fADC = fTB = 0; // Reset Counter
+ fLastADCmask = 0; // Reset
+
+ //AliDebug(3, "Here");
+
+ //if( ((*fDataWord & 0x80000000) == 0x0) && ((*fDataWord & 0x0000000f) == 0xC) )
+ //if( ((*fDataWord & 0xf0000000) == 0x80000000) && ((*fDataWord & 0x0000000f) == 0xC) )
+ if( (*fDataWord & 0x0000000f) == 0xC )
+ { // MCM Header
+ // this changed the status
+ DecodeMCMheader();
+ if ( fMCM < 0 || fMCM > 15 || fROB < 0 || fROB > 7 )
+ {
+ AliWarning("Wrong fMCM or fROB. Skip this data");
+ fRawReader->AddMajorErrorLog(kWrongMCMorROB,Form("MCM=%d, ROB=%d",fMCM,fROB));
+ ChangeStatus(fkNextHC);
+ return kFALSE;
+ }
+
+ if (fMCMWordCrt < fMCMWordsExpected)
+ {
+ AliDebug(5, Form("Going to read data."));
+ ChangeStatus(fkNextData);
+ }
+ else
+ {
+ //AliDebug(5, Form("! fMCMWordCrt < fMCMWordsExpected"));
+ ChangeStatus(fkNextMCM);
+ }
+ //fEndOfDataFlag = kFALSE;
+ return kTRUE;
+ }
+
+ if ( *fDataWord == kEndOfRawDataMarker )
+ { // End of half-chamber data, finished
+ AliDebug(10, "We have reached the eof data. Next should be HC header.");
+ fGTUctr1 = -1;
+
+ ChangeStatus(fkNextHC);
+ fEndOfDataFlag = kTRUE;
+ //AliDebug(5, "Expecting MCM header but got End-Of-Raw-Data Marker");
+ if (fMCMWordsExpected == 0 || fMCMWordsExpected == fMCMWordCrt)
+ {
+ AliDebug(5, Form("Got all mcm words. Returning true."));
+ return kTRUE;
+ }
+ else
+ {
+ AliDebug(5, Form("MCM words missing? %d [expected=%d got=%d] ", fMCMWordsExpected - fMCMWordCrt, fMCMWordsExpected, fMCMWordCrt));
+ //AliWarning(Form("MCM words missing? %d [expected=%d got=%d] ", fMCMWordsExpected - fMCMWordCrt, fMCMWordsExpected, fMCMWordCrt));
+ return kFALSE;
+ }
+ }
+
+ //AliDebug(3, Form("Expecting MCM header but got 0x%x. Going to Next MCM header.", *fDataWord));
+ AliWarning(Form("Expecting MCM header but got 0x%x. Fall back: Next MCM header.", *fDataWord));
+ ChangeStatus(fkNextMCM);
+
+ return kFALSE;
+}
+
+//____________________________________________________________________________
+Bool_t AliTRDRawStreamTB::DecodeHC()
+{
+ //AliDebug(3, "Here");
+
+ // left overs from the last chamber?
+ if (*fDataWord == kEndOfRawDataMarker)
+ {
+ AliDebug(3, "We have reached the eof data. Next should be HC header or end of the event!");
+ ChangeStatus(fkNextHC);
+ return kFALSE;
+ }
+
+// if (kFALSE == fSMinfo[fiSMx].fTrackletEnable)
+// {
+// // jump to data decoding - no traklets to expect
+// ChangeStatus(fkDecodeHC);
+// }
+// else
+// {
+// ChangeStatus(fkNextHC);
+// }
+
+ if ( fNextStatus == fkNextHC && fSMinfo[fiSMx].fTrackletEnable == kTRUE)
+ {
+ //AliDebug(5, "fkNextHC");
+ //
+ // 1) Find end_of_tracklet_marker if tracklets present!
+ //
+ // GTU Link Mask?
+
+ // endoftrackletmarker?
+ if ( *fDataWord == kEndOfTrackletMarker )
+ {
+ AliDebug(3, "End-of-tracklet-marker found");
+ AliDebug(5, Form("Data 0x%x", *fDataWord));
+ ChangeStatus(fkSeekNonEoTracklet);
+ return kTRUE;
+ }
+ else
+ {
+ // Tracklets found
+ //AliDebug(3, "Tracklet found");
+ AliDebug(5, Form("Tracklet data 0x%x", *fDataWord));
+ DecodeTracklet();
+ return kTRUE;
+ }
+ } // if next HC
+ else
+ {
+ if (fSMinfo[fiSMx].fTrackletEnable == kFALSE)
+ ChangeStatus(fkDecodeHC);
+ }
+
+ if (fNextStatus == fkSeekNonEoTracklet)
+ {
+ AliDebug(5, "fkSeekNonEoTracklet");
+
+ //
+ // 2) Look for non-end_of_tracklet_marker
+ //
+ //printf("Word %d: 0x%08x\n", fWordCtr, *fDataWord);
+
+ if ( *fDataWord != kEndOfTrackletMarker )
+ {
+ ChangeStatus(fkDecodeHC);
+ AliDebug(3, "NON end-of-tracklet-marker found");
+ AliDebug(5, Form("Data 0x%x", *fDataWord));
+ //// no do not continue - this should be the hcheader
+ }
+ else
+ {
+ //just go on and find the non-end_of_tracklet_marker
+ return kTRUE;
+ }
+ }
+
+ if ( fNextStatus == fkDecodeHC )
+ {
+ AliDebug(5, "fkDecodeHC");
+
+ //
+ // 3) This Word must be Half Chamber Header
+ //
+ if ( (*fDataWord & 0xf0000000) == 0x80000000 && (*fDataWord & 0x00000003) == 1 )
+ { // HC header
+ AliDebug(5, Form("Is this the HC header? 0x%x", *fDataWord));
+ DecodeHCheader(fTimeBinsCalib); // This is the new header!
+ fLastDET = fDET;
+ fDET = fGeo->GetDetector(fLAYER, fSTACK, fSM);
+ fRowMax = fGeo->GetRowMax(fLAYER,fSTACK,fSM);
+ fColMax = fGeo->GetColMax(fROC);
+
+ fMCMHctr2 = 0;
+ fHCdataCtr = 0;
+ fChamberDone[fDET]++;
+ AliDebug(2, Form("-------------- DET %d fChamberDone[fDET]=%d", fDET, fChamberDone[fDET]));
+
+ ChangeStatus(fkNextMCM);
+ return kTRUE;
+ } //HC header
+ else
+ {
+ AliWarning(Form("Expecting HC header mask but got 0x%x. Fall back: Next HC.", *fDataWord));
+ ChangeStatus(fkNextHC);
+ // before we went to //ChangeStatus(fkNextSM);
+ }
+ } // if decode HC
+
+ return kFALSE;
+}
+//____________________________________________________________________________
+Bool_t AliTRDRawStreamTB::DecodeGTUlinkMask()
+{
+ //
+ // Decode the link masks sent by the GTU. These marke the active optical links
+ // between GTU and Super Module. Up to now only fully active links are found
+ // (0xfff = 12 active links).
+ //
+
+ if ( (*fDataWord & 0xfffff000) == 0xe0000000 )
+ {
+ if ( fRawVersion < 1 || fRawVersion > 3 )
+ {
+ AliError(Form(" Unsupported raw version: %d", fRawVersion));
+ }
+
+ if ( fGTUctr1 == -1 ) fGTUctr2++;
+ fGTUctr1++;
+
+ if ( (fGTUctr1 >= 0) && (fGTUctr1 < 5) && (fGTUctr2 >= 0) && (fGTUctr2 < 18) )
+ {
+ fGTUlinkMask[fGTUctr2][fGTUctr1] = (*fDataWord & 0xfff);
+ }
+
+ //AliDebug(5, Form("GTU link mask 0x%x decoded 0x%x", *fDataWord, fGTUlinkMask[fGTUctr2][fGTUctr1]));
+ return kTRUE;
+ }
+
+ return kFALSE;
+}
+
+// //____________________________________________________________________________
+void AliTRDRawStreamTB::ChangeStatus(Int_t kstat)
+{
+ fLastStatus = fNextStatus;
+ fNextStatus = kstat;
+}
+
+//____________________________________________________________________________
+Bool_t AliTRDRawStreamTB::DecodeSM()
+{
+ fLastDET = -1;
+ fDET = -1;
+ fRetVal = 0;
+ fEqID = 0;
+ fDataSize = 0;
+ fSizeOK = kFALSE;
+
+ Int_t status = DecodeHeadingInfo();
+ if (status == fkWordOK)
+ {
+ ChangeStatus(fkNextHC);
+ return kTRUE;
+ }
+ else
+ {
+ AliWarning(Form("Decoding SM info failed. Fall back: None. Stop.", fEqID));
+ fRawReader->AddMajorErrorLog(kGTULinkMaskMissing,Form("Equipment %d",fEqID));
+ ChangeStatus(fkStop);
+ }
+
+ return kFALSE;
+}
+
+//____________________________________________________________________________
+Bool_t AliTRDRawStreamTB::Next()
+{
+ //
+ // Updates the next data word pointer
+ //
+
+ if (fNextStatus == fkStart)
+ {
+ Init();
+ }
+
+ while (fNextStatus != fkStop && fNextStatus != fkNoMoreData)
+ { // !fkStop
+ NextData();
+
+ switch (fNextStatus)
+ {
+ case fkNextData:
+ {
+ if (DecodeNextRawWord() == kTRUE)
+ {
+ fTB += 3;
+ if (fTB - 3 > 29)
+ {
+ AliWarning(Form("Invalid time bin %d. sm %d det %d rob %d col %d row %d mcm=%d adc=%d ", fTB-3, fSM, fDET, fROB, fCOL, fROW, fMCM, fADC));
+ AliWarning(Form("max=%d index=%d adc=%d", fADClookup[0], fADClookup[1], fADClookup[fADClookup[1]-1]));
+ }
+ if (fSig[0] > fRawDigitThreshold || fSig[1] > fRawDigitThreshold || fSig[2] > fRawDigitThreshold)
+ return kTRUE;
+ }
+ }; break;
+ case fkNextMCM:
+ {
+ if (DecodeMCM() == kFALSE)
+ AliWarning(Form("Decode MCM unsuccessfull. Current Word 0x%x at pos 0x%x", *fDataWord, fPos));
+ }; break;
+ case fkNextHC:
+ case fkSeekNonEoTracklet:
+ case fkDecodeHC:
+ {
+ if (DecodeHC() == kFALSE)
+ {
+ if (*fDataWord == kEndOfRawDataMarker)
+ {
+ AliDebug(2, Form("End of data at 0x%x", fPos));
+ }
+ else
+ {
+ AliWarning(Form("Decode HC unsuccessfull. Current Word 0x%x at pos 0x%x", *fDataWord, fPos));
+ }
+ }
+ }; break;
+ case fkNextSM:
+ {
+ if (DecodeSM() == kFALSE)
+ AliWarning(Form("Decode SM unsuccessfull. Current Word 0x%x at pos 0x%x", *fDataWord, fPos));
+ }; break;
+ case fkNoMoreData:
+ case fkStop:
+ ; break;
+ default:
+ AliWarning(Form("Unknown state %d. Last state %d. Current Word 0x%x at pos 0x%x", fNextStatus, fLastStatus, *fDataWord, fPos));
+ ChangeStatus(fkStop);
+ };
+
+ } // not fkStop
+
+ //AliDebug(1, Form("That's all folks! %d", fSM));
+ return kFALSE;
+}
+
+//____________________________________________________________________________
+Int_t AliTRDRawStreamTB::NextChamber(AliTRDdigitsManager *man)
+{
+ //
+ // Fills single chamber digit array
+ // Return value is the detector number
+ //
+
+ AliTRDdataArrayI *digits = 0;
+ AliTRDdataArrayI *track0 = 0;
+ AliTRDdataArrayI *track1 = 0;
+ AliTRDdataArrayI *track2 = 0;
+ AliTRDSignalIndex *indexes = 0;
+
+ if (fNextStatus == fkStart)
+ {
+ Init();
+ }
+
+// while (fNextStatus != fkStop)
+// { // !fkStop
+// NextData();
+// // catch 3 things
+// // 1) if end of raw data - if chamber complete return
+// // 2) fill the data with signals if data decoded ok
+// // 3) initialize (destroy old) after the det has changed -> just after HC header decoding
+// } // not fkStop
+
+ while (fNextStatus != fkStop)
+ { // !fkStop
+ NextData();
+
+ if (fNextStatus == fkStop)
+ {
+ if (fLastStatus == fkStart)
+ {
+ AliWarning("Stop just on the first word!");
+ continue;
+ }
+// else
+// {
+// if (fEndOfDataFlag == kTRUE)
+// {
+// if (fChamberDone[fDET] == 2)
+// {
+// return fDET;
+// }
+// }
+// }
+ }
+
+ if ( *fDataWord == kEndOfRawDataMarker )
+ { // End of half-chamber data, finished
+ AliDebug(3, "We have reached the eof data. Next should be HC header or we are done.");
+ fGTUctr1 = -1;
+
+ if (fNextStatus != fkStop)
+ ChangeStatus(fkNextHC);
+ fEndOfDataFlag = kTRUE;
+
+ if (fChamberDone[fDET] == 2)
+ {
+ fChamberDone[fDET] = -1;
+ AliDebug(5, Form("Return %d", fDET));
+ return fDET;
+ }
+ continue;
+ }
+
+ switch (fNextStatus)
+ {
+ case fkNextData:
+ {
+ if (DecodeNextRawWord() == kTRUE)
+ {
+ for (Int_t it = 0; it < 3; it++)
+ {
+ if ( fTB + it < fTBins )
+ {
+ if ( fSig[it] > fRawDigitThreshold )
+ {
+ digits->SetDataUnchecked(fROW, fCOL, fTB + it, fSig[it]);
+ indexes->AddIndexTBin(fROW, fCOL, fTB + it);
+ if (man->UsesDictionaries())
+ {
+ track0->SetDataUnchecked(fROW, fCOL, fTB + it, 0);
+ track1->SetDataUnchecked(fROW, fCOL, fTB + it, 0);
+ track2->SetDataUnchecked(fROW, fCOL, fTB + it, 0);
+ } // if dictionaries
+ } // signal above zero
+ } // check the tbins range
+ } // for each tbin of current 3
+ fTB += 3;
+ }
+ else
+ {
+ // can be here as a fall back from decode raw data calling decodemcm
+ if (fEndOfDataFlag == kTRUE)
+ {
+ if (fChamberDone[fDET] == 2)
+ {
+ fChamberDone[fDET] = -1;
+ AliDebug(5, Form("Return %d", fDET));
+ return fDET;
+ }
+ fEndOfDataFlag = kFALSE;
+ }
+ }
+ }; break;
+
+ case fkNextMCM:
+ {
+ if (DecodeMCM() == kFALSE)
+ {
+ AliWarning(Form("Decode MCM unsuccessfull. Current Word 0x%x at pos 0x%x", *fDataWord, fPos));
+ }
+ // default place for end of raw data...
+ if (fEndOfDataFlag == kTRUE)
+ {
+ if (fChamberDone[fDET] == 2)
+ {
+ fChamberDone[fDET] = -1;
+ return fDET;
+ }
+ fEndOfDataFlag = kFALSE;
+ }
+ }; break;
+
+ case fkNextHC:
+ case fkSeekNonEoTracklet:
+ case fkDecodeHC:
+ {
+ if (DecodeHC() == kFALSE)
+ {
+ AliWarning(Form("Decode HC unsuccessfull. Current Word 0x%x at pos 0x%x", *fDataWord, fPos));
+ }
+ else
+ {
+ AliWarning(Form("Decode HC successfull. Current Word 0x%x at pos 0x%x", *fDataWord, fPos));
+ //the hc header should be decoded by now
+ //if (fLastStatus == fkDecodeHC && fNextStatus != fkNextHC)
+ AliDebug(3, Form("Status last %d %d det %d lastdet %d", fLastStatus,fkDecodeHC, fDET, fLastDET));
+ if (fLastStatus == fkDecodeHC && fDET != fLastDET)
+ {
+ AliDebug(4, Form("???? New DET ???? %d last %d", fDET, fLastDET));
+ fLastDET = fDET;
+ // allocate stuff for the new det
+ //man->ResetArrays();
+ digits = man->GetDigits(fDET);
+ track0 = man->GetDictionary(fDET,0);
+ track1 = man->GetDictionary(fDET,1);
+ track2 = man->GetDictionary(fDET,2);
+
+ // Allocate memory space for the digits buffer
+ if (digits->GetNtime() == 0)
+ {
+ AliDebug(5, Form("Alloc digits for det %d rows %d cols %d tbins %d", fDET, fRowMax, fColMax, fTBins));
+ digits->Allocate(fRowMax, fColMax, fTBins);
+ if (man->UsesDictionaries())
+ {
+ track0->Allocate(fRowMax, fColMax, fTBins);
+ track1->Allocate(fRowMax, fColMax, fTBins);
+ track2->Allocate(fRowMax, fColMax, fTBins);
+ }
+ }
+
+ indexes = man->GetIndexes(fDET);
+ indexes->SetSM(fSM);
+ indexes->SetStack(fSTACK);
+ indexes->SetLayer(fLAYER);
+ indexes->SetDetNumber(fDET);
+
+ if (indexes->IsAllocated() == kFALSE)
+ {
+ AliDebug(4, "Allocating indexes");
+ indexes->Allocate(fRowMax, fColMax, fTBins);
+ }
+ } // is the HC header already decoded?
+ } // decode hc ok
+ }; break;
+
+ case fkNextSM:
+ {
+ if (DecodeSM() == kFALSE)
+ AliWarning(Form("Decode SM unsuccessfull. Current Word 0x%x at pos 0x%x", *fDataWord, fPos));
+ }; break;
+
+ case fkStop:
+ ; break;
+
+ default:
+ AliWarning(Form("Unknown state %d. Last state %d. Current Word 0x%x at pos 0x%x", fNextStatus, fLastStatus, *fDataWord, fPos));
+ ChangeStatus(fkStop);
+ };
+
+ } // not fkStop
+
+ // we do not return chambers for which the end-of-data was not received twice (for each HC)
+
+ //AliDebug(1, Form("That's all folks! %d", fSM));
+ //return kFALSE;
+ return -1;
+}
+
+// new stuff
+//____________________________________________________________________________
+Int_t AliTRDRawStreamTB::SkipWords(UInt_t iw)
+{
+ Int_t status = fkWordOK;
+ for (UInt_t i = 0; i < iw; i++)
+ {
+ status = NextData();
+ AliDebug(5, Form("Skipping word %d of %d [0x%x]", i+1, iw, *fDataWord));
+ if (status != fkWordOK)
+ return status;
+ }
+
+ //status = NextData();
+ return status;
+}
+
+//____________________________________________________________________________
+Int_t AliTRDRawStreamTB::DecodeHeadingInfo()
+{
+ // SM info...
+ fSMinfo[fiSMx].Decode(fDataWord);
+ if (fgExtraDebug)
+ fSMinfo[fiSMx].Dump();
+
+ Int_t status = SkipWords(fSMinfo[fiSMx].fHeaderSize);
+ if (status != fkWordOK)
+ return status;
+ else
+ status = NextData();
+
+ //fSMinfo[fiSMx].fStackActive[0] = kTRUE;
+ // now stack info..
+ if (status == fkWordOK)
+ {
+ for (Int_t i = 0; i < 5; i++)
+ {
+ if (fSMinfo[fiSMx].fStackActive[i] == kFALSE)
+ continue;
+ AliDebug(5, Form("Decode stack info %d 0x%x", i, *fDataWord));
+ if (fgStackIndexBug == kFALSE)
+ fStackInfo[fiSMx][i].Decode(fDataWord);
+ else
+ fStackInfo[fiSMx][i].DecodeBug(fDataWord);
+
+ if (fgExtraDebug)
+ fStackInfo[fiSMx][i].Dump();
+
+ status = SkipWords(fStackInfo[fiSMx][i].fHeaderSize);
+ if (status != fkWordOK)
+ return status;
+ else
+ if (i < 4)
+ status = NextData();
+
+ if (status != fkWordOK)
+ return status;
+ }
+ }
+
+ RewindWord();
+ return status;
+}
--- /dev/null
+#ifndef ALITRDRAWSTREAMTB_H
+#define ALITRDRAWSTREAMTB_H
+/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ * See cxx source for full Copyright notice */
+
+/* $Id$ */
+
+///////////////////////////////////////////////////////////////////////////////
+// //
+// This class provides access to TRD digits in raw data. //
+// //
+///////////////////////////////////////////////////////////////////////////////
+
+#include <TObject.h>
+
+class AliTRDgeometry;
+class AliRawReader;
+class AliTRDdigitsManager;
+
+namespace AliTRDrawDataUtilsTB
+{
+ //--------------------------------------------------------
+ // Some constants:
+ //static const UInt_t kEndoftrackletmarker = 0xAAAAAAAA; /*This marks the end of tracklet data words*/
+ //static const UInt_t kEndOfTrackletMarker = 0x10001000; /*This marks the end of tracklet data words*/
+ static const UInt_t kEndOfTrackletMarker = 0xaaaaaaaa; /*This marks the end of tracklet data words*/
+ //static const UInt_t kEndofrawdatamarker = 0x00000000; /*This marks the end of half-chamber-data*/
+ static const UInt_t kEndOfRawDataMarker = 0x00000000; /*This marks the end of half-chamber-data*/
+ static const UInt_t kSizeWord = sizeof(UInt_t); // size of a word in bytes
+
+ //--------------------------------------------------------
+ // SM index word masks
+ static const UInt_t skSMheaderSizeBits = 0xffff0000;
+ static const UInt_t skTrackletsEnableBits = 0x1 << 5;
+ static const UInt_t skStackMasksBits = 0x1f;
+
+ static UInt_t GetSMheaderSize(UInt_t *word)
+ {
+ return (*word & skSMheaderSizeBits) >> 16;
+ }
+
+ static UInt_t GetTrackletEnable(UInt_t *word)
+ {
+ return (*word & skTrackletsEnableBits) >> 5;
+ }
+
+ static UInt_t GetStackMask(UInt_t *word)
+ {
+ return (*word & skStackMasksBits);
+ }
+
+/* static UInt_t GetStackStatus(UInt_t *word, Int_t istack) */
+/* { */
+/* return (*word & (0x1 << istack)); */
+/* } */
+
+ //--------------------------------------------------------
+ struct AliTRDrawSMinfo
+ {
+ UInt_t fHeaderSize;
+ Bool_t fTrackletEnable;
+ Bool_t fStackActive[5];
+ Int_t fActiveStacks;
+
+ void Decode(UInt_t *word)
+ {
+ fHeaderSize = GetSMheaderSize(word);
+
+ if (GetTrackletEnable(word) > 0)
+ fTrackletEnable = kTRUE;
+ else
+ fTrackletEnable = kFALSE;
+
+ UInt_t stackMask = GetStackMask(word);
+ fActiveStacks = 0;
+ for (Int_t i = 0; i < 5; i++)
+ {
+ //if (stackMask & (0x1 << i) > 0)
+ if ((stackMask >> i) & 0x1 > 0)
+ {
+ fStackActive[i] = kTRUE;
+ fActiveStacks++;
+ }
+ else
+ {
+ fStackActive[i] = kFALSE;
+ }
+ }
+ }
+
+ void Dump()
+ {
+ printf("[I] SM Info is : Hsize %d TrackletEnable %d Stacks %d %d %d %d %d\n",
+ fHeaderSize, fTrackletEnable,
+ fStackActive[0], fStackActive[1], fStackActive[2],
+ fStackActive[3], fStackActive[4]);
+
+ }
+ };
+
+ //--------------------------------------------------------
+ // Stack word masks
+ static const UInt_t skStackHeaderSizeBits = 0xffff0000;
+ static const UInt_t skStackLinkMaskBits = 0xfff;
+
+ static UInt_t GetStackHeaderSize(UInt_t *word)
+ {
+ return (*word & skStackHeaderSizeBits) >> 16;
+ }
+
+ static UInt_t GetStackLinkWord(UInt_t *word)
+ {
+ return (*word & skStackLinkMaskBits);
+ }
+
+ static UInt_t GetStackHeaderSizeBug(UInt_t *word)
+ {
+ return (*word & 0x0000ffff);
+ }
+
+ static UInt_t GetStackLinkWordBug(UInt_t *word)
+ {
+ return (*word & 0x0fff) >> 16;
+ }
+
+ struct AliTRDrawStackInfo
+ {
+ UInt_t fHeaderSize;
+ Bool_t fLinksActive[12];
+ Int_t fActiveLinks;
+
+ void Decode(UInt_t *word)
+ {
+ fHeaderSize = GetStackHeaderSize(word);
+
+ UInt_t linkMask = GetStackLinkWord(word);
+ fActiveLinks = 0;
+ for (Int_t i = 0; i < 12; i++)
+ {
+ if (linkMask & (0x1 << i) > 0)
+ {
+ fLinksActive[i] = kTRUE;
+ fActiveLinks++;
+ }
+ else
+ {
+ fLinksActive[i] = kFALSE;
+ }
+ }
+ }
+
+ void DecodeBug(UInt_t *word)
+ {
+ fHeaderSize = GetStackHeaderSizeBug(word);
+
+ UInt_t linkMask = GetStackLinkWordBug(word);
+ for (Int_t i = 0; i < 12; i++)
+ {
+ if (linkMask & (0x1 << i) > 0)
+ fLinksActive[i] = kTRUE;
+ else
+ fLinksActive[i] = kFALSE;
+ }
+ }
+
+ void Dump()
+ {
+ printf("[I] Stack Info is : Hsize %d Links Active %d %d %d %d %d %d %d %d %d %d %d %d\n",
+ fHeaderSize,
+ fLinksActive[0], fLinksActive[1], fLinksActive[2], fLinksActive[3],
+ fLinksActive[4], fLinksActive[5], fLinksActive[6], fLinksActive[7],
+ fLinksActive[8], fLinksActive[9], fLinksActive[10], fLinksActive[11]);
+ }
+ };
+
+ //--------------------------------------------------------
+ // HC word masks
+ // word 0
+ static const UInt_t skSpecialRawVBits = 0x1 << 31;
+ static const UInt_t skRawVMajorBits = 0x7f << 24;
+ static const UInt_t skRawVMinorBits = 0x7f << 17;
+ static const UInt_t skHCExtraWordsBits = 0x7 << 14;
+ static const UInt_t skHCSMBits = 0x1f << 9;
+ static const UInt_t skHCLayerBits = 0x7 << 6;
+ static const UInt_t skHCStackBits = 0x7 << 3;
+ static const UInt_t skHCSideBits = 0x1 << 2;
+
+ static const UInt_t skDCSBoardBits = 0xfff << 20;
+
+ static UInt_t GetSpecialRawV(UInt_t *word)
+ {
+ return (*word & skSpecialRawVBits) >> 31;
+ }
+
+ static UInt_t GetRawVMajor(UInt_t *word)
+ {
+ return (*word & skRawVMajorBits) >> 24;
+ }
+
+ static UInt_t GetRawVMinor(UInt_t *word)
+ {
+ return (*word & skRawVMinorBits) >> 31;
+ }
+
+ static UInt_t GetDCSBoard(UInt_t *word)
+ {
+ return (*word & skDCSBoardBits) >> 20;
+ }
+
+ static UInt_t GetSM(UInt_t *word)
+ {
+ return (*word & skHCSMBits) >> 9;
+ }
+
+ static UInt_t GetStack(UInt_t *word)
+ {
+ return (*word & skHCStackBits) >> 3;
+ }
+
+ static UInt_t GetLayer(UInt_t *word)
+ {
+ return (*word & skHCLayerBits) >> 6;
+ }
+
+ static UInt_t GetSide(UInt_t *word)
+ {
+ return (*word & skHCSideBits) >> 2;
+ }
+
+ static UInt_t GetExtraWords(UInt_t *word)
+ {
+ return (*word & skHCExtraWordsBits) >> 14;
+ //fHCHWords = (*fDataWord >> 14) & 0x7;
+ }
+
+ // word 1
+ //static const UInt_t skTimeBinsBits = 0xfc << 26;
+ static const UInt_t skTimeBinsBits = 0x3f << 26;
+ static const UInt_t skBunchCrossCounterBits = 0xffff << 10;
+ static const UInt_t skPreTriggerCounterBits = 0xf << 6;
+ static const UInt_t skPreTriggerPhase = 0xf << 2;
+
+ static UInt_t GetTimeBins(UInt_t *word)
+ {
+ return (*word & skTimeBinsBits) >> 26;
+ }
+
+ static UInt_t GetBunchCrossCounter(UInt_t *word)
+ {
+ return (*word & skBunchCrossCounterBits) >> 10;
+ }
+
+ static UInt_t GetPreTriggerCounter(UInt_t *word)
+ {
+ return (*word & skPreTriggerCounterBits) >> 6;
+ }
+
+ static UInt_t GetPreTriggerPhase(UInt_t *word)
+ {
+ return (*word & skPreTriggerPhase) >> 2;
+ }
+
+ struct AliTRDrawHCInfo
+ {
+ UInt_t fSpecialRawV;
+ UInt_t fRawVMajor;
+ UInt_t fRawVMinor;
+ UInt_t fNExtraWords;
+ UInt_t fDCSboard;
+ UInt_t fSM;
+ UInt_t fStack;
+ UInt_t fLayer;
+ UInt_t fSide;
+
+/* fBCctr = (*fDataWord >> 16); */
+/* fPTctr = (*fDataWord >> 12) & 0xf; */
+/* fPTphase = (*fDataWord >> 8) & 0xf; */
+/* fTBins = ((*fDataWord >> 2) & 0x3f) + 1; */
+/* fTimeWords = (fTBins - 1)/3 + 1; */
+
+ UInt_t fTimeBins;
+ UInt_t fBunchCrossCounter;
+ UInt_t fPreTriggerCounter;
+ UInt_t fPreTriggerPhase;
+
+ void DecodeH0(UInt_t *word)
+ {
+ fSpecialRawV = GetSpecialRawV(word);
+ fRawVMajor = GetRawVMajor(word);
+ fRawVMinor = GetRawVMinor(word);
+ fNExtraWords = GetExtraWords(word);
+ fDCSboard = GetDCSBoard(word);
+ fSM = GetSM(word);
+ fStack = GetStack(word);
+ fLayer = GetLayer(word);
+ fSide = GetSide(word);
+ }
+
+ void DecodeH1(UInt_t *word)
+ {
+ fTimeBins = GetTimeBins(word);
+ fBunchCrossCounter = GetBunchCrossCounter(word);
+ fPreTriggerCounter = GetPreTriggerCounter(word);
+ fPreTriggerPhase = GetPreTriggerPhase(word);
+ }
+
+ void Dump()
+ {
+/* printf("[I] HC Info is : DCSboard %d SM %d Stack %d Layer %d Side %d \n", */
+/* fDCSboard, fSM, fStack, fLayer, fSide); */
+ printf("[I] HC Info is : RawV %d SM %d Stack %d Layer %d Side %d \n",
+ fRawVMajor, fSM, fStack, fLayer, fSide);
+ }
+ };
+
+ //--------------------------------------------------------
+ // MCM word masks
+ static const UInt_t skROBBits = 0x70000000; // 0x7 << 28
+ static const UInt_t skMCMBits = 0x0f000000; // 0xf << 24
+ static const UInt_t skHCEvCounterBits = 0x00fffff0; //0x00fffff << 4
+
+ static UInt_t GetROB(UInt_t *word)
+ {
+ return (*word & skROBBits) >> 28;
+ }
+
+ static UInt_t GetMCM(UInt_t *word)
+ {
+ return (*word & skMCMBits) >> 24;
+ }
+
+ static UInt_t GetEvCounter(UInt_t *word)
+ {
+ return (*word & skHCEvCounterBits) >> 4;
+ }
+
+ struct AliTRDrawMCMInfo
+ {
+ UInt_t fROB;
+ UInt_t fMCM;
+ UInt_t fEvCounter;
+
+ void Decode(UInt_t *word)
+ {
+ fROB = GetROB(word);
+ fMCM = GetMCM(word);
+ fEvCounter = GetEvCounter(word);
+ }
+
+ void Dump()
+ {
+ printf("[I] MCM Info is : ROB %d MCM %d EvCounter %d\n", fROB, fMCM, fEvCounter);
+ }
+ };
+
+}
+
+class AliTRDRawStreamTB: public TObject {
+
+ public :
+
+ AliTRDRawStreamTB();
+ AliTRDRawStreamTB(AliRawReader *rawReader);
+ virtual ~AliTRDRawStreamTB();
+
+ virtual Bool_t Next(); // Read the next data
+ virtual Int_t NextChamber(AliTRDdigitsManager *man); // read next chamber data
+ virtual Int_t Init(); // Init for the fRawVersion > 1
+
+ enum { kDDLOffset = 0x400 }; // Offset for DDL numbers
+
+ Bool_t SetRawVersion(Int_t rv);
+ Int_t GetRawVersion() const { return fRawVersion; };
+ void SetRawReader(AliRawReader *rawReader);
+
+ // Get Filter settings (does not make a lot of sense):
+ Int_t TRAPfilterTCon() const { return fTCon; };
+ Int_t TRAPfilterPEDon() const { return fPEDon; };
+ Int_t TRAPfilterGAINon() const { return fGAINon; };
+ Int_t TRAPsendsUnfilteredData() const { return fBypass; };
+
+ // Get Tracklet parameters (does not make a lot of sense):
+ Float_t GetTrackletPID() const { return fTracklPID; };
+ Float_t GetTrackletDeflLength() const { return fTracklDefL; };
+ Float_t GetTrackletPadPos() const { return fTracklPadPos; };
+ Int_t GetTrackletPadRow() const { return fTracklPadRow; };
+
+ // Check if the link has optical power (HC sends data)
+ Bool_t IsGTULinkActive(Int_t sm, Int_t la, Int_t sta, Int_t side)
+ { return ( ((fGTUlinkMask[sm][sta]) >> (2*la+side)) & 0x1 ); };
+
+ static void SetStackIndexBug(Bool_t val) {fgStackIndexBug = val;}
+ static void SetForceRawVersion(Int_t val) {fgForceRawVersion = val;}
+ static void SupressWarnings(Bool_t val) {fgSupressWarnings = val;}
+ static void ExtraDebug(Bool_t val) {fgExtraDebug = val;}
+ static void RawBufferMissAligned(Bool_t val) {fgRawDataHack = val;}
+
+ Int_t *GetSignals() { return fSig;} // Signals in the three time bins from Data Word
+ Int_t GetADC() const { return fADC;} // MCM ADC channel and Time Bin of word 1
+ Int_t GetTimeBin() const { return fTB - 3;} // MCM ADC channel and Time Bin of word 1
+ Int_t GetEventNumber() const { return fEv;} // MCM Event number and position of current MCM on TRD chamber
+ Int_t GetROB() const { return fROB;} // MCM Event number and position of current MCM on TRD chamber
+ Int_t GetMCM() const { return fMCM;} // MCM Event number and position of current MCM on TRD chamber
+ Int_t GetSM() const { return fSM;} // Position of CURRENT half chamber in full TRD
+ Int_t GetLayer() const { return fLAYER;} // PLANE = Position of CURRENT half chamber in full TRD
+ Int_t GetStack() const { return fSTACK;} // CHAMBER = Position of CURRENT half chamber in full TRD
+ Int_t GetROC() const { return fROC;} // Position of CURRENT half chamber in full TRD
+ Int_t GetSide() const { return fSIDE;} // Position of CURRENT half chamber in full TRD
+ Int_t GetDCS() const { return fDCS;} // DCS board number read from data (HC header)
+ Int_t GetRow() const { return fROW;}
+ Int_t GetCol() const { return fCOL;} // Detector Pad coordinates
+ Int_t GetDet() const { return fDET;} // helper
+ Int_t GetLastDet() const { return fLastDET;} // helper
+ Int_t GetMaxRow() const { return fRowMax;}
+ Int_t GetMaxCol() const { return fColMax;}
+ Int_t GetNumberOfTimeBins() const {return fTBins;}
+
+ Int_t GetCommonAdditive() const {return fCommonAdditive;}
+ Bool_t IsCurrentPadShared() const {return fIsPadShared;}
+ void SetSharedPadReadout(Bool_t fv) {fSharedPadsOn = fv;}
+ Bool_t IsDataZeroSuppressed() const {return fZeroSuppressed;}
+
+ private :
+
+ Int_t fSig[3]; // Signals in the three time bins from Data Word
+ Int_t fADC; // MCM ADC channel and Time Bin of word 1
+ Int_t fMaxADCgeom; // Max ADC number as returned by AliTRDgeometry::ADCmax()
+ Int_t fTB; // MCM ADC channel and Time Bin of word 1
+ Int_t fEv; // MCM Event number and position of current MCM on TRD chamber
+ Int_t fROB; // MCM Event number and position of current MCM on TRD chamber
+ Int_t fMCM; // MCM Event number and position of current MCM on TRD chamber
+ Int_t fSM; // Position of CURRENT half chamber in full TRD
+ Int_t fLAYER; // Position of CURRENT half chamber in full TRD
+ Int_t fSTACK; // Position of CURRENT half chamber in full TRD
+ Int_t fROC; // Position of CURRENT half chamber in full TRD
+ Int_t fSIDE; // Position of CURRENT half chamber in full TRD
+ Int_t fDCS; // DCS board number read from data (HC header)
+ Int_t fROW; // Detector Row coordinates
+ Int_t fCOL; // Detector Pad coordinates
+ Int_t fDET; // Current detector - version > 1
+ Int_t fLastDET; // Previous detector - version > 1
+
+ Int_t fBCctr; // Counters from HC header (>=V2)
+ Int_t fPTctr; // Counters from HC header (>=V2)
+ Int_t fPTphase; // Counters from HC header (>=V2)
+ Int_t fRVmajor; // Raw version numbers and number of additional HC headerwords (>=V2)
+ Int_t fRVminor; // Raw version numbers and number of additional HC headerwords (>=V2)
+ Int_t fHCHWords; // Raw version numbers and number of additional HC headerwords (>=V2)
+ Int_t fTBins; // Number of time bins read from HC header (>=V2)
+ Bool_t fTCon; // Filter settings read from HC header (>=V2)
+ Bool_t fPEDon; // Filter settings read from HC header (>=V2)
+ Bool_t fGAINon; // Filter settings read from HC header (>=V2)
+ Bool_t fXTon; // Filter settings read from HC header (>=V2)
+ Bool_t fNonLinOn; // Filter settings read from HC header (>=V2)
+ Bool_t fBypass; // Filter settings read from HC header (>=V2)
+ Int_t fCommonAdditive; // Common baseline additive read from HC header (>=V2)
+
+ Bool_t fZeroSuppressed; // Data is zero suppressed
+
+ Int_t fHCHctr1; // HC and MCM Header counter
+ Int_t fHCHctr2; // HC and MCM Header counter
+ Int_t fMCMHctr1; // HC and MCM Header counter
+ Int_t fMCMHctr2; // HC and MCM Header counter
+ Int_t fGTUctr1; // GTU LinkMask Counter
+ Int_t fGTUctr2; // GTU LinkMask Counter
+ Int_t fHCdataCtr; // Data Counter for half chamber
+
+ Float_t fTracklPID; // Tracklet parameters
+ Float_t fTracklDefL; // Tracklet parameters
+ Float_t fTracklPadPos; // Tracklet parameters
+ Int_t fTracklPadRow; // Tracklet parameters
+
+ UShort_t fGTUlinkMask[18][5]; // Mask with active links
+
+ Int_t fMCMWordCrt; // Word Counter for a single MCM
+ Int_t fMCMWordsExpected; // Expected Words from MCM
+
+ AliTRDRawStreamTB(const AliTRDRawStreamTB &stream);
+ AliTRDRawStreamTB &operator=(const AliTRDRawStreamTB &stream);
+ void SwapOnEndian();
+
+ AliRawReader *fRawReader; // Object for reading the raw data
+
+ Int_t fRawVersion; // Which version of raw data decoding is used
+ Int_t fRawDigitThreshold; // Naive "zero"(threshold) supression. Usefull for Raw Data ver 2.
+
+ Int_t fNextStatus; // Navigation in raw versions > 1
+ Int_t fLastStatus; // Navigation in raw versions > 1
+ UInt_t fTbSwitch; // Time Bin Switch for internal use
+ UInt_t fTbSwitchCtr; // Counter for internal use
+ UInt_t fTimeWords; // Number of Words needed to store the data of 1 ADC ch.
+ UInt_t fWordCtr; // Word Counter
+
+ Int_t fRowMax; // Maximum number of pad rows and columns
+ Int_t fColMax; // Maximum number of pad rows and columns
+
+ Bool_t fADCmask[21]; // Mask of active ADCs for zero suppression
+ UInt_t fLastADCmask; // Last ADC read out
+
+ Int_t fChamberDone[540]; // Chamber was processed already (1=1HC, 2=full chamber)
+
+ Int_t fRetVal; // Datadecode return
+ Int_t fEqID; // Equipment id
+ UInt_t fDataSize; // Size of the data available in the current buffer
+ Bool_t fSizeOK; // Did we read anything
+ UInt_t fCountBytes; // Bytes traversed in the buffer
+ UInt_t fBufSize; // Size of the current RawReader buffer
+ Bool_t fkBufferSet; // Is the RawReader buffer available
+ UChar_t *fPos; // Position in the buffer of the RawReader
+ UInt_t *fDataWord; // The pointer to the current 32 bit data word
+ UInt_t fTimeBinsCalib; // N of time bins retrieved from calibration
+
+ Int_t fADClookup[32]; // Lookup for version 3 (1[entries]+1[index]+30[fADC channels] = 32)
+ Int_t fNActiveADCs; // Number of active ADC channels
+ Bool_t fEndOfDataFlag; // End of data flag
+
+ AliTRDrawDataUtilsTB::AliTRDrawSMinfo fSMinfo[18];
+ AliTRDrawDataUtilsTB::AliTRDrawStackInfo fStackInfo[18][5];
+ AliTRDrawDataUtilsTB::AliTRDrawHCInfo fHCInfo;
+ AliTRDrawDataUtilsTB::AliTRDrawMCMInfo fMCMInfo;
+
+ Int_t fiSMx; // Position of CURRENT half chamber in full TRD
+ static Bool_t fgStackIndexBug; // Buggy index word flag
+
+ Bool_t fSharedPadsOn; // Should we return on shared pad readout
+ Bool_t fIsPadShared; // Set if the current pad is shared
+ static Int_t fgForceRawVersion; // Force the raw version specified
+ static Bool_t fgSupressWarnings; // Superss warnings (raw data version and TB missmatch)
+ static Bool_t fgExtraDebug; // Extra info on the screen
+ static Bool_t fgRawDataHack; // skip 23 words - a hack for the DATE raw format
+ enum ETRDzRawStreamError {
+ kHCWordMissing = 1 //
+ ,kMCMADCMaskMissing = 2 //
+ ,kWrongMCMorROB = 3 //
+ ,kGTULinkMaskMissing = 4 //
+ ,kHCHeaderCorrupt = 5 //
+ ,kHCHeaderMissing = 6 //
+ ,kROBSideMismatch = 7 //
+ ,kWrongPadrow = 8 //
+ ,kWrongPadcolumn = 9 //
+ ,kTrackletRowMismatch = 10 //
+ ,kDataMaskError = 11 //
+ ,kADCNumberOverflow = 12 //
+ ,kADCChannelOverflow = 13 //
+ };
+
+ protected:
+
+ AliTRDgeometry *fGeo; // TRD geometry
+
+ Bool_t DecodeGTUlinkMask();
+ Bool_t DecodeADCWord();
+ Bool_t DecodeNextRawWord();
+ Bool_t DecodeMCM();
+ Bool_t DecodeHC();
+ Bool_t DecodeSM();
+ inline void ChangeStatus(Int_t kstat);
+
+ void DecodeHCheader(Int_t timeBins = 0);
+ void DecodeMCMheader();
+ void DecodeTracklet();
+
+ void SetRawDigitThreshold (Int_t ith) {fRawDigitThreshold = ith;} // set the naive zero suppression threshold
+
+ Int_t NextData(); // get the next piece of memory
+ Int_t RewindWord(); //go back one word
+
+ Int_t ChannelsToRead(Int_t ADCmask); // Get the active ADC channels from the mask (V3 and 2)
+
+ Int_t SkipWords(UInt_t iw);
+ Int_t DecodeHeadingInfo();
+
+ enum { fkStart, fkStop, fkWordOK, fkNoMoreData, fkNextSM, fkNextHC, fkSeekNonEoTracklet, fkDecodeHC, fkNextMCM, fkNextData, fkReading};
+
+ ClassDef(AliTRDRawStreamTB, 1) // Class for reading TRD raw digits
+
+};
+#endif