Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

GEM unpacker: bugfix and more cross checks #31863

Merged
merged 10 commits into from
Oct 22, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion CondFormats/GEMObjects/interface/GEMeMap.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
16 changes: 13 additions & 3 deletions DataFormats/GEMDigi/interface/AMC13Event.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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; }
Expand Down
4 changes: 4 additions & 0 deletions EventFilter/GEMRawToDigi/interface/GEMRawToDigi.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,11 @@
class GEMRawToDigi {
public:
std::unique_ptr<gem::AMC13Event> convertWordToAMC13Event(const uint64_t* word);
bool vfatError() const { return vfatError_; }
bool amcError() const { return amcError_; }
Comment on lines +12 to +13
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I do not see use cases.
Are these added for some future use or was some code accidentally not committed?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It was used, but I removed the use cases when I reduced the LogWarnings.
I would like to add a few of these checks to the onlineDQM.


private:
bool vfatError_;
bool amcError_;
};
#endif
91 changes: 41 additions & 50 deletions EventFilter/GEMRawToDigi/plugins/GEMDigiToRawModule.cc
Original file line number Diff line number Diff line change
Expand Up @@ -100,9 +100,9 @@ void GEMDigiToRawModule::produce(edm::StreamID iID, edm::Event& iEvent, edm::Eve
std::vector<std::unique_ptr<AMC13Event>> 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
Expand All @@ -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> amc13Event = std::make_unique<AMC13Event>();

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> amcData = std::make_unique<AMCdata>();

for (uint8_t amcNum = 0; amcNum < GEMeMap::maxAMCs_; ++amcNum) {
uint32_t amcSize = 0;
std::unique_ptr<AMCdata> amcData = std::make_unique<AMCdata>();
for (uint8_t gebId = 0; gebId < GEMeMap::maxGEBs_; ++gebId) {
std::unique_ptr<GEBdata> gebData = std::make_unique<GEBdata>();
GEMROMapping::chamEC geb_ec{fedId, amcNum, gebId};

for (uint8_t gebId = 0; gebId < GEMeMap::maxGEBs_; ++gebId) {
std::unique_ptr<GEBdata> gebData = std::make_unique<GEBdata>();
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; ///<channels from 1to64
uint64_t msData = 0; ///<channels from 65to128

GEMDigiCollection inBxGemDigis = gemBx.second;
const GEMDigiCollection::Range& range = inBxGemDigis.get(gemId);
for (GEMDigiCollection::const_iterator digiIt = range.first; digiIt != range.second; ++digiIt) {
const GEMDigi& digi = (*digiIt);
Expand Down Expand Up @@ -183,36 +182,30 @@ void GEMDigiToRawModule::produce(edm::StreamID iID, edm::Event& iEvent, edm::Eve
continue;
// only make vfat with hits
amcSize += 3;
auto vfatData = std::make_unique<VFATdata>(geb_dc.vfatVer, bx, 0, vfatId, lsData, msData);
auto vfatData = std::make_unique<VFATdata>(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
Expand All @@ -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
Expand Down Expand Up @@ -270,7 +262,6 @@ void GEMDigiToRawModule::produce(edm::StreamID iID, edm::Event& iEvent, edm::Eve

uint64_t* w = reinterpret_cast<uint64_t*>(fedRawData.data());
for (const auto& word : words) {
LogDebug("GEMDigiToRawModule") << std::bitset<64>(word);
*(w++) = word;
}
LogDebug("GEMDigiToRawModule") << " words " << words.size();
Expand Down
66 changes: 56 additions & 10 deletions EventFilter/GEMRawToDigi/plugins/GEMRawToDigiModule.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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<const uint64_t*>(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<const uint64_t*>(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;

Expand All @@ -146,27 +186,28 @@ 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();
}
}

GEMROMapping::vfatDC vfat_dc = gemROMap->vfatPos(vfat_ec);

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;
Expand Down Expand Up @@ -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));
Expand Down
15 changes: 10 additions & 5 deletions EventFilter/GEMRawToDigi/src/GEMRawToDigi.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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<AMC13Event> GEMRawToDigi::convertWordToAMC13Event(const uint64_t* word) {
vfatError_ = false;
amcError_ = false;

auto amc13Event = std::make_unique<AMC13Event>();

amc13Event->setCDFHeader(*word);
Expand Down Expand Up @@ -38,16 +41,18 @@ std::unique_ptr<AMC13Event> 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
Expand Down