Skip to content

Commit

Permalink
Merge pull request #31863 from jshlee/gem-unpacker-update-CMSSW_11_2_…
Browse files Browse the repository at this point in the history
…0_pre6

GEM unpacker: bugfix and more cross checks
  • Loading branch information
cmsbuild authored Oct 22, 2020
2 parents 9d0ce20 + 78a7536 commit 3c9bd1b
Show file tree
Hide file tree
Showing 6 changed files with 125 additions and 69 deletions.
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_; }

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

0 comments on commit 3c9bd1b

Please sign in to comment.