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 numberFdlBoards = 0;
345  int numberPsbBoards = 0;
346 
347  for (CItBoardMaps itBoard = boardMaps.begin(); itBoard != boardMaps.end(); ++itBoard) {
348  int iActiveBit = itBoard->gtBitDaqActiveBoards();
349  bool activeBoardToUnpack = false;
350 
351  if (iActiveBit >= 0) {
352  activeBoardToUnpack = activeBoardsGt & (1 << iActiveBit);
353  } else {
354  // board not in the ActiveBoards for the record
355  continue;
356  }
357 
358  if (activeBoardToUnpack) {
359  switch (itBoard->gtBoardType()) {
360  case GTFE:
361  break;
362  case FDL: {
363  numberFdlBoards++;
364  }
365 
366  break;
367  case PSB: {
368  numberPsbBoards++;
369  }
370 
371  break;
372  case GMT:
373  break;
374  case TCS:
375  break;
376  case TIM:
377  break;
378  default: {
379  // do nothing, all blocks are given in GtBoardType enum
380  if (m_verbosity) {
381  LogDebug("L1GlobalTriggerRawToDigi")
382  << "\nBoard of type " << itBoard->gtBoardType() << " not expected in record.\n"
383  << std::endl;
384  }
385  }
386 
387  break;
388  }
389  }
390  }
391 
392  // produce the L1GlobalTriggerReadoutRecord now, after we found the maximum number of
393  // BxInEvent the record has and how many boards are active (it is just reserving space
394  // for vectors)
395  //LogDebug("L1GlobalTriggerRawToDigi")
396  //<< "\nL1GlobalTriggerRawToDigi: producing L1GlobalTriggerReadoutRecord\n"
397  //<< "\nL1GlobalTriggerRawToDigi: producing L1MuGMTReadoutCollection;\n"
398  //<< std::endl;
399 
400  // get number of Bx in the event from GTFE block corresponding to alternative 0 and 1 in
403 
404  int maxBxInEvent = std::max(m_recordLength0, m_recordLength1);
405 
406  std::unique_ptr<L1GlobalTriggerReadoutRecord> gtReadoutRecord(
407  new L1GlobalTriggerReadoutRecord(maxBxInEvent, numberFdlBoards, numberPsbBoards));
408 
409  // produce also the GMT readout collection and set the reference in GT record
410  std::unique_ptr<L1MuGMTReadoutCollection> gmtrc(new L1MuGMTReadoutCollection(maxBxInEvent));
411 
412  //edm::RefProd<L1MuGMTReadoutCollection> refProdMuGMT = iEvent.getRefBeforePut<
413  // L1MuGMTReadoutCollection> ();
414 
415  //if (m_verbosity) {
416  // LogDebug("L1GlobalTriggerRawToDigi")
417  // << "\nL1GlobalTriggerRawToDigi: set L1MuGMTReadoutCollection RefProd"
418  // << " in L1GlobalTriggerReadoutRecord.\n" << std::endl;
419  //}
420  //gtReadoutRecord->setMuCollectionRefProd(refProdMuGMT);
421 
422  // ... then unpack modules other than GTFE, if requested
423 
424  for (CItBoardMaps itBoard = gtRecordMap.begin(); itBoard != gtRecordMap.end(); ++itBoard) {
425  int iActiveBit = itBoard->gtBitDaqActiveBoards();
426 
427  bool activeBoardToUnpack = false;
428  bool activeBoardInitial = false;
429 
430  int altNrBxBoardVal = -1;
431 
432  if (iActiveBit >= 0) {
433  activeBoardInitial = activeBoardsGtInitial & (1 << iActiveBit);
434  activeBoardToUnpack = activeBoardsGt & (1 << iActiveBit);
435 
436  altNrBxBoardVal = (altNrBxBoardInitial & (1 << iActiveBit)) >> iActiveBit;
437 
438  if (altNrBxBoardVal == 1) {
440  } else if (altNrBxBoardVal == 0) {
442  } else {
443  if (m_verbosity) {
444  edm::LogWarning("L1GlobalTriggerRawToDigi")
445  << "\n\nWARNING: Wrong value altNrBxBoardVal = " << altNrBxBoardVal << " for board " << std::hex
446  << (itBoard->gtBoardId()) << std::dec << "\n iActiveBit = " << iActiveBit
447  << "\n altNrBxBoardInitial = 0x" << std::hex << altNrBxBoardInitial << std::dec
448  << "\n activeBoardsGt = 0x" << std::hex << activeBoardsGt << std::dec
449  << "\n activeBoardInitial = " << activeBoardInitial
450  << "\n activeBoardToUnpack = " << activeBoardToUnpack << "\n Set altNrBxBoardVal tentatively to "
451  << m_recordLength0 << "\n Job may crash or produce wrong results!\n\n"
452  << std::endl;
453  }
454 
456  }
457 
458  // number of BX required to be unpacked
459 
461  if (m_verbosity) {
462  LogDebug("L1GlobalTriggerRawToDigi")
463  << "\nWARNING: Number of available bunch crosses for board" << (itBoard->gtBoardId())
464  << " in the record ( " << m_totalBxInEvent
465  << " ) \n is smaller than the number of bunch crosses requested to be unpacked (" << m_unpackBxInEvent
466  << " )!!! \n Unpacking only " << m_totalBxInEvent << " bunch crosses.\n"
467  << std::endl;
468  }
469 
470  m_lowSkipBxInEvent = 0;
472 
473  } else if (m_unpackBxInEvent < 0) {
474  m_lowSkipBxInEvent = 0;
476 
477  if (m_verbosity) {
478  LogDebug("L1GlobalTriggerRawToDigi") << "\nUnpacking all " << m_totalBxInEvent << " bunch crosses available."
479  << "\n"
480  << std::endl;
481  }
482 
483  } else if (m_unpackBxInEvent == 0) {
486 
487  if (m_verbosity) {
488  LogDebug("L1GlobalTriggerRawToDigi")
489  << "\nNo bxInEvent required to be unpacked from " << m_totalBxInEvent << " bunch crosses available."
490  << "\n"
491  << std::endl;
492  }
493 
494  // change RecordLength
495  // cast int to cms_uint16_t (there are normally 3 or 5 BxInEvent)
496  m_gtfeWord->setRecordLength(static_cast<cms_uint16_t>(m_unpackBxInEvent));
497  m_gtfeWord->setRecordLength1(static_cast<cms_uint16_t>(m_unpackBxInEvent));
498 
499  } else {
502 
503  if (m_verbosity) {
504  LogDebug("L1GlobalTriggerRawToDigi") << "\nUnpacking " << m_unpackBxInEvent << " bunch crosses from "
505  << 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 
516  } else {
517  // board not in the ActiveBoards for the record
518  continue;
519  }
520 
521  if (!activeBoardInitial) {
522  if (m_verbosity) {
523  LogDebug("L1GlobalTriggerRawToDigi") << "\nBoard of type " << itBoard->gtBoardName() << " with index "
524  << itBoard->gtBoardIndex() << " not active initially in raw data.\n"
525  << std::endl;
526  }
527  continue;
528  }
529 
530  // active board initially, could unpack it
531  switch (itBoard->gtBoardType()) {
532  case FDL: {
533  for (int iFdl = 0; iFdl < m_totalBxInEvent; ++iFdl) {
534  // if pointer after FDL payload is greater than pointer at
535  // the end of GT payload, produce empty products and quit unpacking
536  if ((ptrGt + m_gtFdlWord->getSize()) > endPtrGt) {
537  edm::LogError("L1GlobalTriggerRawToDigi")
538  << "\nError: Pointer after FDL " << iFdl << " greater than end pointer."
539  << "\n Put empty products in the event!"
540  << "\n Quit unpacking this event." << std::endl;
541 
543 
544  return;
545  }
546 
547  // unpack only if requested, otherwise skip it
548  if (activeBoardToUnpack) {
549  // unpack only bxInEvent requested, otherwise skip it
550  if ((iFdl >= m_lowSkipBxInEvent) && (iFdl < m_uppSkipBxInEvent)) {
551  m_gtFdlWord->unpack(ptrGt);
552 
553  // add 1 to the GT luminosity number to use the same convention as
554  // offline, where LS number starts with 1;
555  // in GT hardware, LS starts with 0
556  cms_uint16_t lsNr = m_gtFdlWord->lumiSegmentNr() + 1;
558 
559  // add FDL block to GT readout record
560  gtReadoutRecord->setGtFdlWord(*m_gtFdlWord);
561 
562  if (m_verbosity && m_isDebugEnabled) {
563  std::ostringstream myCoutStream;
564  m_gtFdlWord->print(myCoutStream);
565  LogTrace("L1GlobalTriggerRawToDigi") << myCoutStream.str() << "\n" << std::endl;
566  }
567 
568  // ... and reset it
569  m_gtFdlWord->reset();
570  }
571  }
572 
573  ptrGt += m_gtFdlWord->getSize(); // advance with FDL block size
574  }
575  }
576 
577  break;
578  case PSB: {
579  for (int iPsb = 0; iPsb < m_totalBxInEvent; ++iPsb) {
580  // if pointer after PSB payload is greater than pointer at
581  // the end of GT payload, produce empty products and quit unpacking
582  if ((ptrGt + m_gtPsbWord->getSize()) > endPtrGt) {
583  edm::LogError("L1GlobalTriggerRawToDigi")
584  << "\nError: Pointer after PSB " << iPsb << " greater than end pointer."
585  << "\n Put empty products in the event!"
586  << "\n Quit unpacking this event." << std::endl;
587 
589 
590  return;
591  }
592 
593  // unpack only if requested, otherwise skip it
594  if (activeBoardToUnpack) {
595  // unpack only bxInEvent requested, otherwise skip it
596  if ((iPsb >= m_lowSkipBxInEvent) && (iPsb < m_uppSkipBxInEvent)) {
597  unpackPSB(evSetup, ptrGt, *m_gtPsbWord);
598 
599  // add PSB block to GT readout record
600  gtReadoutRecord->setGtPsbWord(*m_gtPsbWord);
601 
602  if (m_verbosity && m_isDebugEnabled) {
603  std::ostringstream myCoutStream;
604  m_gtPsbWord->print(myCoutStream);
605  LogTrace("L1GlobalTriggerRawToDigi") << myCoutStream.str() << "\n" << std::endl;
606  }
607 
608  // ... and reset it
609  m_gtPsbWord->reset();
610  }
611  }
612 
613  ptrGt += m_gtPsbWord->getSize(); // advance with PSB block size
614  }
615  } break;
616  case GMT: {
617  // 17*64/8 TODO FIXME ask Ivan for a getSize() function for GMT record
618  unsigned int gmtRecordSize = 136;
619  unsigned int gmtCollSize = m_totalBxInEvent * gmtRecordSize;
620 
621  // if pointer after GMT payload is greater than pointer at
622  // the end of GT payload, produce empty products and quit unpacking
623  if ((ptrGt + gmtCollSize) > endPtrGt) {
624  edm::LogError("L1GlobalTriggerRawToDigi") << "\nError: Pointer after GMT "
625  << " greater than end pointer."
626  << "\n Put empty products in the event!"
627  << "\n Quit unpacking this event." << std::endl;
628 
630 
631  return;
632  }
633 
634  // unpack only if requested, otherwise skip it
635  if (activeBoardToUnpack) {
636  unpackGMT(ptrGt, gmtrc, iEvent);
637  }
638 
639  ptrGt += gmtCollSize; // advance with GMT block size
640  } break;
641  default: {
642  // do nothing, all blocks are given in GtBoardType enum
643  if (m_verbosity) {
644  LogDebug("L1GlobalTriggerRawToDigi")
645  << "\nBoard of type " << itBoard->gtBoardType() << " not expected in record.\n"
646  << std::endl;
647  }
648  } break;
649  }
650  }
651 
652  // add GTFE block to GT readout record, after updating active boards and record length
653 
654  gtReadoutRecord->setGtfeWord(*m_gtfeWord);
655 
656  // ... and reset it
657  m_gtfeWord->reset();
658 
659  // unpack trailer
660 
661  int trailerSize = 8;
662 
663  // if pointer after trailer is greater than pointer at
664  // the end of GT payload, produce empty products and quit unpacking
665  if ((ptrGt + trailerSize) > endPtrGt) {
666  edm::LogError("L1GlobalTriggerRawToDigi") << "\nError: Pointer after trailer "
667  << " greater than end pointer."
668  << "\n Put empty products in the event!"
669  << "\n Quit unpacking this event." << std::endl;
670 
672 
673  return;
674  }
675 
676  unpackTrailer(ptrGt, cmsTrailer);
677 
678  //
679  if (m_verbosity && m_isDebugEnabled) {
680  std::ostringstream myCoutStream;
681  gtReadoutRecord->print(myCoutStream);
682  LogTrace("L1GlobalTriggerRawToDigi") << "\n The following L1 GT DAQ readout record was unpacked.\n"
683  << myCoutStream.str() << "\n"
684  << std::endl;
685  }
686 
687  // put records into event
688 
689  iEvent.put(std::move(gmtrc));
690  iEvent.put(std::move(gtReadoutRecord));
691 }
692 
693 // unpack header
694 void L1GlobalTriggerRawToDigi::unpackHeader(const unsigned char* gtPtr, FEDHeader& cmsHeader) {
695  // TODO if needed in another format
696 
697  // print the header info
698  if (m_verbosity && m_isDebugEnabled) {
699  const cms_uint64_t* payload = reinterpret_cast<cms_uint64_t*>(const_cast<unsigned char*>(gtPtr));
700 
701  std::ostringstream myCoutStream;
702 
703  // one word only
704  int iWord = 0;
705 
706  myCoutStream << std::setw(4) << iWord << " " << std::hex << std::setfill('0') << std::setw(16) << payload[iWord]
707  << std::dec << std::setfill(' ') << "\n"
708  << std::endl;
709 
710  myCoutStream << " Event_type: " << std::hex << " hex: "
711  << " " << std::setw(1) << std::setfill('0') << cmsHeader.triggerType() << std::setfill(' ')
712  << std::dec << " dec: " << cmsHeader.triggerType() << std::endl;
713 
714  myCoutStream << " LVL1_Id: " << std::hex << " hex: "
715  << "" << std::setw(6) << std::setfill('0') << cmsHeader.lvl1ID() << std::setfill(' ') << std::dec
716  << " dec: " << cmsHeader.lvl1ID() << std::endl;
717 
718  myCoutStream << " BX_Id: " << std::hex << " hex: "
719  << " " << std::setw(3) << std::setfill('0') << cmsHeader.bxID() << std::setfill(' ') << std::dec
720  << " dec: " << cmsHeader.bxID() << std::endl;
721 
722  myCoutStream << " Source_Id: " << std::hex << " hex: "
723  << " " << std::setw(3) << std::setfill('0') << cmsHeader.sourceID() << std::setfill(' ') << std::dec
724  << " dec: " << cmsHeader.sourceID() << std::endl;
725 
726  myCoutStream << " FOV: " << std::hex << " hex: "
727  << " " << std::setw(1) << std::setfill('0') << cmsHeader.version() << std::setfill(' ') << std::dec
728  << " dec: " << cmsHeader.version() << std::endl;
729 
730  myCoutStream << " H: " << std::hex << " hex: "
731  << " " << std::setw(1) << std::setfill('0') << cmsHeader.moreHeaders() << std::setfill(' ')
732  << std::dec << " dec: " << cmsHeader.moreHeaders() << std::endl;
733 
734  LogDebug("L1GlobalTriggerRawToDigi") << "\n CMS Header \n" << myCoutStream.str() << "\n" << std::endl;
735  }
736 }
737 
738 // unpack PSB records
739 // psbPtr pointer to the beginning of the each PSB block obtained from gtPtr
741  const unsigned char* psbPtr,
742  L1GtPsbWord& psbWord) {
743  //LogDebug("L1GlobalTriggerRawToDigi")
744  //<< "\nUnpacking PSB block.\n"
745  //<< std::endl;
746 
748 
749  int psbSize = psbWord.getSize();
750  int psbWords = psbSize / uLength;
751 
752  const cms_uint64_t* payload = reinterpret_cast<cms_uint64_t*>(const_cast<unsigned char*>(psbPtr));
753 
754  for (int iWord = 0; iWord < psbWords; ++iWord) {
755  // fill PSB
756  // the second argument must match the word index defined in L1GtPsbWord class
757 
758  psbWord.setBoardId(payload[iWord], iWord);
759  psbWord.setBxInEvent(payload[iWord], iWord);
760  psbWord.setBxNr(payload[iWord], iWord);
761  psbWord.setEventNr(payload[iWord], iWord);
762 
763  psbWord.setAData(payload[iWord], iWord);
764  psbWord.setBData(payload[iWord], iWord);
765 
766  psbWord.setLocalBxNr(payload[iWord], iWord);
767 
768  LogTrace("L1GlobalTriggerRawToDigi") << std::setw(4) << iWord << " " << std::hex << std::setfill('0')
769  << std::setw(16) << payload[iWord] << std::dec << std::setfill(' ')
770  << std::endl;
771  }
772 }
773 
774 // unpack the GMT record
775 void L1GlobalTriggerRawToDigi::unpackGMT(const unsigned char* chp,
776  std::unique_ptr<L1MuGMTReadoutCollection>& gmtrc,
777  edm::Event& iEvent) {
778  //LogDebug("L1GlobalTriggerRawToDigi")
779  //<< "\nUnpacking GMT collection.\n"
780  //<< std::endl;
781 
782  // 17*64/2 TODO FIXME ask Ivan for a getSize() function for GMT record
783  const unsigned int gmtRecordSize32 = 34;
784 
785  std::unique_ptr<std::vector<L1MuRegionalCand> > DTCands(new std::vector<L1MuRegionalCand>);
786  std::unique_ptr<std::vector<L1MuRegionalCand> > CSCCands(new std::vector<L1MuRegionalCand>);
787  std::unique_ptr<std::vector<L1MuRegionalCand> > RPCbCands(new std::vector<L1MuRegionalCand>);
788  std::unique_ptr<std::vector<L1MuRegionalCand> > RPCfCands(new std::vector<L1MuRegionalCand>);
789  std::unique_ptr<std::vector<L1MuGMTCand> > GMTCands(new std::vector<L1MuGMTCand>);
790 
791  const unsigned* p = (const unsigned*)chp;
792 
793  // min Bx's in the event, computed after m_totalBxInEvent is obtained from GTFE block
794  // assume symmetrical number of BX around L1Accept
795  int iBxInEvent = (m_totalBxInEvent + 1) / 2 - m_totalBxInEvent;
796 
797  for (int iGmtRec = 0; iGmtRec < m_totalBxInEvent; ++iGmtRec) {
798  // unpack only bxInEvent requested, otherwise skip it
799  if ((iGmtRec >= m_lowSkipBxInEvent) && (iGmtRec < m_uppSkipBxInEvent)) {
800  // Dump the block
801  const cms_uint64_t* bp = reinterpret_cast<cms_uint64_t*>(const_cast<unsigned*>(p));
802  for (int iWord = 0; iWord < 17; iWord++) {
803  LogTrace("L1GlobalTriggerRawToDigi") << std::setw(4) << iWord << " " << std::hex << std::setfill('0')
804  << std::setw(16) << *bp++ << std::dec << std::setfill(' ') << std::endl;
805  }
806 
807  L1MuGMTReadoutRecord gmtrr(iBxInEvent);
808 
809  gmtrr.setEvNr((*p) & 0xffffff);
810  gmtrr.setBCERR(((*p) >> 24) & 0xff);
811  p++;
812 
813  gmtrr.setBxNr((*p) & 0xfff);
814  if (((*p) >> 15) & 1) {
815  gmtrr.setBxInEvent((((*p) >> 12) & 7) - 8);
816  } else {
817  gmtrr.setBxInEvent((((*p) >> 12) & 7));
818  }
819  // to do: check here the block length and the board id
820  p++;
821 
822  for (int im = 0; im < 16; im++) {
823  // flip the pt and quality bits -- this should better be done by GMT input chips
824  unsigned waux = *p++;
825  waux = (waux & 0xffff00ff) | ((~waux) & 0x0000ff00);
826  L1MuRegionalCand cand(waux, iBxInEvent);
827  // fix the type assignment (csc=2, rpcb=1) -- should be done by GMT input chips
828  if (im >= 4 && im < 8)
829  cand.setType(1);
830  if (im >= 8 && im < 12)
831  cand.setType(2);
832  cand.setPhiValue(m_TriggerScales->getPhiScale()->getLowEdge(cand.phi_packed()));
833  cand.setEtaValue(m_TriggerScales->getRegionalEtaScale(cand.type_idx())->getCenter(cand.eta_packed()));
834  cand.setPtValue(m_TriggerPtScale->getPtScale()->getLowEdge(cand.pt_packed()));
835  gmtrr.setInputCand(im, cand);
836  if (!cand.empty()) {
837  if (im < 4)
838  DTCands->push_back(cand);
839  if (im >= 4 && im < 8)
840  RPCbCands->push_back(cand);
841  if (im >= 8 && im < 12)
842  CSCCands->push_back(cand);
843  if (im >= 12)
844  RPCfCands->push_back(cand);
845  }
846  }
847 
848  unsigned char* prank = (unsigned char*)(p + 12);
849 
850  for (int im = 0; im < 12; im++) {
851  unsigned waux = *p++;
852  unsigned raux = im < 8 ? *prank++ : 0; // only fwd and brl cands have valid rank
853  L1MuGMTExtendedCand cand(waux, raux, iBxInEvent);
854  cand.setPhiValue(m_TriggerScales->getPhiScale()->getLowEdge(cand.phiIndex()));
855  cand.setEtaValue(m_TriggerScales->getGMTEtaScale()->getCenter(cand.etaIndex()));
856  cand.setPtValue(m_TriggerPtScale->getPtScale()->getLowEdge(cand.ptIndex()));
857  if (im < 4)
858  gmtrr.setGMTBrlCand(im, cand);
859  else if (im < 8)
860  gmtrr.setGMTFwdCand(im - 4, cand);
861  else {
862  gmtrr.setGMTCand(im - 8, cand);
863  if (!cand.empty())
864  GMTCands->push_back(cand);
865  }
866  }
867 
868  // skip the two sort rank words and two chip BX words
869  p += 4;
870 
871  gmtrc->addRecord(gmtrr);
872 
873  } else {
874  // increase the pointer with the GMT record size
875  p += gmtRecordSize32;
876  }
877 
878  // increase the BxInEvent number
879  iBxInEvent++;
880  }
881 
882  iEvent.put(std::move(DTCands), "DT");
883  iEvent.put(std::move(CSCCands), "CSC");
884  iEvent.put(std::move(RPCbCands), "RPCb");
885  iEvent.put(std::move(RPCfCands), "RPCf");
886  iEvent.put(std::move(GMTCands));
887 }
888 
889 // unpack trailer word
890 // trPtr pointer to the beginning of trailer obtained from gtPtr
891 void L1GlobalTriggerRawToDigi::unpackTrailer(const unsigned char* trlPtr, FEDTrailer& cmsTrailer) {
892  // TODO if needed in another format
893 
894  // print the trailer info
895  if (m_verbosity && m_isDebugEnabled) {
896  const cms_uint64_t* payload = reinterpret_cast<cms_uint64_t*>(const_cast<unsigned char*>(trlPtr));
897 
898  std::ostringstream myCoutStream;
899 
900  // one word only
901  int iWord = 0;
902 
903  myCoutStream << std::setw(4) << iWord << " " << std::hex << std::setfill('0') << std::setw(16) << payload[iWord]
904  << std::dec << std::setfill(' ') << "\n"
905  << std::endl;
906 
907  myCoutStream << " Event_length: " << std::hex << " hex: "
908  << "" << std::setw(6) << std::setfill('0') << cmsTrailer.fragmentLength() << std::setfill(' ')
909  << std::dec << " dec: " << cmsTrailer.fragmentLength() << std::endl;
910 
911  myCoutStream << " CRC: " << std::hex << " hex: "
912  << " " << std::setw(4) << std::setfill('0') << cmsTrailer.crc() << std::setfill(' ') << std::dec
913  << " dec: " << cmsTrailer.crc() << std::endl;
914 
915  myCoutStream << " Event_status: " << std::hex << " hex: "
916  << " " << std::setw(2) << std::setfill('0') << cmsTrailer.evtStatus() << std::setfill(' ')
917  << std::dec << " dec: " << cmsTrailer.evtStatus() << std::endl;
918 
919  myCoutStream << " TTS_bits: " << std::hex << " hex: "
920  << " " << std::setw(1) << std::setfill('0') << cmsTrailer.ttsBits() << std::setfill(' ')
921  << std::dec << " dec: " << cmsTrailer.ttsBits() << std::endl;
922 
923  myCoutStream << " More trailers: " << std::hex << " hex: "
924  << " " << std::setw(1) << std::setfill('0') << cmsTrailer.moreTrailers() << std::setfill(' ')
925  << std::dec << " dec: " << cmsTrailer.moreTrailers() << std::endl;
926 
927  LogDebug("L1GlobalTriggerRawToDigi") << "\n CMS Trailer \n" << myCoutStream.str() << "\n" << std::endl;
928  }
929 }
930 
931 // produce empty products in case of problems
933  std::unique_ptr<L1GlobalTriggerReadoutRecord> gtReadoutRecord(new L1GlobalTriggerReadoutRecord());
934 
935  std::unique_ptr<L1MuGMTReadoutCollection> gmtrc(new L1MuGMTReadoutCollection());
936 
937  std::unique_ptr<std::vector<L1MuRegionalCand> > DTCands(new std::vector<L1MuRegionalCand>);
938  std::unique_ptr<std::vector<L1MuRegionalCand> > CSCCands(new std::vector<L1MuRegionalCand>);
939  std::unique_ptr<std::vector<L1MuRegionalCand> > RPCbCands(new std::vector<L1MuRegionalCand>);
940  std::unique_ptr<std::vector<L1MuRegionalCand> > RPCfCands(new std::vector<L1MuRegionalCand>);
941  std::unique_ptr<std::vector<L1MuGMTCand> > GMTCands(new std::vector<L1MuGMTCand>);
942 
943  // put empty records into event
944 
945  iEvent.put(std::move(gmtrc));
946  iEvent.put(std::move(gtReadoutRecord));
947 
948  iEvent.put(std::move(DTCands), "DT");
949  iEvent.put(std::move(CSCCands), "CSC");
950  iEvent.put(std::move(RPCbCands), "RPCb");
951  iEvent.put(std::move(RPCfCands), "RPCf");
952  iEvent.put(std::move(GMTCands));
953 }
954 
955 // dump FED raw data
956 void L1GlobalTriggerRawToDigi::dumpFedRawData(const unsigned char* gtPtr, int gtSize, std::ostream& myCout) {
957  LogDebug("L1GlobalTriggerRawToDigi") << "\nDump FED raw data.\n" << std::endl;
958 
961 
962  int gtWords = gtSize / uLength;
963  LogTrace("L1GlobalTriggerRawToDigi") << "\nFED GT words (" << wLength << " bits):" << gtWords << "\n" << std::endl;
964 
965  const cms_uint64_t* payload = reinterpret_cast<cms_uint64_t*>(const_cast<unsigned char*>(gtPtr));
966 
967  for (unsigned int i = 0; i < gtSize / sizeof(cms_uint64_t); i++) {
968  myCout << std::setw(4) << i << " " << std::hex << std::setfill('0') << std::setw(16) << payload[i] << std::dec
969  << std::setfill(' ') << std::endl;
970  }
971 }
972 
973 // 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:687
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:565
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:130
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:593
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