]> git.uio.no Git - u/mrichter/AliRoot.git/blobdiff - MUON/AliMUONRawStreamTrigger.cxx
Add Centrality vs Mbin histogram
[u/mrichter/AliRoot.git] / MUON / AliMUONRawStreamTrigger.cxx
index 0d9e959031ba5be47b21b30bfa404bcd75c6f257..171156e1e96ffe64d53baf6e72bf7c9707d0b22f 100644 (file)
  * provided "as is" without express or implied warranty.                  *
  **************************************************************************/
 
+/* $Id$ */
 
-///////////////////////////////////////////////////////////////////////////////
-///
+//-----------------------------------------------------------------------------
+/// \class AliMUONRawStreamTrigger
 /// This class provides access to MUON digits in raw data.
 ///
 /// It loops over all MUON 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(under develpment).
+/// The Next method goes to the next local response. If there are no local response left
+/// it returns kFALSE.
 /// It can loop also over DDL and store the decoded rawdata in TClonesArrays
+/// in payload class.
 /// 
-/// First version implement for Trigger
-///
-///////////////////////////////////////////////////////////////////////////////
+/// Version implement for Trigger
+/// \author Christian Finck
+//-----------------------------------------------------------------------------
+
+#include <TArrayS.h>
 
 #include "AliMUONRawStreamTrigger.h"
+#include "AliMUONDarcHeader.h"
+#include "AliMUONRegHeader.h"
+#include "AliMUONLocalStruct.h"
+#include "AliMUONDDLTrigger.h"
+#include "AliMUONLogger.h"
 
 #include "AliRawReader.h"
 #include "AliRawDataHeader.h"
+#include "AliDAQ.h"
 #include "AliLog.h"
 
-#include "AliMUONDarcHeader.h"
-#include "AliMUONRegHeader.h"
-#include "AliMUONLocalStruct.h"
-#include "AliMUONDDLTrigger.h"
+#include <cassert>
 
+/// \cond CLASSIMP
 ClassImp(AliMUONRawStreamTrigger)
+/// \endcond
+
+const Int_t AliMUONRawStreamTrigger::fgkMaxDDL = 2;
+
+//___________________________________________
+AliMUONRawStreamTrigger::AliMUONRawStreamTrigger(TRootIOCtor* /*dummy*/)
+:   AliMUONVRawStreamTrigger(),
+fPayload(0x0),
+fCurrentDDL(0x0),
+fCurrentDDLIndex(fgkMaxDDL),
+fCurrentDarcHeader(0x0),
+fCurrentRegHeader(0x0),
+fCurrentRegHeaderIndex(0),
+fCurrentLocalStruct(0x0),
+fCurrentLocalStructIndex(0),
+fLocalStructRead(kFALSE),
+fDDL(0),
+fNextDDL(kFALSE)
+{
+  ///
+  /// create an object to read MUON raw digits
+  /// Default ctor with no mem allocation for I/O
+  ///
+}
 
+//___________________________________________
 AliMUONRawStreamTrigger::AliMUONRawStreamTrigger()
-  : TObject(),
-    fRawReader(0x0),
+:   AliMUONVRawStreamTrigger(),
+    fPayload(new AliMUONPayloadTrigger()),
+    fCurrentDDL(0x0),
+    fCurrentDDLIndex(fgkMaxDDL),
+    fCurrentDarcHeader(0x0),
+    fCurrentRegHeader(0x0),
+    fCurrentRegHeaderIndex(0),
+    fCurrentLocalStruct(0x0),
+    fCurrentLocalStructIndex(0),
+    fLocalStructRead(kFALSE),
     fDDL(0),
