From: hristov Date: Fri, 7 Dec 2007 18:57:33 +0000 (+0000) Subject: New class that is used by SPD-MOOD to retrieve information on consistency errors... X-Git-Url: http://git.uio.no/git/?p=u%2Fmrichter%2FAliRoot.git;a=commitdiff_plain;h=10bb1a340b9a985893ffb16fd124531aff100cfc New class that is used by SPD-MOOD to retrieve information on consistency errors from AliITSRawStreamSPD (Henrik) --- diff --git a/ITS/AliITSRawStreamSPDErrorLog.cxx b/ITS/AliITSRawStreamSPDErrorLog.cxx new file mode 100644 index 00000000000..af3bd7dc8e9 --- /dev/null +++ b/ITS/AliITSRawStreamSPDErrorLog.cxx @@ -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; errDeleteHistograms(); + + for (UInt_t eq=0; eq<20; eq++) { + for (UInt_t err=0; errSetXTitle("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; errSetXTitle("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; errClear(); + 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; errReset(); + } + } +} +//________________________________________________________________________________________________ +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; errFill(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; errGetBinContent(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 (errorCodeGetBinContent(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 (errorCodeClone()); + 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 +#include +#include +#include + +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 diff --git a/ITS/AliITSRawStreamSPD_NEWGEO.cxx b/ITS/AliITSRawStreamSPD_NEWGEO.cxx index 16cb686ac8d..f51680178cc 100644 --- a/ITS/AliITSRawStreamSPD_NEWGEO.cxx +++ b/ITS/AliITSRawStreamSPD_NEWGEO.cxx @@ -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; iwordAddMajorErrorLog(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; } } + + + + diff --git a/ITS/ITSbaseLinkDef.h b/ITS/ITSbaseLinkDef.h index d9215eee913..4d6d7b0ddfe 100644 --- a/ITS/ITSbaseLinkDef.h +++ b/ITS/ITSbaseLinkDef.h @@ -85,6 +85,7 @@ #pragma link C++ class AliITSRawStreamSSD+; #pragma link C++ class AliITSRawStreamSSDv1+; #pragma link C++ class AliITSEventHeader+; +#pragma link C++ class AliITSRawStreamSPDErrorLog+; diff --git a/ITS/libITSbase.pkg b/ITS/libITSbase.pkg index d6a927d6218..527c8ce1bd4 100644 --- a/ITS/libITSbase.pkg +++ b/ITS/libITSbase.pkg @@ -52,6 +52,7 @@ SRCS = AliITSgeom.cxx \ AliITSgeomTGeo.cxx \ AliITSPlaneEff.cxx \ AliITSPlaneEffSPD.cxx \ + AliITSRawStreamSPDErrorLog.cxx HDRS:= $(SRCS:.cxx=.h)