25 : calculate_crc_(
config.getParameter<
bool>(
"calculateCRC")),
26 fill_counters_(
config.getParameter<
bool>(
"fillCounters")),
27 bx_min_(
config.getParameter<
int>(
"bxMin")),
28 bx_max_(
config.getParameter<
int>(
"bxMax")) {
29 produces<RPCDigiCollection>();
31 produces<RPCAMCLinkCounters>();
40 unsigned char const *uchars(reinterpret_cast<unsigned char const *>(&
word));
41 for (
unsigned char const *uchar = uchars + 7; uchar >= uchars; --uchar) {
49 desc.
add<
bool>(
"calculateCRC",
true);
50 desc.
add<
bool>(
"fillCounters",
true);
51 desc.
add<
int>(
"bxMin", -2);
52 desc.
add<
int>(
"bxMax", 2);
53 descs.
add(
"rpcTwinMuxRawToDigi", desc);
61 feds.insert(tm_link.first.getFED());
74 event.getByToken(
raw_token_, raw_data_collection);
76 std::set<std::pair<RPCDetId, RPCDigi> > rpc_digis;
80 for (
int fed :
feds_) {
85 std::uint16_t crc(0xffff);
96 LogDebug(
"RPCTwinMuxRawToDigi") <<
"Handling FED " << fed <<
" with length " << nwords;
109 while (
word < word_end) {
116 word_end = reinterpret_cast<std::uint64_t const *>(raw_data.
data()) + nwords - 1;
121 FEDTrailer trailer(reinterpret_cast<unsigned char const *>(word_end));
122 if ((
unsigned int)(trailer.
crc()) != crc) {
126 edm::LogWarning(
"RPCTwinMuxRawToDigi") <<
"FED Trailer CRC doesn't match for FED id " << fed;
142 bool more_headers(
true);
143 for (;
word < word_end && more_headers; ++
word) {
154 edm::LogWarning(
"RPCTwinMuxRawToDigi") <<
"FED Header check failed for FED id " << fed;
158 if (
header.sourceID() != fed) {
163 <<
"FED Header Source ID " <<
header.sourceID() <<
" does not match requested FED id " << fed;
169 more_headers =
false;
172 return !more_headers;
181 bool more_trailers(
true);
182 for (--word_end; word_end >
word && more_trailers; --word_end) {
183 FEDTrailer trailer(reinterpret_cast<unsigned char const *>(word_end));
184 LogDebug(
"RPCTwinMuxRawToDigi") <<
"CDF Trailer " << std::hex << *word_end <<
std::dec <<
", length "
186 if (!trailer.
check()) {
190 edm::LogWarning(
"RPCTwinMuxRawToDigi") <<
"FED Trailer check failed for FED id " << fed;
199 <<
" does not match actual data size " << nwords <<
" for FED id " << fed;
206 more_trailers =
false;
211 return !more_trailers;
219 std::set<std::pair<RPCDetId, RPCDigi> > &digis)
const {
227 unsigned int n_amc(block_header.
getNAMC());
228 if (
word + n_amc + 1 >= word_end) {
232 edm::LogWarning(
"RPCTwinMuxRawToDigi") <<
"Block can not be complete for FED " << fed;
237 std::vector<std::pair<unsigned int, unsigned int> > amc_size_map;
238 for (
unsigned int amc = 0;
amc < n_amc; ++
amc) {
239 LogDebug(
"RPCTwinMuxRawToDigi") <<
"Block AMC " <<
amc;
252 <<
"BlockAMCContent is reporting an invalid "
253 <<
"Event Counter or Bunch Counter for FED " << fed <<
", AMC " << amc_content.
getAMCNumber();
257 for (std::pair<unsigned int, unsigned int>
const &amc_size : amc_size_map) {
258 processTwinMux(fed, amc_size.first, amc_size.second,
word, word_end, crc, counters, digis);
261 if (
word < word_end) {
274 unsigned int amc_number,
280 std::set<std::pair<RPCDetId, RPCDigi> > &digis)
const {
281 LogDebug(
"RPCTwinMuxRawToDigi") <<
"TwinMux AMC#" << amc_number <<
", size " <<
size;
289 edm::LogWarning(
"RPCTwinMuxRawToDigi") <<
"Invalid AMC Number " << amc_number <<
" for FED " << fed;
304 <<
"TwinMux Data can not be complete for FED " << fed <<
" AMC #" << amc_number;
316 unsigned int bx_counter(
header.getBXCounter());
327 if (amc_number !=
header.getAMCNumber()) {
332 <<
"AMC Number inconsistent in TwinMuxHeader vs BlockAMCContent: " <<
header.getAMCNumber() <<
" vs "
345 if (
header.hasRPCBXWindow()) {
348 LogDebug(
"RPCTwinMuxRawToDigi") <<
"BX range set to " << bx_min <<
", " << bx_max;
351 bool has_first_rpc_word(
false);
360 if (has_first_rpc_word) {
361 processRPCRecord(fed, amc_number, bx_counter, rpc_record, counters, digis, bx_min, bx_max, 0, 1);
365 has_first_rpc_word =
true;
367 if (!has_first_rpc_word) {
368 edm::LogWarning(
"RPCTwinMuxRawToDigi") <<
"Received second RPC word without first";
371 processRPCRecord(fed, amc_number, bx_counter, rpc_record, counters, digis, bx_min, bx_max, 0, 4);
372 has_first_rpc_word =
false;
376 if (has_first_rpc_word) {
377 processRPCRecord(fed, amc_number, bx_counter, rpc_record, counters, digis, bx_min, bx_max, 0, 1);
390 unsigned int amc_number,
391 unsigned int bx_counter,
394 std::set<std::pair<RPCDetId, RPCDigi> > &digis,
398 unsigned int link_max)
const {
399 LogDebug(
"RPCTwinMuxRawToDigi") <<
"RPCRecord " << std::hex <<
record.getRecord()[0] <<
", " <<
record.getRecord()[1]
401 int bx_offset(
record.getBXOffset());
404 tm_link.setAMCInput(
link);
407 if (link_record.isError()) {
411 LogDebug(
"RPCTwinMuxRawToDigi") <<
"Link in error for " << tm_link;
413 }
else if (!link_record.isAcknowledge()) {
417 LogDebug(
"RPCTwinMuxRawToDigi") <<
"Link without acknowledge for " << tm_link;
421 if (!link_record.getPartitionData()) {
425 int bx(bx_offset - (
int)(link_record.getDelay()));
426 LogDebug(
"RPCTwinMuxRawToDigi") <<
"RPC BX " <<
bx <<
" for offset " << bx_offset;
437 LogDebug(
"RPCTwinMuxRawToDigi") <<
"Skipping unknown TwinMuxLink " << tm_link;
447 LogDebug(
"RPCTwinMuxRawToDigi") <<
"Skipping invalid LinkBoard " << link_record.getLinkBoard() <<
" for record "
448 <<
link <<
" (" << std::hex << link_record.getRecord() <<
" in "
458 LogDebug(
"RPCTwinMuxRawToDigi") <<
"Skipping invalid Connector " << link_record.getConnector() <<
" for record "
459 <<
link <<
" (" << std::hex << link_record.getRecord() <<
" in "
473 LogDebug(
"RPCTwinMuxRawToDigi") <<
"Could not find " << lb_link <<
" for record " <<
link <<
" (" << std::hex
474 << link_record.getRecord() <<
" in " <<
record.getRecord()[0] <<
':'
479 if (bx < bx_min || bx > bx_max) {
490 unsigned int channel_offset(link_record.getPartition() ? 9 : 1);
491 std::uint8_t
data(link_record.getPartitionData());
493 for (
unsigned int channel = 0; channel < 8; ++channel) {
494 if (
data & (0
x1 << channel)) {
495 unsigned int strip(feb_connector.
getStrip(channel + channel_offset));
497 digis.insert(std::pair<RPCDetId, RPCDigi>(det_id,
RPCDigi(
strip,
bx)));
498 LogDebug(
"RPCTwinMuxRawToDigi") <<
"RPCDigi " << det_id.rawId() <<
", " <<
strip <<
", " <<
bx;
510 std::vector<RPCDigi> local_digis;
511 for (std::pair<RPCDetId, RPCDigi>
const &rpc_digi : digis) {
512 LogDebug(
"RPCTwinMuxRawToDigi") <<
"RPCDigi " << rpc_digi.first.rawId() <<
", " << rpc_digi.second.strip() <<
", "
513 << rpc_digi.second.bx();
514 if (rpc_digi.first != rpc_det_id) {
515 if (!local_digis.empty()) {
519 rpc_det_id = rpc_digi.first;
521 local_digis.push_back(rpc_digi.second);
523 if (!local_digis.empty()) {
527 event.put(
std::move(rpc_digi_collection));