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