Skip to content

Commit 3c9bd1b

Browse files
authored
Merge pull request cms-sw#31863 from jshlee/gem-unpacker-update-CMSSW_11_2_0_pre6
GEM unpacker: bugfix and more cross checks
2 parents 9d0ce20 + 78a7536 commit 3c9bd1b

File tree

6 files changed

+125
-69
lines changed

6 files changed

+125
-69
lines changed

CondFormats/GEMObjects/interface/GEMeMap.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ class GEMeMap {
6060
static const int vfatTypeV3_ = 11; // VFAT v3
6161
static const int chipIdMask_ = 0xfff; // chipId mask for 12 bits
6262
static const int maxGEBs_ = 32; // 5 bits for GEB id
63-
static const int maxAMCs_ = 16; // 4 bits for AMC no.
63+
static const int maxAMCs_ = 15; // 4 bits for AMC no.
6464
static const int maxVFatGE0_ = 12; // vFat per eta partition, not known yet for ME0
6565
static const int maxVFatGE11_ = 3; // vFat per eta partition in GE11
6666
static const int maxVFatGE21_ = 6; // vFat per eta partition in GE21

DataFormats/GEMDigi/interface/AMC13Event.h

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,9 +39,15 @@ namespace gem {
3939
union CDFTrailer {
4040
uint64_t word;
4141
struct {
42-
uint64_t tts : 8; // tts (first 4 bits)
43-
uint64_t evtStat : 4; // event status
44-
uint64_t crcCDF : 20; // CDF crc (first 16 bits)
42+
uint64_t res1 : 2;
43+
uint64_t crcModified : 1;
44+
uint64_t moreTrailers : 1;
45+
uint64_t tts : 4; // tts
46+
uint64_t evtStat : 4; // event status
47+
uint64_t res2 : 2;
48+
uint64_t slinkError : 1;
49+
uint64_t wrongFedId : 1;
50+
uint64_t crcCDF : 16; // CDF crc
4551
uint64_t evtLength : 24; // event length
4652
uint64_t eventType : 4; // Event Type
4753
uint64_t cbA : 4; // 0xA
@@ -82,6 +88,10 @@ namespace gem {
8288
void setCDFTrailer(uint64_t word) { cdft_ = word; }
8389
void setCDFTrailer(uint32_t EvtLength);
8490
uint64_t getCDFTrailer() const { return cdft_; }
91+
uint32_t fragmentLength() const { return CDFTrailer{cdft_}.evtLength; }
92+
uint16_t crc() const { return CDFTrailer{cdft_}.crcCDF; }
93+
uint8_t evtStatus() const { return CDFTrailer{cdft_}.evtStat; }
94+
uint8_t ttsBits() const { return CDFTrailer{cdft_}.tts; }
8595

8696
int bxId() const { return (int8_t)CDFHeader{cdfh_}.bxId; }
8797
uint32_t lv1Id() const { return CDFHeader{cdfh_}.lv1Id; }

EventFilter/GEMRawToDigi/interface/GEMRawToDigi.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,11 @@
99
class GEMRawToDigi {
1010
public:
1111
std::unique_ptr<gem::AMC13Event> convertWordToAMC13Event(const uint64_t* word);
12+
bool vfatError() const { return vfatError_; }
13+
bool amcError() const { return amcError_; }
1214

1315
private:
16+
bool vfatError_;
17+
bool amcError_;
1418
};
1519
#endif

EventFilter/GEMRawToDigi/plugins/GEMDigiToRawModule.cc

Lines changed: 41 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -100,9 +100,9 @@ void GEMDigiToRawModule::produce(edm::StreamID iID, edm::Event& iEvent, edm::Eve
100100
std::vector<std::unique_ptr<AMC13Event>> amc13Events;
101101
amc13Events.reserve(FEDNumbering::MAXGEMFEDID - FEDNumbering::MINGEMFEDID + 1);
102102

103-
uint32_t LV1_id = iEvent.id().event();
104-
uint16_t BX_id = iEvent.bunchCrossing();
105-
uint32_t OrN = iEvent.orbitNumber();
103+
int LV1_id = iEvent.id().event();
104+
uint8_t BX_id(iEvent.bunchCrossing());
105+
int OrN = iEvent.orbitNumber();
106106

107107
// making map of bx GEMDigiCollection
108108
// 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
123123
}
124124
}
125125

126-
for (unsigned int fedId = FEDNumbering::MINGEMFEDID; fedId <= FEDNumbering::MAXGEMFEDID; ++fedId) {
126+
for (unsigned int fedId = FEDNumbering::MINGEMFEDID; fedId <= FEDNumbering::MAXME0FEDID; ++fedId) {
127127
uint32_t amc13EvtLength = 0;
128128
std::unique_ptr<AMC13Event> amc13Event = std::make_unique<AMC13Event>();
129129

130-
for (auto const& gemBx : gemBxMap) {
131-
int bx = gemBx.first;
132-
GEMDigiCollection inBxGemDigis = gemBx.second;
130+
for (uint8_t amcNum = 0; amcNum < GEMeMap::maxAMCs_; ++amcNum) {
131+
uint32_t amcSize = 0;
132+
std::unique_ptr<AMCdata> amcData = std::make_unique<AMCdata>();
133133

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

138-
for (uint8_t gebId = 0; gebId < GEMeMap::maxGEBs_; ++gebId) {
139-
std::unique_ptr<GEBdata> gebData = std::make_unique<GEBdata>();
140-
GEMROMapping::chamEC geb_ec{fedId, amcNum, gebId};
138+
if (!gemROMap->isValidChamber(geb_ec))
139+
continue;
140+
GEMROMapping::chamDC geb_dc = gemROMap->chamberPos(geb_ec);
141141

142-
if (!gemROMap->isValidChamber(geb_ec))
143-
continue;
144-
GEMROMapping::chamDC geb_dc = gemROMap->chamberPos(geb_ec);
142+
auto vfats = gemROMap->getVfats(geb_dc.detId);
143+
for (auto const& vfat_ec : vfats) {
144+
GEMROMapping::vfatDC vfat_dc = gemROMap->vfatPos(vfat_ec);
145+
GEMDetId gemId = vfat_dc.detId;
146+
uint16_t vfatId = vfat_ec.vfatAdd;
145147

146-
auto vfats = gemROMap->getVfats(geb_dc.detId);
147-
for (auto const& vfat_ec : vfats) {
148-
GEMROMapping::vfatDC vfat_dc = gemROMap->vfatPos(vfat_ec);
149-
GEMDetId gemId = vfat_dc.detId;
150-
uint16_t vfatId = vfat_ec.vfatAdd;
148+
for (auto const& gemBx : gemBxMap) {
149+
int bc = BX_id + gemBx.first;
151150

152151
bool hasDigi = false;
153-
154152
uint64_t lsData = 0; ///<channels from 1to64
155153
uint64_t msData = 0; ///<channels from 65to128
156154

155+
GEMDigiCollection inBxGemDigis = gemBx.second;
157156
const GEMDigiCollection::Range& range = inBxGemDigis.get(gemId);
158157
for (GEMDigiCollection::const_iterator digiIt = range.first; digiIt != range.second; ++digiIt) {
159158
const GEMDigi& digi = (*digiIt);
@@ -183,36 +182,30 @@ void GEMDigiToRawModule::produce(edm::StreamID iID, edm::Event& iEvent, edm::Eve
183182
continue;
184183
// only make vfat with hits
185184
amcSize += 3;
186-
auto vfatData = std::make_unique<VFATdata>(geb_dc.vfatVer, bx, 0, vfatId, lsData, msData);
185+
auto vfatData = std::make_unique<VFATdata>(geb_dc.vfatVer, bc, 0, vfatId, lsData, msData);
187186
gebData->addVFAT(*vfatData);
188-
189-
} // end of vfats in GEB
190-
191-
if (!gebData->vFATs()->empty()) {
192-
amcSize += 2;
193-
gebData->setChamberHeader(gebData->vFATs()->size() * 3, gebId);
194-
gebData->setChamberTrailer(0, 0, gebData->vFATs()->size() * 3);
195-
amcData->addGEB(*gebData);
196187
}
197188

198-
} // end of GEB loop
199-
200-
if (!amcData->gebs()->empty()) {
201-
amcSize += 5;
202-
amcData->setAMCheader1(amcSize, bx, LV1_id, amcNum);
203-
amcData->setAMCheader2(amcNum, OrN, 1);
204-
amcData->setGEMeventHeader(amcData->gebs()->size(), 0);
205-
amc13Event->addAMCpayload(*amcData);
206-
// AMC header in AMC13Event
207-
uint8_t Blk_No = 0;
208-
uint8_t AMC_No = 0;
209-
uint16_t BoardID = 0;
210-
amc13Event->addAMCheader(amcSize, Blk_No, AMC_No, BoardID);
211-
amc13EvtLength += amcSize + 1; // AMC data size + AMC header size
189+
} // end of vfats in GEB
190+
191+
if (!gebData->vFATs()->empty()) {
192+
amcSize += 2;
193+
gebData->setChamberHeader(gebData->vFATs()->size() * 3, gebId);
194+
gebData->setChamberTrailer(LV1_id, BX_id, gebData->vFATs()->size() * 3);
195+
amcData->addGEB(*gebData);
212196
}
197+
} // end of GEB loop
213198

214-
} // end of AMC loop
215-
} // end of BX loop
199+
amcSize += 5;
200+
amcData->setAMCheader1(amcSize, BX_id, LV1_id, amcNum);
201+
amcData->setAMCheader2(amcNum, OrN, 1);
202+
amcData->setGEMeventHeader(amcData->gebs()->size(), 0);
203+
amc13Event->addAMCpayload(*amcData);
204+
// AMC header in AMC13Event
205+
amc13Event->addAMCheader(amcSize, 0, amcNum, 0);
206+
amc13EvtLength += amcSize + 1; // AMC data size + AMC header size
207+
208+
} // end of AMC loop
216209

217210
if (!amc13Event->getAMCpayloads()->empty()) {
218211
// CDFHeader
@@ -223,9 +216,8 @@ void GEMDigiToRawModule::produce(edm::StreamID iID, edm::Event& iEvent, edm::Eve
223216
amc13Event->setAMC13Trailer(BX_id, LV1_id, BX_id);
224217
//CDF trailer
225218
uint32_t EvtLength = amc13EvtLength + 4; // 2 header and 2 trailer
226-
LogDebug("GEMDigiToRawModule") << " EvtLength: " << int(EvtLength);
227-
228219
amc13Event->setCDFTrailer(EvtLength);
220+
229221
amc13Events.emplace_back(std::move(amc13Event));
230222
} // finished making amc13Event data
231223
} // end of FED loop
@@ -270,7 +262,6 @@ void GEMDigiToRawModule::produce(edm::StreamID iID, edm::Event& iEvent, edm::Eve
270262

271263
uint64_t* w = reinterpret_cast<uint64_t*>(fedRawData.data());
272264
for (const auto& word : words) {
273-
LogDebug("GEMDigiToRawModule") << std::bitset<64>(word);
274265
*(w++) = word;
275266
}
276267
LogDebug("GEMDigiToRawModule") << " words " << words.size();

EventFilter/GEMRawToDigi/plugins/GEMRawToDigiModule.cc

Lines changed: 56 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include "DataFormats/Common/interface/Handle.h"
1111
#include "DataFormats/FEDRawData/interface/FEDNumbering.h"
1212
#include "DataFormats/FEDRawData/interface/FEDRawDataCollection.h"
13+
#include "DataFormats/FEDRawData/interface/FEDTrailer.h"
1314
#include "DataFormats/GEMDigi/interface/AMC13Event.h"
1415
#include "DataFormats/GEMDigi/interface/GEMAMC13EventCollection.h"
1516
#include "DataFormats/GEMDigi/interface/GEMAMCdataCollection.h"
@@ -118,23 +119,62 @@ void GEMRawToDigiModule::produce(edm::StreamID iID, edm::Event& iEvent, edm::Eve
118119

119120
if (nWords < 5)
120121
continue;
121-
const unsigned char* data = fedData.data();
122122

123-
const uint64_t* word = reinterpret_cast<const uint64_t*>(data);
123+
// trailer checks
124+
FEDTrailer trailer(fedData.data() + fedData.size() - FEDTrailer::length);
124125

126+
bool failTrailerCheck = false, failTrailerMatch = false;
127+
if (!trailer.check() || (trailer.fragmentLength() * sizeof(uint64_t) != fedData.size())) {
128+
failTrailerCheck = true;
129+
}
130+
131+
const unsigned char* data = fedData.data();
132+
const uint64_t* word = reinterpret_cast<const uint64_t*>(data);
125133
auto amc13Event = gemRawToDigi_->convertWordToAMC13Event(word);
126134

127-
if (amc13Event == nullptr)
135+
if (amc13Event == nullptr) {
136+
LogDebug("GEMRawToDigiModule") << "AMC13Event FAILED to be produced";
137+
continue;
138+
}
139+
140+
// compare trailers found by last word of fedData.size() and gemRawToDigi
141+
// caused by error in no. of AMC, GEB or VFAT stored in FEDs
142+
if ((amc13Event->fragmentLength() != trailer.fragmentLength()) || (amc13Event->crc() != trailer.crc()))
143+
failTrailerMatch = true;
144+
145+
LogDebug("GEMRawToDigiModule") << "Event bx:" << iEvent.bunchCrossing() << " lv1Id:" << iEvent.id().event()
146+
<< " orbitNumber:" << iEvent.orbitNumber();
147+
LogDebug("GEMRawToDigiModule") << "AMC13 bx:" << amc13Event->bxId() << " lv1Id:" << int(amc13Event->lv1Id())
148+
<< " orbitNumber:" << amc13Event->orbitNumber();
149+
150+
if (failTrailerCheck || failTrailerMatch) {
151+
// best to skip these events since FED is most likely corrupt
152+
edm::LogWarning("GEMRawToDigiModule")
153+
<< "FED trailer: fail check? " << failTrailerCheck << " fail match? " << failTrailerMatch;
128154
continue;
155+
}
156+
157+
bool unknownChamber = false, unknownVFat = false, badVfat = false;
129158

130159
// Read AMC data
131160
for (auto amcData : *(amc13Event->getAMCpayloads())) {
161+
uint16_t amcBx = amcData.bx();
132162
uint8_t amcNum = amcData.amcNum();
163+
LogDebug("GEMRawToDigiModule") << "AMC no.:" << int(amcData.amcNum()) << " bx:" << int(amcData.bx())
164+
<< " lv1Id:" << int(amcData.l1A()) << " orbitNumber:" << int(amcData.orbitNum());
133165

134166
// Read GEB data
135167
for (auto gebData : *amcData.gebs()) {
136168
uint8_t gebId = gebData.inputID();
137169
GEMROMapping::chamEC geb_ec = {fedId, amcNum, gebId};
170+
171+
// check if Chamber exists.
172+
if (!gemROMap->isValidChamber(geb_ec)) {
173+
unknownChamber = true;
174+
LogDebug("GEMRawToDigiModule") << "InValid: amcNum " << int(amcNum) << " gebId " << int(gebId);
175+
continue;
176+
}
177+
138178
GEMROMapping::chamDC geb_dc = gemROMap->chamberPos(geb_ec);
139179
GEMDetId gemChId = geb_dc.detId;
140180

@@ -146,27 +186,28 @@ void GEMRawToDigiModule::produce(edm::StreamID iID, edm::Event& iEvent, edm::Eve
146186

147187
// check if ChipID exists.
148188
if (!gemROMap->isValidChipID(vfat_ec)) {
149-
edm::LogWarning("GEMRawToDigiModule")
150-
<< "InValid: amcNum " << int(amcNum) << " gebId " << int(gebId) << " vfatId " << int(vfatId)
151-
<< " vfat Pos " << int(vfatData.position());
189+
unknownVFat = true;
190+
LogDebug("GEMRawToDigiModule") << "InValid: amcNum " << int(amcNum) << " gebId " << int(gebId) << " vfatId "
191+
<< int(vfatId) << " vfat Pos " << int(vfatData.position());
152192
continue;
153193
}
194+
154195
// check vfat data
155196
if (vfatData.quality()) {
156-
edm::LogWarning("GEMRawToDigiModule")
197+
badVfat = true;
198+
LogDebug("GEMRawToDigiModule")
157199
<< "Quality " << int(vfatData.quality()) << " b1010 " << int(vfatData.b1010()) << " b1100 "
158200
<< int(vfatData.b1100()) << " b1110 " << int(vfatData.b1110());
159201
if (vfatData.crc() != vfatData.checkCRC()) {
160-
edm::LogWarning("GEMRawToDigiModule")
161-
<< "DIFFERENT CRC :" << vfatData.crc() << " " << vfatData.checkCRC();
202+
LogDebug("GEMRawToDigiModule") << "DIFFERENT CRC :" << vfatData.crc() << " " << vfatData.checkCRC();
162203
}
163204
}
164205

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

167208
vfatData.setPhi(vfat_dc.localPhi);
168209
GEMDetId gemId = vfat_dc.detId;
169-
int bx(vfatData.bc());
210+
int bx(vfatData.bc() - amcBx);
170211

171212
for (int chan = 0; chan < VFATdata::nChannels; ++chan) {
172213
uint8_t chan0xf = 0;
@@ -220,6 +261,11 @@ void GEMRawToDigiModule::produce(edm::StreamID iID, edm::Event& iEvent, edm::Eve
220261
outAMC13Event.get()->insertDigi(amc13Event->bxId(), AMC13Event(*amc13Event));
221262
}
222263

264+
if (unknownChamber || unknownVFat || badVfat) {
265+
edm::LogWarning("GEMRawToDigiModule") << "unpacking error: unknown Chamber " << unknownChamber << " unknown VFat "
266+
<< unknownVFat << " bad VFat " << badVfat;
267+
}
268+
223269
} // end of amc13Event
224270

225271
iEvent.put(std::move(outGEMDigis));

EventFilter/GEMRawToDigi/src/GEMRawToDigi.cc

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,13 @@
22
* \author J. Lee, Yechan Kang - UoS
33
*/
44
#include "EventFilter/GEMRawToDigi/interface/GEMRawToDigi.h"
5-
5+
#include "FWCore/MessageLogger/interface/MessageLogger.h"
66
using namespace gem;
77

88
std::unique_ptr<AMC13Event> GEMRawToDigi::convertWordToAMC13Event(const uint64_t* word) {
9+
vfatError_ = false;
10+
amcError_ = false;
11+
912
auto amc13Event = std::make_unique<AMC13Event>();
1013

1114
amc13Event->setCDFHeader(*word);
@@ -38,16 +41,18 @@ std::unique_ptr<AMC13Event> GEMRawToDigi::convertWordToAMC13Event(const uint64_t
3841
} // end of vfat loop
3942

4043
gebData.setChamberTrailer(*(++word));
41-
if (gebData.vfatWordCnt() != gebData.vfatWordCntT())
42-
return nullptr;
44+
if (gebData.vfatWordCnt() != gebData.vfatWordCntT()) {
45+
vfatError_ = true;
46+
}
4347
amcData.addGEB(gebData);
4448

4549
} // end of geb loop
4650

4751
amcData.setGEMeventTrailer(*(++word));
4852
amcData.setAMCTrailer(*(++word));
49-
if (amc13Event->getAMCsize(i) != amcData.dataLength())
50-
return nullptr;
53+
if (amc13Event->getAMCsize(i) != amcData.dataLength()) {
54+
amcError_ = true;
55+
}
5156
amc13Event->addAMCpayload(amcData);
5257

5358
} // end of amc loop

0 commit comments

Comments
 (0)