-    fSubEntries(0),
-    fNextDDL(kTRUE),
-    fMaxDDL(2),
-    fMaxReg(8),
-    fMaxLoc(16)
+    fNextDDL(kFALSE)
 {
-  //
-  // create an object to read MUON raw digits
-  // Default ctor for monitoring purposes
-  //
+  ///
+  /// create an object to read MUON raw digits
+  /// Default ctor for monitoring purposes
+  ///
 
-  fDDLTrigger  = new AliMUONDDLTrigger();
-  fRegHeader   = new AliMUONRegHeader();  
-  fLocalStruct = new AliMUONLocalStruct();
 
 }
 
 //_________________________________________________________________
 AliMUONRawStreamTrigger::AliMUONRawStreamTrigger(AliRawReader* rawReader)
-  : TObject(),
+  : AliMUONVRawStreamTrigger(rawReader),
+    fPayload(new AliMUONPayloadTrigger()),
+    fCurrentDDL(0x0),
+    fCurrentDDLIndex(fgkMaxDDL),
+    fCurrentDarcHeader(0x0),
+    fCurrentRegHeader(0x0),
+    fCurrentRegHeaderIndex(0),
+    fCurrentLocalStruct(0x0),
+    fCurrentLocalStructIndex(0),
+    fLocalStructRead(kFALSE),
     fDDL(0),
-    fSubEntries(0),
-    fNextDDL(kTRUE),
-    fMaxDDL(2),
-    fMaxReg(8),
-    fMaxLoc(16)
+    fNextDDL(kFALSE)
 {
-  //
-  // ctor with AliRawReader as argument
-  // for reconstruction purpose
-  //
+  ///
+  /// ctor with AliRawReader as argument
+  /// for reconstruction purpose
+  ///
 
-  fRawReader   = rawReader;
-
-  fDDLTrigger  = new AliMUONDDLTrigger();
-  fRegHeader   = new AliMUONRegHeader();
-  fLocalStruct = new AliMUONLocalStruct();
-  
-}
-
-//_________________________________________________________________
-AliMUONRawStreamTrigger::AliMUONRawStreamTrigger(const AliMUONRawStreamTrigger& stream) :
-  TObject(stream)
-{
-  //
-  // copy ctor
-  //
-  AliFatal("copy constructor not implemented");
-}
-
-//______________________________________________________________________
-AliMUONRawStreamTrigger& AliMUONRawStreamTrigger::operator = (const AliMUONRawStreamTrigger& 
-                                             /* stream */)
-{ 
-  // 
-  // assignment operator
-  //
-  AliFatal("assignment operator not implemented");
-  return *this;
 }
 
 //___________________________________
 AliMUONRawStreamTrigger::~AliMUONRawStreamTrigger()
 {
-  //
-  // clean up
-  //
-  delete fDDLTrigger;
-  delete fLocalStruct;
-  delete fRegHeader;
+  ///
+  /// clean up
+  ///
+  delete fPayload;
 }
 
 //_____________________________________________________________
