CMS 3D CMS Logo

L1GlobaTriggerRawToDigi.cc
Go to the documentation of this file.
1 
16 // this class header
18 
19 // system include files
20 #include <iostream>
21 #include <iomanip>
22 #include <algorithm>
23 
24 // user include files
27 
32 
36 
40 
45 
48 
51 
54 
55 // constructor(s)
57  :
58 
59  // input tag for DAQ GT record
60  m_daqGtInputTag(pSet.getParameter<edm::InputTag>("DaqGtInputTag")),
61 
62  // FED Id for GT DAQ record
63  // default value defined in DataFormats/FEDRawData/src/FEDNumbering.cc
64  // default value: assume the DAQ record is the last GT record
65  m_daqGtFedId(pSet.getUntrackedParameter<int>("DaqGtFedId", FEDNumbering::MAXTriggerGTPFEDID)),
66 
67  // mask for active boards
68  m_activeBoardsMaskGt(pSet.getParameter<unsigned int>("ActiveBoardsMask")),
69 
70  // EventSetup Tokens
71  m_trigScalesToken(esConsumes<L1MuTriggerScales, L1MuTriggerScalesRcd>()),
72  m_trigPtScaleToken(esConsumes<L1MuTriggerPtScale, L1MuTriggerPtScaleRcd>()),
73  m_l1GtBMToken(esConsumes<L1GtBoardMaps, L1GtBoardMapsRcd>()),
74 
75  // number of bunch crossing to be unpacked
76  m_unpackBxInEvent(pSet.getParameter<int>("UnpackBxInEvent")),
77 
78  // create GTFE, FDL, PSB cards once per producer
79  // content will be reset whenever needed
80 
81  m_lowSkipBxInEvent(0),
82  m_uppSkipBxInEvent(0),
83 
84  m_recordLength0(0),
85  m_recordLength1(0),
86 
87  m_totalBxInEvent(0),
88 
89  m_verbosity(pSet.getUntrackedParameter<int>("Verbosity", 0)),
90 
91  m_isDebugEnabled(edm::isDebugEnabled())
92 
93 {
94  produces<L1GlobalTriggerReadoutRecord>();
95  produces<L1MuGMTReadoutCollection>();
96 
97  produces<std::vector<L1MuRegionalCand> >("DT");
98  produces<std::vector<L1MuRegionalCand> >("CSC");
99  produces<std::vector<L1MuRegionalCand> >("RPCb");
100  produces<std::vector<L1MuRegionalCand> >("RPCf");
101  produces<std::vector<L1MuGMTCand> >();
102  consumes<FEDRawDataCollection>(m_daqGtInputTag);
103 
104  // create GTFE, FDL, PSB cards once per producer
105  // content will be reset whenever needed
106  m_gtfeWord = new L1GtfeWord();
107  m_gtFdlWord = new L1GtFdlWord();
108  m_gtPsbWord = new L1GtPsbWord();
109 
110  if (m_verbosity && m_isDebugEnabled) {
111  LogDebug("L1GlobalTriggerRawToDigi") << "\nInput tag for DAQ GT record: " << m_daqGtInputTag
112  << "\nFED Id for DAQ GT record: " << m_daqGtFedId
113  << "\nMask for active boards (hex format): " << std::hex
114  << std::setw(sizeof(m_activeBoardsMaskGt) * 2) << std::setfill('0')
115  << m_activeBoardsMaskGt << std::dec << std::setfill(' ')
116  << "\nNumber of bunch crossing to be unpacked: " << m_unpackBxInEvent << "\n"
117  << std::endl;
118  }
119 
120  if ((m_unpackBxInEvent > 0) && ((m_unpackBxInEvent % 2) == 0)) {
122 
123  if (m_verbosity) {
124  edm::LogInfo("L1GlobalTriggerRawToDigi")
125  << "\nWARNING: Number of bunch crossing to be unpacked rounded to: " << m_unpackBxInEvent
126  << "\n The number must be an odd number!\n"
127  << std::endl;
128  }
129  }
130 }
131 
132 // destructor
134  delete m_gtfeWord;
135  delete m_gtFdlWord;
136  delete m_gtPsbWord;
137 }
138 
141  static const char* const kComm1 =
142  "# input tag for GT readout collection: \n"
143  "# source = hardware record, \n"
144  "# l1GtPack = GT packer (DigiToRaw)";
145  desc.add<edm::InputTag>("DaqGtInputTag", edm::InputTag("l1GtPack"))->setComment(kComm1);
146  static const char* const kComm2 =
147  "# FED Id for GT DAQ record \n"
148  "# default value defined in DataFormats/FEDRawData/src/FEDNumbering.cc";
149  desc.addUntracked<int>("DaqGtFedId", FEDNumbering::MAXTriggerGTPFEDID)->setComment(kComm2);
150  static const char* const kComm3 =
151  "# mask for active boards (actually 16 bits) \n"
152  "# if bit is zero, the corresponding board will not be unpacked \n"
153  "# default: no board masked";
154  desc.add<unsigned int>("ActiveBoardsMask", 0xFFFF)->setComment(kComm3);
155  static const char* const kComm4 =
156  "# number of 'bunch crossing in the event' (bxInEvent) to be unpacked \n"
157  "# symmetric around L1Accept (bxInEvent = 0): \n"
158  "# 1 (bxInEvent = 0); 3 (F 0 1) (standard record); 5 (E F 0 1 2) (debug record) \n"
159  "# even numbers (except 0) 'rounded' to the nearest lower odd number \n"
160  "# negative value: unpack all available bxInEvent \n"
161  "# if more bxInEvent than available are required, unpack what exists and write a warning";
162  desc.add<int>("UnpackBxInEvent", -1)->setComment(kComm4);
163  desc.addUntracked<int>("Verbosity", 0);
164  descriptions.add("l1GlobalTriggerRawToDigi", desc);
165 }
166 
167 // member functions
168 
169 // method called to produce the data
171  // get records from EventSetup
172 
173  // muon trigger scales
175  m_TriggerScales = trigscales_h.product();
176 
178  m_TriggerPtScale = trigptscale_h.product();
179 
180  // board maps
182 
183  const std::vector<L1GtBoard> boardMaps = l1GtBM->gtBoardMaps();
184  int boardMapsSize = boardMaps.size();
185 
186  typedef std::vector<L1GtBoard>::const_iterator CItBoardMaps;
187 
188  // create an ordered vector for the GT DAQ record
189  // header (pos 0 in record) and trailer (last position in record)
190  // not included, as they are not in board list
191  std::vector<L1GtBoard> gtRecordMap;
192  gtRecordMap.reserve(boardMapsSize);
193 
194  for (int iPos = 0; iPos < boardMapsSize; ++iPos) {
195  for (CItBoardMaps itBoard = boardMaps.begin(); itBoard != boardMaps.end(); ++itBoard) {
196  if (itBoard->gtPositionDaqRecord() == iPos) {
197  gtRecordMap.push_back(*itBoard);
198  break;
199  }
200  }
201  }
202 
203  // raw collection
204 
206  iEvent.getByLabel(m_daqGtInputTag, fedHandle);
207 
208  if (!fedHandle.isValid()) {
209  if (m_verbosity) {
210  edm::LogWarning("L1GlobalTriggerRawToDigi")
211  << "\nWarning: FEDRawDataCollection with input tag " << m_daqGtInputTag
212  << "\nrequested in configuration, but not found in the event."
213  << "\nQuit unpacking this event" << std::endl;
214  }
215 
217 
218  return;
219  }
220 
221  // retrieve data for Global Trigger FED (GT + GMT)
222  const FEDRawData& raw = (fedHandle.product())->FEDData(m_daqGtFedId);
223 
224  int gtSize = raw.size();
225 
226  // get a const pointer to the beginning of the data buffer
227  const unsigned char* ptrGt = raw.data();
228 
229  // get a const pointer to the end of the data buffer
230  const unsigned char* endPtrGt = ptrGt + gtSize;
231 
232  //
233  if (m_verbosity && m_isDebugEnabled) {
234  LogTrace("L1GlobalTriggerRawToDigi") << "\n Size of raw data: " << gtSize << "\n" << std::endl;
235 
236  std::ostringstream myCoutStream;
237  dumpFedRawData(ptrGt, gtSize, myCoutStream);
238 
239  LogTrace("L1GlobalTriggerRawToDigi") << "\n Dump FEDRawData\n" << myCoutStream.str() << "\n" << std::endl;
240  }
241 
242  // unpack header (we have one header only)
243  int headerSize = 8;
244 
245  if ((ptrGt + headerSize) > endPtrGt) {
246  // a common error - no need to print an error anymore
248 
249  return;
250  }
251 
252  FEDHeader cmsHeader(ptrGt);
253  FEDTrailer cmsTrailer(ptrGt + gtSize - headerSize);
254 
255  unpackHeader(ptrGt, cmsHeader);
256  ptrGt += headerSize; // advance with header size
257 
258  // unpack first GTFE to find the length of the record and the active boards
259  // here GTFE assumed immediately after the header
260 
261  // if pointer after GTFE payload is greater than pointer at
262  // the end of GT payload, produce empty products and quit unpacking
263  if ((ptrGt + m_gtfeWord->getSize()) > endPtrGt) {
264  edm::LogError("L1GlobalTriggerRawToDigi") << "\nError: Pointer after GTFE greater than end pointer."
265  << "\n Put empty products in the event!"
266  << "\n Quit unpacking this event." << std::endl;
267 
269 
270  return;
271  }
272 
273  bool gtfeUnpacked = false;
274 
275  for (CItBoardMaps itBoard = boardMaps.begin(); itBoard != boardMaps.end(); ++itBoard) {
276  if (itBoard->gtBoardType() == GTFE) {
277  // unpack GTFE
278  if (itBoard->gtPositionDaqRecord() == 1) {
279  m_gtfeWord->unpack(ptrGt);
280  ptrGt += m_gtfeWord->getSize(); // advance with GTFE block size
281  gtfeUnpacked = true;
282 
283  if (m_verbosity && m_isDebugEnabled) {
284  std::ostringstream myCoutStream;
285  m_gtfeWord->print(myCoutStream);
286  LogTrace("L1GlobalTriggerRawToDigi") << myCoutStream.str() << "\n" << std::endl;
287  }
288 
289  // break the loop - GTFE was found
290  break;
291 
292  } else {
293  if (m_verbosity) {
294  edm::LogWarning("L1GlobalTriggerRawToDigi")
295  << "\nWarning: GTFE block found in raw data does not follow header."
296  << "\nAssumed start position of the block is wrong!"
297  << "\nQuit unpacking this event" << std::endl;
298  }
299 
301 
302  return;
303  }
304  }
305  }
306 
307  // quit if no GTFE found
308  if (!gtfeUnpacked) {
309  if (m_verbosity) {
310  edm::LogWarning("L1GlobalTriggerRawToDigi")
311  << "\nWarning: no GTFE block found in raw data."
312  << "\nCan not find the record length (BxInEvent) and the active boards!"
313  << "\nQuit unpacking this event" << std::endl;
314  }
315 
317 
318  return;
319  }
320 
321  // life normal here, GTFE found
322 
323  // get list of active blocks
324  // blocks not active are not written to the record
325  cms_uint16_t activeBoardsGtInitial = m_gtfeWord->activeBoards();
326  cms_uint16_t altNrBxBoardInitial = m_gtfeWord->altNrBxBoard();
327 
328  // mask some boards, if needed
329  cms_uint16_t activeBoardsGt = activeBoardsGtInitial & m_activeBoardsMaskGt;
330  m_gtfeWord->setActiveBoards(activeBoardsGt);
331 
332  if (m_verbosity) {
333  LogDebug("L1GlobalTriggerRawToDigi") << "\nActive boards before masking: 0x" << std::hex
334  << std::setw(sizeof(activeBoardsGtInitial) * 2) << std::setfill('0')
335  << activeBoardsGtInitial << std::dec << std::setfill(' ')
336  << "\nActive boards after masking: 0x" << std::hex
337  << std::setw(sizeof(activeBoardsGt) * 2) << std::setfill('0') << activeBoardsGt
338  << std::dec << std::setfill(' ') << " \n"
339  << std::endl;
340  }
341 
342  // loop over other blocks in the raw record, count them if they are active
343 
344  int numberGtfeBoards = 0;
345  int numberFdlBoards = 0;
346  int numberPsbBoards = 0;
347  int numberGmtBoards = 0;
348  int numberTcsBoards = 0;
349  int numberTimBoards = 0;
350 
351  for (CItBoardMaps itBoard = boardMaps.begin(); itBoard != boardMaps.end(); ++itBoard) {
352  int iActiveBit = itBoard->gtBitDaqActiveBoards();
353  bool activeBoardToUnpack = false;
354 
355  if (iActiveBit >= 0) {
356  activeBoardToUnpack = activeBoardsGt & (1 << iActiveBit);
357  } else {
358  // board not in the ActiveBoards for the record
359  continue;
360  }
361 
362  if (activeBoardToUnpack) {
363  switch (itBoard->gtBoardType()) {
364  case GTFE: {
365  numberGtfeBoards++;
366  }
367 
368  break;
369  case FDL: {
370  numberFdlBoards++;
371  }
372 
373  break;
374  case PSB: {
375  numberPsbBoards++;
376  }
377 
378  break;
379  case GMT: {
380  numberGmtBoards++;
381  }
382 
383  break;
384  case TCS: {
385  numberTcsBoards++;
386  }
387 
388  break;
389  case TIM: {
390  numberTimBoards++;
391  }
392 
393  break;
394  default: {
395  // do nothing, all blocks are given in GtBoardType enum
396  if (m_verbosity) {
397  LogDebug("L1GlobalTriggerRawToDigi")
398  << "\nBoard of type " << itBoard->gtBoardType() << " not expected in record.\n"
399  << std::endl;
400  }
401  }
402 
403  break;
404  }
405  }
406  }
407 
408  // produce the L1GlobalTriggerReadoutRecord now, after we found the maximum number of
409  // BxInEvent the record has and how many boards are active (it is just reserving space
410  // for vectors)
411  //LogDebug("L1GlobalTriggerRawToDigi")
412  //<< "\nL1GlobalTriggerRawToDigi: producing L1GlobalTriggerReadoutRecord\n"
413  //<< "\nL1GlobalTriggerRawToDigi: producing L1MuGMTReadoutCollection;\n"
414  //<< std::endl;
415 
416  // get number of Bx in the event from GTFE block corresponding to alternative 0 and 1 in
419 
420  int maxBxInEvent = std::max(m_recordLength0, m_recordLength1);
421 
422  std::unique_ptr<L1GlobalTriggerReadoutRecord> gtReadoutRecord(
423  new L1GlobalTriggerReadoutRecord(maxBxInEvent, numberFdlBoards, numberPsbBoards));
424 
425  // produce also the GMT readout collection and set the reference in GT record
426  std::unique_ptr<L1MuGMTReadoutCollection> gmtrc(new L1MuGMTReadoutCollection(maxBxInEvent));
427 
428  //edm::RefProd<L1MuGMTReadoutCollection> refProdMuGMT = iEvent.getRefBeforePut<
429  // L1MuGMTReadoutCollection> ();
430 
431  //if (m_verbosity) {
432  // LogDebug("L1GlobalTriggerRawToDigi")
433  // << "\nL1GlobalTriggerRawToDigi: set L1MuGMTReadoutCollection RefProd"
434  // << " in L1GlobalTriggerReadoutRecord.\n" << std::endl;
435  //}
436  //gtReadoutRecord->setMuCollectionRefProd(refProdMuGMT);
437 
438  // ... then unpack modules other than GTFE, if requested
439 
440  for (CItBoardMaps itBoard = gtRecordMap.begin(); itBoard != gtRecordMap.end(); ++itBoard) {
441  int iActiveBit = itBoard->gtBitDaqActiveBoards();
442 
443  bool activeBoardToUnpack = false;
444  bool activeBoardInitial = false;
445 
446  int altNrBxBoardVal = -1;
447 
448  if (iActiveBit >= 0) {
449  activeBoardInitial = activeBoardsGtInitial & (1 << iActiveBit);
450  activeBoardToUnpack = activeBoardsGt & (1 << iActiveBit);
451 
452  altNrBxBoardVal = (altNrBxBoardInitial & (1 << iActiveBit)) >> iActiveBit;
453 
454  if (altNrBxBoardVal == 1) {
456  } else if (altNrBxBoardVal == 0) {
458  } else {
459  if (m_verbosity) {
460  edm::LogWarning("L1GlobalTriggerRawToDigi")
461  << "\n\nWARNING: Wrong value altNrBxBoardVal = " << altNrBxBoardVal << " for board " << std::hex
462  << (itBoard->gtBoardId()) << std::dec << "\n iActiveBit = " << iActiveBit
463  << "\n altNrBxBoardInitial = 0x" << std::hex << altNrBxBoardInitial << std::dec
464  << "\n activeBoardsGt = 0x" << std::hex << activeBoardsGt << std::dec
465  << "\n activeBoardInitial = " << activeBoardInitial
466  << "\n activeBoardToUnpack = " << activeBoardToUnpack << "\n Set altNrBxBoardVal tentatively to "
467  << m_recordLength0 << "\n Job may crash or produce wrong results!\n\n"
468  << std::endl;
469  }
470 
472  }
473 
474  // number of BX required to be unpacked
475 
477  if (m_verbosity) {
478  LogDebug("L1GlobalTriggerRawToDigi")
479  << "\nWARNING: Number of available bunch crosses for board" << (itBoard->gtBoardId())
480  << " in the record ( " << m_totalBxInEvent
481  << " ) \n is smaller than the number of bunch crosses requested to be unpacked (" << m_unpackBxInEvent
482  << " )!!! \n Unpacking only " << m_totalBxInEvent << " bunch crosses.\n"
483  << std::endl;
484  }
485 
486  m_lowSkipBxInEvent = 0;
488 
489  } else if (m_unpackBxInEvent < 0) {
490  m_lowSkipBxInEvent = 0;
492 
493  if (m_verbosity) {
494  LogDebug("L1GlobalTriggerRawToDigi") << "\nUnpacking all " << m_totalBxInEvent << " bunch crosses available."
495  << "\n"
496  << std::endl;
497  }
498 
499  } else if (m_unpackBxInEvent == 0) {
502 
503  if (m_verbosity) {
504  LogDebug("L1GlobalTriggerRawToDigi")
505  << "\nNo bxInEvent required to be unpacked from " << m_totalBxInEvent << " bunch crosses available."
506  << "\n"
507  << std::endl;
508  }
509 
510  // change RecordLength
511  // cast int to cms_uint16_t (there are normally 3 or 5 BxInEvent)
512  m_gtfeWord->setRecordLength(static_cast<cms_uint16_t>(m_unpackBxInEvent));
513  m_gtfeWord->setRecordLength1(static_cast<cms_uint16_t>(m_unpackBxInEvent));
514 
515  } else {
518 
519  if (m_verbosity) {
520  LogDebug("L1GlobalTriggerRawToDigi") << "\nUnpacking " << m_unpackBxInEvent << " bunch crosses from "
521  << m_totalBxInEvent << " bunch crosses available."
522  << "\n"
523  << std::endl;
524  }
525 
526  // change RecordLength
527  // cast int to cms_uint16_t (there are normally 3 or 5 BxInEvent)
528  m_gtfeWord->setRecordLength(static_cast<cms_uint16_t>(m_unpackBxInEvent));
529  m_gtfeWord->setRecordLength1(static_cast<cms_uint16_t>(m_unpackBxInEvent));
530  }
531 
532  } else {
533  // board not in the ActiveBoards for the record
534  continue;
535  }
536 
537  if (!activeBoardInitial) {
538  if (m_verbosity) {
539  LogDebug("L1GlobalTriggerRawToDigi") << "\nBoard of type " << itBoard->gtBoardName() << " with index "
540  << itBoard->gtBoardIndex() << " not active initially in raw data.\n"
541  << std::endl;
542  }
543  continue;
544  }
545 
546  // active board initially, could unpack it
547  switch (itBoard->gtBoardType()) {
548  case FDL: {
549  for (int iFdl = 0; iFdl < m_totalBxInEvent; ++iFdl) {
550  // if pointer after FDL payload is greater than pointer at
551  // the end of GT payload, produce empty products and quit unpacking
552  if ((ptrGt + m_gtFdlWord->getSize()) > endPtrGt) {
553  edm::LogError("L1GlobalTriggerRawToDigi")
554  << "\nError: Pointer after FDL " << iFdl << " greater than end pointer."
555  << "\n Put empty products in the event!"
556  << "\n Quit unpacking this event." << std::endl;
557 
559 
560  return;
561  }
562 
563  // unpack only if requested, otherwise skip it
564  if (activeBoardToUnpack) {
565  // unpack only bxInEvent requested, otherwise skip it
566  if ((iFdl >= m_lowSkipBxInEvent) && (iFdl < m_uppSkipBxInEvent)) {
567  m_gtFdlWord->unpack(ptrGt);
568 
569  // add 1 to the GT luminosity number to use the same convention as
570  // offline, where LS number starts with 1;
571  // in GT hardware, LS starts with 0
572  cms_uint16_t lsNr = m_gtFdlWord->lumiSegmentNr() + 1;
574 
575  // add FDL block to GT readout record
576  gtReadoutRecord->setGtFdlWord(*m_gtFdlWord);
577 
578  if (m_verbosity && m_isDebugEnabled) {
579  std::ostringstream myCoutStream;
580  m_gtFdlWord->print(myCoutStream);
581  LogTrace("L1GlobalTriggerRawToDigi") << myCoutStream.str() << "\n" << std::endl;
582  }
583 
584  // ... and reset it
585  m_gtFdlWord->reset();
586  }
587  }
588 
589  ptrGt += m_gtFdlWord->getSize(); // advance with FDL block size
590  }
591  }
592 
593  break;
594  case PSB: {
595  for (int iPsb = 0; iPsb < m_totalBxInEvent; ++iPsb) {
596  // if pointer after PSB payload is greater than pointer at
597  // the end of GT payload, produce empty products and quit unpacking
598  if ((ptrGt + m_gtPsbWord->getSize()) > endPtrGt) {
599  edm::LogError("L1GlobalTriggerRawToDigi")
600  << "\nError: Pointer after PSB " << iPsb << " greater than end pointer."
601  << "\n Put empty products in the event!"
602  << "\n Quit unpacking this event." << std::endl;
603 
605 
606  return;
607  }
608 
609  // unpack only if requested, otherwise skip it
610  if (activeBoardToUnpack) {
611  // unpack only bxInEvent requested, otherwise skip it
612  if ((iPsb >= m_lowSkipBxInEvent) && (iPsb < m_uppSkipBxInEvent)) {
613  unpackPSB(evSetup, ptrGt, *m_gtPsbWord);
614 
615  // add PSB block to GT readout record
616  gtReadoutRecord->setGtPsbWord(*m_gtPsbWord);
617 
618  if (m_verbosity && m_isDebugEnabled) {
619  std::ostringstream myCoutStream;
620  m_gtPsbWord->print(myCoutStream);
621  LogTrace("L1GlobalTriggerRawToDigi") << myCoutStream.str() << "\n" << std::endl;
622  }
623 
624  // ... and reset it
625  m_gtPsbWord->reset();
626  }
627  }
628 
629  ptrGt += m_gtPsbWord->getSize(); // advance with PSB block size
630  }
631  } break;
632  case GMT: {
633  // 17*64/8 TODO FIXME ask Ivan for a getSize() function for GMT record
634  unsigned int gmtRecordSize = 136;
635  unsigned int gmtCollSize = m_totalBxInEvent * gmtRecordSize;
636 
637  // if pointer after GMT payload is greater than pointer at
638  // the end of GT payload, produce empty products and quit unpacking
639  if ((ptrGt + gmtCollSize) > endPtrGt) {
640  edm::LogError("L1GlobalTriggerRawToDigi") << "\nError: Pointer after GMT "
641  << " greater than end pointer."
642  << "\n Put empty products in the event!"
643  << "\n Quit unpacking this event." << std::endl;
644 
646 
647  return;
648  }
649 
650  // unpack only if requested, otherwise skip it
651  if (activeBoardToUnpack) {
652  unpackGMT(ptrGt, gmtrc, iEvent);
653  }
654 
655  ptrGt += gmtCollSize; // advance with GMT block size
656  } break;
657  default: {
658  // do nothing, all blocks are given in GtBoardType enum
659  if (m_verbosity) {
660  LogDebug("L1GlobalTriggerRawToDigi")
661  << "\nBoard of type " << itBoard->gtBoardType() << " not expected in record.\n"
662  << std::endl;
663  }
664  } break;
665  }
666  }
667 
668  // add GTFE block to GT readout record, after updating active boards and record length
669 
670  gtReadoutRecord->setGtfeWord(*m_gtfeWord);
671 
672  // ... and reset it
673  m_gtfeWord->reset();
674 
675  // unpack trailer
676 
677  int trailerSize = 8;
678 
679  // if pointer after trailer is greater than pointer at
680  // the end of GT payload, produce empty products and quit unpacking
681  if ((ptrGt + trailerSize) > endPtrGt) {
682  edm::LogError("L1GlobalTriggerRawToDigi") << "\nError: Pointer after trailer "
683  << " greater than end pointer."
684  << "\n Put empty products in the event!"
685  << "\n Quit unpacking this event." << std::endl;
686 
688 
689  return;
690  }
691 
692  unpackTrailer(ptrGt, cmsTrailer);
693 
694  //
695  if (m_verbosity && m_isDebugEnabled) {
696  std::ostringstream myCoutStream;
697  gtReadoutRecord->print(myCoutStream);
698  LogTrace("L1GlobalTriggerRawToDigi") << "\n The following L1 GT DAQ readout record was unpacked.\n"
699  << myCoutStream.str() << "\n"
700  << std::endl;
701  }
702 
703  // put records into event
704 
705  iEvent.put(std::move(gmtrc));
706  iEvent.put(std::move(gtReadoutRecord));
707 }
708 
709 // unpack header
710 void L1GlobalTriggerRawToDigi::unpackHeader(const unsigned char* gtPtr, FEDHeader& cmsHeader) {
711  // TODO if needed in another format
712 
713  // print the header info
714  if (m_verbosity && m_isDebugEnabled) {
715  const cms_uint64_t* payload = reinterpret_cast<cms_uint64_t*>(const_cast<unsigned char*>(gtPtr));
716 
717  std::ostringstream myCoutStream;
718 
719  // one word only
720  int iWord = 0;
721 
722  myCoutStream << std::setw(4) << iWord << " " << std::hex << std::setfill('0') << std::setw(16) << payload[iWord]
723  << std::dec << std::setfill(' ') << "\n"
724  << std::endl;
725 
726  myCoutStream << " Event_type: " << std::hex << " hex: "
727  << " " << std::setw(1) << std::setfill('0') << cmsHeader.triggerType() << std::setfill(' ')
728  << std::dec << " dec: " << cmsHeader.triggerType() << std::endl;
729 
730  myCoutStream << " LVL1_Id: " << std::hex << " hex: "
731  << "" << std::setw(6) << std::setfill('0') << cmsHeader.lvl1ID() << std::setfill(' ') << std::dec
732  << " dec: " << cmsHeader.lvl1ID() << std::endl;
733 
734  myCoutStream << " BX_Id: " << std::hex << " hex: "
735  << " " << std::setw(3) << std::setfill('0') << cmsHeader.bxID() << std::setfill(' ') << std::dec
736  << " dec: " << cmsHeader.bxID() << std::endl;
737 
738  myCoutStream << " Source_Id: " << std::hex << " hex: "
739  << " " << std::setw(3) << std::setfill('0') << cmsHeader.sourceID() << std::setfill(' ') << std::dec
740  << " dec: " << cmsHeader.sourceID() << std::endl;
741 
742  myCoutStream << " FOV: " << std::hex << " hex: "
743  << " " << std::setw(1) << std::setfill('0') << cmsHeader.version() << std::setfill(' ') << std::dec
744  << " dec: " << cmsHeader.version() << std::endl;
745 
746  myCoutStream << " H: " << std::hex << " hex: "
747  << " " << std::setw(1) << std::setfill('0') << cmsHeader.moreHeaders() << std::setfill(' ')
748  << std::dec << " dec: " << cmsHeader.moreHeaders() << std::endl;
749 
750  LogDebug("L1GlobalTriggerRawToDigi") << "\n CMS Header \n" << myCoutStream.str() << "\n" << std::endl;
751  }
752 }
753 
754 // unpack PSB records
755 // psbPtr pointer to the beginning of the each PSB block obtained from gtPtr
757  const unsigned char* psbPtr,
758  L1GtPsbWord& psbWord) {
759  //LogDebug("L1GlobalTriggerRawToDigi")
760  //<< "\nUnpacking PSB block.\n"
761  //<< std::endl;
762 
764 
765  int psbSize = psbWord.getSize();
766  int psbWords = psbSize / uLength;
767 
768  const cms_uint64_t* payload = reinterpret_cast<cms_uint64_t*>(const_cast<unsigned char*>(psbPtr));
769 
770  for (int iWord = 0; iWord < psbWords; ++iWord) {
771  // fill PSB
772  // the second argument must match the word index defined in L1GtPsbWord class
773 
774  psbWord.setBoardId(payload[iWord], iWord);
775  psbWord.setBxInEvent(payload[iWord], iWord);
776  psbWord.setBxNr(payload[iWord], iWord);
777  psbWord.setEventNr(payload[iWord], iWord);
778 
779  psbWord.setAData(payload[iWord], iWord);
780  psbWord.setBData(payload[iWord], iWord);
781 
782  psbWord.setLocalBxNr(payload[iWord], iWord);
783 
784  LogTrace("L1GlobalTriggerRawToDigi") << std::setw(4) << iWord << " " << std::hex << std::setfill('0')
785  << std::setw(16) << payload[iWord] << std::dec << std::setfill(' ')
786  << std::endl;
787  }
788 }
789 
790 // unpack the GMT record
791 void L1GlobalTriggerRawToDigi::unpackGMT(const unsigned char* chp,
792  std::unique_ptr<L1MuGMTReadoutCollection>& gmtrc,
793  edm::Event& iEvent) {
794  //LogDebug("L1GlobalTriggerRawToDigi")
795  //<< "\nUnpacking GMT collection.\n"
796  //<< std::endl;
797 
798  // 17*64/2 TODO FIXME ask Ivan for a getSize() function for GMT record
799  const unsigned int gmtRecordSize32 = 34;
800 
801  std::unique_ptr<std::vector<L1MuRegionalCand> > DTCands(new std::vector<L1MuRegionalCand>);
802  std::unique_ptr<std::vector<L1MuRegionalCand> > CSCCands(new std::vector<L1MuRegionalCand>);
803  std::unique_ptr<std::vector<L1MuRegionalCand> > RPCbCands(new std::vector<L1MuRegionalCand>);
804  std::unique_ptr<std::vector<L1MuRegionalCand> > RPCfCands(new std::vector<L1MuRegionalCand>);
805  std::unique_ptr<std::vector<L1MuGMTCand> > GMTCands(new std::vector<L1MuGMTCand>);
806 
807  const unsigned* p = (const unsigned*)chp;
808 
809  // min Bx's in the event, computed after m_totalBxInEvent is obtained from GTFE block
810  // assume symmetrical number of BX around L1Accept
811  int iBxInEvent = (m_totalBxInEvent + 1) / 2 - m_totalBxInEvent;
812 
813  for (int iGmtRec = 0; iGmtRec < m_totalBxInEvent; ++iGmtRec) {
814  // unpack only bxInEvent requested, otherwise skip it
815  if ((iGmtRec >= m_lowSkipBxInEvent) && (iGmtRec < m_uppSkipBxInEvent)) {
816  // Dump the block
817  const cms_uint64_t* bp = reinterpret_cast<cms_uint64_t*>(const_cast<unsigned*>(p));
818  for (int iWord = 0; iWord < 17; iWord++) {
819  LogTrace("L1GlobalTriggerRawToDigi") << std::setw(4) << iWord << " " << std::hex << std::setfill('0')
820  << std::setw(16) << *bp++ << std::dec << std::setfill(' ') << std::endl;
821  }
822 
823  L1MuGMTReadoutRecord gmtrr(iBxInEvent);
824 
825  gmtrr.setEvNr((*p) & 0xffffff);
826  gmtrr.setBCERR(((*p) >> 24) & 0xff);
827  p++;
828 
829  gmtrr.setBxNr((*p) & 0xfff);
830  if (((*p) >> 15) & 1) {
831  gmtrr.setBxInEvent((((*p) >> 12) & 7) - 8);
832  } else {
833  gmtrr.setBxInEvent((((*p) >> 12) & 7));
834  }
835  // to do: check here the block length and the board id
836  p++;
837 
838  for (int im = 0; im < 16; im++) {
839  // flip the pt and quality bits -- this should better be done by GMT input chips
840  unsigned waux = *p++;
841  waux = (waux & 0xffff00ff) | ((~waux) & 0x0000ff00);
842  L1MuRegionalCand cand(waux, iBxInEvent);
843  // fix the type assignment (csc=2, rpcb=1) -- should be done by GMT input chips
844  if (im >= 4 && im < 8)
845  cand.setType(1);
846  if (im >= 8 && im < 12)
847  cand.setType(2);
848  cand.setPhiValue(m_TriggerScales->getPhiScale()->getLowEdge(cand.phi_packed()));
849  cand.setEtaValue(m_TriggerScales->getRegionalEtaScale(cand.type_idx())->getCenter(cand.eta_packed()));
850  cand.setPtValue(m_TriggerPtScale->getPtScale()->getLowEdge(cand.pt_packed()));
851  gmtrr.setInputCand(im, cand);
852  if (!cand.empty()) {
853  if (im < 4)
854  DTCands->push_back(cand);
855  if (im >= 4 && im < 8)
856  RPCbCands->push_back(cand);
857  if (im >= 8 && im < 12)
858  CSCCands->push_back(cand);
859  if (im >= 12)
860  RPCfCands->push_back(cand);
861  }
862  }
863 
864  unsigned char* prank = (unsigned char*)(p + 12);
865 
866  for (int im = 0; im < 12; im++) {
867  unsigned waux = *p++;
868  unsigned raux = im < 8 ? *prank++ : 0; // only fwd and brl cands have valid rank
869  L1MuGMTExtendedCand cand(waux, raux, iBxInEvent);
870  cand.setPhiValue(m_TriggerScales->getPhiScale()->getLowEdge(cand.phiIndex()));
871  cand.setEtaValue(m_TriggerScales->getGMTEtaScale()->getCenter(cand.etaIndex()));
872  cand.setPtValue(m_TriggerPtScale->getPtScale()->getLowEdge(cand.ptIndex()));
873  if (im < 4)
874  gmtrr.setGMTBrlCand(im, cand);
875  else if (im < 8)
876  gmtrr.setGMTFwdCand(im - 4, cand);
877  else {
878  gmtrr.setGMTCand(im - 8, cand);
879  if (!cand.empty())
880  GMTCands->push_back(cand);
881  }
882  }
883 
884  // skip the two sort rank words and two chip BX words
885  p += 4;
886 
887  gmtrc->addRecord(gmtrr);
888 
889  } else {
890  // increase the pointer with the GMT record size
891  p += gmtRecordSize32;
892  }
893 
894  // increase the BxInEvent number
895  iBxInEvent++;
896  }
897 
898  iEvent.put(std::move(DTCands), "DT");
899  iEvent.put(std::move(CSCCands), "CSC");
900  iEvent.put(std::move(RPCbCands), "RPCb");
901  iEvent.put(std::move(RPCfCands), "RPCf");
902  iEvent.put(std::move(GMTCands));
903 }
904 
905 // unpack trailer word
906 // trPtr pointer to the beginning of trailer obtained from gtPtr
907 void L1GlobalTriggerRawToDigi::unpackTrailer(const unsigned char* trlPtr, FEDTrailer& cmsTrailer) {
908  // TODO if needed in another format
909 
910  // print the trailer info
911  if (m_verbosity && m_isDebugEnabled) {
912  const cms_uint64_t* payload = reinterpret_cast<cms_uint64_t*>(const_cast<unsigned char*>(trlPtr));
913 
914  std::ostringstream myCoutStream;
915 
916  // one word only
917  int iWord = 0;
918 
919  myCoutStream << std::setw(4) << iWord << " " << std::hex << std::setfill('0') << std::setw(16) << payload[iWord]
920  << std::dec << std::setfill(' ') << "\n"
921  << std::endl;
922 
923  myCoutStream << " Event_length: " << std::hex << " hex: "
924  << "" << std::setw(6) << std::setfill('0') << cmsTrailer.fragmentLength() << std::setfill(' ')
925  << std::dec << " dec: " << cmsTrailer.fragmentLength() << std::endl;
926 
927  myCoutStream << " CRC: " << std::hex << " hex: "
928  << " " << std::setw(4) << std::setfill('0') << cmsTrailer.crc() << std::setfill(' ') << std::dec
929  << " dec: " << cmsTrailer.crc() << std::endl;
930 
931  myCoutStream << " Event_status: " << std::hex << " hex: "
932  << " " << std::setw(2) << std::setfill('0') << cmsTrailer.evtStatus() << std::setfill(' ')
933  << std::dec << " dec: " << cmsTrailer.evtStatus() << std::endl;
934 
935  myCoutStream << " TTS_bits: " << std::hex << " hex: "
936  << " " << std::setw(1) << std::setfill('0') << cmsTrailer.ttsBits() << std::setfill(' ')
937  << std::dec << " dec: " << cmsTrailer.ttsBits() << std::endl;
938 
939  myCoutStream << " More trailers: " << std::hex << " hex: "
940  << " " << std::setw(1) << std::setfill('0') << cmsTrailer.moreTrailers() << std::setfill(' ')
941  << std::dec << " dec: " << cmsTrailer.moreTrailers() << std::endl;
942 
943  LogDebug("L1GlobalTriggerRawToDigi") << "\n CMS Trailer \n" << myCoutStream.str() << "\n" << std::endl;
944  }
945 }
946 
947 // produce empty products in case of problems
949  std::unique_ptr<L1GlobalTriggerReadoutRecord> gtReadoutRecord(new L1GlobalTriggerReadoutRecord());
950 
951  std::unique_ptr<L1MuGMTReadoutCollection> gmtrc(new L1MuGMTReadoutCollection());
952 
953  std::unique_ptr<std::vector<L1MuRegionalCand> > DTCands(new std::vector<L1MuRegionalCand>);
954  std::unique_ptr<std::vector<L1MuRegionalCand> > CSCCands(new std::vector<L1MuRegionalCand>);
955  std::unique_ptr<std::vector<L1MuRegionalCand> > RPCbCands(new std::vector<L1MuRegionalCand>);
956  std::unique_ptr<std::vector<L1MuRegionalCand> > RPCfCands(new std::vector<L1MuRegionalCand>);
957  std::unique_ptr<std::vector<L1MuGMTCand> > GMTCands(new std::vector<L1MuGMTCand>);
958 
959  // put empty records into event
960 
961  iEvent.put(std::move(gmtrc));
962  iEvent.put(std::move(gtReadoutRecord));
963 
964  iEvent.put(std::move(DTCands), "DT");
965  iEvent.put(std::move(CSCCands), "CSC");
966  iEvent.put(std::move(RPCbCands), "RPCb");
967  iEvent.put(std::move(RPCfCands), "RPCf");
968  iEvent.put(std::move(GMTCands));
969 }
970 
971 // dump FED raw data
972 void L1GlobalTriggerRawToDigi::dumpFedRawData(const unsigned char* gtPtr, int gtSize, std::ostream& myCout) {
973  LogDebug("L1GlobalTriggerRawToDigi") << "\nDump FED raw data.\n" << std::endl;
974 
977 
978  int gtWords = gtSize / uLength;
979  LogTrace("L1GlobalTriggerRawToDigi") << "\nFED GT words (" << wLength << " bits):" << gtWords << "\n" << std::endl;
980 
981  const cms_uint64_t* payload = reinterpret_cast<cms_uint64_t*>(const_cast<unsigned char*>(gtPtr));
982 
983  for (unsigned int i = 0; i < gtSize / sizeof(cms_uint64_t); i++) {
984  myCout << std::setw(4) << i << " " << std::hex << std::setfill('0') << std::setw(16) << payload[i] << std::dec
985  << std::setfill(' ') << std::endl;
986  }
987 }
988 
989 // static class members
const L1MuTriggerScales * m_TriggerScales
muon trigger scales to convert unpacked data into physical quantities
uint8_t triggerType() const
Event Trigger type identifier.
Definition: FEDHeader.cc:13
bool isDebugEnabled()
const L1MuScale * getGMTEtaScale() const
get the GMT eta scale
const cms_uint16_t altNrBxBoard() const
get/set alternative for number of BX per board
Definition: L1GtfeWord.h:134
virtual void print(std::ostream &myCout) const
pretty print the content of a L1GtfeWord
Definition: L1GtfeWord.cc:253
ESGetTokenH3DDVariant esConsumes(std::string const &Record, edm::ConsumesCollector &)
Definition: DeDxTools.cc:283
void reset()
reset the content of a L1GtPsbWord
Definition: L1GtPsbWord.cc:330
const edm::ESGetToken< L1GtBoardMaps, L1GtBoardMapsRcd > m_l1GtBMToken
EventSetup Token for L1GtBoardMaps.
const cms_uint16_t recordLength1() const
get/set record length for alternative 1
Definition: L1GtfeWord.h:71
const unsigned int getSize() const
get the size of the PSB block in GT DAQ record (in multiple of 8 bits)
Definition: L1GtPsbWord.h:147
const unsigned int getSize() const
get the size of the GTFE block in GT DAQ record (in multiple of 8 bits)
Definition: L1GtfeWord.h:160
void unpackHeader(const unsigned char *, FEDHeader &)
block unpackers
cms_uint16_t m_activeBoardsMaskGt
mask for active boards
uint16_t sourceID() const
Identifier of the FED.
Definition: FEDHeader.cc:19
uint8_t ttsBits() const
Current value of the Trigger Throttling System bits.
Definition: FEDTrailer.cc:19
void produce(edm::Event &, const edm::EventSetup &) override
static const int UnitLength
one unit in the word is UnitLength bits
void setGMTBrlCand(int nr, L1MuGMTExtendedCand const &cand)
set GMT barrel candidate
virtual float getLowEdge(unsigned packed) const =0
get the low edge of bin represented by packed
T const * product() const
Definition: Handle.h:70
int m_recordLength0
total Bx&#39;s in the event, obtained from GTFE block
void setBData(cms_uint16_t bDataVal, int iB)
Definition: L1GtPsbWord.cc:263
~L1GlobalTriggerRawToDigi() override
destructor
void setGMTFwdCand(int nr, L1MuGMTExtendedCand const &cand)
set GMT forward candidate
void unpack(const unsigned char *fdlPtr)
Definition: L1GtFdlWord.cc:689
size_t size() const
Lenght of the data buffer in bytes.
Definition: FEDRawData.h:45
void setInputCand(int nr, unsigned data)
set Input muon
void unpackPSB(const edm::EventSetup &, const unsigned char *, L1GtPsbWord &)
const L1MuScale * getPhiScale() const
get the phi scale
Log< level::Error, false > LogError
void setRecordLength(cms_uint16_t recordLengthValue)
Definition: L1GtfeWord.h:84
virtual float getCenter(unsigned packed) const =0
get the center of bin represented by packed
const L1MuScale * getPtScale() const
get the Pt scale
static const int WordLength
GT DAQ record organized in words of WordLength bits.
#define LogTrace(id)
uint32_t fragmentLength() const
The length of the event fragment counted in 64-bit words including header and trailer.
Definition: FEDTrailer.cc:13
const cms_uint16_t recordLength() const
get/set record length for alternative 0
Definition: L1GtfeWord.h:82
const edm::ESGetToken< L1MuTriggerScales, L1MuTriggerScalesRcd > m_trigScalesToken
EventSetup Token for L1MuTriggerScales.
void setEventNr(cms_uint32_t eventNrValue)
Definition: L1GtPsbWord.h:99
void setBxNr(cms_uint16_t bxNrValue)
Definition: L1GtPsbWord.h:86
virtual void reset()
reset the content of a L1GtfeWord
Definition: L1GtfeWord.cc:240
int iEvent
Definition: GenABIO.cc:224
const L1MuTriggerPtScale * m_TriggerPtScale
T const * product() const
Definition: ESHandle.h:86
void print(std::ostream &myCout) const
pretty print
Definition: L1GtPsbWord.cc:348
void setBoardId(cms_uint16_t boardIdValue)
Definition: L1GtPsbWord.h:60
int m_recordLength1
corresponding to alternative 1 in altNrBxBoard()
const L1MuScale * getRegionalEtaScale(int isys) const
get the regioanl muon trigger eta scale, isys = 0(DT), 1(bRPC), 2(CSC), 3(fwdRPC) ...
void setLumiSegmentNr(const cms_uint16_t &lumiSegmentNrValue)
Definition: L1GtFdlWord.h:249
edm::InputTag m_daqGtInputTag
input tags for GT DAQ record
void setBxInEvent(int bxInEventValue)
Definition: L1GtPsbWord.h:73
void reset()
reset the content of a L1GtFdlWord
Definition: L1GtFdlWord.cc:567
uint16_t crc() const
Cyclic Redundancy Code of the event fragment including header and trailer.
Definition: FEDTrailer.cc:15
unsigned short cms_uint16_t
Definition: typedefs.h:13
bool moreHeaders() const
Definition: FEDHeader.cc:23
void setRecordLength1(cms_uint16_t recordLengthValue)
Definition: L1GtfeWord.h:73
const std::vector< L1GtBoard > & gtBoardMaps() const
get / set / print the L1 GT board map
Definition: L1GtBoardMaps.h:43
L1GlobalTriggerRawToDigi(const edm::ParameterSet &)
constructor(s)
uint8_t evtStatus() const
Event fragment status information.
Definition: FEDTrailer.cc:17
ESHandle< T > getHandle(const ESGetToken< T, R > &iToken) const
Definition: EventSetup.h:151
const cms_uint16_t lumiSegmentNr() const
get/set luminosity segment number of the actual bx
Definition: L1GtFdlWord.h:247
uint16_t bxID() const
The bunch crossing number.
Definition: FEDHeader.cc:17
static void fillDescriptions(edm::ConfigurationDescriptions &descriptions)
Log< level::Info, false > LogInfo
int m_totalBxInEvent
number of Bx for a board, obtained from GTFE block (record length & alternative)
uint8_t version() const
Version identifier of the FED data format.
Definition: FEDHeader.cc:21
void setActiveBoards(cms_uint16_t activeBoardsValue)
Definition: L1GtfeWord.h:121
void add(std::string const &label, ParameterSetDescription const &psetDescription)
void setBxNr(int bxnr)
set counters
void unpackTrailer(const unsigned char *, FEDTrailer &)
unpack trailer word
const unsigned int getSize() const
get the size of the FDL block in GT DAQ record (in multiple of 8 bits)
Definition: L1GtFdlWord.h:271
bool isValid() const
Definition: HandleBase.h:70
HLT enums.
void unpackGMT(const unsigned char *, std::unique_ptr< L1MuGMTReadoutCollection > &, edm::Event &)
unpack the GMT record
void setLocalBxNr(cms_uint16_t localBxNrValue)
Definition: L1GtPsbWord.h:136
const unsigned char * data() const
Return a const pointer to the beginning of the data buffer.
Definition: FEDRawData.cc:24
void print(std::ostream &myCout) const
pretty print the content of a L1GtFdlWord
Definition: L1GtFdlWord.cc:595
void setGMTCand(int nr, L1MuGMTExtendedCand const &cand)
set GMT candidate (does not store rank)
uint32_t lvl1ID() const
Level-1 event number generated by the TTC system.
Definition: FEDHeader.cc:15
unsigned long long cms_uint64_t
Definition: typedefs.h:17
const cms_uint16_t activeBoards() const
get/set boards contributing to EVM respectively DAQ record
Definition: L1GtfeWord.h:119
Log< level::Warning, false > LogWarning
void produceEmptyProducts(edm::Event &)
produce empty products in case of problems
const edm::ESGetToken< L1MuTriggerPtScale, L1MuTriggerPtScaleRcd > m_trigPtScaleToken
EventSetup Token for L1MuTriggerPtScale.
void setAData(cms_uint16_t aDataVal, int iA)
Definition: L1GtPsbWord.cc:191
virtual void unpack(const unsigned char *gtfePtr)
Definition: L1GtfeWord.cc:290
def move(src, dest)
Definition: eostools.py:511
bool moreTrailers() const
Definition: FEDTrailer.cc:21
#define LogDebug(id)
void dumpFedRawData(const unsigned char *, int, std::ostream &)
dump FED raw data