CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
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
11 
12 // Raw data collection headers
15 
16 // GCT Format Translators
20 
21 // Unpack collections class
23 
24 
25 // Namespace resolution
26 using std::cout;
27 using std::endl;
28 using std::vector;
29 using std::string;
30 using std::dec;
31 using std::hex;
32 
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_(0),
45  errors_(0),
46  errorCounters_(MAX_ERR_CODE+1), // initialise with the maximum error codes!
47  unpackFailures_(0)
48 {
49  LogDebug("GCT") << "GctRawToDigi will unpack FED Id " << fedId_;
50 
51  // If the GctFormatTranslate version has been forced from config file, instantiate the relevant one.
52  /*** THIS OBVIOUSLY STINKS - NEED TO REPLACE WITH SOMETHING BETTER THAN MASSIVE IF-ELSE SOON ***/
53  /*** WHEN THIS MESS IS REMOVED REMEMBER THAT THE V38 FORMAT TRANSLATE HAS A DIFERENT CTOR TO THE OTHERS ***/
54  if(formatVersion_ == 0) { edm::LogInfo("GCT") << "The required GCT Format Translator will be automatically determined from the first S-Link packet header."; }
55  else if(formatVersion_ == 1)
56  {
57  edm::LogInfo("GCT") << "You have selected to use GctFormatTranslateMCLegacy";
59  }
60  else if(formatVersion_ == 2)
61  {
62  edm::LogInfo("GCT") << "You have selected to use GctFormatTranslateV35";
64  }
65  else if(formatVersion_ == 3)
66  {
67  edm::LogInfo("GCT") << "You have selected to use GctFormatTranslateV38";
69  }
70  else
71  {
72  edm::LogWarning("GCT") << "You have requested a version of GctFormatTranslate that does not exist! Will attempt to auto-detect "
73  "the required GCT Format Translator from the first S-Link packet header instead.";
74  }
75 
76  if(hltMode_) { edm::LogInfo("GCT") << "HLT unpack mode selected: HLT unpack optimisations will be used."; }
77  if(unpackSharedRegions_) { edm::LogInfo("GCT") << "You have selected to unpack shared RCT calo regions - be warned: "
78  "this is for commissioning purposes only!"; }
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 }
110 
111 
113 {
114  // do anything here that needs to be done at destruction time
115  // (e.g. close files, deallocate resources etc.)
116  delete formatTranslator_;
117 }
118 
119 
120 //
121 // member functions
122 //
123 
124 // ------------ method called once each job just before starting event loop ------------
126 {
127 }
128 
129 
130 // ------------ method called to produce the data ------------
132 {
133  using namespace edm;
134 
135  // Instantiate all the collections the unpacker needs; puts them in event when this object goes out of scope.
136  std::auto_ptr<GctUnpackCollections> colls(new GctUnpackCollections(iEvent));
137  errors_ = colls->errors();
138 
139  // get raw data collection
141  iEvent.getByLabel(inputLabel_, feds);
142 
143  // if raw data collection is present, do the unpacking
144  if (feds.isValid()) {
145 
146  const FEDRawData& gctRcd = feds->FEDData(fedId_);
147 
148  LogDebug("GCT") << "Upacking FEDRawData of size " << std::dec << gctRcd.size();
149 
150  // check for empty events
151  if(gctRcd.size() < 16) {
152  LogDebug("GCT") << "Cannot unpack: empty/invalid GCT raw data (size = "
153  << gctRcd.size() << "). Returning empty collections!";
154  addError(1);
155  return;
156  }
157 
158  // If no format translator yet set, need to auto-detect from header.
159  // If auto format detection fails, we have no concrete format
160  // translator instantiated... set error and bail
161  if(!formatTranslator_) {
162  if(!autoDetectRequiredFormatTranslator(gctRcd.data())) return;
163  }
164 
165  // reset collection of block headers
166  blockHeaders_.clear();
167 
168  // do the unpacking
169  unpack(gctRcd, iEvent, colls.get());
170 
171  // check headers, if enabled
173 
174  // dump summary in verbose mode
175  if(verbose_) { doVerboseOutput(blockHeaders_, colls.get()); }
176 
177  }
178 
179 }
180 
181 
183 {
184 
185  // We should now have a valid formatTranslator pointer
187 
188  const unsigned char * data = d.data(); // The 8-bit wide raw-data array.
189 
190  // Data offset - starts at 16 as there is a 64-bit S-Link header followed
191  // by a 64-bit software-controlled header (for pipeline format version
192  // info that is not yet used).
193  unsigned dPtr = 16;
194 
195  const unsigned dEnd = d.size() - 8; // End of payload is at (packet size - final slink header)
196 
197  // read blocks
198  for (unsigned nb=0; dPtr<dEnd; ++nb)
199  {
200  if(nb >= MAX_BLOCKS) {
201  LogDebug("GCT") << "Reached block limit - bailing out from this event!";
202  addError(6);
203  break;
204  }
205 
206  // read block header
207  GctBlockHeader blockHeader = formatTranslator_->generateBlockHeader(&data[dPtr]);
208 
209  // unpack the block; dPtr+4 is to get to the block data.
210  if(!formatTranslator_->convertBlock(&data[dPtr+4], blockHeader)) // Record if we had an unpack problem then skip rest of event.
211  {
212  LogDebug("GCT") << "Encountered block unpack error - bailing out from this event!";
213  addError(4);
214  break;
215  }
216 
217  // advance pointer
218  dPtr += 4*(blockHeader.blockLength()*blockHeader.nSamples()+1); // *4 because blockLen is in 32-bit words, +1 for header
219 
220  // if verbose or checking block headers, store the header
221  if (verbose_ || checkHeaders_) blockHeaders_.push_back(blockHeader);
222 
223  }
224 
225 }
226 
227 
228 // detect raw data format version from known raw data address
230 {
231  LogDebug("GCT") << "About to auto-detect the required format translator from the firmware version header.";
232 
233  const uint32_t * p32 = reinterpret_cast<const uint32_t *>(d);
234  unsigned firmwareHeader = p32[2];
235 
236  /*** THIS OBVIOUSLY STINKS - NEED TO REPLACE WITH SOMETHING BETTER THAN MASSIVE IF-ELSE SOON ***/
237  /*** WHEN THIS MESS IS REMOVED REMEMBER THAT THE V38 FORMAT TRANSLATE HAS A DIFERENT CTOR TO THE OTHERS ***/
238 
239  if( firmwareHeader >= 25 && firmwareHeader <= 35 )
240  {
241  edm::LogInfo("GCT") << "Firmware Version V" << firmwareHeader << " detected: GctFormatTranslateV" << firmwareHeader << " will be used to unpack.";
243  return true;
244  }
245  else if( firmwareHeader == 38 )
246  {
247  edm::LogInfo("GCT") << "Firmware Version V" << firmwareHeader << " detected: GctFormatTranslateV" << firmwareHeader << " will be used to unpack.";
249  return true;
250  }
251  else if( firmwareHeader == 0x00000000 )
252  {
253  edm::LogInfo("GCT") << "Legacy Monte-Carlo data detected: GctFormatTranslateMCLegacy will be used to unpack.";
255  return true;
256  }
257  // these lines comments otherwise error is not reported!!!
258  // else if(firmwareHeader == 0xdeadffff) { /* Driver detected unknown firmware version. L1TriggerError code? */ }
259  // else if( firmwareHeader == 0xaaaaaaaa) { /* Before driver firmware version checks implemented. L1TriggerError code? */ }
260  else { /* Totally unknown firmware header */
261 
262  LogDebug("GCT") << "Failed to determine unpacker to use from the firmware version header! "
263  "(firmware header = 0x" << hex << firmwareHeader << dec << ")";
264  addError(2);
265  return false;
266  }
267 
268 }
269 
270 
272 
273  // TODO : loop over block headers found this event and check for consistency
274 
275 }
276 
277 
279 {
280  std::ostringstream os;
281  os << "Found " << bHdrs.size() << " GCT block headers" << endl;
282  for (unsigned i=0, size = bHdrs.size(); i < size; ++i)
283  {
284  os << "GCT Raw Data Block : " << formatTranslator_->getBlockDescription(bHdrs[i]) << " : " << bHdrs[i] << endl;
285  }
286  os << *colls << endl;
287  edm::LogVerbatim("GCT") << os.str();
288 }
289 
290 
291 
292 void GctRawToDigi::addError(const unsigned code) {
293 
294  // check this isn't going to break error handling
295  if (code > MAX_ERR_CODE) {
296  LogDebug("GCT") << "Unknown error code : " << code;
297  return;
298  }
299 
300  // print message on first instance of this error and if verbose flag set to true
301  if (errorCounters_.at(code) == 0 && verbose_) {
302  std::ostringstream os;
303  switch(code) {
304  case 0: os << "Reserved error code - not in use"; break;
305  case 1: os << "FED record empty or too short"; break;
306  case 2: os << "Unknown raw data version"; break;
307  case 3: os << "Detected unknown firmware version"; break;
308  case 4: os << "Detected unknown data block"; break;
309  case 5: os << "Block headers out of sync"; break;
310  case 6: os << "Too many blocks"; break;
311  default: os << "Unknown error code";
312  }
313  edm::LogError("GCT") << "Unpacking error " << code << " : " << os.str();
314  }
315 
316  // increment error counter
317  ++(errorCounters_.at(code));
318 
319  // store error in event if possible
320  if (errors_ != 0) {
321  errors_->push_back(L1TriggerError(fedId_, code));
322  }
323  else LogDebug("GCT") << "Detected error (code=" << code << ") but no error collection available!";
324 
325 }
326 
327 // ------------ method called once each job just after ending the event loop ------------
329 {
330  unsigned total=0;
331  std::ostringstream os;
332 
333  for (unsigned i=0 ; i <= MAX_ERR_CODE ; ++i) {
334  total+=errorCounters_.at(i);
335  os << "Error " << i << " (" << errorCounters_.at(i) << ")";
336  if(i < MAX_ERR_CODE) { os << ", "; }
337  }
338 
339  if (total>0 && verbose_) {
340  edm::LogError("GCT") << "Encountered " << total << " unpacking errors: " << os.str();
341  }
342 }
343 
#define LogDebug(id)
int i
Definition: DBlmapReader.cc:9
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.
const bool unpackSharedRegions_
Commissioning option: if true, where applicable the shared RCT calo regions will also be unpacked...
Definition: GctRawToDigi.h:91
GctBlockHeaderCollection blockHeaders_
Definition: GctRawToDigi.h:100
#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:89
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:88
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...
virtual void produce(edm::Event &, const edm::EventSetup &)
Unpacks/packs the V38 raw format.
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:49
static const unsigned MAX_BLOCKS
The maximum number of blocks we will try to unpack before thinking something is wrong.
Definition: GctRawToDigi.h:82
edm::InputTag inputLabel_
FED collection label.
Definition: GctRawToDigi.h:85
const unsigned formatVersion_
Defines unpacker verison to be used (e.g.: &quot;Auto-detect&quot;, &quot;MCLegacy&quot;, &quot;V35&quot;, etc).
Definition: GctRawToDigi.h:92
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:243
virtual void beginJob()
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.
bool get(ProductID const &oid, Handle< PROD > &result) const
Definition: Event.h:282
const unsigned numberOfRctSamplesToUnpack_
Number of BXs of RCT data to unpack (assuming they are in the raw data)
Definition: GctRawToDigi.h:90
bool getByLabel(InputTag const &tag, Handle< PROD > &result) const
Definition: Event.h:361
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:94
const bool checkHeaders_
If true, check block headers for synchronisation.
Definition: GctRawToDigi.h:93
static const unsigned MAX_ERR_CODE
Definition: GctRawToDigi.h:103
Unpacks/packs the MC Legacy data originally produced by the GctBlockPacker class. ...
int fedId_
GCT FED ID.
Definition: GctRawToDigi.h:86
void unpack(const FEDRawData &d, edm::Event &e, GctUnpackCollections *const colls)
Unpacks the raw data.
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:29
std::vector< unsigned > errorCounters_
Counts number of errors for each code (index)
Definition: GctRawToDigi.h:105
void setUnpackCollections(GctUnpackCollections *const collections)
Set the pointer to the unpack collections.
tuple cout
Definition: gather_cfg.py:121
GctFormatTranslateBase * formatTranslator_
pointer to the block-to-digi converter
Definition: GctRawToDigi.h:97
L1TriggerErrorCollection * errors_
pointer to error collection
Definition: GctRawToDigi.h:104
uint32_t nSamples() const
Get the number of time samples.
tuple size
Write out results.
virtual GctBlockHeader generateBlockHeader(const unsigned char *data) const =0
Generate a block header from four 8-bit values.