CMS 3D CMS Logo

GctRawToDigi.cc
Go to the documentation of this file.
2 
3 // System headers
4 #include <vector>
5 #include <sstream>
6 #include <iostream>
7 
8 // Framework headers
13 
14 // Raw data collection headers
17 
18 // GCT Format Translators
22 
23 // Unpack collections class
25 
26 // Namespace resolution
27 using std::cout;
28 using std::dec;
29 using std::endl;
30 using std::hex;
31 using std::string;
32 using std::vector;
33 
35  : inputLabel_(iConfig.getParameter<edm::InputTag>("inputLabel")),
36  fedId_(iConfig.getUntrackedParameter<int>("gctFedId", FEDNumbering::MINTriggerGCTFEDID)),
37  hltMode_(iConfig.getParameter<bool>("hltMode")),
38  numberOfGctSamplesToUnpack_(iConfig.getParameter<unsigned>("numberOfGctSamplesToUnpack")),
39  numberOfRctSamplesToUnpack_(iConfig.getParameter<unsigned>("numberOfRctSamplesToUnpack")),
40  unpackSharedRegions_(iConfig.getParameter<bool>("unpackSharedRegions")),
41  formatVersion_(iConfig.getParameter<unsigned>("unpackerVersion")),
42  checkHeaders_(iConfig.getUntrackedParameter<bool>("checkHeaders", false)),
43  verbose_(iConfig.getUntrackedParameter<bool>("verbose", false)),
44  formatTranslator_(nullptr),
45  errors_(nullptr),
46  errorCounters_(MAX_ERR_CODE + 1), // initialise with the maximum error codes!
47  unpackFailures_(0) {
48  LogDebug("GCT") << "GctRawToDigi will unpack FED Id " << fedId_;
49 
50  // If the GctFormatTranslate version has been forced from config file, instantiate the relevant one.
51  /*** THIS OBVIOUSLY STINKS - NEED TO REPLACE WITH SOMETHING BETTER THAN MASSIVE IF-ELSE SOON ***/
52  /*** WHEN THIS MESS IS REMOVED REMEMBER THAT THE V38 FORMAT TRANSLATE HAS A DIFERENT CTOR TO THE OTHERS ***/
53  if (formatVersion_ == 0) {
54  edm::LogInfo("GCT")
55  << "The required GCT Format Translator will be automatically determined from the first S-Link packet header.";
56  } else if (formatVersion_ == 1) {
57  edm::LogInfo("GCT") << "You have selected to use GctFormatTranslateMCLegacy";
59  } else if (formatVersion_ == 2) {
60  edm::LogInfo("GCT") << "You have selected to use GctFormatTranslateV35";
62  } else if (formatVersion_ == 3) {
63  edm::LogInfo("GCT") << "You have selected to use GctFormatTranslateV38";
66  } else {
67  edm::LogWarning("GCT")
68  << "You have requested a version of GctFormatTranslate that does not exist! Will attempt to auto-detect "
69  "the required GCT Format Translator from the first S-Link packet header instead.";
70  }
71 
72  if (hltMode_) {
73  edm::LogInfo("GCT") << "HLT unpack mode selected: HLT unpack optimisations will be used.";
74  }
76  edm::LogInfo("GCT") << "You have selected to unpack shared RCT calo regions - be warned: "
77  "this is for commissioning purposes only!";
78  }
79 
81  // GCT input collections
82  produces<L1GctFibreCollection>();
83  produces<L1CaloEmCollection>();
84  produces<L1CaloRegionCollection>();
85 
86  // GCT internal collections
87  produces<L1GctInternEmCandCollection>();
88  produces<L1GctInternJetDataCollection>();
89  produces<L1GctInternEtSumCollection>();
90  produces<L1GctInternHFDataCollection>();
91  produces<L1GctInternHtMissCollection>();
92 
93  // GCT output collections
94  produces<L1GctEmCandCollection>("isoEm");
95  produces<L1GctEmCandCollection>("nonIsoEm");
96  produces<L1GctJetCandCollection>("cenJets");
97  produces<L1GctJetCandCollection>("forJets");
98  produces<L1GctJetCandCollection>("tauJets");
99  produces<L1GctHFBitCountsCollection>();
100  produces<L1GctHFRingEtSumsCollection>();
101  produces<L1GctEtTotalCollection>();
102  produces<L1GctEtHadCollection>();
103  produces<L1GctEtMissCollection>();
104  produces<L1GctHtMissCollection>();
105  produces<L1GctJetCountsCollection>(); // Deprecated (empty collection still needed by GT)
106 
107  // Error collection
108  produces<L1TriggerErrorCollection>();
109  consumes<FEDRawDataCollection>(inputLabel_);
110 }
111 
113  // do anything here that needs to be done at destruction time
114  // (e.g. close files, deallocate resources etc.)
115  delete formatTranslator_;
116 }
117 
120  desc.add<bool>("unpackSharedRegions", false);
121  desc.add<unsigned int>("numberOfGctSamplesToUnpack", 1);
122  desc.add<unsigned int>("numberOfRctSamplesToUnpack", 1);
123  desc.add<bool>("hltMode", false);
124  desc.add<edm::InputTag>("inputLabel", edm::InputTag("rawDataCollector"));
125  static const char* const kComment =
126  " \n"
127  " value | Unpacker/RAW Format Version \n"
128  "-----------|---------------------------------------------------------------------------- \n"
129  " 0 | Auto-detects RAW Format in use - the recommended option \n"
130  " 1 | Force usage of the Monte-Carlo Legacy unpacker (unpacks DigiToRaw events) \n"
131  " 2 | Force usage of the RAW Format V35 unpacker \n"
132  " 3 | Force usage of the RAW Format V38 unpacker \n";
133  desc.add<unsigned int>("unpackerVersion", 0)->setComment(kComment);
134  desc.addUntracked<int>("gctFedId", 745);
135  desc.addUntracked<bool>("checkHeaders", false), desc.addUntracked<bool>("verbose", false);
136  descriptions.add("gctRawToDigi", desc);
137 }
138 
139 //
140 // member functions
141 //
142 
143 // ------------ method called to produce the data ------------
145  using namespace edm;
146 
147  // Instantiate all the collections the unpacker needs; puts them in event when this object goes out of scope.
148  std::unique_ptr<GctUnpackCollections> colls(new GctUnpackCollections(iEvent));
149  errors_ = colls->errors();
150 
151  // get raw data collection
153  iEvent.getByLabel(inputLabel_, feds);
154 
155  // if raw data collection is present, do the unpacking
156  if (feds.isValid()) {
157  const FEDRawData& gctRcd = feds->FEDData(fedId_);
158 
159  LogDebug("GCT") << "Upacking FEDRawData of size " << std::dec << gctRcd.size();
160 
161  // check for empty events
162  if (gctRcd.size() < 16) {
163  LogDebug("GCT") << "Cannot unpack: empty/invalid GCT raw data (size = " << gctRcd.size()
164  << "). Returning empty collections!";
165  addError(1);
166  return;
167  }
168 
169  // If no format translator yet set, need to auto-detect from header.
170  // If auto format detection fails, we have no concrete format
171  // translator instantiated... set error and bail
172  if (!formatTranslator_) {
174  return;
175  }
176 
177  // reset collection of block headers
178  blockHeaders_.clear();
179 
180  // do the unpacking
181  unpack(gctRcd, iEvent, colls.get());
182 
183  // check headers, if enabled
184  if (checkHeaders_)
185  checkHeaders();
186 
187  // dump summary in verbose mode
188  if (verbose_) {
189  doVerboseOutput(blockHeaders_, colls.get());
190  }
191  }
192 }
193 
195  // We should now have a valid formatTranslator pointer
197 
198  const unsigned char* data = d.data(); // The 8-bit wide raw-data array.
199 
200  // Data offset - starts at 16 as there is a 64-bit S-Link header followed
201  // by a 64-bit software-controlled header (for pipeline format version
202  // info that is not yet used).
203  unsigned dPtr = 16;
204 
205  const unsigned dEnd = d.size() - 8; // End of payload is at (packet size - final slink header)
206 
207  // read blocks
208  for (unsigned nb = 0; dPtr < dEnd; ++nb) {
209  if (nb >= MAX_BLOCKS) {
210  LogDebug("GCT") << "Reached block limit - bailing out from this event!";
211  addError(6);
212  break;
213  }
214 
215  // read block header
217 
218  // unpack the block; dPtr+4 is to get to the block data.
219  if (!formatTranslator_->convertBlock(&data[dPtr + 4],
220  blockHeader)) // Record if we had an unpack problem then skip rest of event.
221  {
222  LogDebug("GCT") << "Encountered block unpack error - bailing out from this event!";
223  addError(4);
224  break;
225  }
226 
227  // advance pointer
228  dPtr += 4 * (blockHeader.blockLength() * blockHeader.nSamples() +
229  1); // *4 because blockLen is in 32-bit words, +1 for header
230 
231  // if verbose or checking block headers, store the header
232  if (verbose_ || checkHeaders_)
233  blockHeaders_.push_back(blockHeader);
234  }
235 }
236 
237 // detect raw data format version from known raw data address
239  LogDebug("GCT") << "About to auto-detect the required format translator from the firmware version header.";
240 
241  const uint32_t* p32 = reinterpret_cast<const uint32_t*>(d);
242  unsigned firmwareHeader = p32[2];
243 
244  /*** THIS OBVIOUSLY STINKS - NEED TO REPLACE WITH SOMETHING BETTER THAN MASSIVE IF-ELSE SOON ***/
245  /*** WHEN THIS MESS IS REMOVED REMEMBER THAT THE V38 FORMAT TRANSLATE HAS A DIFERENT CTOR TO THE OTHERS ***/
246 
247  if (firmwareHeader >= 25 && firmwareHeader <= 35) {
248  edm::LogInfo("GCT") << "Firmware Version V" << firmwareHeader << " detected: GctFormatTranslateV" << firmwareHeader
249  << " will be used to unpack.";
251  return true;
252  } else if (firmwareHeader == 38) {
253  edm::LogInfo("GCT") << "Firmware Version V" << firmwareHeader << " detected: GctFormatTranslateV" << firmwareHeader
254  << " will be used to unpack.";
257  return true;
258  } else if (firmwareHeader == 0x00000000) {
259  edm::LogInfo("GCT") << "Legacy Monte-Carlo data detected: GctFormatTranslateMCLegacy will be used to unpack.";
261  return true;
262  }
263  // these lines comments otherwise error is not reported!!!
264  // else if(firmwareHeader == 0xdeadffff) { /* Driver detected unknown firmware version. L1TriggerError code? */ }
265  // else if( firmwareHeader == 0xaaaaaaaa) { /* Before driver firmware version checks implemented. L1TriggerError code? */ }
266  else { /* Totally unknown firmware header */
267 
268  LogDebug("GCT") << "Failed to determine unpacker to use from the firmware version header! "
269  "(firmware header = 0x"
270  << hex << firmwareHeader << dec << ")";
271  addError(2);
272  return false;
273  }
274 }
275 
277  // TODO : loop over block headers found this event and check for consistency
278 }
279 
281  const GctUnpackCollections* const colls) const {
282  std::ostringstream os;
283  os << "Found " << bHdrs.size() << " GCT block headers" << endl;
284  for (unsigned i = 0, size = bHdrs.size(); i < size; ++i) {
285  os << "GCT Raw Data Block : " << formatTranslator_->getBlockDescription(bHdrs[i]) << " : " << bHdrs[i] << endl;
286  }
287  os << *colls << endl;
288  edm::LogVerbatim("GCT") << os.str();
289 }
290 
291 void GctRawToDigi::addError(const unsigned code) {
292  // check this isn't going to break error handling
293  if (code > MAX_ERR_CODE) {
294  LogDebug("GCT") << "Unknown error code : " << code;
295  return;
296  }
297 
298  // print message on first instance of this error and if verbose flag set to true
299  if (errorCounters_.at(code) == 0 && verbose_) {
300  std::ostringstream os;
301  switch (code) {
302  case 0:
303  os << "Reserved error code - not in use";
304  break;
305  case 1:
306  os << "FED record empty or too short";
307  break;
308  case 2:
309  os << "Unknown raw data version";
310  break;
311  case 3:
312  os << "Detected unknown firmware version";
313  break;
314  case 4:
315  os << "Detected unknown data block";
316  break;
317  case 5:
318  os << "Block headers out of sync";
319  break;
320  case 6:
321  os << "Too many blocks";
322  break;
323  default:
324  os << "Unknown error code";
325  }
326  edm::LogError("GCT") << "Unpacking error " << code << " : " << os.str();
327  }
328 
329  // increment error counter
330  ++(errorCounters_.at(code));
331 
332  // store error in event if possible
333  if (errors_ != nullptr) {
334  errors_->push_back(L1TriggerError(fedId_, code));
335  } else
336  LogDebug("GCT") << "Detected error (code=" << code << ") but no error collection available!";
337 }
338 
339 // ------------ method called once each job just after ending the event loop ------------
341  unsigned total = 0;
342  std::ostringstream os;
343 
344  for (unsigned i = 0; i <= MAX_ERR_CODE; ++i) {
345  total += errorCounters_.at(i);
346  os << "Error " << i << " (" << errorCounters_.at(i) << ")";
347  if (i < MAX_ERR_CODE) {
348  os << ", ";
349  }
350  }
351 
352  if (total > 0 && verbose_) {
353  edm::LogError("GCT") << "Encountered " << total << " unpacking errors: " << os.str();
354  }
355 }
356 
size
Write out results.
Log< level::Info, true > LogVerbatim
std::vector< GctBlockHeader > GctBlockHeaderCollection
bool autoDetectRequiredFormatTranslator(const unsigned char *data)
Looks at the firmware version header in the S-Link packet and instantiates relevant format translator...
const bool unpackSharedRegions_
Commissioning option: if true, where applicable the shared RCT calo regions will also be unpacked...
Definition: GctRawToDigi.h:88
GctBlockHeaderCollection blockHeaders_
Definition: GctRawToDigi.h:97
const unsigned numberOfGctSamplesToUnpack_
Number of BXs of GCT data to unpack (assuming they are in the raw data)
Definition: GctRawToDigi.h:84
void addError(const unsigned code)
const bool hltMode_
If true, only outputs the GCT data sent to the GT (number of BXs defined by numberOfGctSamplesToUnpac...
Definition: GctRawToDigi.h:82
size_t size() const
Lenght of the data buffer in bytes.
Definition: FEDRawData.h:48
Unpacks/packs the V38 raw format.
Log< level::Error, false > LogError
void checkHeaders()
check block headers for consistency
virtual void endJob()
method called at job end - use to print summary report
void produce(edm::Event &, const edm::EventSetup &) override
static const unsigned MAX_BLOCKS
The maximum number of blocks we will try to unpack before thinking something is wrong.
Definition: GctRawToDigi.h:75
~GctRawToDigi() override
edm::InputTag inputLabel_
FED collection label.
Definition: GctRawToDigi.h:78
const unsigned formatVersion_
Defines unpacker verison to be used (e.g.: "Auto-detect", "MCLegacy", "V35", etc).
Definition: GctRawToDigi.h:89
virtual bool convertBlock(const unsigned char *d, const GctBlockHeader &hdr)=0
Get digis from the block - will return true if it succeeds, false otherwise.
uint32_t blockLength() const
Get the fundamental block length (for 1 time sample)
int iEvent
Definition: GenABIO.cc:224
GctRawToDigi(const edm::ParameterSet &)
Definition: GctRawToDigi.cc:34
Simple class for holding the basic attributes of an 32-bit block header.
Unpacks/packs the V35 raw format.
static const char *const kComment
const unsigned numberOfRctSamplesToUnpack_
Number of BXs of RCT data to unpack (assuming they are in the raw data)
Definition: GctRawToDigi.h:86
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:16
d
Definition: ztail.py:151
RAII and useful methods for the many dataformat collections required by the GCT unpacker.
const bool verbose_
If true, then debug print out for each event.
Definition: GctRawToDigi.h:91
Log< level::Info, false > LogInfo
const std::string & getBlockDescription(const GctBlockHeader &header) const
Get block description.
const bool checkHeaders_
If true, check block headers for synchronisation.
Definition: GctRawToDigi.h:90
static const unsigned MAX_ERR_CODE
Definition: GctRawToDigi.h:100
Unpacks/packs the MC Legacy data originally produced by the GctBlockPacker class. ...
uint32_t nSamples() const
Get the number of time samples.
void add(std::string const &label, ParameterSetDescription const &psetDescription)
int fedId_
GCT FED ID.
Definition: GctRawToDigi.h:79
void unpack(const FEDRawData &d, edm::Event &e, GctUnpackCollections *const colls)
Unpacks the raw data.
HLT enums.
char data[epos_bytes_allocation]
Definition: EPOS_Wrapper.h:80
std::vector< unsigned > errorCounters_
Counts number of errors for each code (index)
Definition: GctRawToDigi.h:102
void setUnpackCollections(GctUnpackCollections *const collections)
Set the pointer to the unpack collections.
const unsigned char * data() const
Return a const pointer to the beginning of the data buffer.
Definition: FEDRawData.cc:24
GctFormatTranslateBase * formatTranslator_
pointer to the block-to-digi converter
Definition: GctRawToDigi.h:94
Log< level::Warning, false > LogWarning
void doVerboseOutput(const GctBlockHeaderCollection &bHdrs, const GctUnpackCollections *const colls) const
Prints out a list of blocks and the various numbers of trigger objects that have been unpacked from t...
L1TriggerErrorCollection * errors_
pointer to error collection
Definition: GctRawToDigi.h:101
#define LogDebug(id)
static void fillDescriptions(edm::ConfigurationDescriptions &descriptions)
virtual GctBlockHeader generateBlockHeader(const unsigned char *data) const =0
Generate a block header from four 8-bit values.