CMS 3D CMS Logo

RPCAMCRawToDigi.cc
Go to the documentation of this file.
2 
3 #include <memory>
4 
12 
19 
21  : calculate_crc_(config.getParameter<bool>("calculateCRC"))
22  , fill_counters_(config.getParameter<bool>("fillCounters"))
23  , rpc_unpacker_(RPCAMCUnpackerFactory::get()->create(config.getParameter<std::string>("RPCAMCUnpacker")
24  , *this
25  , config.getParameter<edm::ParameterSet>("RPCAMCUnpackerSettings")))
26 {
27  if (fill_counters_) {
28  produces<RPCAMCLinkCounters>();
29  }
30 
31  raw_token_ = consumes<FEDRawDataCollection>(config.getParameter<edm::InputTag>("inputTag"));
32 }
33 
35 {}
36 
38 {
40  desc.add<edm::InputTag>("inputTag", edm::InputTag("rawDataCollector", ""));
41  desc.add<bool>("calculateCRC", true);
42  desc.add<bool>("fillCounters", true);
43  desc.add<std::string>("RPCAMCUnpacker", "RPCAMCUnpacker");
45  descs.add("RPCAMCRawToDigi", desc);
46 }
47 
49 {
50  rpc_unpacker_->beginRun(run, setup);
51 }
52 
54 {
55  // Get RAW Data
56  edm::Handle<FEDRawDataCollection> raw_data_collection;
57  event.getByToken(raw_token_, raw_data_collection);
58 
59  std::unique_ptr<RPCAMCLinkCounters> counters(new RPCAMCLinkCounters());
60 
61  std::map<RPCAMCLink, rpcamc13::AMCPayload> amc_payload;
62 
63  // Loop over the FEDs
64  for (int fed : rpc_unpacker_->getFeds()) {
65 
66  if (fill_counters_) {
68  }
69 
70  std::uint16_t crc(0xffff);
71 
72  FEDRawData const & raw_data = raw_data_collection->FEDData(fed);
73  unsigned int nwords(raw_data.size() / sizeof(std::uint64_t));
74  if (!nwords) {
75  continue;
76  }
77 
78  std::uint64_t const * word(reinterpret_cast<std::uint64_t const *>(raw_data.data()));
79  std::uint64_t const * word_end = word + nwords;
80 
81  LogDebug("RPCAMCRawToDigi") << "Handling FED " << fed << " with length " << nwords;
82 
83  // Handle the CDF Headers
84  if (!processCDFHeaders(fed
85  , word, word_end
86  , crc, *counters)) {
87  continue;
88  }
89 
90  // Handle the CDF Trailers
91  if (!processCDFTrailers(fed, nwords
92  , word, word_end
93  , crc, *counters)) {
94  continue;
95  }
96 
97  // Loop over the Blocks
98  if (!processBlocks(fed
99  , word, word_end
100  , crc, *counters, amc_payload)) {
101  continue;
102  }
103 
104  // Complete CRC check with trailer
105  if (calculate_crc_) {
106  word = word_end;
107  word_end = reinterpret_cast<std::uint64_t const *>(raw_data.data()) + nwords - 1;
108  for ( ; word < word_end ; ++word) {
109  compute_crc16_64bit(crc, *word);
110  }
111  compute_crc16_64bit(crc, (*word & 0xffffffff0000ffff)); // trailer excluding crc
112  FEDTrailer trailer(reinterpret_cast<unsigned char const *>(word_end));
113  if ((unsigned int)(trailer.crc()) != crc) {
114  if (fill_counters_) {
116  }
117  edm::LogWarning("RPCAMCRawToDigi") << "FED Trailer CRC doesn't match for FED id " << fed;
118  continue;
119  }
120  }
121 
122  }
123 
124  rpc_unpacker_->produce(event, setup
125  , amc_payload);
126 
127  if (fill_counters_) {
128  event.put(std::move(counters));
129  }
130 }
131 
133  , std::uint64_t const * & word, std::uint64_t const * & word_end
134  , std::uint16_t & crc
135  , RPCAMCLinkCounters & counters) const
136 {
137  bool more_headers(true);
138  for ( ; word < word_end && more_headers ; ++word) {
139  if (calculate_crc_) {
140  compute_crc16_64bit(crc, *word);
141  }
142 
143  LogDebug("RPCAMCRawToDigi") << "CDF Header " << std::hex << *word << std::dec;
144  FEDHeader header(reinterpret_cast<unsigned char const *>(word));
145  if (!header.check()) {
146  if (fill_counters_) {
148  }
149  edm::LogWarning("RPCAMCRawToDigi") << "FED Header check failed for FED id " << fed;
150  ++word;
151  return false;
152  }
153  if (header.sourceID() != fed) {
154  if (fill_counters_) {
156  }
157  edm::LogWarning("RPCAMCRawToDigi") << "FED Header Source ID " << header.sourceID()
158  << " does not match requested FED id " << fed;
159  ++word;
160  return false;
161  }
162 
163  // moreHeaders() not used
164  // more_headers = header.moreHeaders();
165  more_headers = false;
166  }
167 
168  return !more_headers;
169 }
170 
171 bool RPCAMCRawToDigi::processCDFTrailers(int fed, unsigned int nwords
172  , std::uint64_t const * & word, std::uint64_t const * & word_end
173  , std::uint16_t & crc
174  , RPCAMCLinkCounters & counters) const
175 {
176  bool more_trailers(true);
177  for (--word_end ; word_end > word && more_trailers ; --word_end) {
178  FEDTrailer trailer(reinterpret_cast<unsigned char const *>(word_end));
179  LogDebug("RPCAMCRawToDigi") << "CDF Trailer " << std::hex << *word_end << std::dec
180  << ", length " << trailer.fragmentLength();
181  if (!trailer.check()) {
182  if (fill_counters_) {
184  }
185  edm::LogWarning("RPCAMCRawToDigi") << "FED Trailer check failed for FED id " << fed;
186  return false;
187  }
188  if (trailer.fragmentLength() != nwords) {
189  if (fill_counters_) {
191  }
192  edm::LogWarning("RPCAMCRawToDigi") << "FED Trailer length " << trailer.fragmentLength()
193  << " does not match actual data size " << nwords
194  << " for FED id " << fed;
195  return false;
196  }
197 
198  // moreTrailers() not used
199  // more_trailers = trailer.moreTrailers();
200  more_trailers = false;
201  }
202 
203  ++word_end;
204 
205  return !more_trailers;
206 }
207 
209  , std::uint64_t const * & word, std::uint64_t const * word_end
210  , std::uint16_t & crc
211  , RPCAMCLinkCounters & counters
212  , std::map<RPCAMCLink, rpcamc13::AMCPayload> & amc_payload) const
213 {
214  while (word < word_end) {
215  rpcamc13::Header header(*word);
216  if (calculate_crc_) {
217  compute_crc16_64bit(crc, *word);
218  }
219  ++word;
220 
221  unsigned int n_amc(header.getNAMC());
222  if (word + n_amc + 1 >= word_end) { // AMC Headers and AMC13 Trailer
223  if (fill_counters_) {
225  }
226  edm::LogWarning("RPCAMCRawToDigi") << "AMC13 Block can not be complete for FED " << fed;
227  word = word_end;
228  return false;
229  }
230 
231  std::uint64_t const * payload_word(word + n_amc);
232  std::uint64_t const * payload_word_end(payload_word);
233  for (unsigned int amc = 0 ; amc < n_amc ; ++amc) {
234  rpcamc13::AMCHeader amc13_amc_header(*word);
235  if (calculate_crc_) {
236  compute_crc16_64bit(crc, *word);
237  }
238  ++word;
239 
240  unsigned int size_in_block(amc13_amc_header.getSizeInBlock());
241  if (size_in_block == 0) {
242  continue;
243  }
244  payload_word = payload_word_end;
245  payload_word_end += size_in_block;
246 
247  unsigned int amc_number(amc13_amc_header.getAMCNumber());
248  if (amc_number > (unsigned int)RPCAMCLink::max_amcnumber_) {
249  if (fill_counters_) {
251  }
252  edm::LogWarning("RPCAMCRawToDigi") << "Invalid AMC Number " << amc_number << " for FED " << fed;
253  continue;
254  }
255 
256  if (payload_word_end > word_end) {
257  if (fill_counters_) {
259  }
260  edm::LogWarning("RPCAMCRawToDigi") << "AMC Block can not be complete for FED " << fed
261  << " at AMC " << amc_number;
262  return false;
263  }
264 
265  rpcamc13::AMCPayload & payload(amc_payload[RPCAMCLink(fed, amc_number)]);
266 
267  if (amc13_amc_header.isFirstBlock()) {
268  payload.setAMCHeader(amc13_amc_header);
269  if (fill_counters_) {
270  counters.add(RPCAMCLinkEvents::amc_event_, RPCAMCLink(fed, amc_number));
271  }
272 
273  if (!amc13_amc_header.isValid()) {
274  if (fill_counters_) {
275  counters.add(RPCAMCLinkEvents::amc_amc13_evc_bc_invalid_, RPCAMCLink(fed, amc_number));
276  }
277  edm::LogWarning("RPCAMCRawToDigi") << "AMC13 AMC Header is reporting an invalid "
278  << "Event Counter or Bunch Counter for FED " << fed
279  << ", AMC " << amc_number;
280  payload.setValid(false);
281  }
282 
283  rpcamc::Header amc_amc_header(payload_word);
284  if (amc_number!= amc_amc_header.getAMCNumber()) {
285  if (fill_counters_) {
286  counters.add(RPCAMCLinkEvents::amc_number_mismatch_, RPCAMCLink(fed, amc_number));
287  }
288  edm::LogWarning("RPCAMCRawToDigi") << "AMC Number inconsistent in AMC13 AMC Header vs AMC Header: " << amc_number
289  << " vs " << amc_amc_header.getAMCNumber();
290  payload.setValid(false);
291  }
292 
293  if (amc_amc_header.hasDataLength()
294  && amc13_amc_header.hasTotalSize()
295  && amc13_amc_header.getSize() != amc_amc_header.getDataLength()) {
296  if (fill_counters_) {
297  counters.add(RPCAMCLinkEvents::amc_size_mismatch_, RPCAMCLink(fed, amc_number));
298  }
299  edm::LogWarning("RPCAMCRawToDigi") << "AMC size inconsistent in AMC13 AMC Header vs AMC Header: " << amc13_amc_header.getSize()
300  << " vs " << amc_amc_header.getDataLength();
301  payload.setValid(false);
302  }
303  }
304 
305  if (amc13_amc_header.isLastBlock()) {
306  if (!amc13_amc_header.isFirstBlock()) {
307  edm::LogWarning("RPCAMCRawToDigi") << "Multiple blocks";
308  }
309  payload.getAMCHeader().setCRCOk(amc13_amc_header.isCRCOk());
310  payload.getAMCHeader().setLengthCorrect(amc13_amc_header.isLengthCorrect());
311 
312  if (!amc13_amc_header.isCRCOk()) {
313  if (fill_counters_) {
314  counters.add(RPCAMCLinkEvents::amc_amc13_crc_mismatch_, RPCAMCLink(fed, amc_number));
315  }
316  edm::LogWarning("RPCAMCRawToDigi") << "AMC13 AMC Header is reporting a mismatched "
317  << "Event Counter or Bunch Counter for FED " << fed
318  << ", AMC " << amc_number;
319  payload.setValid(false);
320  }
321 
322  if (!amc13_amc_header.isLengthCorrect()) {
323  if (fill_counters_) {
325  }
326  edm::LogWarning("RPCAMCRawToDigi") << "AMC13 AMC Header is reporting an incorrect length "
327  << "for FED " << fed << ", AMC " << amc_number;
328  payload.setValid(false);
329  }
330 
331  if (amc13_amc_header.hasTotalSize()
332  && amc13_amc_header.getSize() != (payload.getData().size() + size_in_block)) {
333  if (fill_counters_) {
335  }
336  edm::LogWarning("RPCAMCRawToDigi") << "Size in AMC13 AMC Header doesn't match payload size "
337  << "for FED " << fed << ", AMC " << amc_number;
338  payload.setValid(false);
339  }
340 
341  if (!payload.getData().empty() && (payload.getData().size() + size_in_block) < 3) {
342  if (fill_counters_) {
343  counters.add(RPCAMCLinkEvents::amc_payload_incomplete_, RPCAMCLink(fed, amc_number));
344  }
345  edm::LogWarning("RPCAMCRawToDigi") << "Size in AMC13 AMC Header doesn't match payload size "
346  << "for FED " << fed << ", AMC " << amc_number;
347  payload.setValid(false);
348  }
349  }
350 
351  if (size_in_block > 0) {
352  payload.insert(payload_word, size_in_block);
353  }
354  }
355 
356  if (calculate_crc_) {
357  for ( ; word < payload_word_end ; ++word) {
358  compute_crc16_64bit(crc, *word);
359  }
360  } else {
361  word = payload_word_end;
362  }
363 
364  if (calculate_crc_) {
365  compute_crc16_64bit(crc, *word);
366  }
367  ++word;
368  }
369  return true;
370 }
371 
#define LogDebug(id)
unsigned int getDataLength() const
static unsigned int const fed_amc13_amc_number_invalid_
T getParameter(std::string const &) const
static unsigned int const fed_trailer_crc_mismatch_
static unsigned int const amc_payload_incomplete_
static unsigned int const amc_size_mismatch_
void setAMCHeader(AMCHeader const &header)
static void compute_crc16_64bit(std::uint16_t &crc, std::uint64_t const &word)
static unsigned int const amc_event_
def create(alignables, pedeDump, additionalData, outputFile, config)
static unsigned int const fed_header_check_fail_
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:17
bool check() const
Check that the header is OK.
Definition: FEDHeader.cc:72
RPCAMCRawToDigi(edm::ParameterSet const &config)
edm::EDGetTokenT< FEDRawDataCollection > raw_token_
uint16_t sourceID() const
Identifier of the FED.
Definition: FEDHeader.cc:32
def setup(process, global_tag, zero_tesla=False)
Definition: GeneralSetup.py:1
uint16_t crc() const
Cyclic Redundancy Code of the event fragment including header and trailer.
Definition: FEDTrailer.cc:22
bool check() const
Check that the trailer is OK.
Definition: FEDTrailer.cc:83
unsigned int getNAMC() const
Definition: config.py:1
static unsigned int const amc_amc13_evc_bc_invalid_
void produce(edm::Event &event, edm::EventSetup const &setup) override
std::vector< std::uint64_t > const & getData() const
static unsigned int const fed_trailer_length_mismatch_
bool isLengthCorrect() const
size_t size() const
Lenght of the data buffer in bytes.
Definition: FEDRawData.h:47
uint32_t fragmentLength() const
The length of the event fragment counted in 64-bit words including header and trailer.
Definition: FEDTrailer.cc:17
bool hasDataLength() const
bool isCRCOk() const
AMCHeader const & getAMCHeader() const
unsigned int getSize() const
static void fillDescription(edm::ParameterSetDescription &desc)
void setLengthCorrect(bool length_correct)
const FEDRawData & FEDData(int fedid) const
retrieve data for fed
unsigned int getSizeInBlock() const
void insert(std::uint64_t const *word_begin, unsigned int size)
double amc
Definition: hdecay.h:20
static unsigned int const amc_amc13_length_incorrect_
bool isFirstBlock() const
bool hasTotalSize() const
unsigned int getAMCNumber() const
static void fillDescriptions(edm::ConfigurationDescriptions &descs)
static unsigned int const amc_amc13_size_inconsistent_
bool isLastBlock() const
ParameterDescriptionBase * add(U const &iLabel, T const &value)
bool isValid() const
static unsigned int const fed_header_id_mismatch_
static unsigned int const amc_number_mismatch_
static unsigned int const fed_amc13_block_incomplete_
void setValid(bool valid)
unsigned int getAMCNumber() const
void add(unsigned int event, RPCAMCLink const &link, unsigned int count=1)
static unsigned int const fed_event_
unsigned long long uint64_t
Definition: Time.h:15
bool processCDFTrailers(int fed, unsigned int nwords, std::uint64_t const *&word, std::uint64_t const *&word_end, std::uint16_t &crc, RPCAMCLinkCounters &counters) const
bool processBlocks(int fed, std::uint64_t const *&word, std::uint64_t const *word_end, std::uint16_t &crc, RPCAMCLinkCounters &counters, std::map< RPCAMCLink, rpcamc13::AMCPayload > &amc_payload) const
void add(std::string const &label, ParameterSetDescription const &psetDescription)
static unsigned int const amc_amc13_block_incomplete_
static unsigned int const amc_amc13_crc_mismatch_
bool processCDFHeaders(int fed, std::uint64_t const *&word, std::uint64_t const *&word_end, std::uint16_t &crc, RPCAMCLinkCounters &counters) const
HLT enums.
const unsigned char * data() const
Return a const pointer to the beginning of the data buffer.
Definition: FEDRawData.cc:28
void setCRCOk(bool crc_ok)
Definition: AMCSpec.h:8
void beginRun(edm::Run const &run, edm::EventSetup const &setup) override
std::unique_ptr< RPCAMCUnpacker > rpc_unpacker_
static unsigned int const fed_trailer_check_fail_
def move(src, dest)
Definition: eostools.py:510
T get(const Candidate &c)
Definition: component.h:55
Definition: event.py:1
Definition: Run.h:43