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  consumes<FEDRawDataCollection>(inputLabel_);
110 }
111 
112 
114 {
115  // do anything here that needs to be done at destruction time
116  // (e.g. close files, deallocate resources etc.)
117  delete formatTranslator_;
118 }
119 
120 
121 //
122 // member functions
123 //
124 
125 // ------------ method called to produce the data ------------
127 {
128  using namespace edm;
129 
130  // Instantiate all the collections the unpacker needs; puts them in event when this object goes out of scope.
131  std::auto_ptr<GctUnpackCollections> colls(new GctUnpackCollections(iEvent));
132  errors_ = colls->errors();
133 
134  // get raw data collection
136  iEvent.getByLabel(inputLabel_, feds);
137 
138  // if raw data collection is present, do the unpacking
139  if (feds.isValid()) {
140 
141  const FEDRawData& gctRcd = feds->FEDData(fedId_);
142 
143  LogDebug("GCT") << "Upacking FEDRawData of size " << std::dec << gctRcd.size();
144 
145  // check for empty events
146  if(gctRcd.size() < 16) {
147  LogDebug("GCT") << "Cannot unpack: empty/invalid GCT raw data (size = "
148  << gctRcd.size() << "). Returning empty collections!";
149  addError(1);
150  return;
151  }
152 
153  // If no format translator yet set, need to auto-detect from header.
154  // If auto format detection fails, we have no concrete format
155  // translator instantiated... set error and bail
156  if(!formatTranslator_) {
157  if(!autoDetectRequiredFormatTranslator(gctRcd.data())) return;
158  }
159 
160  // reset collection of block headers
161  blockHeaders_.clear();
162 
163  // do the unpacking
164  unpack(gctRcd, iEvent, colls.get());
165 
166  // check headers, if enabled
168 
169  // dump summary in verbose mode
170  if(verbose_) { doVerboseOutput(blockHeaders_, colls.get()); }
171 
172  }
173 
174 }
175 
176 
178 {
179 
180  // We should now have a valid formatTranslator pointer
182 
183  const unsigned char * data = d.data(); // The 8-bit wide raw-data array.
184 
185  // Data offset - starts at 16 as there is a 64-bit S-Link header followed
186  // by a 64-bit software-controlled header (for pipeline format version
187  // info that is not yet used).
188  unsigned dPtr = 16;
189 
190  const unsigned dEnd = d.size() - 8; // End of payload is at (packet size - final slink header)
191 
192  // read blocks
193  for (unsigned nb=0; dPtr<dEnd; ++nb)
194  {
195  if(nb >= MAX_BLOCKS) {
196  LogDebug("GCT") << "Reached block limit - bailing out from this event!";
197  addError(6);
198  break;
199  }
200 
201  // read block header
202  GctBlockHeader blockHeader = formatTranslator_->generateBlockHeader(&data[dPtr]);
203 
204  // unpack the block; dPtr+4 is to get to the block data.
205  if(!formatTranslator_->convertBlock(&data[dPtr+4], blockHeader)) // Record if we had an unpack problem then skip rest of event.
206  {
207  LogDebug("GCT") << "Encountered block unpack error - bailing out from this event!";
208  addError(4);
209  break;
210  }
211 
212  // advance pointer
213  dPtr += 4*(blockHeader.blockLength()*blockHeader.nSamples()+1); // *4 because blockLen is in 32-bit words, +1 for header
214 
215  // if verbose or checking block headers, store the header
216  if (verbose_ || checkHeaders_) blockHeaders_.push_back(blockHeader);
217 
218  }
219 
220 }
221 
222 
223 // detect raw data format version from known raw data address
225 {
226  LogDebug("GCT") << "About to auto-detect the required format translator from the firmware version header.";
227 
228  const uint32_t * p32 = reinterpret_cast<const uint32_t *>(d);
229  unsigned firmwareHeader = p32[2];
230 
231  /*** THIS OBVIOUSLY STINKS - NEED TO REPLACE WITH SOMETHING BETTER THAN MASSIVE IF-ELSE SOON ***/
232  /*** WHEN THIS MESS IS REMOVED REMEMBER THAT THE V38 FORMAT TRANSLATE HAS A DIFERENT CTOR TO THE OTHERS ***/
233 
234  if( firmwareHeader >= 25 && firmwareHeader <= 35 )
235  {
236  edm::LogInfo("GCT") << "Firmware Version V" << firmwareHeader << " detected: GctFormatTranslateV" << firmwareHeader << " will be used to unpack.";
238  return true;
239  }
240  else if( firmwareHeader == 38 )
241  {
242  edm::LogInfo("GCT") << "Firmware Version V" << firmwareHeader << " detected: GctFormatTranslateV" << firmwareHeader << " will be used to unpack.";
244  return true;
245  }
246  else if( firmwareHeader == 0x00000000 )
247  {
248  edm::LogInfo("GCT") << "Legacy Monte-Carlo data detected: GctFormatTranslateMCLegacy will be used to unpack.";
250  return true;
251  }
252  // these lines comments otherwise error is not reported!!!
253  // else if(firmwareHeader == 0xdeadffff) { /* Driver detected unknown firmware version. L1TriggerError code? */ }
254  // else if( firmwareHeader == 0xaaaaaaaa) { /* Before driver firmware version checks implemented. L1TriggerError code? */ }
255  else { /* Totally unknown firmware header */
256 
257  LogDebug("GCT") << "Failed to determine unpacker to use from the firmware version header! "
258  "(firmware header = 0x" << hex << firmwareHeader << dec << ")";
259  addError(2);
260  return false;
261  }
262 
263 }
264 
265 
267 
268  // TODO : loop over block headers found this event and check for consistency
269 
270 }
271 
272 
274 {
275  std::ostringstream os;
276  os << "Found " << bHdrs.size() << " GCT block headers" << endl;
277  for (unsigned i=0, size = bHdrs.size(); i < size; ++i)
278  {
279  os << "GCT Raw Data Block : " << formatTranslator_->getBlockDescription(bHdrs[i]) << " : " << bHdrs[i] << endl;
280  }
281  os << *colls << endl;
282  edm::LogVerbatim("GCT") << os.str();
283 }
284 
285 
286 
287 void GctRawToDigi::addError(const unsigned code) {
288 
289  // check this isn't going to break error handling
290  if (code > MAX_ERR_CODE) {
291  LogDebug("GCT") << "Unknown error code : " << code;
292  return;
293  }
294 
295  // print message on first instance of this error and if verbose flag set to true
296  if (errorCounters_.at(code) == 0 && verbose_) {
297  std::ostringstream os;
298  switch(code) {
299  case 0: os << "Reserved error code - not in use"; break;
300  case 1: os << "FED record empty or too short"; break;
301  case 2: os << "Unknown raw data version"; break;
302  case 3: os << "Detected unknown firmware version"; break;
303  case 4: os << "Detected unknown data block"; break;
304  case 5: os << "Block headers out of sync"; break;
305  case 6: os << "Too many blocks"; break;
306  default: os << "Unknown error code";
307  }
308  edm::LogError("GCT") << "Unpacking error " << code << " : " << os.str();
309  }
310 
311  // increment error counter
312  ++(errorCounters_.at(code));
313 
314  // store error in event if possible
315  if (errors_ != 0) {
316  errors_->push_back(L1TriggerError(fedId_, code));
317  }
318  else LogDebug("GCT") << "Detected error (code=" << code << ") but no error collection available!";
319 
320 }
321 
322 // ------------ method called once each job just after ending the event loop ------------
324 {
325  unsigned total=0;
326  std::ostringstream os;
327 
328  for (unsigned i=0 ; i <= MAX_ERR_CODE ; ++i) {
329  total+=errorCounters_.at(i);
330  os << "Error " << i << " (" << errorCounters_.at(i) << ")";
331  if(i < MAX_ERR_CODE) { os << ", "; }
332  }
333 
334  if (total>0 && verbose_) {
335  edm::LogError("GCT") << "Encountered " << total << " unpacking errors: " << os.str();
336  }
337 }
338 
#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:89
GctBlockHeaderCollection blockHeaders_
Definition: GctRawToDigi.h:98
#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:87
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:86
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.
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
virtual 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:80
edm::InputTag inputLabel_
FED collection label.
Definition: GctRawToDigi.h:83
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:90
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
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:309
const unsigned numberOfRctSamplesToUnpack_
Number of BXs of RCT data to unpack (assuming they are in the raw data)
Definition: GctRawToDigi.h:88
bool getByLabel(InputTag const &tag, Handle< PROD > &result) const
Definition: Event.h:390
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:92
const bool checkHeaders_
If true, check block headers for synchronisation.
Definition: GctRawToDigi.h:91
static const unsigned MAX_ERR_CODE
Definition: GctRawToDigi.h:101
Unpacks/packs the MC Legacy data originally produced by the GctBlockPacker class. ...
int fedId_
GCT FED ID.
Definition: GctRawToDigi.h:84
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:28
std::vector< unsigned > errorCounters_
Counts number of errors for each code (index)
Definition: GctRawToDigi.h:103
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:95
volatile std::atomic< bool > shutdown_flag false
L1TriggerErrorCollection * errors_
pointer to error collection
Definition: GctRawToDigi.h:102
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.