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