// File: $RCSfile: hmdcunpacker.cc,v $ // // Author (previous Co-Author) Peter Zumbruch // old Author: Walter Karig // // Version: $Revision: 1.83 $ // Modified by $Author: wuestenf $ on $Date: 2008-09-26 11:41:01 $ //_HADES_CLASS_DESCRIPTION //////////////////////////////////////////////////////////// // // HMdcUnpacker // // Unpacker for mdc data // decodes the raw list mode data and fills the HMdcRaw category // using information from the parameter containers HMdcEvReadout // and HMdcRawStruct. // For decoding the functions of HMdcDataWord are used. // Additionally the categories HMdcRawEventHeader and on purpose // the HMdcDataWord (not yet implemented) // // The constructor gives several (additional) options // when being called: // // HMdcUnpacker( subEvtId, debug, consistency ) // HMdcUnpacker( subEvtId, version, debug, consistency) // // subEvtId : subevent Id for which this // Instance is called by the Hades::eventLoop() calls to // the HldSource and derived classes // // version : decoding version for the unpacker // // version = 1, used for data since 2002-10-01 12:00:00 // includes new naming scheme for the SAMs // version = 0, used for data before 2002-10-01 12:00:00 // // if not set in the constructor or via setDecodeVersion() // the decoding is derived from the referenceRunId (if set) // or the runId // // (reference)RunId < versionSwitchId : version 0 // (reference)RunId > versionSwitchId : version 1 // // debug : additional debug features of the Unpacker for debugging // the hardware // // debug = TRUE: // // 1) Errors/Warnings are extended by // detailed informations of the dataword // (if not switched of by setQuietMode()) // 2) HMdcRawEventHeader is written out for every call // of decodeSubHeader // of the Header (not only for not zero error // words in the sub header (ROC) // 3) HMdcDataWord is written to tree (not yet implemented) // persistency changeable with setPersistencyDataWord() // // debug = FALSE: (default) // // 1) Errors/Warnings are displayed in a reduced set // (if not completely switched of by setQuietMode()) // 2) HMdcRawEventHeader is only written out for a non zero error word // in the sub header (ROC) // // consistency: enables a rough border checking on the hardware level // on the data words while decoding. // this is actually a feature of HMdcDataWord::decode() HMdcDataWord::subheader() // which is called during execute(). // // //////////////////////////////////////////////////////////// #include "hades.h" #include "hcategory.h" #include "hdatasource.h" #include "hiterator.h" #include "hldsubevt.h" #include "hevent.h" #include "hmdcraw.h" #include "hmdcrawstruct.h" #include "hspectrometer.h" #include "hmdcdetector.h" #include "hruntimedb.h" #include "heventheader.h" #include "hmdcdef.h" #include "TSystem.h" #include "hmdcdataword.h" #include "hmdcevreadout.h" #include "hmdcraweventheader.h" #include "hmdcunpacker.h" #include "hmessagemgr.h" ClassImp(HMdcUnpacker) HMdcDataWord *HMdcUnpacker::dataword=0; Bool_t HMdcUnpacker::noComment=kFALSE; const TString HMdcUnpacker::excludeBlackListContextDefaultString="undefined exclude black list context"; const TString HMdcUnpacker::recoverBlackListContextDefaultString="undefined recover black list context"; HMdcUnpacker::HMdcUnpacker(Int_t id , Bool_t dbg, Bool_t consisCheck) : HldUnpack() { // id = sub event id for which the unpacker is called by subEvtId = id; dataword = new HMdcDataWord(); debug=dbg; consistencyCheck=consisCheck; setDefaults(); } // ---------------------------------------------------------------------------------------------------- HMdcUnpacker::HMdcUnpacker(Int_t id, Int_t myversion, Bool_t dbg, Bool_t consisCheck) { HMdcUnpacker(id, dbg, consisCheck); setDecodeVersion(myversion); } // ---------------------------------------------------------------------------------------------------- HMdcUnpacker::HMdcUnpacker(HMdcUnpacker& mdc) { subEvtId = mdc.subEvtId; dataword = mdc.dataword; debug = mdc.debug; consistencyCheck = mdc.consistencyCheck; setDefaults(); setDecodeVersion(mdc.getDecodeVersion()); } // ---------------------------------------------------------------------------------------------------- HMdcUnpacker::~HMdcUnpacker() { if(dataword) delete dataword; dataword=0; if (excludeBlackListMask) delete[] excludeBlackListMask ; if (excludeBlackListAdress) delete[] excludeBlackListAdress; if (excludedBlackListCounters) delete[] excludedBlackListCounters; if (recoverBlackListMask) delete[] recoverBlackListMask ; if (recoverBlackListAdress) delete[] recoverBlackListAdress; if (recoveredBlackListCounters) delete[] recoveredBlackListCounters; } // ---------------------------------------------------------------------------------------------------- void HMdcUnpacker::setDefaults(void) { // set the default values for all intrinsic variables // called by the constructor pReadout = NULL; standalone=kFALSE; tdcMode=0; pMdcRawEventHeaderCat=0; disableSamNrConsistencyCheck=kFALSE; mdcRawEventHeaderCatPersistency=kFALSE; mdcDataWordCatPersistency=kFALSE; fillDataWord=kFALSE; subHeaderDecodeVersion=0; maxDecodeVersion=1; setDecodeVersion(1,kFALSE); unpackerDebug=kFALSE; rocEvtHeaderSize = UNCOMPRESSED_ROC_HEADERSIZE; noComment=kFALSE; for(Int_t s=0; s<6; s++) { for(Int_t m=0; m<4; m++) { setup[s][m]=0; } } rawc=NULL; pRawCat = NULL; pMdcRawEventHeaderCat = NULL; pMdcDataWordCat = NULL; continueDecodingAfterInconsistency=kFALSE; excludeBlackList=kFALSE; excludedBlackListCounters=NULL; excludeBlackListMask=NULL; excludeBlackListAdress=NULL; excludeBlackListContext=excludeBlackListContextDefaultString; excludeBlackListSize = 0; recoverBlackList=kFALSE; recoveredBlackListCounters=NULL; recoverBlackListMask=NULL; recoverBlackListAdress=NULL; recoverBlackListContext=recoverBlackListContextDefaultString; recoveryStorage = NULL; recoveryStorageCounter = 0; recoverBlackListSize = 0; createBlackListRecoveryTools=0; } // ---------------------------------------------------------------------------------------------------- Bool_t HMdcUnpacker::getQuietMode() { // get status of quietMode // quiet = kTRUE : messaging switch off // = kFALSE: messages are displayed return noComment; } // ---------------------------------------------------------------------------------------------------- void HMdcUnpacker::setQuietMode(Bool_t quiet) { // switch to disable all error messages and warnings from hmdcunpacker AND hmdcdataword // quiet = kTRUE : messaging switch of // = kFALSE: messages are displayed noComment = quiet; dataword->setQuietMode(quiet); if (quiet) warningSetQuietMode(); } // ---------------------------------------------------------------------------------------------------- void HMdcUnpacker::setContinueDecodingAfterInconsistency(Bool_t cont) { // this function is only for debugging use! // the decoding of the data words continue even if there is // unconsistency in the datawords // cont = kTRUE : continue // cont = kFALSE: skip event continueDecodingAfterInconsistency=cont; } // ---------------------------------------------------------------------------------------------------- UInt_t HMdcUnpacker::getDecodeVersion(void) { // returns decoding version of the unpacker // // version : decoding version for the unpacker // // version = 1, used for data since 2002-10-01 12:00:00 // includes new naming scheme for the SAMs // version = 0, used for data before 2002-10-01 12:00:00 // return decodeVersion; } // ---------------------------------------------------------------------------------------------------- void HMdcUnpacker::setDecodeVersion(UInt_t version,Bool_t manual) { // set decoding version of the unpacker // // version : decoding version for the unpacker // // version = 1, used for data since 2002-10-01 12:00:00 // includes new naming scheme for the SAMs // version = 0, used for data before 2002-10-01 12:00:00 // // manual : used for internal calls // // if version exceeds the value of maxDecodeVersion exit is called if (version>maxDecodeVersion || version < 0) { errorAndExitSetDecodeVersion(version); } else { decodeVersion=version; versionSetManual=manual; } } // ---------------------------------------------------------------------------------------------------- Int_t HMdcUnpacker::getTdcMode(void) { // returns mode the tdc is triggering on signals // mode 0 (default) : trigger on leading and trailing edge // mode 1 : trigger on 2 leading edges: return tdcMode; } // ---------------------------------------------------------------------------------------------------- void HMdcUnpacker::setTdcMode(Int_t i) { // In measurement mode the TDC accepts two hits per channel. The TDC can hereby // trigger either on on a leading and the trailing edge of a single pulse // or on two leading edges. // This influences the polarity of the hitCounter in the HMdcRaw Class: // mode 0 : trigger on leading and trailing edge // (hit multiplicity nHits: +1 or +2) // mode 1 : trigger on 2 leading edges: // (hit multiplicity nHits: -1 or -2) // (0 default if i is not equal to 0 or 1) tdcMode=(i == 0 || i == 1)? i : 0; return; } // ---------------------------------------------------------------------------------------------------- void HMdcUnpacker::setRocEvtHeaderSize(UInt_t ui) { // function to set the size in words of the ROC Header rocEvtHeaderSize=ui; } // ---------------------------------------------------------------------------------------------------- TString HMdcUnpacker::myexec(Char_t * in) { // tool to execute an arbitray unix command // the output is returned as an Char_t pointer (maximum size 1000) // TODO: check whether PTools::myexec or other method can replace it Char_t textfile[1000]; FILE *pipe = gSystem->OpenPipe(in,"r"); fscanf(pipe,"%s",textfile); gSystem->ClosePipe(pipe); return TString(textfile); } // ---------------------------------------------------------------------------------------------------- void HMdcUnpacker::print(TString parent) { // prints out the variables of the unpacker object Info(parent.Data(),"############################################################"); Info(parent.Data(),"HMdcUnpacker: ClassName %s :",this->ClassName()); Info(parent.Data(),"%s: %p ClassName %s","HMdcEvReadout",pReadout,(pReadout)?pReadout->ClassName():"---"); //!Lookup up table Info(parent.Data(),"%s: %3i ","sub event Id",subEvtId); Info(parent.Data(),"%s: %i","TdcMode",tdcMode); Info(parent.Data(),"%s: %s","debug",(debug)?"kTRUE":"kFALSE"); Info(parent.Data(),"%s: %s","consistencyCheck",(consistencyCheck)?"kTRUE":"kFALSE"); Info(parent.Data(),"%s: %s","disableSamNrConsistencyCheck",(disableSamNrConsistencyCheck)?"kTRUE":"kFALSE"); Info(parent.Data(),"%s: %s","mdcRawEventHeaderCatPersistency",(mdcRawEventHeaderCatPersistency)?"kTRUE":"kFALSE"); Info(parent.Data(),"%s: %s","mdcDataWordCatPersistency",(mdcDataWordCatPersistency)?"kTRUE":"kFALSE"); Info(parent.Data(),"%s: %s","fillDataWord",(fillDataWord)?"kTRUE":"kFALSE"); Info(parent.Data(),"%s: %s","standalone",standalone?"kTRUE":"kFALSE"); Info(parent.Data(),"%s: %3i ","decodeVersion",decodeVersion); Info(parent.Data(),"%s: %2i ","subHeaderDecodeVersion",subHeaderDecodeVersion); Info(parent.Data(),"%s: %10i ","versionSwitchId (RunId) from which on to use version 1",versionSwitchId); Info(parent.Data(),"%s: %3i ","ROC headerSize",rocEvtHeaderSize); }; // ---------------------------------------------------------------------------------------------------- // ---------------------------------------------------------------------------------------------------- // init Bool_t HMdcUnpacker::init() { // Initialisation of // - lookup table // - category for raw-level storage // - additional category if debug option // - additional Tree if debug option // - local mdc setup table for lookup // get Setup informations of Mdcs getMdcSetup(); pRawCat = NULL; // get pointer to runtime data base HRuntimeDb *rtdb = gHades->getRuntimeDb(); // get parameter containers: // -- MdcRawStruct rawc = (HMdcRawStruct*) rtdb->getContainer("MdcRawStruct"); if (!rawc) { errorInitCannotGetParameterContainer("MdcRawStruct"); return kFALSE; } // ---- Needs explicit initialization, if not yet done, i.e not yet set to static if (!rawc->isStatic()) ((HParSet*)rawc)->init(); // -- MdcEvReadout pReadout = (HMdcEvReadout*) rtdb->getContainer("MdcEvReadout"); if (!pReadout) { errorInitCannotGetParameterContainer("MdcEvReadout"); return kFALSE; } // exclude / recover black lists if (excludeBlackList) // feature up to now only used for beamtime sep05/apr06 { if (initExcludeBlackList() == EXIT_FAILURE) {exit(EXIT_FAILURE);} } if (recoverBlackList) // feature up to now only used for beamtime sep05/apr06 { if (initRecoverBlackList() == EXIT_FAILURE) {exit(EXIT_FAILURE);} } // initialize categories: // -- catMdcRaw if(!(pRawCat = initCategory(catMdcRaw, "catMdcRaw")) ){ return kFALSE; } // -- catMdcRaw catMdcRawEventHeader if(!(pMdcRawEventHeaderCat = initCategory(catMdcRawEventHeader,"catMdcRawEventHeader"))){ return kFALSE; } // -- MdcDataWord if (debug && fillDataWord) { if (!(pMdcDataWordCat = initCategory(catMdcDataWord, "catMdcDataWord")) ){ return kFALSE; }} // set persistencies: // -- RawEventHeader pMdcRawEventHeaderCat->setPersistency(mdcRawEventHeaderCatPersistency); // -- MdcDataWord if (debug && fillDataWord) { pMdcDataWordCat->setPersistency(mdcDataWordCatPersistency); } // end of init return kTRUE; } // ---------------------------------------------------------------------------------------------------- // init - helpers void HMdcUnpacker::getMdcSetup() { // gets Mdc detector setup // and initializes setup array HMdcDetector* mdcDet=(HMdcDetector*)(((HSpectrometer*)(gHades->getSetup()))->getDetector("Mdc")); if (!mdcDet) { errorAndExitGetMdcSetup(); } for(Int_t sector=0; sector<6; sector++) { for(Int_t module=0; module<4; module++) { setup[sector][module]=(mdcDet->getModule(sector, module)) ? 1:0; } } } // ---------------------------------------------------------------------------------------------------- HCategory* HMdcUnpacker::initCategory(Cat_t cat, TString catname, TString detector) { // inits the container cat // looks first whether it already exists // otherwise it is created // default for detector is "Mdc" // catname is used for Error handling HCategory * category = 0; category = (HCategory*)(((HEvent*)(gHades->getCurrentEvent()))->getCategory(cat)); if (!category) { category=(HCategory*)((HMdcDetector*)(((HSpectrometer*)(gHades->getSetup()))->getDetector(detector.Data()))->buildCategory(cat)); if (!category) { errorInitCategoryCannotGetCategory(catname); return NULL; } if (!((HEvent*)(gHades->getCurrentEvent()))->addCategory(cat,category,detector.Data())) { errorInitCategoryCannotAddCategory(catname,detector); return NULL; } } return category; } // ---------------------------------------------------------------------------------------------------- Int_t HMdcUnpacker::initExcludeBlackList(void) { // initializes list of black listed mask and adress matches to be exclude from data stream // beamtime sep2005 // number of sets: 1 // #0: missing mboNr in sector IV, module 4 // beamtime apr2006 // number of sets: 1 // #0: missing mboNr in sector IV, module 4 if ( !excludeBlackListContext.CompareTo("sep05") || !excludeBlackListContext.CompareTo("apr06") || !excludeBlackListContext.CompareTo("may06") ) { excludeBlackListSize=1; if (excludeBlackListSize) { excludeBlackListMask = new UInt_t[excludeBlackListSize]; excludeBlackListAdress = new UInt_t[excludeBlackListSize]; excludedBlackListCounters = new Int_t[excludeBlackListSize]; // list of masks excludeBlackListMask [0]=0xffe00000; // list of adresses excludeBlackListAdress[0]=0x2cc00000; for (Int_t arrayIndex=0; arrayIndexgetSamNumberToSector(samNr); if (sector < 0) { if(!noComment) warningExecuteNoValidSectorEntryInLookupTableForSamNr(samNr); return 1; } // -- valid sector entry in lookuptable for samNr Int_t module = pReadout->getSamNumberToModule(samNr); if (module < 0) { if(!noComment) warningExecuteNoValidModuleEntryInLookupTableForSamNr(samNr); return 1; } // if sector and module are in testMdcSetup // --> fill data if (testMdcSetup(sector, module)) { if (0 > fill()) { if(!noComment) errorExecuteErrorInFill(); return 1; } } return 1; } // ---------------------------------------------------------------------------------------------------- Bool_t HMdcUnpacker::testMdcSetup(Int_t sector, Int_t module) { // Tests the Mdc setup if the module are present // in the running analysis at position sector, module return (setup[sector][module]==1); } // ---------------------------------------------------------------------------------------------------- // ---------------------------------------------------------------------------------------------------- // execute helpers Int_t HMdcUnpacker::getSubEvtIdToSamNr(Int_t localSubEvtId, Bool_t expectUndefined) { // determines the samNr from the sub event id localSubEvtId // in addition it crosschecks the samNr with the DAQ specifications // and does boundary checks by default. // You can switch it off by setDisableSamNrConsistencyCheck() Int_t samNr; // determine samNr switch(decodeVersion) { case 0: samNr = 2*(localSubEvtId - 201); // version before Nov02 break; case 1: samNr = localSubEvtId - 201; // version since Nov02 break; default: samNr = -1; } // additional checks if (disableSamNrConsistencyCheck) { if (samNr < 0) return -1; return samNr; } // additional checks by default on !! switch(decodeVersion) { case 0: if (!(200 < localSubEvtId && localSubEvtId < 300)) { if(!noComment) errorGetSubEvtIdToSamNrSubEvtIdOutOfMdcRange(localSubEvtId, "]200,300["); return -1; } break; case 1: if (!(200 <= localSubEvtId && localSubEvtId < 300)) { if(!noComment) errorGetSubEvtIdToSamNrSubEvtIdOutOfMdcRange(localSubEvtId, "[200,300["); return -1; } break; default: samNr = -1; } Int_t rocSector = pReadout->getSamNumberToSector(samNr); if (rocSector==-1 && !expectUndefined) { if(!noComment) errorGetSubEvtIdToSamNrSamNrNotInLookupTable(localSubEvtId,samNr); return -1; } return samNr; } // ---------------------------------------------------------------------------------------------------- // ---------------------------------------------------------------------------------------------------- // filling Int_t HMdcUnpacker::fill() { // fill function: // performs the loop over the subevent data // // -- if the ROC header size > 0 (change it via setRocEvtHeaderSize()) // then the roc header is decoded via decodeSubHeader() // otherwise the whole subevent is decoded as once // // -- The data loop performs the following steps // 1.a. if enabled check for recoverable blacklisted adresses and store them // 1.b. if enabled check for further blacklisted adresses and ignore them // 2. call of decode for each dataword // 3. the hardware address is matched to the sector/module/mbo/tdc coordinates of HMdcRaw // via the lookup table HMdcEvReadout // 4. a new/existing slot at the corresponding address is requested // 5. the time information is filled to this slot // // -- if enabled recover recoverable datawords after the data loop // // -- if the debug and fillDataWord flag is set (set via setFillDataWord() and setDebug()) // the extended dataword information is written to the category HMdcDataword() // (the persistency of this container can be set via setPersistencyDataWord()) // // -- the return values of the function are: // 1 : success // -1 : Error while decoding the dataword // -1 : Error while decoding the roc header // -1 : Error while decoding the in data loop (data pointer exceeds data range) // -2 : Error while filling the to category HMdcRaw // // -- in the case that there is no entry in the lookup table // for a correctly decoded dataword there the next dataword is taken // // -------------------------------------------------------------------------- // DETAILS: // The single steps of this function are: // // 1. check for existing pointers to subEvt and pReadout // - if not // -> "goto" end of function returning 1 // // 2. if the decode version is not set manually (via setDecodeVersion()) // -> call determineDecodeVersion() // // 3. get subEvt's pointers to data and its end // // 4. check for positive difference (data-end > 0) // - if not // -> leave function with return code -1 // // 5. if decodingMode() returns kFALSE (DETAILS see decodingMode()) // -> leave function with return code -1 // // 6. if "recoverBlackList" is enabled // -> call prepareBlackListRecovery() // // 7. sub sub event while loop // // 7.1. determine end of subsub event loop from subsub event header // // 7.2. subsub event dataword loop // // 7.2.1. check whether subsub event endpointer exceeds sub event pointer // - yes: // -> skipping rest of sub event returning -1 // (incl. a possible correction of recoverable datawords) // -> exception: "ontinueAfterInconsistency" is enabled // -> continue with next dataword at 7.2 // // 7.2.2. if "recoverBlackList" is enabled // -> check if dataword matches the list criteria // - yes: // -> call storeForRecoveryFromBlackList() // and continue with next dataword at 7.2 // // 7.2.3. if "recoverBlackList" is enabled // -> check if dataword matches the list criteria // - yes: // -> continue with next dataword at 7.2 // // 7.2.4. dataword decoding // // * behaviour during the dataword decoding: // - if the consistency check is switched // - on // -> decode returns // - kFALSE if any of the border checks failed // - kTRUE else // - off // -> decode returns kTRUE // // - in case of an inconsistency: (kFALSE returned from decode with checkInconsistency switched on) // -> the decoding of all following datawords of this sub event is skipped // (including a possible correction of recoverable datawords) // the function returns -1 // -> exception: "continueDecodingAfterInconsistency" is enabled // - then, ignoring this maybe hazardous error (!!!), // decoding is continued with the next dataword at 7.2 // // - in case of errors and "noComment" disabled // -> error messages are issued // and if also unpackerDebug is enabled // -> the dataword is dumped to the screen // // 7.2.5. fill data to Raw categories calling fillData() // in case of failures of fillData(): // - adress, setup or matching table errors // -> continue with next dataword at 7.2 // - "cannot get Slot" (severe problems) // -> leave function returning -1 and skipping rest of sub event // (incl. possible recovery of datawords) // // 7.2.6. END OF subsub event dataword loop // // 7.3. increase data pointer by subsub event size // // 7.4. END OF sub event while loop // // 8. if recoverBlackList is enabled // -> call of executeBlackListRecovery() // - same return code behaviour as in 7.2.5 (fillData()) // // 9. leave function always returning 1 // // if pointer to sub event and lookup table exist ... if (pSubEvt && pReadout) { // if the decode version is not set by user, determine decode version if (!versionSetManual) determineDecodeVersion(); UInt_t* data = pSubEvt->getData(); UInt_t* end = pSubEvt->getEnd(); UInt_t subEvtSize = 0; UInt_t offset = 0; UInt_t *enddata = 0; Int_t diff = (end-data); if (diff<0) { // TODO errorFillNegativeSizeOfSubEvent() return -1; } UInt_t eventSize = ((diff))+1; // ---------- determine decoding mode --- affects rocEvtHeaderSize if (!decodingMode()) return -1; // TODO: missing comment rocEvtHeaderSize = getRocEvtHeaderSize(); // recovery preparations for black list recovery if (recoverBlackList) { prepareBlackListRecovery(eventSize); } // data loop while( data < end ) { dataword->clearAll(); //decoding sub-header (filling sub header information to dataword) if (rocEvtHeaderSize > 0) // data stream contains ROC headers { if (!decodeSubHeader(data,subEvtSize)) { if(!noComment) errorFillDecodeSubHeaderFailed(); return -1; } offset = subEvtSize + rocEvtHeaderSize; enddata = data+offset; } else // data stream does not contain ROC headers { enddata = end; } //decoding data words for(UInt_t* dataPointer=data+rocEvtHeaderSize; dataPointerclear(); dataword->clearHeader(); if (dataPointer > end) { if(!noComment) errorFillDataPointerExceedingRange(dataPointer,end,enddata); if (continueDecodingAfterInconsistency) continue; if(!noComment) errorFillSkippingRestOfSubEvent(); return -1; } // Is dataword included in an recovery black list? // TODO: recovery black list from oracle (->init section) // first masking then comparing to adress // if it matches this dataword is stored // until the end of the while loop and then processes if (recoverBlackList && (recoverBlackListSize >0)) { if (storeForRecoveryFromBlackList(dataPointer)) continue; } // Is dataword included in an excluding black list // ... and not yet skipped by recovery? // TODO: black list from oracle // first masking then comparing to adress // if it matches this dataword is ignored if (excludeBlackList && (excludeBlackListSize > 0)) { if (excludeBlackListData(dataPointer)) continue; } // >>>> here the decoding of the data word is done // // behaviour: // - if the consistency check is switched on then decode returns // - kFALSE if any of the border checks failed // - kTRUE else // - kTRUE // // in case of an inconsistency: (kFALSE returned from decode with checkInconsistency switched on) // - the decoding of all following datawords of this sub event is skipped // (including a possible correction of recoverable datawords) the function returns -1 // - except "continueDecodingAfterInconsistency" is enabled, // then ignoring this maybe hazardous error (!!!) decoding is continued with the next dataword // // in case of errors and "noComment" disabled // -> error messages are issued // and if also unpackerDebug is enabled // -> the dataword is dumped to the screen if(!dataword->decode(*dataPointer, decodeVersion,consistencyCheck)) { if(!noComment && unpackerDebug) dataword->dump(decodeVersion); if (continueDecodingAfterInconsistency) continue; if(!noComment) errorFillSkippingRestOfSubEvent(); return -1; } // fill data to HMdcRaw categories including all checks switch(fillData()) { case 0: break; case 1: continue; // case of failing checks on Setup and Boundaries case -2: return -2; // cannot get slot for HMdcRaw default: errorAndExitFillUnknownReturnValueOfFillData(); } } data += offset; } // recovery of corrupted data if(recoverBlackList && recoveryStorageCounter>0) { switch(executeBlackListRecovery()) { case 0: break; case -2: return -2; // cannot get slot for HMdcRaw default: errorAndExitFillUnknownReturnValueOfFillData(); } } } return 1; } // -------------------------------------------------------------------------------- // -------------------------------------------------------------------------------- // filling helpers void HMdcUnpacker::determineDecodeVersion(void) { // Begin_Html obsolete !!! End_Html // Begin_Html cannot be used any more since nov02, because the runId's are now End_Html // Begin_Html random numbers not containing any useful time information End_Html // Begin_Html you have to set the decode version manually with setDecodeVersion() End_Html // // method to determine from the referenceId/runId the time and so the valid version for decoding // see the discription in setDecodeVersion() // if (!versionSetManual) { determineDecodeVersionCtr++; if ( determineDecodeVersionCtr == 1) { switch(compareEventDateTimeTo(2002,10,1,12,0,0)) // 2002-10-01/12:00:00 { case 0: // "now" setDecodeVersion(1,kFALSE); break; case 1: // event before date setDecodeVersion(1,kFALSE); break; case -1: // event before date setDecodeVersion(0,kFALSE); break; default: errorAndExitDetermineDecodeVersion(); break; } if (unpackerDebug) {infoDetermineDecodeVersion();} } } } // ---------------------------------------------------------------------------------------------------- Int_t HMdcUnpacker::compareEventDateTimeTo(UInt_t cyear,UInt_t cmonth, UInt_t cday,UInt_t chour,UInt_t cmin,UInt_t csec) { // function to compare were the date and time of the event is relative to the given Time and Date // returns: // // 0 : time and date are the same // 1 : time and date of event are after the given time // -1 : time and date of event are before the given time HEventHeader * header = 0; header = ((HEvent*)(gHades->getCurrentEvent()))->getHeader(); if (header != 0) { Char_t command[1000]; sprintf(command,"date --date=\"%04i-%02i-%02i %02i:%02i:%02i\" +%%s",cyear,cmonth,cday,chour,cmin,csec); Int_t ctime = atoi((myexec(command)).Data()); UInt_t date = header->getDate(); UInt_t time = header->getTime(); UInt_t year = (date & 0xFF0000) >> 16; year = (year < 94)? year + 2000 : year + 1900; UInt_t month = ((date & 0xFF00) >> 8) + 1; UInt_t day = date & 0xFF; UInt_t hour = (time & 0xFF0000) >> 16; UInt_t min = (time & 0xFF00) >> 8; UInt_t sec = (time & 0xFF); if (unpackerDebug) Info("compareEventDateTimeTo()"," SubEvtId %i - time-stamp: %04i-%02i-%02i %02i:%02i:%02i", subEvtId,year,month,day,hour,min,sec); sprintf(command,"date --date=\"%04i-%02i-%02i %02i:%02i:%02i\" +%%s",year,month,day,hour,min,sec); Int_t evttime = atoi((myexec(command)).Data()); if (evttime == ctime) return 0; if (evttime >= ctime) return 1; if (evttime <= ctime) return -1; } else { errorAndExitCompareEventDateTimeTo(); } return -99; } // ---------------------------------------------------------------------------------------------------- Bool_t HMdcUnpacker::decodingMode(void) { // evaluates the decoding info in the sub event header // // dependent on the decoding information in the sub event header // the following modes are selected: // // the least significant byte of the decoding word determines the compression modes: // so decoding & f = // // 0 : not allowed by definition of the sub event header // // 1 : uncompressed structure // - the event contains a roc sub structure // - error bits and roc event sizes are determined from the roc headers // and filled independently to HMdcRawEventHeader // // 2 : compressed structure // - the only contains pure data words // - error informations are determined from // the second least significant byte // and assigned to all roc header synchronously // to HMdcRawEventHeader but shifted by 4 bits to the left (*16) // also the size of the complete sub event is assigned to each roc // to distinguish from the case they have a negativ sign. // // any other value: not defined Int_t rocSector = 0; Int_t rocModule = 0; UInt_t decoding = pSubEvt->getDecoding(); UInt_t compressMode = decoding & 0xf; UInt_t errorBits = decoding & 0xf0; // bits intentionally not shifted !!! switch(compressMode) { case UNCOMPRESSED: setRocEvtHeaderSize(UNCOMPRESSED_ROC_HEADERSIZE); return kTRUE; break; case COMPRESSED: setRocEvtHeaderSize(COMPRESSED_ROC_HEADERSIZE); if (errorBits!=0 || debug) { UInt_t size = pSubEvt->getSize(); UInt_t id = pSubEvt->getId() & 0x7fffffff; Int_t samNr = getSubEvtIdToSamNr(subEvtId); if (samNr != -1) { rocSector = pReadout->getSamNumberToSector(samNr); rocModule = pReadout->getSamNumberToModule(samNr); } else { rocSector = 0 - subEvtId; rocModule = 0 - subEvtId; } for (Int_t rocNumber=1; rocNumber<=5; rocNumber++) { fillMdcRawEventHeader(errorBits, rocModule, rocNumber, rocSector, 0-size, id); } } return kTRUE; break; default: if(!noComment) errorDecodingModeInvalidCompressMode(compressMode,decoding); break; } return kFALSE; } // ---------------------------------------------------------------------------------------------------- Bool_t HMdcUnpacker::decodeSubHeader(UInt_t *data, UInt_t &subEvtSize) { // decodes the sub header (ROC-Header) // and returns the size of this header // // If the errorFlag of the ROC-Header is set or // the debug flag of the unpacker is set // the header is written out to the category HMdcRawEventHeader // (set its persistency via, setPersistencyRawEventHeader()) // // If the standalone mode is chosen the trigger type (id) of the whole event // is set to the trigger type of the roc header if it is a calibration trigger // (If MDCs are not run via the common daq system, but in a standalone mode, // the event trig type is not provided in the event header (it is always 1).) Int_t errorFlag = 0; Int_t trigType = 0; Int_t rocNumber = 0; Int_t rocSector = 0; Int_t rocModule = 0; dataword->clearHeader(); if(!dataword->subHeader(data,subHeaderDecodeVersion,consistencyCheck)) { if(!noComment) errorDecodeSubHeaderCannotDecode(); return kFALSE; } rocNumber = dataword->getRocNb(); errorFlag = dataword->getErrorFlag(); trigType = dataword->getTrigType(); subEvtSize = dataword->getSubEvtSize(); // fill raw event header container if (errorFlag!=0 || debug) { fillMdcRawEventHeader(errorFlag, rocModule, rocNumber, rocSector, subEvtSize, trigType); } // if data was taken in "standalone" mode, // i.e. Trigger Tag is not contained in EventHeader // Then, in case of a calibration trigger, // the event Header Id is replaced by the trigger Type of the roc Header. if (standalone) { static const Int_t kMdc_Standalone_CalibrationEvent=9; if (trigType == kMdc_Standalone_CalibrationEvent) { ((HEventHeader*)((HEvent*)(gHades->getCurrentEvent()))->getHeader())->setId(kMdc_Standalone_CalibrationEvent); } } return kTRUE; } // ---------------------------------------------------------------------------------------------------- Int_t HMdcUnpacker::fillMdcRawEventHeader(Int_t errorFlag, Int_t rocModule, Int_t rocNumber, Int_t rocSector, Int_t subEvtSize, Int_t trigType) { // function for filling the category HMdcRawEventHeader HLocation dummy; HMdcRawEventHeader *pMdcRawEventHeader= NULL; pMdcRawEventHeader = (HMdcRawEventHeader*) pMdcRawEventHeaderCat->getNewSlot(dummy); if (pMdcRawEventHeader) { pMdcRawEventHeader = new (pMdcRawEventHeader) HMdcRawEventHeader(); } else { if(!noComment) errorFillMdcRawEventHeaderCannotGetSlot(); return -2; } Int_t samNr; // samNr = sam * 2 + samPos samNr = -1; samNr = getSubEvtIdToSamNr(subEvtId); if (samNr != -1) { rocSector = pReadout->getSamNumberToSector(samNr); rocModule = pReadout->getSamNumberToModule(samNr); } else { rocSector = 0 - subEvtId; // until lookup-table sam->sector/module exists rocModule = 0 - subEvtId; // until lookup-table sam->sector/module exists } pMdcRawEventHeader->set(errorFlag, rocModule, rocNumber, rocSector, subEvtId, subEvtSize, trigType); return 0; } // ---------------------------------------------------------------------------------------------------- void HMdcUnpacker::prepareBlackListRecovery(UInt_t eventSize) { if (0!=createBlackListRecoveryTools) { // clear previous pointers and content and counters recoveryStorageCounter=0; if (recoveryStorage) delete[] recoveryStorage; recoveryStorage = NULL; // create temporary array for \"difficult\" data recoveryStorage = new UInt_t[eventSize]; // clear array recoveryStorageCounter=0; memset(recoveryStorage,0,eventSize*sizeof(UInt_t)); } } // -------------------------------------------------------------------------------- Int_t HMdcUnpacker::executeBlackListRecovery() { Int_t returnValue=0; if (0!=createBlackListRecoveryTools) { switch(createBlackListRecoveryTools) { case 0x092005: returnValue = recoverBlackListSep2005(); break; case 0x042006: returnValue = recoverBlackListApr2006(); break; case 0x092008: if(subEvtId == 222) returnValue = recoverBlackListSep2005(); else if(subEvtId == 204) returnValue = recoverBlackListSep2008(); break; default: returnValue=0; errorFillUnknownCodeForBlacklistRecovery(); break; } // finally clear storage if (recoveryStorage) delete[] recoveryStorage; recoveryStorage=NULL; } return returnValue; } // -------------------------------------------------------------------------------- Bool_t HMdcUnpacker::storeForRecoveryFromBlackList(UInt_t *data) { // Is dataword include in an recovery black list? // TODO: recovery black list from oracle // first masking then comparing to adress // if it matches this dataword is stored // until the end of the while loop and then processes // // returns kTRUE if data word matches // kFALSE else static Bool_t skipDataWord; skipDataWord=kFALSE; for (Int_t arrayIndex=0; arrayIndex< recoverBlackListSize; arrayIndex++) { // check if dataword deb masked by mask matches the remaining adress if ((*data & recoverBlackListMask[arrayIndex])==recoverBlackListAdress[arrayIndex]) { // for later recovery store all datawords recoveredBlackListCounters[arrayIndex]++; recoveryStorage[recoveryStorageCounter]=*data; recoveryStorageCounter++; skipDataWord=kTRUE; break; } } if (skipDataWord) return kTRUE; else return kFALSE; } // -------------------------------------------------------------------------------- Bool_t HMdcUnpacker::excludeBlackListData(UInt_t* data) { // Is dataword included in an excluding black list? // TODO: black list from oracle // first masking then comparing to adress // if it matches this dataword is ignored // // returns kTRUE if data word matches // kFALSE else static Bool_t skipDataWord; skipDataWord=kFALSE; for (Int_t arrayIndex=0; arrayIndex< excludeBlackListSize; arrayIndex++) { // check if dataword deb masked by mask matches the remaining adress if ((*data & excludeBlackListMask[arrayIndex])==excludeBlackListAdress[arrayIndex]) { excludedBlackListCounters[arrayIndex]++; if (unpackerDebug && !noComment) { warningExcludeDataWords(*data, excludeBlackListMask[arrayIndex], excludeBlackListAdress[arrayIndex]); } skipDataWord=kTRUE; break; } } if (skipDataWord) { return kTRUE;} else return kFALSE; } // -------------------------------------------------------------------------------- // -------------------------------------------------------------------------------- // fillData Int_t HMdcUnpacker::fillData(void) { // Converts the content of the already decoded dataword via the lookup table HMdcEvReadout // to sector/module/mbo/tdc coordinates. // Then, if available the information is stored in a new or added to an existing // data slot of HMdcRaw // If activated, the raw data is written by fillMdcDataWord() // (formerly additional debug had to be switched on, not necessary any more) // variables used inside loop static Int_t sector; static Int_t module; static Int_t mbo ; static Int_t tdc ; // First the hardware address contained dataword // is matched to the sector/module/mbo/tdc coordinates of HMdcRaw // via the lookup table HMdcEvReadout // reset to default values sector = module = mbo = tdc = -1; if (!matchHardwareAdressToSecModMboTdc(sector, module, mbo, tdc)) { return 1; // in case of failing checks on Setup and Boundaries } dataword->setAddress(sector,module,mbo,tdc,0); // first get a free or existing slot static HMdcRaw *pMdcRaw; pMdcRaw = NULL; pMdcRaw = getFreeOrExistingSlot(sector, module, mbo, tdc); if (!pMdcRaw) return -2; // cannot get slot // fill the time to this slot if (!pMdcRaw->setTime(dataword->getTime(),tdcMode, noComment)) { if(!noComment) errorFillErrorFillingDataWord(); if (unpackerDebug) dataword->dump(decodeVersion); } // fill dataWord to category HMdcDataWord if(fillDataWord) fillMdcDataWord(sector,module,mbo,tdc); return 0; } // -------------------------------------------------------------------------------- // -------------------------------------------------------------------------------- // fillData helpers Bool_t HMdcUnpacker::matchHardwareAdressToSecModMboTdc(Int_t §or, Int_t &module, Int_t &mbo, Int_t &tdc) { // the hardware address is matched to the sector/module/mbo/tdc coordinates of HMdcRaw // via the lookup table HMdcEvReadout // the result is checked for consistency // deb is the pointer to the current rwa dataword // // kFALSE is returned in case of failures // otherwise kTRUE Int_t nsam = -1; switch (decodeVersion) { case 0: nsam = dataword->getSam()*2+dataword->getSamP(); break; case 1: nsam = dataword->getVirtualSamNr(); break; } Int_t nroc = dataword->getRoc(); Int_t nrocP = dataword->getRocP(); Int_t nbus = dataword->getBus(); if (nsam <0 || nroc <0 || nrocP <0 || nbus <0) { if (!noComment) errorFillNoValidAddressInLookUpTable(); if (unpackerDebug) dataword->dump(decodeVersion); return kFALSE; } HMdcEvReadoutBus& bus =(*pReadout)[nsam][nroc][nrocP][nbus]; sector= bus.getSec(); module= bus.getMod(); mbo = bus.getMbo(); tdc = getTdc(dataword->getTdc(),dataword->getChan()); if(!checkMdcSetup(sector,module)) { return kFALSE; } if(!checkMboRawStructBounds(sector,module,mbo,tdc)) { return kFALSE; } return kTRUE; } // ---------------------------------------------------------------------------------------------------- Bool_t HMdcUnpacker::checkMdcSetup(Int_t sector, Int_t module) { // checks whether module and sector are set in the MdcSetup // returns kTRUE if set, // kFALSE else if(!testMdcSetup(sector,module)) { if(!noComment) { errorCheckMdcSetup(sector,module); if (unpackerDebug) dataword->dump(decodeVersion); } return kFALSE; } return kTRUE; } // ---------------------------------------------------------------------------------------------------- Bool_t HMdcUnpacker::checkMboRawStructBounds(Int_t sector,Int_t module, Int_t mbo, Int_t tdc) { // checks consistency whether sector, module, mbo, tdc values are inside // the bounds of the parameter container MboRawStruct // return value // kTRUE the checks were passed // kFALSE if otherwise Int_t nMaxSector = rawc->getSize() ; if (sector >= nMaxSector || sector < 0 ) { if (!noComment) { errorCheckMboRawStructBoundsOutOfBounds(tdc, nMaxSector); if (unpackerDebug) dataword->dump(decodeVersion); } return kFALSE; } Int_t nMaxModule = (*rawc)[sector].getSize() ; if (module >= nMaxModule || module < 0 ) { if (!noComment) { errorCheckMboRawStructBoundsOutOfBounds(tdc, nMaxModule, sector); if (unpackerDebug) dataword->dump(decodeVersion); } return kFALSE; } Int_t nMaxMbo = (*rawc)[sector][module].getSize() ; if (mbo >= nMaxMbo || mbo < 0 ) { if (!noComment) { errorCheckMboRawStructBoundsOutOfBounds(tdc, nMaxMbo, sector, module); if (unpackerDebug) dataword->dump(decodeVersion); } return kFALSE; } Int_t nMaxTdc = (*rawc)[sector][module][mbo].getNTdcs() ; if (tdc >= nMaxTdc || tdc < 0 ) { if (!noComment) { errorCheckMboRawStructBoundsOutOfBounds(tdc, nMaxTdc, sector, module, mbo); if (unpackerDebug) dataword->dump(decodeVersion); } return kFALSE; } return kTRUE; } // -------------------------------------------------------------------------------- HMdcRaw* HMdcUnpacker::getFreeOrExistingSlot(Int_t §or, Int_t &module, Int_t &mbo, Int_t &tdc) { // get a free or existing slot from the HMdcRaw category // at the location of HLocation loc // returns the pointer to the (new) HMdcRaw object // NULL if it couldn't be done HLocation loc; loc.set(4, 0, 0, 0, 0); // filling the data to the location // set location indexes loc[0] = sector; loc[1] = module; loc[2] = mbo; loc[3] = tdc; HMdcRaw *pMdcRaw = (HMdcRaw*) pRawCat->getObject(loc); if (!pMdcRaw) { pMdcRaw = (HMdcRaw*) pRawCat->getSlot(loc); if (pMdcRaw) { pMdcRaw = new (pMdcRaw) HMdcRaw(); //setAddress to sector,module,mbo and tdc pMdcRaw->setAddress(sector,module,mbo,tdc); } else { if(!noComment) errorFillCannotGetSlot(sector,module,mbo,tdc); if (unpackerDebug) pSubEvt->dumpIt(); } } return pMdcRaw; } // ---------------------------------------------------------------------------------------------------- Int_t HMdcUnpacker::fillMdcDataWord(Int_t sector,Int_t module,Int_t mbo,Int_t tdc) { // function for filling the category HMdcDataword // Int_t entry=0; UChar_t maxentry=10; maxentry=8; HLocation dataLoc; dataLoc.set(5,0,0,0,0,0); //set location indexes dataLoc[0] = sector; dataLoc[1] = module; dataLoc[2] = mbo; dataLoc[3] = tdc; dataLoc[4] = entry; HMdcDataWord *pMdcDataWord=NULL; for (entry = 0; entry < maxentry; entry++) { pMdcDataWord = NULL; dataLoc[4] = entry; pMdcDataWord = (HMdcDataWord*) pMdcDataWordCat->getObject(dataLoc); if (!pMdcDataWord) break; // Info("HMdcUnpacker","%2i %10p ",entry,pMdcDataWord); // Info("HMdcUnpacker","s:%i m:%i mb:%2i td:%2i e:%2i ",dataLoc[0],dataLoc[1],dataLoc[2],dataLoc[3],dataLoc[4]); // dataLoc.Dump(); // pMdcDataWord->print(); } // cout << ".............................." << endl; // Info("HMdcUnpacker","%2i %10p ",entry,pMdcDataWord); // Info("HMdcUnpacker","s:%i m:%i mb:%2i td:%2i e:%2i ",dataLoc[0],dataLoc[1],dataLoc[2],dataLoc[3],dataLoc[4]); // dataLoc.Dump(); if (pMdcDataWord) { if (entry==maxentry-1) { if(!noComment) errorFillMdcDataWordTooManyEntriesToSameLocation(maxentry); } else { if(!noComment) errorFillMdcDataWordCannotGetSlot(); } return -2; } else { pMdcDataWord = (HMdcDataWord*) pMdcDataWordCat->getSlot(dataLoc); if (pMdcDataWord) { pMdcDataWord = new (pMdcDataWord) HMdcDataWord(*dataword); pMdcDataWord->setAdress(sector,module,mbo,tdc,entry); } else { // dataLoc.Dump(); if(!noComment) errorFillMdcDataWordCannotGetSlot(); return -2; } } return 1; } // ---------------------------------------------------------------------------------------------------- Int_t HMdcUnpacker::recoverBlackListApr2006() { // Hardware bugfix for beamtime apr2006: // In Module IV (Orsay) of Sector IV (SubEvtId 222) // The mob id of the two motherboards in the LVL1 chain // of mbo 113 and mbo 115 is corrupted. // // Up to now the Blacklist option ignored all datawords of this if activated // Now it the channels should if possible be reconstructed: // // Because mbo 113 is a 64-channel board and mbo 115 is a 96 Long_t // the topmost 32 channels can automatically be assigned to mbo 115 // // Since this is the same error as in Sep2005 // recoverBlackListSep2005 is called return recoverBlackListSep2005(); } // ---------------------------------------------------------------------------------------------------- Int_t HMdcUnpacker::recoverBlackListSep2005() { // Hardware bugfix for beamtime sep05: // In Module IV (Orsay) of Sector IV (SubEvtId 222) // The mob id of the two motherboards in the LVL1 chain // of mbo 113 and mbo 115 is corrupted. // // Up to now the Blacklist option ignored all datawords of this if activated // Now the channels should, if possible, be reconstructed: // // Because mbo 113 is a 64-channel board and mbo 115 is a 96 Long_t // the topmost 32 channels can automatically be assigned to mbo 115 // for later recovery store all datawords UInt_t datum; Int_t arrayIndex; Int_t hitCounter[64]; Int_t hitCounterRecovered[64]; memset(hitCounter ,0,64*sizeof(Int_t)); memset(hitCounterRecovered,0,64*sizeof(Int_t)); Int_t tdc; for (UInt_t index=0; index< recoveryStorageCounter; index++) { datum = recoveryStorage[index]; // (a) matches mask #0 // check if dataword masked by mask #0 matches the remaining adress #0 arrayIndex=0; if ((datum & recoverBlackListMask[arrayIndex])==recoverBlackListAdress[arrayIndex]) { // decode w/o consistency check if(!dataword->decode( datum, decodeVersion)) { if(!noComment){ warningRecoverBlackListSep2005SkippingDataWord(datum); } continue; } // get tdc // reset to default values tdc = -1; tdc = getTdc(dataword->getTdc(),dataword->getChan()); if (tdc < 0) continue; // if tdc > 63 assign values to Long_t motherboard (LVL1 Position = 2) , i.e. modify dataword if (tdc > 63) { // set LVL1 Position to 2; dataword->setMboNb(2); // redecode if (!dataword->decode(dataword->getCodedDataWord(), decodeVersion, consistencyCheck)) {continue;} // fill data to HMdcRaw categories including all checks switch(fillData()) { case 0: break; case 1: continue; // case of failing checks on Setup and Boundaries case -2: return -2; // cannot get slot for HMdcRaw default: errorAndExitRecoverBlackListSep2005UnknownReturnValueOfFillData(); } recoveredBlackListCounters[arrayIndex]++; } else { // if tdc < 63 count hits hitCounter[tdc]++; } } } for (UInt_t index=0; index< recoveryStorageCounter; index++) { datum = recoveryStorage[index]; // (b) matches mask #0 // check if dataword masked by mask #0 matches the remaining adress #0 arrayIndex=0; if ((datum & recoverBlackListMask[arrayIndex])==recoverBlackListAdress[arrayIndex]) { // decode w/o consistency check if(!dataword->decode( datum, decodeVersion)) { continue; } // get tdc // reset to default values tdc = -1; tdc = getTdc(dataword->getTdc(),dataword->getChan()); if (tdc < 0) continue; if (tdc < 64) { // 2,6 -> Fill to both if (hitCounter[tdc] == 2 || hitCounter[tdc] == 6) { // set LVL1 Position to 1; dataword->setMboNb(1); // redecode if (!dataword->decode(dataword->getCodedDataWord(), decodeVersion, consistencyCheck)) {continue;} // fill data to HMdcRaw categories including all checks switch(fillData()) { case 0: break; case 1: continue; // case of failing checks on Setup and Boundaries case -2: return -2; // cannot get slot for HMdcRaw default: errorAndExitRecoverBlackListSep2005UnknownReturnValueOfFillData(); } // set LVL1 Position to 2; dataword->setMboNb(2); // redecode if (!dataword->decode(dataword->getCodedDataWord(), decodeVersion, consistencyCheck)) {continue;} // fill data to HMdcRaw categories including all checks switch(fillData()) { case 0: break; case 1: continue; // case of failing checks on Setup and Boundaries case -2: return -2; // cannot get slot for HMdcRaw default: errorAndExitRecoverBlackListSep2005UnknownReturnValueOfFillData(); } hitCounterRecovered[tdc]++; recoveredBlackListCounters[arrayIndex]++; } // 4 Hits fill first 2 hits to mbo 1 and last 2 hits to mbo 2 else if (hitCounter[tdc] == 4) { if (hitCounterRecovered[tdc] < 2) { dataword->setMboNb(1); } else { dataword->setMboNb(2); } // redecode if (!dataword->decode(dataword->getCodedDataWord(), decodeVersion, consistencyCheck)) {continue;} // fill data to HMdcRaw categories including all checks switch(fillData()) { case 0: break; case 1: continue; // case of failing checks on Setup and Boundaries case -2: return -2; // cannot get slot for HMdcRaw default: errorAndExitRecoverBlackListSep2005UnknownReturnValueOfFillData(); } hitCounterRecovered[tdc]++; recoveredBlackListCounters[arrayIndex]++; } // 12 Hits fill first 6 hits to mbo 1 and last 6 hits to mbo 2 else if (hitCounter[tdc] == 12) { if (hitCounterRecovered[tdc] < 6) { dataword->setMboNb(1); } else { dataword->setMboNb(2); } // redecode if (!dataword->decode(dataword->getCodedDataWord(), decodeVersion, consistencyCheck)) {continue;} // fill data to HMdcRaw categories including all checks switch(fillData()) { case 0: break; case 1: continue; // case of failing checks on Setup and Boundaries case -2: return -2; // cannot get slot for HMdcRaw default: errorAndExitRecoverBlackListSep2005UnknownReturnValueOfFillData(); } hitCounterRecovered[tdc]++; recoveredBlackListCounters[arrayIndex]++; } else { if(!noComment){ warningRecoverBlackListSep2005IgnoringDatum(hitCounter[tdc],datum); } } } } } return 0; } // ------------------------------------------------------------------------------- Int_t HMdcUnpacker::recoverBlackListSep2008(void) { UInt_t datum; Int_t arrayIndex; for (UInt_t index=0; index< recoveryStorageCounter; index++) { datum = recoveryStorage[index]; // (b) matches mask #0 // check if dataword masked by mask #0 matches the remaining adress #0 arrayIndex=0; //cout << datum<< " " <decode( datum, decodeVersion)) { continue; } if(dataword->getTdc() >= 8) dataword->setTdcNb(dataword->getTdc()-8); dataword->setMboNb(1); // redecode if (!dataword->decode(dataword->getCodedDataWord(), decodeVersion, consistencyCheck)) {continue;} // fill data to HMdcRaw categories including all checks switch(fillData()) { case 0: break; case 1: continue; // case of failing checks on Setup and Boundaries case -2: return -2; // cannot get slot for HMdcRaw default: errorAndExitRecoverBlackListSep2005UnknownReturnValueOfFillData(); } recoveredBlackListCounters[arrayIndex]++; } } return 0; } // ------------------------------------------------------------------------------- void HMdcUnpacker::enableExcludeBlackList(TString context) { gHades->getMsg()->info(10,HMessageMgr::DET_MDC,GetName(),"Setting up exclude blacklist for subevent %i\n",subEvtId); setExcludeBlackListInternal(kTRUE); setExcludeBlackListContext(context); } // ------------------------------------------------------------------------------- void HMdcUnpacker::disableExcludeBlackList() { setExcludeBlackListInternal(kFALSE); setExcludeBlackListContext(HMdcUnpacker::excludeBlackListContextDefaultString); } // ------------------------------------------------------------------------------- void HMdcUnpacker::setExcludeBlackList(Bool_t b) { if(b) { errorAndExitSetExcludeBlackListObsoleteCall(); } else { disableExcludeBlackList(); } } // ------------------------------------------------------------------------------- void HMdcUnpacker::setExcludeBlackListContext(TString context) { context.ToLower(); excludeBlackListContext=context; } // ------------------------------------------------------------------------------- void HMdcUnpacker::setExcludeBlackList(TString context) { // function set/unset exclude black list feature via HMdcUnpacker::setExcludeBlackList // and its context via HMdcUnpacker::setExcludeBlackListContext // in one line. // // if context is empty or equal to HMdcUnpacker::excludeBlackListContextDefaultString // the feature is deactivated. // Any other value activates this, provided a corresponding table exists // up to now "sep05" is the only valid context // (see HMdcUnpacker::init() function) setExcludeBlackListContext(context); if (!context.IsNull() && context.CompareTo(excludeBlackListContextDefaultString)) { setExcludeBlackList(kTRUE); } else { setExcludeBlackList(kFALSE);} } // ------------------------------------------------------------------------------- void HMdcUnpacker::enableRecoverBlackList(TString context) { gHades->getMsg()->info(10,HMessageMgr::DET_MDC,GetName(),"Setting up recovery blacklist for subevent %i\n",subEvtId); setRecoverBlackListInternal(kTRUE); setRecoverBlackListContext(context); } // ------------------------------------------------------------------------------- void HMdcUnpacker::disableRecoverBlackList() { setRecoverBlackListInternal(kFALSE); setRecoverBlackListContext(HMdcUnpacker::recoverBlackListContextDefaultString); } // ------------------------------------------------------------------------------- void HMdcUnpacker::setRecoverBlackList(Bool_t b) { if(b) { errorAndExitSetRecoverBlackListObsoleteCall(); } else { disableRecoverBlackList(); } } // ------------------------------------------------------------------------------- void HMdcUnpacker::setRecoverBlackListContext(TString context) { context.ToLower(); recoverBlackListContext=context; } // ------------------------------------------------------------------------------- void HMdcUnpacker::setRecoverBlackList(TString context) { // function set/unset recover black list feature via HMdcUnpacker::setRecoverBlackList // and its context via HMdcUnpacker::setRecoverBlackListContext // in one line. // // if context is empty or equal to HMdcUnpacker::recoverBlackListContextDefaultString // the feature is deactivated. // Any other value activates this, provided a corresponding table exists // up to now "sep05" is the only valid context // (see HMdcUnpacker::init() function) setRecoverBlackListContext(context); if (!context.IsNull() && context.CompareTo(recoverBlackListContextDefaultString)) { setRecoverBlackList(kTRUE); } else { setRecoverBlackList(kFALSE);} } // ------------------------------------------------------------------------------- Bool_t HMdcUnpacker::finalize() { // finalize function // returning always kTRUE if (excludeBlackList) printExcludedBlackListCounter(); if (recoverBlackList) printRecoveredBlackListCounter(); return kTRUE; } // ---------------------------------------------------------------------------------------------------- // ---------------------------------------------------------------------------------------------------- // print functions void HMdcUnpacker::printExcludedBlackListCounter() { // prints out messages for each mask - adress pair how many excludes were encountered Bool_t print=kFALSE; for (Int_t arrayIndex=0; arrayIndex< excludeBlackListSize; arrayIndex++) { // check if any excludes were encountered if (excludedBlackListCounters[arrayIndex]>0) { print=kTRUE; break; } } if (print) { for (Int_t arrayIndex=0; arrayIndex< excludeBlackListSize; arrayIndex++) { Warning("printExcludedBlackListCounter", " subEvtId: %i - %i Data words were excluded by mask 0x%x and adress 0x%x", subEvtId, excludedBlackListCounters[arrayIndex], excludeBlackListMask [arrayIndex], excludeBlackListAdress [arrayIndex] ); } } } // ---------------------------------------------------------------------------------------------------- void HMdcUnpacker::printRecoveredBlackListCounter() { // prints out messages for each mask - adress pair how many recovers were encountered Bool_t print=kFALSE; for (Int_t arrayIndex=0; arrayIndex< recoverBlackListSize; arrayIndex++) { // check if any recovers were encountered if (recoveredBlackListCounters[arrayIndex]>0) { print=kTRUE; break; } } if (print) { for (Int_t arrayIndex=0; arrayIndex< recoverBlackListSize; arrayIndex++) { Info("printRecoverdBlackListCounter", " subEvtId: %i - %i Data words were recovered by mask 0x%x and adress 0x%x", subEvtId, recoveredBlackListCounters[arrayIndex], recoverBlackListMask [arrayIndex], recoverBlackListAdress [arrayIndex] ); } } } // ---------------------------------------------------------------------------------------------------- // ---------------------------------------------------------------------------------------------------- // info functions void HMdcUnpacker::infoDetermineDecodeVersion(void) { Info("determineDecodeVersion()"," SubEvtId %i - decode version: %i ", subEvtId, getDecodeVersion()); } // ---------------------------------------------------------------------------------------------------- // ---------------------------------------------------------------------------------------------------- // warnings functions void HMdcUnpacker::warningExcludeDataWords(UInt_t data, UInt_t mask, UInt_t adress) { Warning("fill()"," Event: %i - SubEvtId %i - excluded data word %x due to matching mask 0x%x and adress 0x%x", ((HEventHeader*)((HEvent*)(gHades->getCurrentEvent())->getHeader()))->getEventSeqNumber(), subEvtId, data, mask, adress); } // ---------------------------------------------------------------------------------------------------- void HMdcUnpacker::warningExecuteNoValidModuleEntryInLookupTableForSamNr(Int_t samNr) { Warning("execute", " Event: %i - SubEvtId %i - no valid module entry in lookuptable for virtual samNr: %i (=lookup table index+1) ... sub event id %i ignored", ((HEventHeader*)((HEvent*)(gHades->getCurrentEvent())->getHeader()))->getEventSeqNumber(), subEvtId,samNr,subEvtId); } // ---------------------------------------------------------------------------------------------------- void HMdcUnpacker::warningExecuteNoValidSectorEntryInLookupTableForSamNr(Int_t samNr) { Warning("execute", " Event: %i - SubEvtId %i - no valid sector entry in lookuptable for virtual samNr: %i (=lookup table index+1) ... sub event id %i ignored", ((HEventHeader*)((HEvent*)(gHades->getCurrentEvent())->getHeader()))->getEventSeqNumber(), subEvtId,samNr,subEvtId); } // ---------------------------------------------------------------------------------------------------- void HMdcUnpacker::warningExecuteSamNrNegative(Int_t samNr) { Warning("execute", " Event: %i - SubEvtId %i - samNr: %i (=lookup table index+1) negative ... sub event id %i ignored", ((HEventHeader*)((HEvent*)(gHades->getCurrentEvent())->getHeader()))->getEventSeqNumber(), subEvtId,samNr,subEvtId); } // ---------------------------------------------------------------------------------------------------- void HMdcUnpacker::warningInitExcludeBlackListNoValidContext(TString context) { Warning("init()", "No valid exclude list defined for context \"%s\" ... 'BlackList' feature is deaktivated", context.Data()); } // ---------------------------------------------------------------------------------------------------- void HMdcUnpacker::warningInitRecoverBlackListNoValidContext(TString context) { Warning("init()", "No valid exclude list defined for context \"%s\" ... 'BlackList' feature is deaktivated", context.Data()); } // -------------------------------------------------------------------------------- void HMdcUnpacker::warningRecoverBlackListSep2005IgnoringDatum(Int_t ctr, UInt_t datum) { Warning("recoverBlackList", "sep05: neither 2, 4, 6 or 12 Hits but %i ... ignoring datum: 0x%x", ctr, datum); } // ---------------------------------------------------------------------------------------------------- void HMdcUnpacker::warningRecoverBlackListSep2005SkippingDataWord(UInt_t datum) { Warning("recoverBlackListSep2005()","skipping dataword %x",datum); } // ---------------------------------------------------------------------------------------------------- void HMdcUnpacker::warningSetQuietMode(void) { Warning("setQuietMode", "subEvtId %i - from now on all error and warning messages of this unpacker are skipped, be aware of the consequences", subEvtId); } // ---------------------------------------------------------------------------------------------------- // ---------------------------------------------------------------------------------------------------- // error functions void HMdcUnpacker::errorCheckMboRawStructBoundsOutOfBounds(Int_t value, Int_t maxValue, Int_t sector, Int_t module, Int_t mbo) { Int_t eventSeqNr = -1; if (gHades) eventSeqNr = (((HEventHeader*)((HEvent*)(gHades->getCurrentEvent())->getHeader()))->getEventSeqNumber()); if (sector == -100 && module==-100 && mbo ==-100) { // sector value error Error("checkMboRawStructBounds", " Event: %i - SubEvtId %3i - sector %i, number out of bounds [0,%i[ for dataword 0x%x", eventSeqNr, subEvtId, value, maxValue, dataword->getCodedDataWord()); } else if (module==-100 && mbo ==-100) { // module value error Error("checkMboRawStructBounds", " Event: %i - SubEvtId %3i - module %i, number out of bounds [0,%i[ for sector: %i for dataword 0x%x ", eventSeqNr, subEvtId, value, maxValue, sector, dataword->getCodedDataWord()); } else if (mbo ==-100) { // mbo value error Error("checkMboRawStructBounds", " Event: %i - SubEvtId %3i - mbo %i, number out of bounds [0,%i[ for sector: %i, module: %i for dataword 0x%x", eventSeqNr, subEvtId, value, maxValue, sector, module, dataword->getCodedDataWord()); } else { // tdc value error Error("checkMboRawStructBounds", " Event: %i - SubEvtId %3i - tdc %i, number out of bounds [0,%i[ for sector: %i, module: %i, mbo: %i for dataword 0x%x", eventSeqNr, subEvtId, value, maxValue, sector, module, mbo, dataword->getCodedDataWord()); } } // ---------------------------------------------------------------------------------------------------- void HMdcUnpacker::errorCheckMdcSetup(Int_t sector, Int_t module) { Int_t eventSeqNr = -1; if (gHades) eventSeqNr = (((HEventHeader*)((HEvent*)(gHades->getCurrentEvent())->getHeader()))->getEventSeqNumber()); Error("checkMdcSetup()", " Event: %i - SubEvtId %3i - though sector %i, module %i are excluded in the setup, dataword: 0x%08x points to this detector.", eventSeqNr,subEvtId,sector,module, dataword->getCodedDataWord()); } // ---------------------------------------------------------------------------------------------------- void HMdcUnpacker::errorDecodeSubHeaderCannotDecode() { Error("decodeSubHeader()","SubEvtId %i - can't decode sub header ",subEvtId); } // ---------------------------------------------------------------------------------------------------- void HMdcUnpacker::errorDecodingModeInvalidCompressMode(UInt_t compressMode,UInt_t decoding) { Error("decodingMode()"," Event: %i - SubEvtId %i - compressMode %i from decoding word 0x%x invalid ... sub event id %i ignored", ((HEventHeader*)((HEvent*)(gHades->getCurrentEvent())->getHeader()))->getEventSeqNumber(), subEvtId,compressMode,decoding,subEvtId); } // ---------------------------------------------------------------------------------------------------- void HMdcUnpacker::errorExecuteErrorInFill() { if(!noComment) Error("execute"," Event: %i - SubEvtId %i - error in unpacking", ((HEventHeader*)((HEvent*)(gHades->getCurrentEvent())->getHeader()))->getEventSeqNumber(), subEvtId); } // ---------------------------------------------------------------------------------------------------- void HMdcUnpacker::errorExecuteNoValidPointerTo(TString pointerName) { Error("execute"," Event: %i - SubEvtId %i - pointer to %s zero", ((HEventHeader*)((HEvent*)(gHades->getCurrentEvent())->getHeader()))->getEventSeqNumber(), subEvtId, pointerName.Data()); } // ------------------------------------------------------------------------------- void HMdcUnpacker::errorFillCannotGetSlot(Int_t sector, Int_t module, Int_t mbo, Int_t tdc) { Error("fill()", " Event: %i - SubEvtId %i - can't get slot for s:%i m:%i mb:%i tdc:%i ...", ((HEventHeader*)((HEvent*)(gHades->getCurrentEvent())->getHeader()))->getEventSeqNumber(), subEvtId,sector,module,mbo,tdc); Error("fill()", " ..... skipping unpacking for the rest of this sub event!!!"); } // -------------------------------------------------------------------------------- void HMdcUnpacker::errorFillDecodeSubHeaderFailed() { Error("fill()"," Event: %i - SubEvtId %i - decoding of sub header (ROC) failed", ((HEventHeader*)((HEvent*)(gHades->getCurrentEvent())->getHeader()))->getEventSeqNumber(), subEvtId); Error("fill()", " ..... skipping unpacking for the rest of this sub event!!!"); } // ------------------------------------------------------------------------------- void HMdcUnpacker::errorFillDataPointerExceedingRange(UInt_t* deb, UInt_t* end, UInt_t* enddata) { Error("fill()", " Event: %i - SubEvtId %i - data pointer %p exceeding range of sub event end %p\n with calculated end point at %p", ((HEventHeader*)((HEvent*)(gHades->getCurrentEvent())->getHeader()))->getEventSeqNumber(), subEvtId,deb,end,enddata); } // ------------------------------------------------------------------------------- void HMdcUnpacker::errorFillErrorFillingDataWord() { Error("fill()"," Event: %i - SubEvtId %i - error filling slot for dataword 0x%08x", ((HEventHeader*)((HEvent*)(gHades->getCurrentEvent())->getHeader()))->getEventSeqNumber(), subEvtId, dataword->getCodedDataWord()); } // ---------------------------------------------------------------------------------------------------- void HMdcUnpacker::errorFillMdcDataWordTooManyEntriesToSameLocation(Int_t maxentry) { Error("fillMdcDataWord()", " SubEvtId %i - to many entries to the same location entries>%i", subEvtId,maxentry); } // ---------------------------------------------------------------------------------------------------- void HMdcUnpacker::errorFillMdcDataWordCannotGetSlot() { Error("fillMdcRawEventHeader()", "SubEvtId %i - can't get slot for MdcDataWord",subEvtId); Error("fillMdcRawEventHeader()", " ..... but continuing unpacking for the rest of this sub event!!!"); } // ---------------------------------------------------------------------------------------------------- void HMdcUnpacker::errorFillMdcRawEventHeaderCannotGetSlot() { Error("fillMdcRawEventHeader()", "SubEvtId %i - can't get slot for MdcEventHeader",subEvtId); Error("fillMdcRawEventHeader()", " ..... but continuing unpacking for the rest of this sub event!!!"); } // ------------------------------------------------------------------------------- void HMdcUnpacker::errorFillNoValidAddressInLookUpTable() { Error("fill()", " Event: %i - SubEvtId %3i - No valid address in lookup table [HMdcEvReadout] for this dataword: 0x%08x", ((HEventHeader*)((HEvent*)(gHades->getCurrentEvent())->getHeader()))->getEventSeqNumber(), subEvtId, dataword->getCodedDataWord()); } // ------------------------------------------------------------------------------- void HMdcUnpacker::errorFillSkippingRestOfSubEvent(void) { Error("fill()", " ..... skipping unpacking for the rest of this sub event!!!"); } // -------------------------------------------------------------------------------- void HMdcUnpacker::errorFillUnknownCodeForBlacklistRecovery() { Error("fill()","unknown code for blacklist recovery"); } // ---------------------------------------------------------------------------------------------------- void HMdcUnpacker::errorGetSubEvtIdToSamNrSamNrNotInLookupTable(UInt_t localSubEvtId, Int_t samNr) { Error("getSubEvtIdToSamNr()", "SubEvtId %i - calculated samNr: %i is not in the lookup table (HMdcEvReadout)", localSubEvtId,samNr); } // ---------------------------------------------------------------------------------------------------- void HMdcUnpacker::errorGetSubEvtIdToSamNrSubEvtIdOutOfMdcRange(UInt_t localSubEvtId, TString range) { Error("getSubEvtIdToSamNr()"," SubEvtId %i - sub event id: %i, out of mdc range %s", localSubEvtId,localSubEvtId, range.Data()); } // ---------------------------------------------------------------------------------------------------- void HMdcUnpacker::errorInitCannotGetParameterContainer(TString container) { Error("init()"," SubEvtId %i - can't get parameter container \"%s\" ",subEvtId,container.Data()); } // ---------------------------------------------------------------------------------------------------- void HMdcUnpacker::errorInitCategoryCannotAddCategory(TString catname, TString detector) { Error("initCategory()"," SubEvtId %i - can't add category \"%s\" to detector \"%s\"",subEvtId,catname.Data(),detector.Data()); } // ---------------------------------------------------------------------------------------------------- void HMdcUnpacker::errorInitCategoryCannotGetCategory(TString catname) { Error("initCategory()"," SubEvtId %i - can't create or get category \"%s\"",subEvtId,catname.Data()); } // ---------------------------------------------------------------------------------------------------- // ---------------------------------------------------------------------------------------------------- // errorAndExit functions void HMdcUnpacker::errorAndExitCompareEventDateTimeTo() { Error("compareEventDateTimeTo()", " SubEvtId %i - no data header defined in current event of gHades ... exiting", subEvtId); exit(EXIT_FAILURE); } // ---------------------------------------------------------------------------------------------------- void HMdcUnpacker::errorAndExitDetermineDecodeVersion(void) { Error("determineDecodeVersion()", " SubEvtId %i - cannot determine decode version ... exiting",subEvtId); exit(EXIT_FAILURE); } // -------------------------------------------------------------------------------- void HMdcUnpacker::errorAndExitFillUnknownReturnValueOfFillData() { Error("fill()","unknown return value by fillData()... exiting()"); exit(EXIT_FAILURE); } // ---------------------------------------------------------------------------------------------------- void HMdcUnpacker::errorAndExitGetMdcSetup() { Error("getMdcSetup()"," SubEvtId %i - Mdc-Detector setup (gHades->getSetup()->getDetector(\"Mdc\")) missing... exiting()", subEvtId); exit(EXIT_FAILURE); } // ---------------------------------------------------------------------------------------------------- void HMdcUnpacker::errorAndExitInitExcludeBlackListNoValidContext() { Error("initExcludeBlackList()","you have activated the excludeBlackList feature w/o specifying any context. \ \n Add setExcludeBlackListContext(\"context\") for the HMdcUnpacker object to your code! \n \ ... exiting!"); exit(EXIT_FAILURE); } // ---------------------------------------------------------------------------------------------------- void HMdcUnpacker::errorAndExitInitRecoverBlackListNoValidContext() { Error("initRecoverBlackList()","you have activated the excludeBlackList feature w/o specifying any context. \ \n Add setRecoverBlackListContext(\"context\") for the HMdcUnpacker object to your code! \n \ ... exiting!"); exit(EXIT_FAILURE); } // -------------------------------------------------------------------------------- void HMdcUnpacker::errorAndExitRecoverBlackListSep2005UnknownReturnValueOfFillData() { Error("fill()","unknown return value by fillData()... exiting()"); exit(EXIT_FAILURE); } // ------------------------------------------------------------------------------- void HMdcUnpacker::errorAndExitSetDecodeVersion(UInt_t version) { Error("setDecodeVersion()", " SubEvtId %i - selected version %i out of range [0,%i] ... exiting", subEvtId, version, maxDecodeVersion); exit(EXIT_FAILURE); }; // ---------------------------------------------------------------------------------------------------- void HMdcUnpacker::errorAndExitSetExcludeBlackListObsoleteCall() { Error("setExcludeBlackList(Bool_t b)", "obsolete function not supporting any context ... use enableExcludeBlackList(TString context) instead ... exiting\n"); exit(EXIT_FAILURE); } // ------------------------------------------------------------------------------- void HMdcUnpacker::errorAndExitSetRecoverBlackListObsoleteCall() { Error("setExcludeBlackList(Bool_t b)", "obsolete function not supporting any context ... use enableExcludeBlackList(TString context) instead ... exiting\n"); exit(EXIT_FAILURE); }