-Bool_t AliMUONRawStreamTrigger::Next()
+Bool_t AliMUONRawStreamTrigger::Next(UChar_t& id,   UChar_t& dec,      Bool_t& trigY, 
+                                    UChar_t& yPos, UChar_t& sXDev,    UChar_t& xDev,
+                                    UChar_t& xPos, Bool_t& triggerY,  Bool_t& triggerX,
+                                    TArrayS& xPattern, TArrayS& yPattern)
 {
-// read the next raw digit (buspatch structure)
-// returns kFALSE if there is no digit left
-
-//   if (fNextDDL){
-//     if(!NextDDL()) return kFALSE;
-//   }
-//   Int_t nEntries = fDDLTrigger->GetBusPatchEntries();
-
-//   if (fSubEntries < nEntries) {
-//     fLocalStruct =  (AliMUONLocalStruct*)fDDLTrigger->GetBusPatchEntry(fSubEntries);
-//     fSubEntries++;
-//     fNextDDL = kFALSE;
-//     return kTRUE;
-//   } else {
-//     fDDLTrigger->GetBusPatchArray()->Delete();
-//     fSubEntries = 0;
-//     fNextDDL = kTRUE;
-//     return Next(); 
-//   }
-
-  return kFALSE;
+  ///
+  /// read the next raw digit (local structure)
+  /// returns kFALSE if there is no digit left
+  /// Should call First() before this method to start the iteration.
+  ///
+  
+  if ( IsDone() ) return kFALSE;
+  
+  if ( fLocalStructRead ) {
+
+    Bool_t ok = GetNextLocalStruct();
+    if (!ok)
+    {
+      // this is the end
+      return kFALSE;
+    } 
+  }
+
+  fLocalStructRead = kTRUE;
+
+  id    = fCurrentLocalStruct->GetId();
+  dec   = fCurrentLocalStruct->GetDec(); 
+  trigY = fCurrentLocalStruct->GetTrigY();
+  yPos  = fCurrentLocalStruct->GetYPos();
+  sXDev = fCurrentLocalStruct->GetSXDev();
+  xDev  = fCurrentLocalStruct->GetXDev();
+  xPos  = fCurrentLocalStruct->GetXPos();
+
+  triggerX = fCurrentLocalStruct->GetTriggerX();
+  triggerY = fCurrentLocalStruct->GetTriggerY();
+
+  fCurrentLocalStruct->GetXPattern(xPattern);
+  fCurrentLocalStruct->GetYPattern(yPattern);
+
+  return kTRUE;
 }
 
 //______________________________________________________
-Bool_t AliMUONRawStreamTrigger::NextDDL()
+Bool_t AliMUONRawStreamTrigger::IsDone() const
 {
-  // reading tracker DDL
-  // store buspatch info into Array
-  // store only non-empty structures (buspatch info with datalength !=0)
-
- // reading DDL for trigger
-
-  AliMUONDarcHeader* darcHeader = fDDLTrigger->GetDarcHeader();
+  /// Whether the iteration is finished or not
+  return (fCurrentLocalStruct==0);
+}
 
-  Int_t kDarcHeaderSize = darcHeader->GetHeaderLength(); 
-  Int_t kRegHeaderSize  = fRegHeader->GetHeaderLength() ;
-  Bool_t scalerEvent    = kFALSE;
+//______________________________________________________
+void AliMUONRawStreamTrigger::First()
+{
+  /// Initialize the iteration process.
+  
+  fCurrentDDLIndex = -1;
+  // Must reset all the pointers because if we return before calling
+  // GetNextLocalStruct() the user might call CurrentDDL(), CurrentBlockHeader(),
+  // CurrentRegHeader() or CurrentLocalStruct() which should return reasonable
+  // results in that case.
+  fCurrentDDL         = 0;
+  fCurrentDarcHeader  = 0;
+  fCurrentRegHeader   = 0;
+  fCurrentLocalStruct = 0;
+  
+  // Find the first non-empty structure
+  if (not GetNextDDL()) return;
+  if (not GetNextRegHeader()) return;
+  GetNextLocalStruct();
+}
 
