]> git.uio.no Git - u/mrichter/AliRoot.git/commitdiff
New class that is used by SPD-MOOD to retrieve information on consistency errors...
authorhristov <hristov@f7af4fe6-9843-0410-8265-dc069ae4e863>
Fri, 7 Dec 2007 18:57:33 +0000 (18:57 +0000)
committerhristov <hristov@f7af4fe6-9843-0410-8265-dc069ae4e863>
Fri, 7 Dec 2007 18:57:33 +0000 (18:57 +0000)
ITS/AliITSRawStreamSPDErrorLog.cxx [new file with mode: 0644]
ITS/AliITSRawStreamSPDErrorLog.h [new file with mode: 0644]
ITS/AliITSRawStreamSPD_NEWGEO.cxx
ITS/ITSbaseLinkDef.h
ITS/libITSbase.pkg

diff --git a/ITS/AliITSRawStreamSPDErrorLog.cxx b/ITS/AliITSRawStreamSPDErrorLog.cxx
new file mode 100644 (file)
index 0000000..af3bd7d
--- /dev/null
@@ -0,0 +1,384 @@
+///////////////////////////////////////////////////////////////////////
+// Author: Henrik Tydesjo                                            //
+// For easier handling of error messages from AliITSRawStreamSPD.    //
+// The purpose of this class is to make possible the switch to the   //
+// AliRoot raw data parsing routines in the onlinte monitoring       //
+// programs, like SPD-MOOD, and still keep all the old functionality.//
+///////////////////////////////////////////////////////////////////////
+
+#include "AliITSRawStreamSPDErrorLog.h"
+#include "AliLog.h"
+
+ClassImp(AliITSRawStreamSPDErrorLog)
+//________________________________________________________________________________________________
+AliITSRawStreamSPDErrorLog::AliITSRawStreamSPDErrorLog() :
+  fText(NULL), fTextTmpGeneral(NULL)
+{
+  // default constructor
+  fText=new TGText();
+  fTextTmpGeneral=new TGText();
+  for (UInt_t eq=0; eq<20; eq++) {
+    fTextTmp[eq] = new TGText();
+    fNEvents[eq] = 0;
+    fPayloadSizeSet[eq] = kFALSE;
+    fByteOffset[eq] = 0;
+    fSuppressEq[eq] = kFALSE;
+    for (UInt_t err=0; err<kNrErrorCodes; err++) {
+      fNErrors[err][eq] = 0;
+    }
+  }
+  for (UInt_t err=0; err<kNrErrorCodes; err++) {
+    fSuppressMess[err] = kFALSE;
+  }
+  InitHistograms();
+}
+//________________________________________________________________________________________________
+AliITSRawStreamSPDErrorLog::AliITSRawStreamSPDErrorLog(const AliITSRawStreamSPDErrorLog& logger) :
+  TObject(logger), fText(NULL), fTextTmpGeneral(NULL)
+{
+  // copy constructor
+  for (UInt_t eq=0; eq<20; eq++) {
+    for (UInt_t err=0; err<kNrErrorCodes; err++) {
+      fNErrors[err][eq] = logger.fNErrors[err][eq];
+      fErrEventCounter[err][eq] = logger.fErrEventCounter[err][eq];
+    }
+    fNEvents[eq] = logger.fNEvents[eq];
+    fPayloadSize[eq] = logger.fPayloadSize[eq];
+    fPayloadSizeSet[eq] = logger.fPayloadSizeSet[eq];
+    fByteOffset[eq] = logger.fByteOffset[eq];
+    fSuppressEq[eq] = logger.fSuppressEq[eq];
+  }
+  for (UInt_t err=0; err<kNrErrorCodes; err++) {
+    fSuppressMess[err] = logger.fSuppressMess[err];
+  }
+  
+  fText = new TGText(logger.fText);
+  fTextTmpGeneral = new TGText(logger.fTextTmpGeneral);
+  for (UInt_t eq=0; eq<20; eq++) {
+    fTextTmp[eq] = new TGText(logger.fTextTmp[eq]);
+  }
+  
+  for (UInt_t eq=0; eq<20; eq++) {
+    for (UInt_t err=0; err<kNrErrorCodes; err++) {
+      fConsErrEvent[err][eq] = new TGraph(*logger.fConsErrEvent[err][eq]);
+      fConsErrPos[err][eq] = new TH1F(*logger.fConsErrPos[err][eq]);
+    }
+    fConsErrType[eq] = new TH1F(*logger.fConsErrType[eq]);
+    fConsErrFraction[eq] = new TH1F(*logger.fConsErrFraction[eq]);
+  }
+  
+}
+//________________________________________________________________________________________________
+AliITSRawStreamSPDErrorLog& AliITSRawStreamSPDErrorLog::operator=(const AliITSRawStreamSPDErrorLog& logger) {
+  // assignment operator
+  if (this!=&logger) {
+    delete fText;
+    delete fTextTmpGeneral;
+    delete[] fTextTmp;
+    this->DeleteHistograms();
+
+    for (UInt_t eq=0; eq<20; eq++) {
+      for (UInt_t err=0; err<kNrErrorCodes; err++) {
+       fNErrors[err][eq] = logger.fNErrors[err][eq];
+       fErrEventCounter[err][eq] = logger.fErrEventCounter[err][eq];
+      }
+      fNEvents[eq] = logger.fNEvents[eq];
+      fPayloadSize[eq] = logger.fPayloadSize[eq];
+      fPayloadSizeSet[eq] = logger.fPayloadSizeSet[eq];
+      fByteOffset[eq] = logger.fByteOffset[eq];
+      fSuppressEq[eq] = logger.fSuppressEq[eq];
+    }
+    for (UInt_t err=0; err<kNrErrorCodes; err++) {
+      fSuppressMess[err] = logger.fSuppressMess[err];
+    }
+
+    fText = new TGText(logger.fText);
+    fTextTmpGeneral = new TGText(logger.fTextTmpGeneral);
+    for (UInt_t eq=0; eq<20; eq++) {
+      fTextTmp[eq] = new TGText(logger.fTextTmp[eq]);
+    }
+    
+    for (UInt_t eq=0; eq<20; eq++) {
+      for (UInt_t err=0; err<kNrErrorCodes; err++) {
+       fConsErrEvent[err][eq] = new TGraph(*logger.fConsErrEvent[err][eq]);
+       fConsErrPos[err][eq] = new TH1F(*logger.fConsErrPos[err][eq]);
+      }
+      fConsErrType[eq] = new TH1F(*logger.fConsErrType[eq]);
+      fConsErrFraction[eq] = new TH1F(*logger.fConsErrFraction[eq]);
+    }
+
+  }
+  return *this;
+  
+}
+//________________________________________________________________________________________________
+AliITSRawStreamSPDErrorLog::~AliITSRawStreamSPDErrorLog() {
+  // destructor
+  DeleteHistograms();
+  delete fText;
+  delete fTextTmpGeneral;
+  delete[] fTextTmp;
+}
+//________________________________________________________________________________________________
+void AliITSRawStreamSPDErrorLog::InitHistograms() {
+  // initialize histograms
+  for (UInt_t eq=0; eq<20; eq++) {
+    TString histName, histTitle;
+    histName = Form("ConsErrType %d",eq);
+    histTitle = Form("Distribution of errors, eq %d",eq);
+    fConsErrType[eq]=new TH1F(histName.Data(),histTitle.Data(),kNrErrorCodes,-0.5,kNrErrorCodes-0.5);
+    fConsErrType[eq]->SetXTitle("Error Code");
+    fConsErrType[eq]->SetYTitle("Nr Errors");
+    
+    histName = Form("ConsErrFraction %d",eq);
+    histTitle = Form("Fraction of events with errors, eq %d",eq);
+    fConsErrFraction[eq]=new TH1F(histName.Data(),histTitle.Data(),kNrErrorCodes,-0.5,kNrErrorCodes-0.5);
+    fConsErrFraction[eq]->SetXTitle("Error Code");
+    fConsErrFraction[eq]->SetYTitle("Fraction");
+    
+    for (UInt_t err=0; err<kNrErrorCodes; err++) {
+      fConsErrEvent[err][eq]=new TGraph();
+      fErrEventCounter[err][eq] = 0;
+      histName = Form("ConsErrPos %d %d",err,eq);
+      histTitle = Form("Position in event, eq %d , error code %d",eq,err);
+      fConsErrPos[err][eq]=new TH1F(histName.Data(),histTitle.Data(),200,0,100);
+      fConsErrPos[err][eq]->SetXTitle("Position [%]");
+      fConsErrPos[err][eq]->SetYTitle("Nr Errors");
+    }
+  }
+}
+//________________________________________________________________________________________________
+void AliITSRawStreamSPDErrorLog::DeleteHistograms() const {
+  // delete histograms
+  for (UInt_t eq=0; eq<20; eq++) {
+    delete fConsErrType[eq];
+    delete fConsErrFraction[eq];
+    for (UInt_t err=0; err<kNrErrorCodes; err++) {
+      delete fConsErrEvent[err][eq];
+      delete fConsErrPos[err][eq];
+    }
+  }
+}
+//________________________________________________________________________________________________
+void AliITSRawStreamSPDErrorLog::Reset() {
+  // Reset
+  fText->Clear();
+  for (UInt_t eq=0; eq<20; eq++) {
+    fTextTmp[eq]->Clear();
+    fConsErrType[eq]->Reset();
+    fConsErrFraction[eq]->Reset();
+    fNEvents[eq] = 0;
+    fPayloadSizeSet[eq] = kFALSE;
+    for (UInt_t err=0; err<kNrErrorCodes; err++) {
+      fNErrors[err][eq] = 0;
+      delete fConsErrEvent[err][eq];
+      fErrEventCounter[err][eq] = 0;
+      fConsErrEvent[err][eq] = new TGraph();
+      fConsErrPos[err][eq]->Reset();
+    }
+  }
+}
+//________________________________________________________________________________________________
+void AliITSRawStreamSPDErrorLog::ProcessError(UInt_t errorCode, UInt_t eq, Int_t bytesRead, Int_t headersRead, const Char_t *errMess) {
+  // Process an error
+  if (eq>=20) {
+    AliWarning(Form("Equipment number (%d) out of bounds",eq));
+    return;
+  }
+  // check if we want to exclude the error...
+  if (!(fSuppressMess[errorCode] || fSuppressEq[eq])) {
+    fNErrors[errorCode][eq]++;
+    if (errorCode!=kTotal) fNErrors[kTotal][eq]++;
+
+    if (fPayloadSizeSet) {
+      fConsErrPos[errorCode][eq]->Fill(100.*bytesRead/fPayloadSize[eq]);
+      if (errorCode!=kTotal) fConsErrPos[kTotal][eq]->Fill(100.*bytesRead/fPayloadSize[eq]);
+    }
+
+    TString msg;
+    if (bytesRead<0) {
+      msg = Form("%s",errMess);
+    }
+    else {
+      msg = Form("%s (%d bytes read, %d chip headers read)",errMess,bytesRead+fByteOffset[eq],headersRead);
+    }
+    fTextTmp[eq]->InsLine(fTextTmp[eq]->RowCount(),msg.Data());
+  }
+}
+//________________________________________________________________________________________________
+void AliITSRawStreamSPDErrorLog::AddMessage(const Char_t *errMess) {
+  // add a general message to the buffer
+  fTextTmpGeneral->InsLine(fTextTmpGeneral->RowCount(),errMess);
+}
+//________________________________________________________________________________________________
+void AliITSRawStreamSPDErrorLog::SummarizeEvent(UInt_t eventNum) {
+  // summarize the information for the current event
+  TString msg;
+  if (fText->RowCount()>5000) {
+    fText->Clear();
+    msg = "*** previous errors cleared ***";
+    fText->InsLine(fText->RowCount(),msg.Data());
+  }
+  if (fTextTmpGeneral->RowCount()>1) {
+    msg = Form("*** Event %d , General Errors: ***",eventNum);
+    fText->InsLine(fText->RowCount(),msg.Data());
+    fText->AddText(fTextTmpGeneral);
+    fTextTmpGeneral->Clear();
+  }
+  for (UInt_t eq=0; eq<20; eq++) {
+    for (UInt_t err=0; err<kNrErrorCodes; err++) {
+      fConsErrType[eq]->Fill(err,fNErrors[err][eq]);
+      if (fNErrors[err][eq]>0){
+       fConsErrEvent[err][eq]->SetPoint(fErrEventCounter[err][eq],eventNum,fNErrors[err][eq]);
+       fErrEventCounter[err][eq]++;
+       fConsErrFraction[eq]->Fill(err);
+      }
+    }
+    fNEvents[eq]++;
+    if (fNErrors[kTotal][eq]>0) {
+      msg = Form("*** Event %d , Eq %d: ***",eventNum,eq);
+      fText->InsLine(fText->RowCount(),msg.Data());
+      fText->AddText(fTextTmp[eq]);
+      fText->InsLine(fText->RowCount()," ");
+    }
+    fPayloadSizeSet[eq]=kFALSE;
+    fByteOffset[eq]=0;
+    fTextTmp[eq]->Clear();
+    for (UInt_t err=0; err<kNrErrorCodes; err++) {
+      fNErrors[err][eq]=0;
+    }
+  }
+}
+//________________________________________________________________________________________________
+void AliITSRawStreamSPDErrorLog::SetPayloadSize(UInt_t eq, UInt_t size) {
+  // set the payload size for this event
+  if (eq<20) {
+    fPayloadSize[eq]=size;
+    fPayloadSizeSet[eq]=kTRUE;
+  }
+  else {
+    AliWarning(Form("Equipment number (%d) out of range",eq));
+  }
+}
+//________________________________________________________________________________________________
+void AliITSRawStreamSPDErrorLog::SetByteOffset(UInt_t eq, Int_t size) {
+  // set byte offset (equipment header size)
+  if (eq<20) {
+    fByteOffset[eq]=size;
+  }
+  else {
+    AliWarning(Form("Equipment number (%d) out of range",eq));
+  }
+}
+//________________________________________________________________________________________________
+void AliITSRawStreamSPDErrorLog::SuppressErrorMessages(UInt_t errorCode, Bool_t suppr) {
+  // suppress error messages for specific error code
+  if (errorCode<kNrErrorCodes) {
+    fSuppressMess[errorCode] = suppr;
+  }
+  else {
+    AliWarning(Form("Error code (%d) out of range",errorCode));
+  }
+}
+//________________________________________________________________________________________________
+void AliITSRawStreamSPDErrorLog::SuppressErrorEq(UInt_t eq, Bool_t suppr) {
+  // suppress error messages for specific equipment
+  if (eq<20) {
+    fSuppressEq[eq] = suppr;
+  }
+  else {
+    AliWarning(Form("Eq id (%d) out of range",eq));
+  }
+}
+//________________________________________________________________________________________________
+UInt_t AliITSRawStreamSPDErrorLog::GetNrErrors(UInt_t errorCode, UInt_t eq) {
+  // returns the number of errors for this event for a specific error code and equipment
+  if (errorCode<kNrErrorCodes && eq<20) return fNErrors[errorCode][eq];
+  else {
+    AliWarning(Form("Error code (%d) or equipment (%d) out of range, returning 0",errorCode,eq));
+    return 0;
+  }
+}
+//________________________________________________________________________________________________
+UInt_t AliITSRawStreamSPDErrorLog::GetNrErrorsAllEq(UInt_t errorCode) {
+  // returns the number of errors for this event for a specific error code and all equipments
+  if (errorCode<kNrErrorCodes) {
+    UInt_t returnval=0;
+    for (UInt_t eq=0; eq<20; eq++) {
+      returnval += fNErrors[errorCode][eq];
+    }
+    return returnval;
+  }
+  else {
+    AliWarning(Form("Error code (%d) out of range, returning 0",errorCode));
+    return 0;
+  }
+}
+//________________________________________________________________________________________________
+UInt_t AliITSRawStreamSPDErrorLog::GetNrErrorsTotal(UInt_t errorCode, UInt_t eq) {
+  // returns the total number of errors for a specific error code and equipment
+  if (errorCode<kNrErrorCodes && eq<20) {
+    return (UInt_t) fConsErrType[eq]->GetBinContent(errorCode+1);
+  }
+  else {
+    AliWarning(Form("Error code (%d) or equipment (%d) out of range, returning 0",errorCode,eq));
+    return 0;
+  }
+}
+//________________________________________________________________________________________________
+UInt_t AliITSRawStreamSPDErrorLog::GetNrErrorsTotalAllEq(UInt_t errorCode) {
+  // returns the total number of errors for a specific error code and for all equipment
+  if (errorCode<kNrErrorCodes) {
+    UInt_t returnval=0;
+    for (UInt_t eq=0; eq<20; eq++) {
+      returnval += (UInt_t) fConsErrType[eq]->GetBinContent(errorCode+1);
+    }
+    return returnval;
+  }
+  else {
+    AliWarning(Form("Error code (%d) out of range, returning 0",errorCode));
+    return 0;
+  }
+}
+//________________________________________________________________________________________________
+TGraph* AliITSRawStreamSPDErrorLog::GetConsErrEvent(UInt_t errorCode, UInt_t eq) {
+  // returns a pointer to the graph
+  if (errorCode<kNrErrorCodes && eq<20) return fConsErrEvent[errorCode][eq];
+  else {
+    AliWarning(Form("Error code (%d) or equipment (%d) out of range, returning NULL",errorCode,eq));
+    return NULL;
+  }
+}
+//________________________________________________________________________________________________
+TH1F* AliITSRawStreamSPDErrorLog::GetConsErrType(UInt_t eq) {
+  // returns a pointer to the histogram
+  if (eq<20) return fConsErrType[eq];
+  else {
+    AliWarning(Form("Eq nr (%d) out of bounds",eq));
+    return NULL;
+  }
+}
+//________________________________________________________________________________________________
+TH1F* AliITSRawStreamSPDErrorLog::GetConsErrFraction(UInt_t eq) {
+  // creates a new histogram and returns a pointer to it. 
+  // NB!!! Take care of deleting this object later
+  if (eq<20) {
+    TH1F* returnhisto = (TH1F*)(fConsErrFraction[eq]->Clone());
+    if (fNEvents[eq]!=0) returnhisto->Scale(1./fNEvents[eq]);
+    //    returnhisto->SetMaximum(1.);
+    return returnhisto;
+  }
+  else {
+    AliWarning(Form("Eq nr (%d) out of bounds",eq));
+    return NULL;
+  }
+}
+//________________________________________________________________________________________________
+TH1F* AliITSRawStreamSPDErrorLog::GetConsErrPos(UInt_t errorCode, UInt_t eq) {
+  // returns a pointer to the histogram
+  if (errorCode<kNrErrorCodes && eq<20) return fConsErrPos[errorCode][eq];
+  else {
+    AliWarning(Form("Error code (%d) or equipment (%d) out of range, returning NULL",errorCode,eq));
+    return NULL;
+  }
+}
diff --git a/ITS/AliITSRawStreamSPDErrorLog.h b/ITS/AliITSRawStreamSPDErrorLog.h
new file mode 100644 (file)
index 0000000..838b018
--- /dev/null
@@ -0,0 +1,77 @@
+#ifndef ALIITSRAWSTREAMSPDERRORLOG_H
+#define ALIITSRAWSTREAMSPDERRORLOG_H
+
+///////////////////////////////////////////////////////////////////////
+// Author: Henrik Tydesjo                                            //
+// For easier handling of error messages from AliITSRawStreamSPD.    //
+// The purpose of this class is to make possible the switch to the   //
+// AliRoot raw data parsing routines in the onlinte monitoring       //
+// programs, like SPD-MOOD, and still keep all the old functionality.//
+///////////////////////////////////////////////////////////////////////
+
+#include <TH1F.h>
+#include <TH2F.h>
+#include <TGraph.h>
+#include <TGText.h>
+
+class AliITSRawStreamSPDErrorLog : public TObject {
+
+ public:
+  AliITSRawStreamSPDErrorLog();
+  AliITSRawStreamSPDErrorLog(const AliITSRawStreamSPDErrorLog& logger);
+  AliITSRawStreamSPDErrorLog& operator=(const AliITSRawStreamSPDErrorLog& logger);
+  virtual ~AliITSRawStreamSPDErrorLog();
+
+  enum    {kNrErrorCodes = 15};
+  enum    {kTotal = 0};
+
+  void    Reset();
+  void    ProcessError(UInt_t errorCode, UInt_t eq, Int_t bytesRead, Int_t headersRead, const Char_t *errMess);
+  void    AddMessage(const Char_t *errMess);
+  void    SummarizeEvent(UInt_t eventNum);
+
+  UInt_t  GetNrErrors(UInt_t errorCode, UInt_t eq);
+  UInt_t  GetNrErrorsAllEq(UInt_t errorCode);
+  UInt_t  GetNrErrorsTotal(UInt_t errorCode, UInt_t eq);
+  UInt_t  GetNrErrorsTotalAllEq(UInt_t errorCode);
+
+  void    SetPayloadSize(UInt_t eq, UInt_t size);
+  void    SetByteOffset(UInt_t eq, Int_t size);
+  void    SuppressErrorMessages(UInt_t errorCode, Bool_t suppr = kTRUE);
+  void    SuppressErrorEq(UInt_t eq, Bool_t suppr = kTRUE);
+
+  static  UInt_t GetNrErrorCodes(){return kNrErrorCodes;}
+
+  TGraph* GetConsErrEvent(UInt_t errorCode, UInt_t eq);
+  TH1F*   GetConsErrType(UInt_t eq);
+  TH1F*   GetConsErrFraction(UInt_t eq);
+  TH1F*   GetConsErrPos(UInt_t errorCode, UInt_t eq);
+  TGText* GetText() {return fText;}
+
+
+ private:
+  Int_t   fNErrors[kNrErrorCodes][20];          // number of errors for this event, for each code and eq
+  UInt_t  fNEvents[20];                         // number of events used, for each eq
+  UInt_t  fPayloadSize[20];                     // size of payload for this event, for each eq
+  Bool_t  fPayloadSizeSet[20];                  // was the payload size set for this eq?
+  UInt_t  fErrEventCounter[kNrErrorCodes][20];  // event counter used when filling graph
+  Int_t   fByteOffset[20];                      // offset: how many bytes in the equipment header, for each eq
+  Bool_t  fSuppressMess[kNrErrorCodes];         // do we suppress error messages for a specific error code?
+  Bool_t  fSuppressEq[20];                      // do we suppress error messages for a specific eq?
+
+  TGraph  *fConsErrEvent[kNrErrorCodes][20];    // graphs to display number of errors found in each event
+  TH1F    *fConsErrType[20];                    // histogram of how many errors for each error code
+  TH1F    *fConsErrFraction[20];                // histogram of rate of events with errors for each error code
+  TH1F    *fConsErrPos[kNrErrorCodes][20];      // histogram of where in payload the errors occur
+
+  TGText  *fText;                               // text buffer for all events analyzed so far
+  TGText  *fTextTmp[20];                        // text buffer for this event (defined error codes)
+  TGText  *fTextTmpGeneral;                     // text buffer for this event (general errors)
+
+  void    InitHistograms();
+  void    DeleteHistograms() const;
+
+  ClassDef(AliITSRawStreamSPDErrorLog, 1);
+};
+
+#endif
index 16cb686ac8d83697d76023b9a8be1249467a0b78..f51680178cc49753d0717c4963695021e4d710dc 100644 (file)
@@ -27,7 +27,6 @@
 
 ClassImp(AliITSRawStreamSPD)
 
