diff --git a/CondFormats/GEMObjects/interface/GEMeMap.h b/CondFormats/GEMObjects/interface/GEMeMap.h index f662690ee0d52..7242430068a09 100644 --- a/CondFormats/GEMObjects/interface/GEMeMap.h +++ b/CondFormats/GEMObjects/interface/GEMeMap.h @@ -60,7 +60,7 @@ class GEMeMap { static const int vfatTypeV3_ = 11; // VFAT v3 static const int chipIdMask_ = 0xfff; // chipId mask for 12 bits static const int maxGEBs_ = 32; // 5 bits for GEB id - static const int maxAMCs_ = 16; // 4 bits for AMC no. + static const int maxAMCs_ = 15; // 4 bits for AMC no. static const int maxVFatGE0_ = 12; // vFat per eta partition, not known yet for ME0 static const int maxVFatGE11_ = 3; // vFat per eta partition in GE11 static const int maxVFatGE21_ = 6; // vFat per eta partition in GE21 diff --git a/DataFormats/GEMDigi/interface/AMC13Event.h b/DataFormats/GEMDigi/interface/AMC13Event.h index 3f05e675acc48..6ccfe5d991189 100644 --- a/DataFormats/GEMDigi/interface/AMC13Event.h +++ b/DataFormats/GEMDigi/interface/AMC13Event.h @@ -39,9 +39,15 @@ namespace gem { union CDFTrailer { uint64_t word; struct { - uint64_t tts : 8; // tts (first 4 bits) - uint64_t evtStat : 4; // event status - uint64_t crcCDF : 20; // CDF crc (first 16 bits) + uint64_t res1 : 2; + uint64_t crcModified : 1; + uint64_t moreTrailers : 1; + uint64_t tts : 4; // tts + uint64_t evtStat : 4; // event status + uint64_t res2 : 2; + uint64_t slinkError : 1; + uint64_t wrongFedId : 1; + uint64_t crcCDF : 16; // CDF crc uint64_t evtLength : 24; // event length uint64_t eventType : 4; // Event Type uint64_t cbA : 4; // 0xA @@ -82,6 +88,10 @@ namespace gem { void setCDFTrailer(uint64_t word) { cdft_ = word; } void setCDFTrailer(uint32_t EvtLength); uint64_t getCDFTrailer() const { return cdft_; } + uint32_t fragmentLength() const { return CDFTrailer{cdft_}.evtLength; } + uint16_t crc() const { return CDFTrailer{cdft_}.crcCDF; } + uint8_t evtStatus() const { return CDFTrailer{cdft_}.evtStat; } + uint8_t ttsBits() const { return CDFTrailer{cdft_}.tts; } int bxId() const { return (int8_t)CDFHeader{cdfh_}.bxId; } uint32_t lv1Id() const { return CDFHeader{cdfh_}.lv1Id; } diff --git a/EventFilter/GEMRawToDigi/interface/GEMRawToDigi.h b/EventFilter/GEMRawToDigi/interface/GEMRawToDigi.h index 4aa9e5d10019d..f5997127a4756 100644 --- a/EventFilter/GEMRawToDigi/interface/GEMRawToDigi.h +++ b/EventFilter/GEMRawToDigi/interface/GEMRawToDigi.h @@ -9,7 +9,11 @@ class GEMRawToDigi { public: std::unique_ptr convertWordToAMC13Event(const uint64_t* word); + bool vfatError() const { return vfatError_; } + bool amcError() const { return amcError_; } private: + bool vfatError_; + bool amcError_; }; #endif diff --git a/EventFilter/GEMRawToDigi/plugins/GEMDigiToRawModule.cc b/EventFilter/GEMRawToDigi/plugins/GEMDigiToRawModule.cc index f9160ca142dcf..81db0ec5e1b0e 100644 --- a/EventFilter/GEMRawToDigi/plugins/GEMDigiToRawModule.cc +++ b/EventFilter/GEMRawToDigi/plugins/GEMDigiToRawModule.cc @@ -100,9 +100,9 @@ void GEMDigiToRawModule::produce(edm::StreamID iID, edm::Event& iEvent, edm::Eve std::vector> amc13Events; amc13Events.reserve(FEDNumbering::MAXGEMFEDID - FEDNumbering::MINGEMFEDID + 1); - uint32_t LV1_id = iEvent.id().event(); - uint16_t BX_id = iEvent.bunchCrossing(); - uint32_t OrN = iEvent.orbitNumber(); + int LV1_id = iEvent.id().event(); + uint8_t BX_id(iEvent.bunchCrossing()); + int OrN = iEvent.orbitNumber(); // making map of bx GEMDigiCollection // each bx will be saved as new AMC13Event, so GEMDigiCollection needs to be split into bx @@ -123,37 +123,36 @@ void GEMDigiToRawModule::produce(edm::StreamID iID, edm::Event& iEvent, edm::Eve } } - for (unsigned int fedId = FEDNumbering::MINGEMFEDID; fedId <= FEDNumbering::MAXGEMFEDID; ++fedId) { + for (unsigned int fedId = FEDNumbering::MINGEMFEDID; fedId <= FEDNumbering::MAXME0FEDID; ++fedId) { uint32_t amc13EvtLength = 0; std::unique_ptr amc13Event = std::make_unique(); - for (auto const& gemBx : gemBxMap) { - int bx = gemBx.first; - GEMDigiCollection inBxGemDigis = gemBx.second; + for (uint8_t amcNum = 0; amcNum < GEMeMap::maxAMCs_; ++amcNum) { + uint32_t amcSize = 0; + std::unique_ptr amcData = std::make_unique(); - for (uint8_t amcNum = 0; amcNum < GEMeMap::maxAMCs_; ++amcNum) { - uint32_t amcSize = 0; - std::unique_ptr amcData = std::make_unique(); + for (uint8_t gebId = 0; gebId < GEMeMap::maxGEBs_; ++gebId) { + std::unique_ptr gebData = std::make_unique(); + GEMROMapping::chamEC geb_ec{fedId, amcNum, gebId}; - for (uint8_t gebId = 0; gebId < GEMeMap::maxGEBs_; ++gebId) { - std::unique_ptr gebData = std::make_unique(); - GEMROMapping::chamEC geb_ec{fedId, amcNum, gebId}; + if (!gemROMap->isValidChamber(geb_ec)) + continue; + GEMROMapping::chamDC geb_dc = gemROMap->chamberPos(geb_ec); - if (!gemROMap->isValidChamber(geb_ec)) - continue; - GEMROMapping::chamDC geb_dc = gemROMap->chamberPos(geb_ec); + auto vfats = gemROMap->getVfats(geb_dc.detId); + for (auto const& vfat_ec : vfats) { + GEMROMapping::vfatDC vfat_dc = gemROMap->vfatPos(vfat_ec); + GEMDetId gemId = vfat_dc.detId; + uint16_t vfatId = vfat_ec.vfatAdd; - auto vfats = gemROMap->getVfats(geb_dc.detId); - for (auto const& vfat_ec : vfats) { - GEMROMapping::vfatDC vfat_dc = gemROMap->vfatPos(vfat_ec); - GEMDetId gemId = vfat_dc.detId; - uint16_t vfatId = vfat_ec.vfatAdd; + for (auto const& gemBx : gemBxMap) { + int bc = BX_id + gemBx.first; bool hasDigi = false; - uint64_t lsData = 0; ///(geb_dc.vfatVer, bx, 0, vfatId, lsData, msData); + auto vfatData = std::make_unique(geb_dc.vfatVer, bc, 0, vfatId, lsData, msData); gebData->addVFAT(*vfatData); - - } // end of vfats in GEB - - if (!gebData->vFATs()->empty()) { - amcSize += 2; - gebData->setChamberHeader(gebData->vFATs()->size() * 3, gebId); - gebData->setChamberTrailer(0, 0, gebData->vFATs()->size() * 3); - amcData->addGEB(*gebData); } - } // end of GEB loop - - if (!amcData->gebs()->empty()) { - amcSize += 5; - amcData->setAMCheader1(amcSize, bx, LV1_id, amcNum); - amcData->setAMCheader2(amcNum, OrN, 1); - amcData->setGEMeventHeader(amcData->gebs()->size(), 0); - amc13Event->addAMCpayload(*amcData); - // AMC header in AMC13Event - uint8_t Blk_No = 0; - uint8_t AMC_No = 0; - uint16_t BoardID = 0; - amc13Event->addAMCheader(amcSize, Blk_No, AMC_No, BoardID); - amc13EvtLength += amcSize + 1; // AMC data size + AMC header size + } // end of vfats in GEB + + if (!gebData->vFATs()->empty()) { + amcSize += 2; + gebData->setChamberHeader(gebData->vFATs()->size() * 3, gebId); + gebData->setChamberTrailer(LV1_id, BX_id, gebData->vFATs()->size() * 3); + amcData->addGEB(*gebData); } + } // end of GEB loop - } // end of AMC loop - } // end of BX loop + amcSize += 5; + amcData->setAMCheader1(amcSize, BX_id, LV1_id, amcNum); + amcData->setAMCheader2(amcNum, OrN, 1); + amcData->setGEMeventHeader(amcData->gebs()->size(), 0); + amc13Event->addAMCpayload(*amcData); + // AMC header in AMC13Event + amc13Event->addAMCheader(amcSize, 0, amcNum, 0); + amc13EvtLength += amcSize + 1; // AMC data size + AMC header size + + } // end of AMC loop if (!amc13Event->getAMCpayloads()->empty()) { // CDFHeader @@ -223,9 +216,8 @@ void GEMDigiToRawModule::produce(edm::StreamID iID, edm::Event& iEvent, edm::Eve amc13Event->setAMC13Trailer(BX_id, LV1_id, BX_id); //CDF trailer uint32_t EvtLength = amc13EvtLength + 4; // 2 header and 2 trailer - LogDebug("GEMDigiToRawModule") << " EvtLength: " << int(EvtLength); - amc13Event->setCDFTrailer(EvtLength); + amc13Events.emplace_back(std::move(amc13Event)); } // finished making amc13Event data } // end of FED loop @@ -270,7 +262,6 @@ void GEMDigiToRawModule::produce(edm::StreamID iID, edm::Event& iEvent, edm::Eve uint64_t* w = reinterpret_cast(fedRawData.data()); for (const auto& word : words) { - LogDebug("GEMDigiToRawModule") << std::bitset<64>(word); *(w++) = word; } LogDebug("GEMDigiToRawModule") << " words " << words.size(); diff --git a/EventFilter/GEMRawToDigi/plugins/GEMRawToDigiModule.cc b/EventFilter/GEMRawToDigi/plugins/GEMRawToDigiModule.cc index 1b5cedabe0e3a..4aea0fc923bb9 100644 --- a/EventFilter/GEMRawToDigi/plugins/GEMRawToDigiModule.cc +++ b/EventFilter/GEMRawToDigi/plugins/GEMRawToDigiModule.cc @@ -10,6 +10,7 @@ #include "DataFormats/Common/interface/Handle.h" #include "DataFormats/FEDRawData/interface/FEDNumbering.h" #include "DataFormats/FEDRawData/interface/FEDRawDataCollection.h" +#include "DataFormats/FEDRawData/interface/FEDTrailer.h" #include "DataFormats/GEMDigi/interface/AMC13Event.h" #include "DataFormats/GEMDigi/interface/GEMAMC13EventCollection.h" #include "DataFormats/GEMDigi/interface/GEMAMCdataCollection.h" @@ -118,23 +119,62 @@ void GEMRawToDigiModule::produce(edm::StreamID iID, edm::Event& iEvent, edm::Eve if (nWords < 5) continue; - const unsigned char* data = fedData.data(); - const uint64_t* word = reinterpret_cast(data); + // trailer checks + FEDTrailer trailer(fedData.data() + fedData.size() - FEDTrailer::length); + bool failTrailerCheck = false, failTrailerMatch = false; + if (!trailer.check() || (trailer.fragmentLength() * sizeof(uint64_t) != fedData.size())) { + failTrailerCheck = true; + } + + const unsigned char* data = fedData.data(); + const uint64_t* word = reinterpret_cast(data); auto amc13Event = gemRawToDigi_->convertWordToAMC13Event(word); - if (amc13Event == nullptr) + if (amc13Event == nullptr) { + LogDebug("GEMRawToDigiModule") << "AMC13Event FAILED to be produced"; + continue; + } + + // compare trailers found by last word of fedData.size() and gemRawToDigi + // caused by error in no. of AMC, GEB or VFAT stored in FEDs + if ((amc13Event->fragmentLength() != trailer.fragmentLength()) || (amc13Event->crc() != trailer.crc())) + failTrailerMatch = true; + + LogDebug("GEMRawToDigiModule") << "Event bx:" << iEvent.bunchCrossing() << " lv1Id:" << iEvent.id().event() + << " orbitNumber:" << iEvent.orbitNumber(); + LogDebug("GEMRawToDigiModule") << "AMC13 bx:" << amc13Event->bxId() << " lv1Id:" << int(amc13Event->lv1Id()) + << " orbitNumber:" << amc13Event->orbitNumber(); + + if (failTrailerCheck || failTrailerMatch) { + // best to skip these events since FED is most likely corrupt + edm::LogWarning("GEMRawToDigiModule") + << "FED trailer: fail check? " << failTrailerCheck << " fail match? " << failTrailerMatch; continue; + } + + bool unknownChamber = false, unknownVFat = false, badVfat = false; // Read AMC data for (auto amcData : *(amc13Event->getAMCpayloads())) { + uint16_t amcBx = amcData.bx(); uint8_t amcNum = amcData.amcNum(); + LogDebug("GEMRawToDigiModule") << "AMC no.:" << int(amcData.amcNum()) << " bx:" << int(amcData.bx()) + << " lv1Id:" << int(amcData.l1A()) << " orbitNumber:" << int(amcData.orbitNum()); // Read GEB data for (auto gebData : *amcData.gebs()) { uint8_t gebId = gebData.inputID(); GEMROMapping::chamEC geb_ec = {fedId, amcNum, gebId}; + + // check if Chamber exists. + if (!gemROMap->isValidChamber(geb_ec)) { + unknownChamber = true; + LogDebug("GEMRawToDigiModule") << "InValid: amcNum " << int(amcNum) << " gebId " << int(gebId); + continue; + } + GEMROMapping::chamDC geb_dc = gemROMap->chamberPos(geb_ec); GEMDetId gemChId = geb_dc.detId; @@ -146,19 +186,20 @@ void GEMRawToDigiModule::produce(edm::StreamID iID, edm::Event& iEvent, edm::Eve // check if ChipID exists. if (!gemROMap->isValidChipID(vfat_ec)) { - edm::LogWarning("GEMRawToDigiModule") - << "InValid: amcNum " << int(amcNum) << " gebId " << int(gebId) << " vfatId " << int(vfatId) - << " vfat Pos " << int(vfatData.position()); + unknownVFat = true; + LogDebug("GEMRawToDigiModule") << "InValid: amcNum " << int(amcNum) << " gebId " << int(gebId) << " vfatId " + << int(vfatId) << " vfat Pos " << int(vfatData.position()); continue; } + // check vfat data if (vfatData.quality()) { - edm::LogWarning("GEMRawToDigiModule") + badVfat = true; + LogDebug("GEMRawToDigiModule") << "Quality " << int(vfatData.quality()) << " b1010 " << int(vfatData.b1010()) << " b1100 " << int(vfatData.b1100()) << " b1110 " << int(vfatData.b1110()); if (vfatData.crc() != vfatData.checkCRC()) { - edm::LogWarning("GEMRawToDigiModule") - << "DIFFERENT CRC :" << vfatData.crc() << " " << vfatData.checkCRC(); + LogDebug("GEMRawToDigiModule") << "DIFFERENT CRC :" << vfatData.crc() << " " << vfatData.checkCRC(); } } @@ -166,7 +207,7 @@ void GEMRawToDigiModule::produce(edm::StreamID iID, edm::Event& iEvent, edm::Eve vfatData.setPhi(vfat_dc.localPhi); GEMDetId gemId = vfat_dc.detId; - int bx(vfatData.bc()); + int bx(vfatData.bc() - amcBx); for (int chan = 0; chan < VFATdata::nChannels; ++chan) { uint8_t chan0xf = 0; @@ -220,6 +261,11 @@ void GEMRawToDigiModule::produce(edm::StreamID iID, edm::Event& iEvent, edm::Eve outAMC13Event.get()->insertDigi(amc13Event->bxId(), AMC13Event(*amc13Event)); } + if (unknownChamber || unknownVFat || badVfat) { + edm::LogWarning("GEMRawToDigiModule") << "unpacking error: unknown Chamber " << unknownChamber << " unknown VFat " + << unknownVFat << " bad VFat " << badVfat; + } + } // end of amc13Event iEvent.put(std::move(outGEMDigis)); diff --git a/EventFilter/GEMRawToDigi/src/GEMRawToDigi.cc b/EventFilter/GEMRawToDigi/src/GEMRawToDigi.cc index 9409da674cbe0..51d0f84d070d3 100644 --- a/EventFilter/GEMRawToDigi/src/GEMRawToDigi.cc +++ b/EventFilter/GEMRawToDigi/src/GEMRawToDigi.cc @@ -2,10 +2,13 @@ * \author J. Lee, Yechan Kang - UoS */ #include "EventFilter/GEMRawToDigi/interface/GEMRawToDigi.h" - +#include "FWCore/MessageLogger/interface/MessageLogger.h" using namespace gem; std::unique_ptr GEMRawToDigi::convertWordToAMC13Event(const uint64_t* word) { + vfatError_ = false; + amcError_ = false; + auto amc13Event = std::make_unique(); amc13Event->setCDFHeader(*word); @@ -38,16 +41,18 @@ std::unique_ptr GEMRawToDigi::convertWordToAMC13Event(const uint64_t } // end of vfat loop gebData.setChamberTrailer(*(++word)); - if (gebData.vfatWordCnt() != gebData.vfatWordCntT()) - return nullptr; + if (gebData.vfatWordCnt() != gebData.vfatWordCntT()) { + vfatError_ = true; + } amcData.addGEB(gebData); } // end of geb loop amcData.setGEMeventTrailer(*(++word)); amcData.setAMCTrailer(*(++word)); - if (amc13Event->getAMCsize(i) != amcData.dataLength()) - return nullptr; + if (amc13Event->getAMCsize(i) != amcData.dataLength()) { + amcError_ = true; + } amc13Event->addAMCpayload(amcData); } // end of amc loop