**************************************************************************/
-///////////////////////////////////////////////////////////////////////////////
-///
-/// Class Payload
///
+/// \class AliMUONPayloadTracker
/// Decodes rawdata from buffer and stores in TClonesArray.
-///
/// First version implement for Tracker
///
-///////////////////////////////////////////////////////////////////////////////
+/// \author Christian Finck
#include "AliMUONPayloadTracker.h"
#include "AliRawReader.h"
#include "AliRawDataHeader.h"
+
+#ifndef DATE_SYS
#include "AliLog.h"
+#endif
#include "AliMUONDspHeader.h"
#include "AliMUONBlockHeader.h"
#include "AliMUONBusStruct.h"
#include "AliMUONDDLTracker.h"
+/// \cond CLASSIMP
ClassImp(AliMUONPayloadTracker)
+/// \endcond
AliMUONPayloadTracker::AliMUONPayloadTracker()
: TObject(),
+ fBusPatchId(0),
+ fDspId(0),
+ fBlkId(0),
+ fMaxDDL(20),
fMaxBlock(2),
fMaxDsp(5),
- fMaxBus(5)
+ fMaxBus(5),
+ fDDLTracker(new AliMUONDDLTracker()),
+ fBusStruct(new AliMUONBusStruct()),
+ fBlockHeader(new AliMUONBlockHeader()),
+ fDspHeader(new AliMUONDspHeader())
{
//
- // create an object to read MUON raw digits
- // Default ctor for monitoring purposes
- //
- fBusPatchManager = new AliMpBusPatch();
- fBusPatchManager->ReadBusPatchFile();
-
- fDDLTracker = new AliMUONDDLTracker();
- fBusStruct = new AliMUONBusStruct();
- fBlockHeader = new AliMUONBlockHeader();
- fDspHeader = new AliMUONDspHeader();
-}
-
-//_________________________________________________________________
-AliMUONPayloadTracker::AliMUONPayloadTracker(const AliMUONPayloadTracker& stream) :
- TObject(stream)
-{
- //
- // copy ctor
+ // create an object to decode MUON payload
//
- AliFatal("copy constructor not implemented");
-}
-//______________________________________________________________________
-AliMUONPayloadTracker& AliMUONPayloadTracker::operator = (const AliMUONPayloadTracker&
- /* stream */)
-{
- //
- // assignment operator
- //
- AliFatal("assignment operator not implemented");
- return *this;
}
-
//___________________________________
AliMUONPayloadTracker::~AliMUONPayloadTracker()
{
//
// clean up
//
- delete fBusPatchManager;
delete fDDLTracker;
delete fBusStruct;
delete fBlockHeader;
}
//______________________________________________________
-Bool_t AliMUONPayloadTracker::Decode(UInt_t* buffer, Int_t ddl)
+Bool_t AliMUONPayloadTracker::Decode(UInt_t* buffer, Int_t totalDDLSize)
{
- // reading tracker DDL
- // store buspatch info into Array
- // store only non-empty structures (buspatch info with datalength !=0)
+
+ // Each DDL is made with 2 Blocks each of which consists of 5 DSP's at most
+ // and each of DSP has at most 5 buspatches.
+ // The different structures, Block (CRT), DSP (FRT) and Buspatch,
+ // are identified by a key word 0xFC0000FC, 0xF000000F and 0xB000000B respectively.
+ // (fBusPatchManager no more needed !)
//Read Header Size of DDL,Block,DSP and BusPatch
static Int_t kDspHeaderSize = fDspHeader->GetHeaderLength();
static Int_t kBusPatchHeaderSize = fBusStruct->GetHeaderLength();
- // Int_t totalDDLSize;
+ // size structures
Int_t totalBlockSize;
Int_t totalDspSize;
Int_t totalBusPatchSize;
Int_t dataSize;
+ Int_t bufSize;
+ // indexes
+ Int_t indexBlk;
+ Int_t indexDsp;
+ Int_t indexBusPatch;
+ Int_t index = 0;
+ Int_t iBlock = 0;
- Int_t iBusPerDSP[5]; // number of bus patches per DSP
- Int_t iDspMax; // number max of DSP per block
-
- // minimum data size (only header's)
- // Int_t blankDDLSize;
- Int_t blankBlockSize;
- Int_t blankDspSize;
-
- AliDebug(3, Form("DDL Number %d\n", ddl ));
-
- // getting DSP info
- fBusPatchManager->GetDspInfo(ddl/2, iDspMax, iBusPerDSP);
-
- // Each DDL is made with 2 Blocks each of which consists of 5 DSP's at most
- // and each of DSP has at most 5 buspatches.
- // This information is used to calculate the size of headers (Block and DSP)
- // which has empty data.
-
- // blankDDLSize = 2*kBlockHeaderSize + 2*iDspMax*kDspHeaderSize;
- blankBlockSize = kBlockHeaderSize + iDspMax*kDspHeaderSize;
- // totalDDLSize = sizeof(buffer)/4;
-
- for (Int_t i = 0; i < iDspMax; i++) {
- // blankDDLSize += 2*iBusPerDSP[i]*kBusPatchHeaderSize;
- blankBlockSize += iBusPerDSP[i]*kBusPatchHeaderSize;
- }
-
- // Compare the DDL header with an empty DDL header size to read the file
- // if(totalDDLSize > blankDDLSize) { //should not happen in real life
-
- // indexes
- Int_t indexDsp;
- Int_t indexBusPatch;
- Int_t index = 0;
+ // CROCUS CRT
+ while (buffer[index] == fBlockHeader->GetDefaultDataKey()) {
- for(Int_t iBlock = 0; iBlock < 2 ;iBlock++){ // loop over 2 blocks
+ if (iBlock > fMaxBlock) break;
+
+ // copy within padding words
+ memcpy(fBlockHeader->GetHeader(),&buffer[index], (kBlockHeaderSize)*4);
- // copy within padding words
- memcpy(fBlockHeader->GetHeader(),&buffer[index], (kBlockHeaderSize+1)*4);
+ totalBlockSize = fBlockHeader->GetTotalLength();
- totalBlockSize = fBlockHeader->GetTotalLength();
+ indexBlk = index;
+ index += kBlockHeaderSize;
- fDDLTracker->AddBlkHeader(*fBlockHeader);
+ // copy in TClonesArray
+ fDDLTracker->AddBlkHeader(*fBlockHeader);
- if (fBlockHeader->GetPadding() == 0xDEAD) // skipping padding word
- index++;
+ // Crocus FRT
+ Int_t iDsp = 0;
+ while (buffer[index] == fDspHeader->GetDefaultDataKey()) {
- if(totalBlockSize > blankBlockSize) { // compare block header
- index += kBlockHeaderSize;
+ if (iDsp > fMaxDsp) break; // if ever...
+
+ memcpy(fDspHeader->GetHeader(),&buffer[index], kDspHeaderSize*4);
- for(Int_t iDsp = 0; iDsp < iDspMax ;iDsp++){ //DSP loop
+ totalDspSize = fDspHeader->GetTotalLength();
+ indexDsp = index;
+ index += kDspHeaderSize;
- if (iDsp > fMaxDsp) break;
-
- memcpy(fDspHeader->GetHeader(),&buffer[index], kDspHeaderSize*4);
+// if (fDspHeader->GetPaddingWord() != fDspHeader->GetDefaultPaddingWord()) {
+// // copy the field of Padding word into ErrorWord field
+// fDspHeader->SetErrorWord(fDspHeader->GetPaddingWord());
+// index--;
+// }
- totalDspSize = fDspHeader->GetTotalLength();
- indexDsp = index;
+ // copy in TClonesArray
+ fDDLTracker->AddDspHeader(*fDspHeader, iBlock);
- blankDspSize = kDspHeaderSize + iBusPerDSP[iDsp]*kBusPatchHeaderSize; // no data just header
+ // buspatch structure
+ Int_t iBusPatch = 0;
+ while (buffer[index] == fBusStruct->GetDefaultDataKey()) {
- fDDLTracker->AddDspHeader(*fDspHeader, iBlock);
+ if (iBusPatch > fMaxBus) break; // if ever
+
+ //copy buffer into header structure
+ memcpy(fBusStruct->GetHeader(), &buffer[index], kBusPatchHeaderSize*4);
- if(totalDspSize > blankDspSize) { // Compare DSP Header
- index += kDspHeaderSize;
+ totalBusPatchSize = fBusStruct->GetTotalLength();
+ indexBusPatch = index;
- for(Int_t iBusPatch = 0; iBusPatch < iBusPerDSP[iDsp]; iBusPatch++) {
-
- if (iBusPatch > fMaxBus) break;
-
- //copy buffer into header structure
- memcpy(fBusStruct->GetBusPatchHeader(), &buffer[index], kBusPatchHeaderSize*4);
-
- totalBusPatchSize = fBusStruct->GetTotalLength();
- indexBusPatch = index;
-
- //Check Buspatch header, not empty events
- if(totalBusPatchSize > kBusPatchHeaderSize) {
-
- index += kBusPatchHeaderSize;
- dataSize = fBusStruct->GetLength();
- Int_t bufSize = fBusStruct->GetBufSize();
-
- if(dataSize > 0) { // check data present
- if (dataSize > bufSize) fBusStruct->SetAlloc(dataSize);
-
- //copy buffer into data structure
- memcpy(fBusStruct->GetData(), &buffer[index], dataSize*4);
- fBusStruct->SetBlockId(iBlock); // could be usefull in future applications ?
- fBusStruct->SetDspId(iDsp);
- fDDLTracker->AddBusPatch(*fBusStruct, iBlock, iDsp);
-
- } // dataSize test
-
- } // testing buspatch
-
- index = indexBusPatch + totalBusPatchSize;
-
- } //buspatch loop
-
- } // dsp test
-
- index = indexDsp + totalDspSize;
-
- } // dsp loop
-
- } //block test
-
- index = totalBlockSize;
-
- } //block loop
-
- // } //loop checking the header size of DDL
+ //Check Buspatch header, not empty events
+ if(totalBusPatchSize > kBusPatchHeaderSize) {
+
+ index += kBusPatchHeaderSize;
+ dataSize = fBusStruct->GetLength();
+ bufSize = fBusStruct->GetBufSize();
+
+ if(dataSize > 0) { // check data present
+ if (dataSize > bufSize) // check buffer size
+ fBusStruct->SetAlloc(dataSize);
+
+ //copy buffer into data structure
+ memcpy(fBusStruct->GetData(), &buffer[index], dataSize*4);
+ fBusStruct->SetBlockId(iBlock); // could be usefull in future applications ?
+ fBusStruct->SetDspId(iDsp);
+
+ // check parity
+ CheckDataParity();
+
+ // copy in TClonesArray
+ fDDLTracker->AddBusPatch(*fBusStruct, iBlock, iDsp);
+
+ } // dataSize test
+
+ } // testing buspatch
+
+ index = indexBusPatch + totalBusPatchSize;
+ if (index >= totalDDLSize) {// check the end of DDL
+ index = totalDDLSize - 1; // point to the last element of buffer
+ break;
+ }
+ iBusPatch++;
+ } // buspatch loop
+
+ // skipping additionnal word if padding
+ if (fDspHeader->GetPaddingWord() == 1) {
+ if (buffer[index++] != fDspHeader->GetDefaultPaddingWord())
+
+#ifndef DATE_SYS
+ AliWarning(Form("Error in padding word for iBlock %d, iDsp %d, iBus %d\n",
+ iBlock, iDsp, iBusPatch));
+#else
+ printf("Error in padding word for iBlock %d, iDsp %d, iBus %d\n", iBlock, iDsp, iBusPatch);
+#endif
+ }
+
+ index = indexDsp + totalDspSize;
+ if (index >= totalDDLSize) {
+ index = totalDDLSize - 1;
+ break;
+ }
+ iDsp++;
+ } // dsp loop
+
+ index = indexBlk + totalBlockSize;
+ if (index >= totalDDLSize) {
+ index = totalDDLSize - 1;
+ break;
+ }
+ iBlock++;
+ } // block loop
return kTRUE;
}
if (blk > 2) blk = 2;
fMaxBlock = blk;
}
+
+//______________________________________________________
+Bool_t AliMUONPayloadTracker::CheckDataParity()
+{
+ // parity check
+ // taken from MuTrkBusPatch.cxx (sotfware test for CROCUS)
+ // A. Baldisseri
+
+ Int_t parity;
+ UInt_t data;
+
+ Int_t dataSize = fBusStruct->GetLength();
+ for (int idata = 0; idata < dataSize; idata++) {
+
+ data = fBusStruct->GetData(idata);
+
+ // Compute the parity for each data word
+ parity = data & 0x1;
+ for (Int_t i = 1; i <= 30; i++)
+ parity ^= ((data >> i) & 0x1);
+
+ // Check
+ if (parity != fBusStruct->GetParity(idata)) {
+#ifndef DATE_SYS
+ AliWarning(Form("Parity error in word %d for manuId %d and channel %d\n",
+ idata, fBusStruct->GetManuId(idata), fBusStruct->GetChannelId(idata)));
+#else
+ printf("Parity error in word %d for manuId %d and channel %d\n",
+ idata, fBusStruct->GetManuId(idata), fBusStruct->GetChannelId(idata));
+#endif
+
+ return kFALSE;
+
+ }
+ }
+ return kTRUE;
+}