-
 const Int_t AliITSRawStreamSPD::fgkDDLModuleMap[kDDLsNumber][kModulesPerDDL] = {
   { 4, 5, 0, 1, 80, 81, 84, 85, 88, 89, 92, 93},
   {12,13, 8, 9, 96, 97,100,101,104,105,108,109},
@@ -50,14 +49,17 @@ const Int_t AliITSRawStreamSPD::fgkDDLModuleMap[kDDLsNumber][kModulesPerDDL] = {
   {71,70,67,66,211,210,215,214,219,218,223,222},
   {79,78,75,74,227,226,231,230,235,234,239,238}
 };
-
-
+//__________________________________________________________________________
 AliITSRawStreamSPD::AliITSRawStreamSPD(AliRawReader* rawReader) :
   AliITSRawStream(rawReader),
-  fEventNumber(-1),fChipAddr(0),fHalfStaveNr(0),fCol(0),fRow(0),
+  fEventCounter(-1),fChipAddr(0),fHalfStaveNr(0),fCol(0),fRow(0),
   fData(0),fOffset(0),fHitCount(0),
   fDataChar1(0),fDataChar2(0),fDataChar3(0),fDataChar4(0),
-  fFirstWord(kTRUE),fPrevEventId(0xffffffff)
+  fFirstWord(kTRUE),fPrevEventId(0xffffffff),
+  fEqPLBytesRead(0),fEqPLChipHeadersRead(0),fEqPLChipTrailersRead(0),
+  fHeaderOrTrailerReadLast(kFALSE),fExpectedHeaderTrailerCount(0),
+  fFillOutOfSynch(kFALSE),fDDLID(-1),fLastDDLID(-1),fAdvancedErrorLog(kFALSE),
+  fAdvLogger(NULL)
 {
   // create an object to read ITS SPD raw digits
   fRawReader->Select("ITSSPD");
@@ -67,9 +69,30 @@ AliITSRawStreamSPD::AliITSRawStreamSPD(AliRawReader* rawReader) :
   }
   NewEvent();
 }
