]> git.uio.no Git - u/mrichter/AliRoot.git/blobdiff - MUON/AliMUONPayloadTracker.cxx
Adding CreateIterator(void) and GetNeighbours() pure virtual methods,
[u/mrichter/AliRoot.git] / MUON / AliMUONPayloadTracker.cxx
index 23dca5b67d3e8fef13d3ee5cc15f10baedf47fcc..b07cf47e0588c55f979cba031c787e3b01238fc3 100644 (file)
  **************************************************************************/
 
 
-///////////////////////////////////////////////////////////////////////////////
-///
-/// 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;
@@ -92,11 +72,14 @@ AliMUONPayloadTracker::~AliMUONPayloadTracker()
 }
 
 //______________________________________________________
-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
@@ -104,126 +87,130 @@ Bool_t AliMUONPayloadTracker::Decode(UInt_t* buffer, Int_t ddl)
   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;
 }
@@ -244,3 +231,40 @@ void AliMUONPayloadTracker::SetMaxBlock(Int_t blk)
   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;
+}