-  // reset TClones
-  darcHeader->GetRegHeaderArray()->Delete();
-  //darcHeader->GetRegHeaderArray()->Clear("C");
+//______________________________________________________
+Bool_t AliMUONRawStreamTrigger::GetNextDDL()
+{
+  /// Returns the next DDL present
+  
+  assert( GetReader() != 0 );
 
-  // loop over the two ddl's
-  if (fDDL >= fMaxDDL) {
-    fDDL = 0;
+  
+  Bool_t kFound(kFALSE);
+  
+  while ( fCurrentDDLIndex < fgkMaxDDL-1 && !kFound ) 
+  {
+    ++fCurrentDDLIndex;
+    GetReader()->Reset();
+    GetReader()->Select("MUONTRG",fCurrentDDLIndex,fCurrentDDLIndex);
+    if ( GetReader()->ReadHeader() ) 
+    {
+      kFound = kTRUE;
+    }
+  }
+  
+  if ( !kFound ) 
+  {
+    // fCurrentDDLIndex is set to fgkMaxDDL so that we exit the above loop immediately
+    // for a subsequent call to this method, unless NextEvent is called in between.
+    fCurrentDDLIndex = fgkMaxDDL;
+    // We have not actually been able to complete the loading of the new DDL so
+    // we are still on the old one. In this case we do not need to reset fCurrentDDL.
+    //fCurrentDDL = 0;
+    if (IsErrorLogger()) AddErrorMessage();
     return kFALSE;
   }
+  
+  Int_t totalDataWord  = GetReader()->GetDataSize(); // in bytes
+  
+  Bool_t scalerEvent =  GetReader()->GetDataHeader()->GetL1TriggerMessage() & 0x1;
 
-  fRawReader->Reset();
-  fRawReader->Select(0XA,fDDL,fDDL);  //Select the DDL file to be read  
-
-  fRawReader->ReadHeader();
+  AliDebug(3, Form("DDL Number %d totalDataWord %d\n", fCurrentDDLIndex,
+                   totalDataWord));
 
-  Int_t totalDataWord = fRawReader->GetDataSize(); // in bytes
   UInt_t *buffer = new UInt_t[totalDataWord/4];
 
-  fRawReader->ReadNext((UChar_t*)buffer, totalDataWord); 
-  
-  Int_t index = 0;
-  darcHeader->SetWord(buffer[index++]);
-
-  if(darcHeader->GetEventType() == 2) {
-    scalerEvent = kTRUE;
-  } else
-    scalerEvent = kFALSE;
-
-  if(scalerEvent) {
-    // 6 DARC scaler words
-    memcpy(darcHeader->GetDarcScalers(), &buffer[index], darcHeader->GetDarcScalerLength()*4);
-    index += darcHeader->GetDarcScalerLength();
+  if ( !GetReader()->ReadNext((UChar_t*)buffer, totalDataWord) )
+  {
+    // We have not actually been able to complete the loading of the new DDL so
+    // we are still on the old one. In this case we do not need to reset fCurrentDDL.
+    //fCurrentDDL = 0;
+    delete [] buffer;
+    return kFALSE;
   }
 
-  if (buffer[index++] != darcHeader->GetEndOfDarc())
-    AliWarning(Form("Wrong end of Darc word %x instead of %x\n",buffer[index-1], darcHeader->GetEndOfDarc())); 
+#ifndef R__BYTESWAP  
+  Swap(buffer, totalDataWord / sizeof(UInt_t)); // swap needed for mac power pc
+#endif
 
-  // 4 words of global board input + Global board output
-  memcpy(darcHeader->GetGlobalInput(), &buffer[index], (kDarcHeaderSize-1)*4); 
-  index += kDarcHeaderSize- 1; // kind tricky cos scaler info in-between Darc header
+  fPayload->ResetDDL();
+  
 
-  if(scalerEvent) {
-    // 10 Global scaler words
-    memcpy(darcHeader->GetGlobalScalers(), &buffer[index], darcHeader->GetGlobalScalerLength()*4);
-    index += darcHeader->GetGlobalScalerLength();
-  }
 
-  if (buffer[index++] != darcHeader->GetEndOfGlobal())
-    AliWarning(Form("Wrong end of Global word %d instead of %d\n",buffer[index-1], darcHeader->GetEndOfGlobal()));
-    
-  // 8 regional boards
-  for (Int_t iReg = 0; iReg < fMaxReg; iReg++) {           //loop over regeonal card
+  Bool_t ok = fPayload->Decode(buffer, scalerEvent);
 
-    memcpy(fRegHeader->GetHeader(), &buffer[index], kRegHeaderSize*4);
-    index += kRegHeaderSize;
+  delete[] buffer;
+  
+  fCurrentDDL = fPayload->GetDDLTrigger();
+  
+  fCurrentDarcHeader = fCurrentDDL->GetDarcHeader();
+  
+  fCurrentRegHeaderIndex = -1;
 
-    fDDLTrigger->AddRegHeader(*fRegHeader);
-    // 11 regional scaler word
-    if(scalerEvent) {
-      memcpy(fRegHeader->GetScalers(), &buffer[index], fRegHeader->GetScalerLength()*4);
-      index += fRegHeader->GetScalerLength();
-    }
 
-    if (buffer[index++] != fRegHeader->GetEndOfReg())
-      AliWarning(Form("Wrong end of Reg word %x instead of %x\n",buffer[index-1], fRegHeader->GetEndOfReg()));
-
-    // 16 local cards per regional board
-    for (Int_t iLoc = 0; iLoc < fMaxLoc; iLoc++) {         //loop over local card
-         
-      Int_t dataSize = fLocalStruct->GetLength();;
-
-      // 5 word trigger information
-      memcpy(fLocalStruct->GetData(), &buffer[index], dataSize*4); 
-      index += dataSize;        
-
-      // 45 regional scaler word
-      if(scalerEvent) {
-       memcpy(fLocalStruct->GetScalers(), &buffer[index], fLocalStruct->GetScalerLength()*4);
-       index += fLocalStruct->GetScalerLength();
-      }
-
-      if (buffer[index++] != fLocalStruct->GetEndOfLocal())
-       AliWarning(Form("Wrong end of local word %x instead of %x\n",buffer[index-1], fLocalStruct->GetEndOfLocal()));
-         
-      fDDLTrigger->AddLocStruct(*fLocalStruct, iReg);
-
-    } // local card loop
-       
-  } // regional card loop
-      
-  delete [] buffer;
+  return ok;
+}
 
 
-  fDDL++;
+//______________________________________________________
+Bool_t AliMUONRawStreamTrigger::GetNextRegHeader()
+{
+  /// Returns the next Reg Header present
 
+  assert( fCurrentDarcHeader != 0 );
+  assert( fCurrentDDL != 0 );
+
+  fCurrentRegHeader = 0;
+  
+  Int_t i = fCurrentRegHeaderIndex;
+  
+  while ( fCurrentRegHeader == 0 && i < fCurrentDarcHeader->GetRegHeaderEntries()-1 )
+  {
+    ++i;
+    fCurrentRegHeader = fCurrentDarcHeader->GetRegHeaderEntry(i);
+  }
+     
+  if ( !fCurrentRegHeader ) 
+  {
+    Bool_t ok = GetNextDDL();
+    if (!ok) 
+    {
+      return kFALSE;
+    }
+    else
+    {
+      return GetNextRegHeader();
+    }
+  }
+  
+  fCurrentRegHeaderIndex = i;
+  
+  fCurrentLocalStructIndex = -1;
+  
   return kTRUE;
 }
 
 //______________________________________________________
-void AliMUONRawStreamTrigger::ResetDDL()
+Bool_t AliMUONRawStreamTrigger::GetNextLocalStruct()
 {
-  // reseting TClonesArray
-  // after each DDL
-  //
-  AliMUONDarcHeader* darcHeader = fDDLTrigger->GetDarcHeader();
-  darcHeader->GetRegHeaderArray()->Clear("C");
+  /// Find the next non-empty local structure
+  
+  assert( fCurrentRegHeader != 0 );
+  
+  fCurrentLocalStruct = 0;
+
+  Int_t i = fCurrentLocalStructIndex;
+  
+  while ( fCurrentLocalStruct == 0 && i < fCurrentRegHeader->GetLocalEntries()-1 ) 
+  {
+    ++i;
+    fCurrentLocalStruct = fCurrentRegHeader->GetLocalEntry(i);
+  }
+    
+  if ( !fCurrentLocalStruct ) 
+  {
+    Bool_t ok = GetNextRegHeader();
+    if (!ok)
+    {
+      return kFALSE;
+    }
+    else
+    {
+      return GetNextLocalStruct();
+    }
+  }
+  
+  fCurrentLocalStructIndex = i;
+  
+  fLocalStructRead = kFALSE;
+  
+  return kTRUE;
 }
 
 //______________________________________________________
-void AliMUONRawStreamTrigger::SetMaxDDL(Int_t ddl) 
+Bool_t AliMUONRawStreamTrigger::NextDDL()
 {
-  // set DDL number
-  if (ddl > 2) ddl = 2;
-  fMaxDDL = ddl;
+  /// reading tracker DDL
+  /// store local info into Array
+  /// store only non-empty structures
+
+  // reset TClones
+  fPayload->ResetDDL();
+
+
+  // loop over the two ddl's
+
+  while ( fDDL < fgkMaxDDL ) {
+    GetReader()->Reset();
+    GetReader()->Select("MUONTRG", fDDL, fDDL);  //Select the DDL file to be read  
+    if (GetReader()->ReadHeader()) break;
+    AliDebug(3,Form("Skipping DDL %d which does not seem to be there",fDDL));
+    ++fDDL;
+  }
+
+  if (fDDL >= fgkMaxDDL) {
+    fDDL = 0;
+    if (IsErrorLogger()) AddErrorMessage();
+    return kFALSE;
+  }
+
+  AliDebug(3, Form("DDL Number %d\n", fDDL ));
+
+  Int_t totalDataWord = GetReader()->GetDataSize(); // in bytes
+
+  Bool_t scalerEvent =  GetReader()->GetDataHeader() && GetReader()->GetDataHeader()->GetL1TriggerMessage() & 0x1;
+
+
+  UInt_t *buffer = new UInt_t[totalDataWord/4];
+
+  // check not necessary yet, but for future developments
+  if (!GetReader()->ReadNext((UChar_t*)buffer, totalDataWord)) return kFALSE; 
+  
+#ifndef R__BYTESWAP
+  Swap(buffer, totalDataWord / sizeof(UInt_t)); // swap needed for mac power pc
+#endif
+
+  fPayload->Decode(buffer, scalerEvent);
+
+
+  fDDL++;
+
+  delete [] buffer;
+
+
+  return kTRUE;
 }
 
+// //______________________________________________________
+// void AliMUONRawStreamTrigger::SetMaxReg(Int_t reg) 
+// {
+//   /// set regional card number
+//   fPayload->SetMaxReg(reg);
+// }
+
 //______________________________________________________
-void AliMUONRawStreamTrigger::SetMaxReg(Int_t reg
+void AliMUONRawStreamTrigger::SetMaxLoc(Int_t loc
 {
-  // set regional card number
-  if (reg > 8) reg = 8;
-  fMaxReg = reg;
+  /// set local card number
+  fPayload->SetMaxLoc(loc);
 }
 
 //______________________________________________________
-void AliMUONRawStreamTrigger::SetMaxLoc(Int_t loc) 
+void AliMUONRawStreamTrigger::AddErrorMessage()
 {
-  // set local card number
-  if (loc > 16) loc = 16;
-  fMaxLoc = loc;
+/// add message into logger of AliRawReader per event
+
+  TString msg;
+  Int_t occurance = 0;
+  AliMUONLogger* log = fPayload->GetErrorLogger();
+  
+  log->ResetItr();
+  while(log->Next(msg, occurance))
+  { 
+    if (msg.Contains("Darc"))
+      GetReader()->AddMajorErrorLog(kDarcEoWErr, msg.Data());
+
+    if (msg.Contains("Global"))
+      GetReader()->AddMajorErrorLog(kGlobalEoWErr, msg.Data());
+
+    if (msg.Contains("Regional"))
+      GetReader()->AddMajorErrorLog(kRegEoWErr, msg.Data());
+
+    if (msg.Contains("Local"))
+      GetReader()->AddMajorErrorLog(kLocalEoWErr, msg.Data());
+  }
+  
+  log->Clear(); // clear after each event
 }