-
-Bool_t AliITSRawStreamSPD::ReadNextShort() 
+//__________________________________________________________________________
+AliITSRawStreamSPD::AliITSRawStreamSPD(const AliITSRawStreamSPD& rstream) :
+  AliITSRawStream(rstream.fRawReader),
+  fEventCounter(-1),fChipAddr(0),fHalfStaveNr(0),fCol(0),fRow(0),
+  fData(0),fOffset(0),fHitCount(0),
+  fDataChar1(0),fDataChar2(0),fDataChar3(0),fDataChar4(0),
+  fFirstWord(kTRUE),fPrevEventId(0xffffffff),
+  fEqPLBytesRead(0),fEqPLChipHeadersRead(0),fEqPLChipTrailersRead(0),
+  fHeaderOrTrailerReadLast(kFALSE),fExpectedHeaderTrailerCount(0),
+  fFillOutOfSynch(kFALSE),fDDLID(-1),fLastDDLID(-1),fAdvancedErrorLog(kFALSE),
+  fAdvLogger(NULL)
 {
+  // copy constructor
+  AliError("Copy constructor should not be used.");
+}
+//__________________________________________________________________________
+AliITSRawStreamSPD& AliITSRawStreamSPD::operator=(const AliITSRawStreamSPD& rstream) {
+  // assignment operator
+  if (this!=&rstream) {}
+  AliError("Assignment opertator should not be used.");
+  return *this;
+}
+//__________________________________________________________________________
+Bool_t AliITSRawStreamSPD::ReadNextShort() {
   // read next 16 bit word into fData
   if (fFirstWord) {
     Bool_t b1 = fRawReader->ReadNextChar(fDataChar1);
@@ -92,12 +115,12 @@ Bool_t AliITSRawStreamSPD::ReadNextShort()
     fFirstWord=kTRUE;
     fData = fDataChar1+(fDataChar2<<8);
   }
-
+  fEqPLBytesRead+=2;
+  
   return kTRUE;
 }
