--- /dev/null
+///////////////////////////////////////////////////////////////////////
+// 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;
+ }
+}
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},
{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");
}
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);
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) {
}
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;
}
}
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;
}
}
}
}
-
+//__________________________________________________________________________
Bool_t AliITSRawStreamSPD::GetHhalfStaveScanned(UInt_t hs) const {
if (hs<6) return (Bool_t)((fCalHeadWord[0]>>(6+hs)) & (0x00000001));
else return kFALSE;
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);
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);
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++) {
}
return 20; // error
}
-
+//__________________________________________________________________________
UInt_t AliITSRawStreamSPD::GetOnlineHSFromOffline(UInt_t module) {
// offline->online (hs)
for (UInt_t eqId=0; eqId<20; eqId++) {
}
return 6; // error
}
-
+//__________________________________________________________________________
UInt_t AliITSRawStreamSPD::GetOnlineChipFromOffline(UInt_t module, UInt_t colM) {
// offline->online (chip)
for (UInt_t eq=0; eq<20; eq++) {
}
return 10; // error
}
-
+//__________________________________________________________________________
UInt_t AliITSRawStreamSPD::GetOnlineColFromOffline(UInt_t module, UInt_t colM) {
// offline->online (col)
if (module<80) { // inner layer
}
return 32; // error
}
-
+//__________________________________________________________________________
UInt_t AliITSRawStreamSPD::GetOnlineRowFromOffline(UInt_t module, UInt_t rowM) {
// offline->online (row)
if (module<80) { // inner layer
}
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
}
}
}
-
+//__________________________________________________________________________
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
return 255-row;
}
}
+
+
+
+