-
-Bool_t AliITSRawStreamSPD::ReadNextInt() 
-{
+//__________________________________________________________________________
+Bool_t AliITSRawStreamSPD::ReadNextInt() {
   // reads next 32 bit into fDataChar1..4 
   // (if first 16 bits read already, just completes the present word)
   if (fFirstWord) {
@@ -112,45 +135,61 @@ Bool_t AliITSRawStreamSPD::ReadNextInt()
   }
   return kFALSE;
 }
-
-void AliITSRawStreamSPD::NewEvent()
-{
+//__________________________________________________________________________
+void AliITSRawStreamSPD::NewEvent() {
   // call this to reset flags for a new event
   for (UInt_t eqId=0; eqId<20; eqId++) {
     fCalHeadRead[eqId]=kFALSE;
   }
-  fEventNumber=-1;
+  fEventCounter = -1;
+  fDDLID = -1;
+  fLastDDLID = -1;
 }
-
-Bool_t AliITSRawStreamSPD::ReadCalibHeader()
-{
+//__________________________________________________________________________
+Bool_t AliITSRawStreamSPD::ReadCalibHeader() {
   // read the extra calibration header
-  // returns kTRUE if the header is present and has length > 0
+  // returns kTRUE if the header is present and there is no problem reading it
 
   Int_t ddlID = fRawReader->GetDDLID();
   if (ddlID==-1) { // we may need to read one word to get the blockAttr
     if (!ReadNextShort()) return kFALSE;
     ddlID = fRawReader->GetDDLID();
   }
-  UChar_t attr = fRawReader->GetBlockAttributes();
+  // reset flags and counters
+  fEqPLBytesRead = 2;
+  fEqPLChipHeadersRead = 0;
+  fEqPLChipTrailersRead = 0;
+  fHeaderOrTrailerReadLast = kFALSE;
+  fFillOutOfSynch = kFALSE;
+
+  // check what number of chip headers/trailers to expect
+  fExpectedHeaderTrailerCount = 0;
+  for (UInt_t hs=0; hs<6; hs++) {
+    if (!fRawReader->TestBlockAttribute(hs)) fExpectedHeaderTrailerCount+=10;
+  }
+
   if (ddlID>=0 && ddlID<20) fCalHeadRead[ddlID]=kTRUE;
-  if ((attr & 0x40) == 0x40) { // is the header present?
+  if (fRawReader->TestBlockAttribute(6)) { // is the calib header present?
     if (ReadNextInt()) {
       // length of cal header:
       UInt_t calLen = fDataChar1+(fDataChar2<<8)+(fDataChar3<<16)+(fDataChar4<<24);
       if (calLen>kCalHeadLenMax) {
-       fRawReader->AddMajorErrorLog(kCalHeaderLengthErr,Form("Header length %d > max = %d",calLen,kCalHeadLenMax));
-       AliWarning(Form("Header length problem. %d > %d (max)",calLen,kCalHeadLenMax));
+       TString errMess = Form("Header length %d > max = %d",calLen,kCalHeadLenMax);
+       AliError(errMess.Data());
+       fRawReader->AddMajorErrorLog(kCalHeaderLengthErr,errMess.Data());
+       if (fAdvancedErrorLog) fAdvLogger->ProcessError(kCalHeaderLengthErr,ddlID,-1,-1,errMess.Data());
        return kFALSE;
       }
-      else if (calLen>0) {
+      else {
        for (UInt_t iword=0; iword<calLen; iword++) {
          if (ReadNextInt()) {
            fCalHeadWord[iword] = fDataChar1+(fDataChar2<<8)+(fDataChar3<<16)+(fDataChar4<<24);
          }
          else {
-           fRawReader->AddMajorErrorLog(kCalHeaderLengthErr,"header length problem");
-           AliWarning("header length problem");
+           TString errMess = "Header length problem";
+           AliError(errMess.Data());
+           fRawReader->AddMajorErrorLog(kCalHeaderLengthErr,errMess.Data());
+           if (fAdvancedErrorLog) fAdvLogger->ProcessError(kCalHeaderLengthErr,ddlID,-1,-1,errMess.Data());
            return kFALSE;
          }
        }
@@ -161,104 +200,207 @@ Bool_t AliITSRawStreamSPD::ReadCalibHeader()
 
   return kFALSE;
 }
-
-Bool_t AliITSRawStreamSPD::Next()
-{
+//__________________________________________________________________________
+Bool_t AliITSRawStreamSPD::Next() {
 // read the next raw digit
 // returns kFALSE if there is no digit left
 
-  Int_t ddlID=-1;
   fPrevModuleID = fModuleID;
 
   while (ReadNextShort()) {
 
-    ddlID = fRawReader->GetDDLID();
-    if (ddlID>=0 && ddlID<20) {
-      if (!fCalHeadRead[ddlID]) {
-       ReadCalibHeader();
+    fLastDDLID = fDDLID;
+    fDDLID = fRawReader->GetDDLID();
+    if (fDDLID>=0 && fDDLID<20) {
+      if (!fCalHeadRead[fDDLID]) {
+       if (fLastDDLID!=-1) {  // if not the first equipment for this event
+         fEqPLBytesRead -= 2;
+         CheckHeaderAndTrailerCount(fLastDDLID);
+       }
+       if (ReadCalibHeader()) continue;
       }
     }
     else {
-      fRawReader->AddMajorErrorLog(kDDLNumberErr,Form("Wrong DDL number %d",ddlID)); 
-      AliWarning(Form("DDL number error (= %d) , setting it to 19", ddlID));
-      ddlID=19;
+      TString errMess = Form("Error in DDL number (=%d) , setting it to 19",fDDLID);
+      AliError(errMess.Data());
+      fRawReader->AddMajorErrorLog(kDDLNumberErr,errMess.Data()); 
+      if (fAdvancedErrorLog) fAdvLogger->AddMessage(errMess.Data());
+      fDDLID=19;
     }
 
     if ((fData & 0xC000) == 0x4000) {         // header
+      if (fHeaderOrTrailerReadLast) {
+       TString errMess = "Chip trailer missing";
+       AliError(errMess.Data());
+       fRawReader->AddMajorErrorLog(kTrailerMissingErr,errMess.Data());
+       if (fAdvancedErrorLog) fAdvLogger->ProcessError(kTrailerMissingErr,fLastDDLID,fEqPLBytesRead,fEqPLChipHeadersRead,errMess.Data());
+      }
+      fHeaderOrTrailerReadLast = kTRUE;
+      fEqPLChipHeadersRead++;
       fHitCount = 0;
-      UShort_t eventNumber = (fData >> 4) & 0x007F;
-      if (fEventNumber < 0) {
-       fEventNumber = eventNumber;
+      UShort_t eventCounter = (fData >> 4) & 0x007F;
+      if (fEventCounter < 0) {
+       fEventCounter = eventCounter;
       } 
-      else if (eventNumber != fEventNumber) {
-       fRawReader->AddMajorErrorLog(kEventNumberErr,Form("Reading event number %d instead of %d",eventNumber,fEventNumber));
-       AliWarning(Form("mismatching event numbers: %d != %d",eventNumber, fEventNumber));
+      else if (eventCounter != fEventCounter) {
+       TString errMess;
+       if (fEqPLChipHeadersRead==1) {
+         errMess = Form("Mismatching event counters between this equipment and the previous: %d != %d",
+                        eventCounter,fEventCounter);
+       }
+       else {
+         errMess = Form("Mismatching event counters between this chip header and the previous: %d != %d",
+                        eventCounter,fEventCounter);
+       }
+       fEventCounter = eventCounter;
+       AliError(errMess.Data());
+       fRawReader->AddMajorErrorLog(kEventCounterErr,errMess.Data());
+       if (fAdvancedErrorLog) fAdvLogger->ProcessError(kEventCounterErr,fDDLID,fEqPLBytesRead,fEqPLChipHeadersRead,errMess.Data());
       }
       fChipAddr = fData & 0x000F;
       if (fChipAddr>9) {
-       fRawReader->AddMajorErrorLog(kChipAddrErr,Form("Overflow chip address %d - set to 9",fChipAddr));
-       AliWarning(Form("overflow chip addr (= %d) , setting it to 9", fChipAddr));
-       fChipAddr=9;
+       TString errMess = Form("Overflow chip address %d - set to 0",fChipAddr);
+       AliError(errMess.Data());
+       fRawReader->AddMajorErrorLog(kChipAddrErr,errMess.Data());
+       if (fAdvancedErrorLog) fAdvLogger->ProcessError(kChipAddrErr,fDDLID,fEqPLBytesRead,fEqPLChipHeadersRead,errMess.Data());
+       fChipAddr=0;
       }
       fHalfStaveNr = (fData & 0x3800)>>11;
       if (fHalfStaveNr>5 || fRawReader->TestBlockAttribute(fHalfStaveNr)) {
-       fRawReader->AddMajorErrorLog(kStaveNumberErr,Form("Half stave number error %d - set to 5",fHalfStaveNr));
-       AliWarning(Form("half stave number error(=%d) , setting it to 5", fHalfStaveNr));
-       fHalfStaveNr=5;
+       TString errMess = Form("Half stave number error: %d - set to 0",fHalfStaveNr);
+       AliError(errMess.Data());
+       fRawReader->AddMajorErrorLog(kHSNumberErr,errMess.Data());
+       if (fAdvancedErrorLog) fAdvLogger->ProcessError(kHSNumberErr,fDDLID,fEqPLBytesRead,fEqPLChipHeadersRead,errMess.Data());
+       fHalfStaveNr=0;
       }
       // translate  ("online") ddl, hs, chip nr  to  ("offline") module id :
-      fModuleID = GetOfflineModuleFromOnline(ddlID,fHalfStaveNr,fChipAddr);
-      //      fOffset = 32 * (fChipAddr % 5);
+      fModuleID = GetOfflineModuleFromOnline(fDDLID,fHalfStaveNr,fChipAddr);
     } 
     else if ((fData & 0xC000) == 0x0000) {    // trailer
+      if ( (fEqPLBytesRead+fFillOutOfSynch*2)%4 != 0 ) {
+       TString errMess = "Fill word is missing";
+       AliError(errMess.Data());
+       fRawReader->AddMajorErrorLog(kFillMissingErr,errMess.Data());
+       if (fAdvancedErrorLog) fAdvLogger->ProcessError(kFillMissingErr,fDDLID,fEqPLBytesRead,fEqPLChipHeadersRead,errMess.Data());
+       if (fFillOutOfSynch) fFillOutOfSynch = kFALSE;
+       else fFillOutOfSynch = kTRUE;
+      }
+      if (!fHeaderOrTrailerReadLast) {
+       TString errMess = "Trailer without previous header";
+       AliError(errMess.Data());
+       fRawReader->AddMajorErrorLog(kTrailerWithoutHeaderErr,errMess.Data());
+       if (fAdvancedErrorLog) fAdvLogger->ProcessError(kTrailerWithoutHeaderErr,fLastDDLID,fEqPLBytesRead,fEqPLChipHeadersRead,errMess.Data());
+      }
+      fHeaderOrTrailerReadLast = kFALSE;
+      fEqPLChipTrailersRead++;
       UShort_t hitCount = fData & 0x1FFF;
       if (hitCount != fHitCount){
-       fRawReader->AddMajorErrorLog(kNumbHitsErr,Form("Number of hits %d instead of %d",hitCount,fHitCount));
-       AliWarning(Form("wrong number of hits: %d != %d", fHitCount, hitCount));
+       TString errMess = Form("Number of hits %d, while %d expected",fHitCount,hitCount);
+       AliError(errMess.Data());
+       fRawReader->AddMajorErrorLog(kNumberHitsErr,errMess.Data());
+       if (fAdvancedErrorLog) fAdvLogger->ProcessError(kNumberHitsErr,fDDLID,fEqPLBytesRead,fEqPLChipHeadersRead,errMess.Data());
       }
     }
     else if ((fData & 0xC000) == 0x8000) {    // pixel hit
+      if (!fHeaderOrTrailerReadLast) {
+       TString errMess = "Chip header missing";
+       AliError(errMess.Data());
+       fRawReader->AddMajorErrorLog(kHeaderMissingErr,errMess.Data());
+       if (fAdvancedErrorLog) fAdvLogger->ProcessError(kHeaderMissingErr,fDDLID,fEqPLBytesRead,fEqPLChipHeadersRead,errMess.Data());
+       fHeaderOrTrailerReadLast = kTRUE;
+      }
       fHitCount++;
       fCol = (fData & 0x001F);
       fRow = (fData >> 5) & 0x00FF;
 
-      fCoord1 = GetOfflineColFromOnline(ddlID,fHalfStaveNr,fChipAddr,fCol);
-      fCoord2 = GetOfflineRowFromOnline(ddlID,fHalfStaveNr,fChipAddr,fRow);
-
-      // translate  ("online") chipcol, chiprow  to  ("offline") col (coord1), row (coord2): 
-      // This will change, waiting for new geometry!!!
-      //      fCoord1 = fCol;
-      //      if      (fModuleID < 80 && ddlID < 10) fCoord1=31-fCoord1;
-      //      else if (fModuleID >=80 && ddlID >=10) fCoord1=31-fCoord1;
-      //      fCoord1 += fOffset;
-      //      if (ddlID>=10) fCoord1=159-fCoord1;
-      //      fCoord2 = fRow;
-      //      if (fModuleID<80) fCoord2=255-fCoord2;
+      fCoord1 = GetOfflineColFromOnline(fDDLID,fHalfStaveNr,fChipAddr,fCol);
+      fCoord2 = GetOfflineRowFromOnline(fDDLID,fHalfStaveNr,fChipAddr,fRow);
 
       return kTRUE;
     } 
     else {                                    // fill word
       if ((fData & 0xC000) != 0xC000) {
-       fRawReader->AddMajorErrorLog(kWrongWordErr,"Wrong fill word");
-       AliWarning("wrong fill word!");
+       TString errMess = "Wrong fill word!";
+       AliError(errMess.Data());
+       fRawReader->AddMajorErrorLog(kWrongFillWordErr,errMess.Data());
+       if (fAdvancedErrorLog) fAdvLogger->ProcessError(kWrongFillWordErr,fDDLID,fEqPLBytesRead,fEqPLChipHeadersRead,errMess.Data());
+      }
+      if ( (fEqPLBytesRead+fFillOutOfSynch*2)%4 != 2 ) {
+       TString errMess = "Fill word is unexpected";
+       AliError(errMess.Data());
+       fRawReader->AddMajorErrorLog(kFillUnexpectErr,errMess.Data());
+       if (fAdvancedErrorLog) fAdvLogger->ProcessError(kFillUnexpectErr,fDDLID,fEqPLBytesRead,fEqPLChipHeadersRead,errMess.Data());
+       if (fFillOutOfSynch) fFillOutOfSynch = kFALSE;
+       else fFillOutOfSynch = kTRUE;
       }
     }
 
   }
-
+  if (fDDLID>=0 && fDDLID<20) {
+    CheckHeaderAndTrailerCount(fDDLID);
+  }
   return kFALSE;
 }
+//__________________________________________________________________________
+void AliITSRawStreamSPD::CheckHeaderAndTrailerCount(Int_t ddlID) {
+  // Checks that the number of header and trailers found for the ddl are as expected
+  if (fEqPLChipHeadersRead != fExpectedHeaderTrailerCount) {
+    TString errMess = Form("Chip header count inconsistent %d != %d (expected) for ddl %d",
+                          fEqPLChipHeadersRead,fExpectedHeaderTrailerCount,ddlID);
+    AliError(errMess.Data());
+    fRawReader->AddMajorErrorLog(kHeaderCountErr,errMess.Data());
+    if (fAdvancedErrorLog) fAdvLogger->ProcessError(kHeaderCountErr,ddlID,-1,-1,errMess.Data());
+  }
+  if (fEqPLChipTrailersRead != fExpectedHeaderTrailerCount) {
+    TString errMess = Form("Chip trailer count inconsistent %d != %d (expected) for ddl %d",
+                          fEqPLChipTrailersRead,fExpectedHeaderTrailerCount,ddlID);
+    AliError(errMess.Data());
+    fRawReader->AddMajorErrorLog(kHeaderCountErr,errMess.Data());
+    if (fAdvancedErrorLog) fAdvLogger->ProcessError(kHeaderCountErr,ddlID,-1,-1,errMess.Data());
+  }
+}
+//__________________________________________________________________________
+void AliITSRawStreamSPD::ActivateAdvancedErrorLog(Bool_t activate, AliITSRawStreamSPDErrorLog* advLogger) {
+  // Activate the advanced error logging.
+  // Logger object has to be created elsewhere and a pointer sent here.
+  fAdvancedErrorLog=activate;
+  if (activate && advLogger!=NULL) {
+    fAdvLogger = advLogger;
+  }
+  if (fAdvLogger==NULL) {
+    fAdvancedErrorLog=kFALSE;
+  }
+}
+//__________________________________________________________________________
+const Char_t* AliITSRawStreamSPD::GetErrorName(UInt_t errorCode) {
+  // Returns a string for each error code
+  if      (errorCode==kTotal)                   return "All Errors";
+  else if (errorCode==kHeaderMissingErr)        return "Header Missing";
+  else if (errorCode==kTrailerMissingErr)       return "Trailer Missing";
+  else if (errorCode==kTrailerWithoutHeaderErr) return "Trailer Unexpected";
+  else if (errorCode==kHeaderCountErr)          return "Header Count Wrong";
+  else if (errorCode==kTrailerCountErr)         return "Trailer Count Wrong";
+  else if (errorCode==kFillUnexpectErr)         return "Fill Unexpected";
+  else if (errorCode==kFillMissingErr)          return "Fill Missing";
+  else if (errorCode==kWrongFillWordErr)        return "Fill Word Wrong";
+  else if (errorCode==kNumberHitsErr)           return "Hit Count Wrong";
+  else if (errorCode==kEventCounterErr)         return "Event Counter Error";
+  else if (errorCode==kDDLNumberErr)            return "DDL Number Error";
+  else if (errorCode==kHSNumberErr)             return "HS Number Error";
+  else if (errorCode==kChipAddrErr)             return "Chip Address Error";
+  else if (errorCode==kCalHeaderLengthErr)      return "Calib Header Length Error";
+  else return "";
+}
+//__________________________________________________________________________
 Bool_t AliITSRawStreamSPD::GetHalfStavePresent(UInt_t hs) {
   // Reads the half stave present status from the block attributes
   Int_t ddlID = fRawReader->GetDDLID();
   if (ddlID==-1) {
-    fRawReader->AddMinorErrorLog(kHalfStaveStatusErr,"DDL ID = -1. Cannot read block attributes.");
     AliWarning("DDL ID = -1. Cannot read block attributes. Return kFALSE.");
     return kFALSE;
   }
   else {
     if (hs>=6) {
-      fRawReader->AddMinorErrorLog(kHalfStaveStatusErr,Form( "HS >= 6 requested (%d). Return kFALSE.",hs));
       AliWarning(Form("HS >= 6 requested (%d). Return kFALSE.",hs));
       return kFALSE;
     }
@@ -271,7 +413,7 @@ Bool_t AliITSRawStreamSPD::GetHalfStavePresent(UInt_t hs) {
     }
   }
 }
-
+//__________________________________________________________________________
 Bool_t AliITSRawStreamSPD::GetHhalfStaveScanned(UInt_t hs) const {
   if (hs<6) return (Bool_t)((fCalHeadWord[0]>>(6+hs)) & (0x00000001));
   else return kFALSE;
@@ -296,18 +438,12 @@ Bool_t AliITSRawStreamSPD::GetHminTHchipPresent(UInt_t chip) const {
   if (chip<10) return ((( fCalHeadWord[7]>>(16+chip)) & 0x00000001) == 1);
   else return kFALSE;
 }
-
-
-
-
+//__________________________________________________________________________
 Int_t AliITSRawStreamSPD::GetModuleNumber(UInt_t iDDL, UInt_t iModule) {
   if (iDDL<20 && iModule<12) return fgkDDLModuleMap[iDDL][iModule];
   else return 240;
 }
-
-
-
-
+//__________________________________________________________________________
 Bool_t AliITSRawStreamSPD::OfflineToOnline(UInt_t module, UInt_t colM, UInt_t rowM, UInt_t& eq, UInt_t& hs, UInt_t& chip, UInt_t& col, UInt_t& row) {
   // converts offline coordinates to online
   eq = GetOnlineEqIdFromOffline(module);
@@ -318,8 +454,7 @@ Bool_t AliITSRawStreamSPD::OfflineToOnline(UInt_t module, UInt_t colM, UInt_t ro
   if (eq>=20 || hs>=6 || chip>=10 || col>=32 || row>=256) return kFALSE;
   else return kTRUE;
 }
-
-
+//__________________________________________________________________________
 Bool_t AliITSRawStreamSPD::OnlineToOffline(UInt_t eq, UInt_t hs, UInt_t chip, UInt_t col, UInt_t row, UInt_t& module, UInt_t& colM, UInt_t& rowM) {
   // converts online coordinates to offline
   module = GetOfflineModuleFromOnline(eq,hs,chip);
@@ -328,8 +463,7 @@ Bool_t AliITSRawStreamSPD::OnlineToOffline(UInt_t eq, UInt_t hs, UInt_t chip, UI
   if (module>=240 || colM>=160 || rowM>=256) return kFALSE;
   else return kTRUE;
 }
-
-
+//__________________________________________________________________________
 UInt_t AliITSRawStreamSPD::GetOnlineEqIdFromOffline(UInt_t module) {
   // offline->online (eq)
   for (UInt_t eqId=0; eqId<20; eqId++) {
@@ -339,7 +473,7 @@ UInt_t AliITSRawStreamSPD::GetOnlineEqIdFromOffline(UInt_t module) {
   }
   return 20; // error
 }
-
+//__________________________________________________________________________
 UInt_t AliITSRawStreamSPD::GetOnlineHSFromOffline(UInt_t module) {
   // offline->online (hs)
   for (UInt_t eqId=0; eqId<20; eqId++) {
@@ -349,7 +483,7 @@ UInt_t AliITSRawStreamSPD::GetOnlineHSFromOffline(UInt_t module) {
   }
   return 6; // error
 }
-
+//__________________________________________________________________________
 UInt_t AliITSRawStreamSPD::GetOnlineChipFromOffline(UInt_t module, UInt_t colM) {
   // offline->online (chip)
   for (UInt_t eq=0; eq<20; eq++) {
@@ -366,7 +500,7 @@ UInt_t AliITSRawStreamSPD::GetOnlineChipFromOffline(UInt_t module, UInt_t colM)
   }
   return 10; // error
 }
-
+//__________________________________________________________________________
 UInt_t AliITSRawStreamSPD::GetOnlineColFromOffline(UInt_t module, UInt_t colM) {
   // offline->online (col)
   if (module<80) { // inner layer
@@ -377,7 +511,7 @@ UInt_t AliITSRawStreamSPD::GetOnlineColFromOffline(UInt_t module, UInt_t colM) {
   }
   return 32; // error
 }
-
+//__________________________________________________________________________
 UInt_t AliITSRawStreamSPD::GetOnlineRowFromOffline(UInt_t module, UInt_t rowM) {
   // offline->online (row)
   if (module<80) { // inner layer
@@ -388,17 +522,13 @@ UInt_t AliITSRawStreamSPD::GetOnlineRowFromOffline(UInt_t module, UInt_t rowM) {
   }
   return 256; // error
 }
-
-
-
-
-
+//__________________________________________________________________________
 UInt_t AliITSRawStreamSPD::GetOfflineModuleFromOnline(UInt_t eqId, UInt_t hs, UInt_t chip) {
   // online->offline (module)
   if (eqId<20 && hs<6 && chip<10) return fgkDDLModuleMap[eqId][hs*2+chip/5];
   else return 240;
 }
-
+//__________________________________________________________________________
 UInt_t AliITSRawStreamSPD::GetOfflineColFromOnline(UInt_t eqId, UInt_t hs, UInt_t chip, UInt_t col) {
   // online->offline (col)
   if (eqId>=20 || hs>=6 || chip>=10 || col>=32) return 160; // error
@@ -420,7 +550,7 @@ UInt_t AliITSRawStreamSPD::GetOfflineColFromOnline(UInt_t eqId, UInt_t hs, UInt_
     }
   }
 }
-
+//__________________________________________________________________________
 UInt_t AliITSRawStreamSPD::GetOfflineRowFromOnline(UInt_t eqId, UInt_t hs, UInt_t chip, UInt_t row) {
   // online->offline (row)
   if (eqId>=20 || hs>=6 || chip>=10 || row>=256) return 256; // error
@@ -431,3 +561,7 @@ UInt_t AliITSRawStreamSPD::GetOfflineRowFromOnline(UInt_t eqId, UInt_t hs, UInt_
     return 255-row;
   }
 }
+
+
+
+
index d9215eee91306e0c847bf81e5f0f1dcdba0663aa..4d6d7b0ddfe5305a3d1baaec8fd6a2e832d99b30 100644 (file)
@@ -85,6 +85,7 @@
 #pragma link C++ class AliITSRawStreamSSD+;
 #pragma link C++ class AliITSRawStreamSSDv1+;
 #pragma link C++ class AliITSEventHeader+;
+#pragma link C++ class AliITSRawStreamSPDErrorLog+;
 
 
 
index d6a927d6218b764e3163a6eec0c632deb142b6bf..527c8ce1bd463c018f423ac0760781c15c37851a 100644 (file)
@@ -52,6 +52,7 @@ SRCS =        AliITSgeom.cxx \
                AliITSgeomTGeo.cxx \
                AliITSPlaneEff.cxx \
                AliITSPlaneEffSPD.cxx \
+               AliITSRawStreamSPDErrorLog.cxx
 
 HDRS:=  $(SRCS:.cxx=.h)