CMS 3D CMS Logo

L1GTDigiToRaw.cc
Go to the documentation of this file.
1 
16 // this class header
18 
19 // system include files
20 #include <vector>
21 #include <iostream>
22 #include <iomanip>
23 
24 // user include files
27 
31 
34 
39 
43 
46 
49 
52 
55 
56 // constructor(s)
58  :
59 
60  m_daqGtFedId(pSet.getUntrackedParameter<int>("DaqGtFedId", FEDNumbering::MAXTriggerGTPFEDID)),
61  m_daqGtInputToken(consumes<L1GlobalTriggerReadoutRecord>(pSet.getParameter<edm::InputTag>("DaqGtInputTag"))),
62  m_muGmtInputToken(consumes<L1MuGMTReadoutCollection>(pSet.getParameter<edm::InputTag>("MuGmtInputTag"))),
63  m_daqGtInputTag(pSet.getParameter<edm::InputTag>("DaqGtInputTag")),
64  m_muGmtInputTag(pSet.getParameter<edm::InputTag>("MuGmtInputTag")),
65  m_activeBoardsMaskGt(pSet.getParameter<unsigned int>("ActiveBoardsMask")),
66  m_totalBxInEvent(0),
67  m_minBxInEvent(0),
68  m_maxBxInEvent(),
69  m_verbosity(pSet.getUntrackedParameter<int>("Verbosity", 0)),
70  m_isDebugEnabled(edm::isDebugEnabled())
71 
72 {
74  LogDebug("L1GTDigiToRaw") << "\nFED Id for DAQ GT record: " << m_daqGtFedId << " \n"
75  << "\nInput tag for DAQ GT record: " << m_daqGtInputTag << " \n"
76  << "\nInput tag for GMT record: " << m_muGmtInputTag << " \n"
77  << "\nMask for active boards (hex format): " << std::hex
78  << std::setw(sizeof(m_activeBoardsMaskGt) * 2) << std::setfill('0')
79  << m_activeBoardsMaskGt << std::dec << std::setfill(' ') << " \n"
80  << std::endl;
81  }
82 
83  //
84  produces<FEDRawDataCollection>();
85 }
86 
87 // member functions
88 
89 // method called to produce the data
91  // define new FEDRawDataCollection
92  // it contains ALL FEDs in an event
93  std::unique_ptr<FEDRawDataCollection> allFedRawData(new FEDRawDataCollection);
94 
95  FEDRawData& gtRawData = allFedRawData->FEDData(m_daqGtFedId);
96 
97  // get records from EventSetup
98 
99  // board maps
101  evSetup.get<L1GtBoardMapsRcd>().get(l1GtBM);
102 
103  const std::vector<L1GtBoard> boardMaps = l1GtBM->gtBoardMaps();
104  int boardMapsSize = boardMaps.size();
105 
106  typedef std::vector<L1GtBoard>::const_iterator CItBoardMaps;
107 
108  // create an ordered vector for the GT DAQ record
109  // header (pos 0 in record) and trailer (last position in record)
110  // not included, as they are not in board list
111  std::vector<L1GtBoard> gtRecordMap;
112  gtRecordMap.reserve(boardMapsSize);
113 
114  for (int iPos = 0; iPos < boardMapsSize; ++iPos) {
115  for (CItBoardMaps itBoard = boardMaps.begin(); itBoard != boardMaps.end(); ++itBoard) {
116  if (itBoard->gtPositionDaqRecord() == iPos) {
117  gtRecordMap.push_back(*itBoard);
118  break;
119  }
120  }
121  }
122 
123  // get L1GlobalTriggerReadoutRecord
125  iEvent.getByToken(m_daqGtInputToken, gtReadoutRecord);
126 
127  if (!gtReadoutRecord.isValid()) {
128  if (m_verbosity) {
129  edm::LogWarning("L1GTDigiToRaw") << "\nWarning: L1GlobalTriggerReadoutRecord with input tag " << m_daqGtInputTag
130  << "\nrequested in configuration, but not found in the event."
131  << "\nQuit packing this event" << std::endl;
132  }
133 
134  // put the raw data in the event
135  iEvent.put(std::move(allFedRawData));
136 
137  return;
138  }
139 
140  if (m_verbosity && m_isDebugEnabled) {
141  std::ostringstream myCoutStream;
142  gtReadoutRecord->print(myCoutStream);
143  LogTrace("L1GTDigiToRaw") << "\n The following L1 GT DAQ readout record will be packed.\n"
144  << " Some boards could be disabled before packing,"
145  << " see detailed board packing.\n"
146  << myCoutStream.str() << "\n"
147  << std::endl;
148  }
149 
150  // get GTFE block
151  L1GtfeWord gtfeBlock = gtReadoutRecord->gtfeWord();
152 
153  // get the number of Bx in the event for alternative 0 and alternative 1
154  cms_uint16_t recordLength0 = gtfeBlock.recordLength();
155  cms_uint16_t recordLength1 = gtfeBlock.recordLength1();
156 
157  // get list of active boards from the GTFE payload
158  // and mask some boards, if required
159  // boards not active are not written to the record
160 
161  cms_uint16_t activeBoardsGtInitial = gtfeBlock.activeBoards();
162  cms_uint16_t altNrBxBoardInitial = gtfeBlock.altNrBxBoard();
163 
164  // mask some boards, if needed
165 
166  cms_uint16_t activeBoardsGt = activeBoardsGtInitial & m_activeBoardsMaskGt;
167 
168  if (m_verbosity && m_isDebugEnabled) {
169  LogDebug("L1GTDigiToRaw") << "\nActive boards before masking(hex format): " << std::hex
170  << std::setw(sizeof(activeBoardsGtInitial) * 2) << std::setfill('0')
171  << activeBoardsGtInitial << std::dec << std::setfill(' ')
172  << "Active boards after masking(hex format): " << std::hex
173  << std::setw(sizeof(activeBoardsGt) * 2) << std::setfill('0') << activeBoardsGt
174  << std::dec << std::setfill(' ') << " \n"
175  << std::endl;
176  }
177 
178  // get the size of the record
179 
180  unsigned int gtDataSize = 0;
181 
182  unsigned int headerSize = 8;
183  gtDataSize += headerSize;
184 
185  for (CItBoardMaps itBoard = boardMaps.begin(); itBoard != boardMaps.end(); ++itBoard) {
186  if (itBoard->gtBoardType() == GTFE) {
187  gtDataSize += gtfeBlock.getSize();
188  continue;
189  }
190 
191  int iActiveBit = itBoard->gtBitDaqActiveBoards();
192  bool activeBoardToPack = false;
193 
194  int altNrBxBoardVal = -1;
195 
196  if (iActiveBit >= 0) {
197  activeBoardToPack = activeBoardsGt & (1 << iActiveBit);
198 
199  altNrBxBoardVal = (altNrBxBoardInitial & (1 << iActiveBit)) >> iActiveBit;
200 
201  if (altNrBxBoardVal == 1) {
202  m_totalBxInEvent = recordLength1;
203  } else if (altNrBxBoardVal == 0) {
204  m_totalBxInEvent = recordLength0;
205  } else {
206  if (m_verbosity) {
207  edm::LogWarning("L1GTDigiToRaw")
208  << "\n\nWARNING: Wrong value altNrBxBoardVal = " << altNrBxBoardVal << " for board " << std::hex
209  << (itBoard->gtBoardId()) << std::dec << "\n iActiveBit = " << iActiveBit
210  << "\n altNrBxBoardInitial = 0x" << std::hex << altNrBxBoardInitial << std::dec
211  << "\n activeBoardsGt = 0x" << std::hex << activeBoardsGt << std::dec
212  << "\n activeBoardToPack = " << activeBoardToPack << "\n Set altNrBxBoardVal tentatively to "
213  << recordLength0 << "\n Job may crash or produce wrong results!\n\n"
214  << std::endl;
215  }
216 
217  m_totalBxInEvent = recordLength0;
218  }
219 
220  } else {
221  // board not in the ActiveBoards for the record
222  continue;
223  }
224 
225  if (activeBoardToPack) {
226  switch (itBoard->gtBoardType()) {
227  case GTFE: {
228  // size already added;
229  }
230 
231  break;
232  case FDL: {
233  L1GtFdlWord fdlBlock;
234  gtDataSize += m_totalBxInEvent * fdlBlock.getSize();
235  }
236 
237  break;
238  case PSB: {
239  L1GtPsbWord psbBlock;
240  gtDataSize += m_totalBxInEvent * psbBlock.getSize();
241  }
242 
243  break;
244  case GMT: {
245  // 17*64/8 TODO FIXME ask Ivan for a getSize() function for GMT record
246  unsigned int gmtRecordSize = 136;
247  unsigned int gmtCollSize = m_totalBxInEvent * gmtRecordSize;
248  gtDataSize += gmtCollSize;
249  }
250 
251  break;
252  case TCS: {
253  L1TcsWord tcsBlock;
254  gtDataSize += tcsBlock.getSize();
255  }
256 
257  break;
258  case TIM: {
259  // not considered
260  }
261 
262  break;
263  default: {
264  // do nothing, all blocks are given in GtBoardType enum
265  }
266 
267  break;
268  }
269  }
270  }
271 
272  unsigned int trailerSize = 8;
273  gtDataSize += trailerSize;
274 
275  // resize, GT raw data record has variable length,
276  // depending on active boards (read in GTFE)
277  gtRawData.resize(gtDataSize);
278 
279  // ptrGt: pointer to the beginning of GT record in the raw data
280 
281  unsigned char* ptrGt = gtRawData.data();
282  unsigned char* ptrGtBegin = gtRawData.data();
283 
284  if (m_verbosity && m_isDebugEnabled) {
285  LogDebug("L1GTDigiToRaw") << "\n Size of raw data: " << gtRawData.size() << "\n" << std::endl;
286  }
287 
288  // ------- pack boards -------
289 
290  // pack header
291  packHeader(ptrGt, iEvent);
292  ptrGt += headerSize; // advance with header size
293 
294  // loop over other blocks in the raw record, if they are active
295 
296  for (CItBoardMaps itBoard = gtRecordMap.begin(); itBoard != gtRecordMap.end(); ++itBoard) {
297  if (itBoard->gtBoardType() == GTFE) {
298  packGTFE(evSetup, ptrGt, gtfeBlock, activeBoardsGt);
299 
300  if (m_verbosity && m_isDebugEnabled) {
301  std::ostringstream myCoutStream;
302  gtfeBlock.print(myCoutStream);
303  LogTrace("L1GTDigiToRaw") << myCoutStream.str() << "\n" << std::endl;
304  }
305 
306  ptrGt += gtfeBlock.getSize(); // advance with GTFE block size
307 
308  continue;
309  }
310 
311  // pack modules other than GTFE if they are active
312 
313  int iActiveBit = itBoard->gtBitDaqActiveBoards();
314  bool activeBoardToPack = false;
315 
316  int altNrBxBoardVal = -1;
317 
318  if (iActiveBit >= 0) {
319  activeBoardToPack = activeBoardsGt & (1 << iActiveBit);
320 
321  altNrBxBoardVal = (altNrBxBoardInitial & (1 << iActiveBit)) >> iActiveBit;
322 
323  if (altNrBxBoardVal == 1) {
324  m_totalBxInEvent = recordLength1;
325  } else if (altNrBxBoardVal == 0) {
326  m_totalBxInEvent = recordLength0;
327  } else {
328  if (m_verbosity) {
329  edm::LogWarning("L1GTDigiToRaw")
330  << "\n\nWARNING: Wrong value altNrBxBoardVal = " << altNrBxBoardVal << " for board " << std::hex
331  << (itBoard->gtBoardId()) << std::dec << "\n iActiveBit = " << iActiveBit
332  << "\n altNrBxBoardInitial = 0x" << std::hex << altNrBxBoardInitial << std::dec
333  << "\n activeBoardsGt = 0x" << std::hex << activeBoardsGt << std::dec
334  << "\n activeBoardToPack = " << activeBoardToPack << "\n Set altNrBxBoardVal tentatively to "
335  << recordLength0 << "\n Job may crash or produce wrong results!\n\n"
336  << std::endl;
337  }
338 
339  m_totalBxInEvent = recordLength0;
340  }
341 
343  m_maxBxInEvent = (m_totalBxInEvent + 1) / 2 - 1;
344 
345  } else {
346  // board not in the ActiveBoards for the record
347  continue;
348  }
349 
350  if (activeBoardToPack) {
351  if (m_verbosity && m_isDebugEnabled) {
352  LogDebug("L1GTDigiToRaw") << "\nBoard " << std::hex << "0x" << (itBoard->gtBoardId()) << std::dec
353  << "\n Number of bunch crosses in the record: " << m_totalBxInEvent << " = "
354  << "[" << m_minBxInEvent << ", " << m_maxBxInEvent << "] BX\n"
355  << std::endl;
356  }
357 
358  // active board, pack it
359  switch (itBoard->gtBoardType()) {
360  case FDL: {
361  for (int iBxInEvent = m_minBxInEvent; iBxInEvent <= m_maxBxInEvent; ++iBxInEvent) {
362  L1GtFdlWord fdlBlock = gtReadoutRecord->gtFdlWord(iBxInEvent);
363  packFDL(evSetup, ptrGt, fdlBlock);
364 
365  if (m_verbosity && m_isDebugEnabled) {
366  std::ostringstream myCoutStream;
367  fdlBlock.print(myCoutStream);
368  LogTrace("L1GTDigiToRaw") << myCoutStream.str() << "\n" << std::endl;
369  }
370 
371  ptrGt += fdlBlock.getSize(); // advance with FDL block size
372  }
373 
374  } break;
375  case PSB: {
376  if (m_verbosity && m_isDebugEnabled) {
377  LogDebug("L1GTDigiToRaw") << "\nBoard of type " << itBoard->gtBoardName() << " with index "
378  << itBoard->gtBoardIndex() << " and boardId " << std::hex << itBoard->gtBoardId()
379  << std::dec << "\n"
380  << std::endl;
381  }
382 
383  for (int iBxInEvent = m_minBxInEvent; iBxInEvent <= m_maxBxInEvent; ++iBxInEvent) {
384  L1GtPsbWord psbBlock = gtReadoutRecord->gtPsbWord(itBoard->gtBoardId(), iBxInEvent);
385 
386  packPSB(evSetup, ptrGt, psbBlock);
387 
388  if (m_verbosity && m_isDebugEnabled) {
389  std::ostringstream myCoutStream;
390  psbBlock.print(myCoutStream);
391  LogTrace("L1GTDigiToRaw") << myCoutStream.str() << "\n" << std::endl;
392  }
393 
394  ptrGt += psbBlock.getSize(); // advance with PSB block size
395  }
396 
397  } break;
398  case GMT: {
399  // get GMT record TODO separate GMT record or via RefProd from GT record
401  iEvent.getByToken(m_muGmtInputToken, gmtrc_handle);
402  if (!gmtrc_handle.isValid()) {
403  if (m_verbosity) {
404  edm::LogWarning("L1GTDigiToRaw")
405  << "\nWarning: L1MuGMTReadoutCollection with input tag " << m_muGmtInputTag
406  << "\nrequested in configuration, but not found in the event."
407  << "\nQuit packing this event" << std::endl;
408  }
409 
410  std::unique_ptr<FEDRawDataCollection> allFedRawData(new FEDRawDataCollection);
411 
412  // put the raw data in the event
413  iEvent.put(std::move(allFedRawData));
414 
415  return;
416  }
417 
418  L1MuGMTReadoutCollection const* gmtrc = gmtrc_handle.product();
419 
420  // pack the GMT record
421 
422  unsigned int gmtCollSize = 0;
423  gmtCollSize = packGmtCollection(ptrGt, gmtrc);
424  ptrGt += gmtCollSize; // advance with GMT collection size
425 
426  } break;
427  default: {
428  // do nothing, all blocks are given in GtBoardType enum
429  break;
430  }
431  }
432  }
433  }
434 
435  // pack trailer
436  packTrailer(ptrGt, ptrGtBegin, gtDataSize);
437 
438  // put the raw data in the event
439  iEvent.put(std::move(allFedRawData));
440 }
441 
442 // pack header
443 void L1GTDigiToRaw::packHeader(unsigned char* ptrGt, edm::Event& iEvent) {
444  // TODO FIXME where from to get all numbers?
445 
446  // Event Trigger type identifier
447  int triggerTypeVal = 0;
448 
449  // Level-1 event number generated by the TTC system
450  int lvl1IdVal = iEvent.id().event();
451 
452  // The bunch crossing number
453  int bxCross = iEvent.bunchCrossing();
454  cms_uint16_t bxCrossHw = 0;
455  if ((bxCross & 0xFFF) == bxCross) {
456  bxCrossHw = static_cast<cms_uint16_t>(bxCross);
457  } else {
458  bxCrossHw = 0; // Bx number too large, set to 0!
459  if (m_verbosity && m_isDebugEnabled) {
460  LogDebug("L1GTDigiToRaw") << "\nBunch cross number [hex] = " << std::hex << bxCross
461  << "\n larger than 12 bits. Set to 0! \n"
462  << std::dec << std::endl;
463  }
464  }
465  int bxIdVal = bxCrossHw;
466 
467  // Identifier of the FED
468  int sourceIdVal = m_daqGtFedId;
469 
470  // Version identifier of the FED data format
471  int versionVal = 0;
472 
473  // 0 -> the current header word is the last one.
474  // 1-> other header words can follow
475  // (always 1 for ECAL)
476  bool moreHeadersVal = false;
477 
478  FEDHeader gtFEDHeader(ptrGt);
479 
480  gtFEDHeader.set(ptrGt, triggerTypeVal, lvl1IdVal, bxIdVal, sourceIdVal, versionVal, moreHeadersVal);
481 }
482 
483 // pack the GTFE block
485  unsigned char* ptrGt,
486  L1GtfeWord& gtfeBlock,
487  cms_uint16_t activeBoardsGtValue) {
488  if (m_verbosity && m_isDebugEnabled) {
489  LogDebug("L1GTDigiToRaw") << "\nPacking GTFE \n" << std::endl;
490  }
491 
493 
494  // initialize the required number of word64
495  int nrWord64 = gtfeBlock.getSize() / uLength;
496  std::vector<cms_uint64_t> tmpWord64;
497  tmpWord64.resize(nrWord64);
498 
499  for (int iWord = 0; iWord < nrWord64; ++iWord) {
500  tmpWord64[iWord] = 0x0000000000000000ULL;
501  }
502 
503  // fill the values in the words
504  for (int iWord = 0; iWord < nrWord64; ++iWord) {
505  gtfeBlock.setBoardIdWord64(tmpWord64[iWord], iWord);
506  gtfeBlock.setRecordLength1Word64(tmpWord64[iWord], iWord);
507  gtfeBlock.setRecordLengthWord64(tmpWord64[iWord], iWord);
508  gtfeBlock.setBxNrWord64(tmpWord64[iWord], iWord);
509  gtfeBlock.setSetupVersionWord64(tmpWord64[iWord], iWord);
510  gtfeBlock.setActiveBoardsWord64(tmpWord64[iWord], iWord, activeBoardsGtValue);
511  gtfeBlock.setAltNrBxBoardWord64(tmpWord64[iWord], iWord);
512  gtfeBlock.setTotalTriggerNrWord64(tmpWord64[iWord], iWord);
513  }
514 
515  // put the words in the FED record
516 
517  cms_uint64_t* pw = reinterpret_cast<cms_uint64_t*>(const_cast<unsigned char*>(ptrGt));
518 
519  for (int iWord = 0; iWord < nrWord64; ++iWord) {
520  *pw++ = tmpWord64[iWord];
521 
522  if (m_verbosity && m_isDebugEnabled) {
523  LogTrace("L1GTDigiToRaw") << std::setw(4) << iWord << " " << std::hex << std::setfill('0') << std::setw(16)
524  << tmpWord64[iWord] << std::dec << std::setfill(' ') << std::endl;
525  }
526  }
527 }
528 
529 // pack the FDL block
530 void L1GTDigiToRaw::packFDL(const edm::EventSetup& evSetup, unsigned char* ptrGt, L1GtFdlWord& fdlBlock) {
531  if (m_verbosity && m_isDebugEnabled) {
532  LogDebug("L1GTDigiToRaw") << "\nPacking FDL \n" << std::endl;
533  }
534 
536 
537  // initialize the required number of word64
538  int nrWord64 = fdlBlock.getSize() / uLength;
539  std::vector<cms_uint64_t> tmpWord64;
540  tmpWord64.resize(nrWord64);
541 
542  for (int iWord = 0; iWord < nrWord64; ++iWord) {
543  tmpWord64[iWord] = 0x0000000000000000ULL;
544  }
545 
546  // fill the values in the words
547  for (int iWord = 0; iWord < nrWord64; ++iWord) {
548  fdlBlock.setBoardIdWord64(tmpWord64[iWord], iWord);
549  fdlBlock.setBxInEventWord64(tmpWord64[iWord], iWord);
550  fdlBlock.setBxNrWord64(tmpWord64[iWord], iWord);
551  fdlBlock.setEventNrWord64(tmpWord64[iWord], iWord);
552 
553  fdlBlock.setGtTechnicalTriggerWordWord64(tmpWord64[iWord], iWord);
554 
555  fdlBlock.setGtDecisionWordAWord64(tmpWord64[iWord], iWord);
556  fdlBlock.setGtDecisionWordBWord64(tmpWord64[iWord], iWord);
557 
558  fdlBlock.setGtDecisionWordExtendedWord64(tmpWord64[iWord], iWord);
559 
560  fdlBlock.setPhysicsDeclaredWord64(tmpWord64[iWord], iWord);
561  fdlBlock.setGtPrescaleFactorIndexTechWord64(tmpWord64[iWord], iWord);
562  fdlBlock.setGtPrescaleFactorIndexAlgoWord64(tmpWord64[iWord], iWord);
563  fdlBlock.setNoAlgoWord64(tmpWord64[iWord], iWord);
564  fdlBlock.setFinalORWord64(tmpWord64[iWord], iWord);
565 
566  fdlBlock.setOrbitNrWord64(tmpWord64[iWord], iWord);
567  fdlBlock.setLumiSegmentNrWord64(tmpWord64[iWord], iWord);
568  fdlBlock.setLocalBxNrWord64(tmpWord64[iWord], iWord);
569  }
570 
571  // put the words in the FED record
572 
573  cms_uint64_t* pw = reinterpret_cast<cms_uint64_t*>(const_cast<unsigned char*>(ptrGt));
574 
575  for (int iWord = 0; iWord < nrWord64; ++iWord) {
576  *pw++ = tmpWord64[iWord];
577 
578  if (m_verbosity && m_isDebugEnabled) {
579  LogTrace("L1GTDigiToRaw") << std::setw(4) << iWord << " " << std::hex << std::setfill('0') << std::setw(16)
580  << tmpWord64[iWord] << std::dec << std::setfill(' ') << std::endl;
581  }
582  }
583 }
584 
585 // pack the PSB block
586 void L1GTDigiToRaw::packPSB(const edm::EventSetup& evSetup, unsigned char* ptrGt, L1GtPsbWord& psbBlock) {
587  if (m_verbosity && m_isDebugEnabled) {
588  LogDebug("L1GTDigiToRaw") << "\nPacking PSB \n" << std::endl;
589  }
590 
592 
593  // initialize the required number of word64
594  int nrWord64 = psbBlock.getSize() / uLength;
595  std::vector<cms_uint64_t> tmpWord64;
596  tmpWord64.resize(nrWord64);
597 
598  for (int iWord = 0; iWord < nrWord64; ++iWord) {
599  tmpWord64[iWord] = 0x0000000000000000ULL;
600  }
601 
602  // fill the values in the words
603  for (int iWord = 0; iWord < nrWord64; ++iWord) {
604  psbBlock.setBoardIdWord64(tmpWord64[iWord], iWord);
605  psbBlock.setBxInEventWord64(tmpWord64[iWord], iWord);
606  psbBlock.setBxNrWord64(tmpWord64[iWord], iWord);
607  psbBlock.setEventNrWord64(tmpWord64[iWord], iWord);
608 
609  psbBlock.setADataWord64(tmpWord64[iWord], iWord);
610  psbBlock.setBDataWord64(tmpWord64[iWord], iWord);
611 
612  psbBlock.setLocalBxNrWord64(tmpWord64[iWord], iWord);
613  }
614 
615  // put the words in the FED record
616 
617  cms_uint64_t* pw = reinterpret_cast<cms_uint64_t*>(const_cast<unsigned char*>(ptrGt));
618 
619  for (int iWord = 0; iWord < nrWord64; ++iWord) {
620  *pw++ = tmpWord64[iWord];
621 
622  if (m_verbosity && m_isDebugEnabled) {
623  LogTrace("L1GTDigiToRaw") << std::setw(4) << iWord << " " << std::hex << std::setfill('0') << std::setw(16)
624  << tmpWord64[iWord] << std::dec << std::setfill(' ') << std::endl;
625  }
626  }
627 }
628 
629 // pack the GMT collection using packGMT (GMT record packing)
630 unsigned int L1GTDigiToRaw::packGmtCollection(unsigned char* ptrGt, L1MuGMTReadoutCollection const* digis) {
631  if (m_verbosity && m_isDebugEnabled) {
632  LogDebug("L1GTDigiToRaw") << "\nPacking GMT collection \n" << std::endl;
633  }
634 
635  unsigned gmtsize = 0;
636 
637  // loop range: int m_totalBxInEvent is normally even (L1A-1, L1A, L1A+1, with L1A = 0)
638  for (int iBxInEvent = m_minBxInEvent; iBxInEvent <= m_maxBxInEvent; ++iBxInEvent) {
639  L1MuGMTReadoutRecord const& gmtrr = digis->getRecord(iBxInEvent);
640  gmtsize = packGMT(gmtrr, ptrGt);
641  ptrGt += gmtsize;
642  }
643 
644  return m_totalBxInEvent * gmtsize;
645 }
646 
647 // pack a GMT record
648 unsigned L1GTDigiToRaw::packGMT(L1MuGMTReadoutRecord const& gmtrr, unsigned char* chp) {
649  const unsigned SIZE = 136;
650  const unsigned boardId = 0xdd12;
651  memset(chp, 0, SIZE);
652 
653  unsigned* p = (unsigned*)chp;
654 
655  // event number + bcerr
656  *p++ = (gmtrr.getEvNr() & 0xffffff) | ((gmtrr.getBCERR() & 0xff) << 24);
657  // bx number, bx in event, length(?), board-id(?)
658  *p++ = (gmtrr.getBxNr() & 0xfff) | ((gmtrr.getBxInEvent() & 0xf) << 12) | (boardId << 16);
659 
660  std::vector<L1MuRegionalCand> vrc;
661  std::vector<L1MuRegionalCand>::const_iterator irc;
662  unsigned* pp = p;
663 
664  vrc = gmtrr.getDTBXCands();
665  pp = p;
666  for (irc = vrc.begin(); irc != vrc.end(); irc++) {
667  *pp++ = (*irc).getDataWord();
668  }
669  p += 4;
670 
671  vrc = gmtrr.getBrlRPCCands();
672  pp = p;
673  for (irc = vrc.begin(); irc != vrc.end(); irc++) {
674  *pp++ = (*irc).getDataWord();
675  }
676  p += 4;
677 
678  vrc = gmtrr.getCSCCands();
679  pp = p;
680  for (irc = vrc.begin(); irc != vrc.end(); irc++) {
681  *pp++ = (*irc).getDataWord();
682  }
683  p += 4;
684 
685  vrc = gmtrr.getFwdRPCCands();
686  pp = p;
687  for (irc = vrc.begin(); irc != vrc.end(); irc++) {
688  *pp++ = (*irc).getDataWord();
689  }
690  p += 4;
691 
692  // the regional candidates are written to the record with inverted Pt and qual bits
693  pp = p - 16;
694  for (int i = 0; i < 16; i++) {
695  unsigned w = *pp;
696  *pp++ = (w & 0xffff00ff) | ((~w) & 0x0000ff00);
697  }
698 
699  std::vector<L1MuGMTExtendedCand> vgc;
700  std::vector<L1MuGMTExtendedCand>::const_iterator igc;
701 
702  vgc = gmtrr.getGMTBrlCands();
703  pp = p;
704  for (igc = vgc.begin(); igc != vgc.end(); igc++) {
705  *pp++ = (*igc).getDataWord();
706  }
707  p += 4;
708 
709  vgc = gmtrr.getGMTFwdCands();
710  pp = p;
711  for (igc = vgc.begin(); igc != vgc.end(); igc++) {
712  *pp++ = (*igc).getDataWord();
713  }
714  p += 4;
715 
716  vgc = gmtrr.getGMTCands();
717  pp = p;
718  for (igc = vgc.begin(); igc != vgc.end(); igc++) {
719  *pp++ = (*igc).getDataWord();
720  }
721  p += 4;
722 
723  unsigned char* chpp;
724 
725  vgc = gmtrr.getGMTBrlCands();
726  chpp = (unsigned char*)p;
727  for (igc = vgc.begin(); igc != vgc.end(); igc++) {
728  *chpp++ = (*igc).rank();
729  }
730  p++;
731 
732  vgc = gmtrr.getGMTFwdCands();
733  chpp = (unsigned char*)p;
734  for (igc = vgc.begin(); igc != vgc.end(); igc++) {
735  *chpp++ = (*igc).rank();
736  }
737  p++;
738 
739  return SIZE;
740 }
741 
742 unsigned int L1GTDigiToRaw::flipPtQ(unsigned int w) { return ((w & 0xffff00ff) | ((~w) & 0x0000ff00)); }
743 
744 // pack trailer
745 void L1GTDigiToRaw::packTrailer(unsigned char* ptrGt, unsigned char* ptrGtBegin, int dataSize) {
746  // TODO FIXME where from to get all numbers?
747 
748  // The length of the event fragment counted in 64-bit words including header and trailer
749  int lengthVal = dataSize / 8;
750 
751  // Cyclic Redundancy Code of the event fragment including header and trailer
752  int crcVal = evf::compute_crc(ptrGtBegin, dataSize);
753 
754  // Event fragment status information
755  int evtStatusVal = 0;
756 
757  // Current value of the Trigger Throttling System bits.
758  int ttsBitsVal = 0;
759 
760  // 0 -> the current trailer word is the last one.
761  // 1-> other trailer words can follow
762  // (always 0 for ECAL)
763  bool moreTrailersVal = false;
764 
765  FEDTrailer gtFEDTrailer(ptrGt);
766  gtFEDTrailer.set(ptrGt, lengthVal, crcVal, evtStatusVal, ttsBitsVal, moreTrailersVal);
767 }
768 
769 // static class members
L1GtPsbWord::setBoardIdWord64
void setBoardIdWord64(cms_uint64_t &word64, int iWord)
Definition: L1GtPsbWord.cc:123
L1GtPsbWord::setEventNrWord64
void setEventNrWord64(cms_uint64_t &word64, int iWord)
Definition: L1GtPsbWord.cc:173
L1MuGMTReadoutRecord::getFwdRPCCands
std::vector< L1MuRegionalCand > getFwdRPCCands() const
get forward RPC candidates vector
Definition: L1MuGMTReadoutRecord.cc:173
FEDNumbering.h
L1GtfeWord::activeBoards
const cms_uint16_t activeBoards() const
get/set boards contributing to EVM respectively DAQ record
Definition: L1GtfeWord.h:119
L1GTDigiToRaw::packGTFE
void packGTFE(const edm::EventSetup &, unsigned char *, L1GtfeWord &, cms_uint16_t activeBoardsGtValue)
Definition: L1GTDigiToRaw.cc:484
L1GTDigiToRaw::flipPtQ
unsigned int flipPtQ(unsigned int)
Definition: L1GTDigiToRaw.cc:742
L1GtFdlWord::setNoAlgoWord64
void setNoAlgoWord64(cms_uint64_t &word64, const int iWord)
Definition: L1GtFdlWord.cc:514
mps_fire.i
i
Definition: mps_fire.py:355
L1GlobalTriggerReadoutSetup::UnitLength
static const int UnitLength
one unit in the word is UnitLength bits
Definition: L1GlobalTriggerReadoutSetup.h:56
amcDumpToRaw_cfi.boardId
boardId
Definition: amcDumpToRaw_cfi.py:9
MessageLogger.h
FDL
Definition: L1GtDefinitions.h:27
edm::Handle::product
T const * product() const
Definition: Handle.h:70
PSB
Definition: L1GtDefinitions.h:27
L1GTDigiToRaw::m_minBxInEvent
int m_minBxInEvent
Definition: L1GTDigiToRaw.h:102
ESHandle.h
L1GTDigiToRaw::packHeader
void packHeader(unsigned char *, edm::Event &)
block packers ----------—
Definition: L1GTDigiToRaw.cc:443
FEDRawDataCollection
Definition: FEDRawDataCollection.h:18
edm
HLT enums.
Definition: AlignableModifier.h:19
L1MuGMTReadoutCollection.h
AlCaHLTBitMon_ParallelJobs.p
p
Definition: AlCaHLTBitMon_ParallelJobs.py:153
L1GTDigiToRaw::packPSB
void packPSB(const edm::EventSetup &, unsigned char *, L1GtPsbWord &)
Definition: L1GTDigiToRaw.cc:586
L1TcsWord
Definition: L1TcsWord.h:29
L1MuGMTReadoutRecord::getEvNr
int getEvNr() const
Definition: L1MuGMTReadoutRecord.h:64
L1GtFdlWord::setGtDecisionWordBWord64
void setGtDecisionWordBWord64(cms_uint64_t &word64, const int iWord)
Definition: L1GtFdlWord.cc:388
L1GtfeWord::print
virtual void print(std::ostream &myCout) const
pretty print the content of a L1GtfeWord
Definition: L1GtfeWord.cc:253
L1GtPsbWord::getSize
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
L1MuGMTReadoutRecord::getDTBXCands
std::vector< L1MuRegionalCand > getDTBXCands() const
get DT candidates vector
Definition: L1MuGMTReadoutRecord.cc:140
GTFE
Definition: L1GtDefinitions.h:27
L1GtPsbWord.h
L1GTDigiToRaw::m_activeBoardsMaskGt
cms_uint16_t m_activeBoardsMaskGt
mask for active boards
Definition: L1GTDigiToRaw.h:95
L1GtPsbWord::setBxInEventWord64
void setBxInEventWord64(cms_uint64_t &word64, int iWord)
Definition: L1GtPsbWord.cc:141
L1GtfeWord
Definition: L1GtfeWord.h:30
L1GlobalTriggerReadoutRecord::gtPsbWord
const L1GtPsbWord gtPsbWord(cms_uint16_t boardIdValue, int bxInEventValue) const
get / set PSB word (record) in the GT readout record
Definition: L1GlobalTriggerReadoutRecord.cc:421
L1GtPsbWord::setADataWord64
void setADataWord64(cms_uint64_t &word64, int iWord)
Definition: L1GtPsbWord.cc:233
L1GtPsbWord
Definition: L1GtPsbWord.h:29
L1GtFdlWord::setOrbitNrWord64
void setOrbitNrWord64(cms_uint64_t &word64, const int iWord)
Definition: L1GtFdlWord.cc:536
edm::Handle
Definition: AssociativeIterator.h:50
L1GlobalTriggerReadoutRecord
Definition: L1GlobalTriggerReadoutRecord.h:46
L1GtFdlWord::setBoardIdWord64
void setBoardIdWord64(cms_uint64_t &word64, const int iWord)
Definition: L1GtFdlWord.cc:179
FEDRawData::data
const unsigned char * data() const
Return a const pointer to the beginning of the data buffer.
Definition: FEDRawData.cc:24
FEDRawData
Definition: FEDRawData.h:19
L1GtFdlWord::setLumiSegmentNrWord64
void setLumiSegmentNrWord64(cms_uint64_t &word64, const int iWord)
Definition: L1GtFdlWord.cc:549
L1MuRegionalCand.h
L1GtPsbWord::setLocalBxNrWord64
void setLocalBxNrWord64(cms_uint64_t &word64, int iWord)
Definition: L1GtPsbWord.cc:323
FEDNumbering
Definition: FEDNumbering.h:17
L1GtfeWord::setRecordLengthWord64
void setRecordLengthWord64(cms_uint64_t &word64, int iWord)
Definition: L1GtfeWord.cc:142
L1GtfeWord::setAltNrBxBoardWord64
void setAltNrBxBoardWord64(cms_uint64_t &word64, int iWord)
Definition: L1GtfeWord.cc:212
L1TcsWord.h
L1GtfeWord::recordLength
const cms_uint16_t recordLength() const
get/set record length for alternative 0
Definition: L1GtfeWord.h:82
L1GTDigiToRaw::m_verbosity
int m_verbosity
verbosity level
Definition: L1GTDigiToRaw.h:110
L1GtfeWord::setRecordLength1Word64
void setRecordLength1Word64(cms_uint64_t &word64, int iWord)
Definition: L1GtfeWord.cc:129
L1GtFdlWord::setGtPrescaleFactorIndexTechWord64
void setGtPrescaleFactorIndexTechWord64(cms_uint64_t &word64, const int iWord)
Definition: L1GtFdlWord.cc:490
edm::EventSetup::get
T get() const
Definition: EventSetup.h:73
L1MuGMTReadoutRecord::getCSCCands
std::vector< L1MuRegionalCand > getCSCCands() const
get CSC candidates vector
Definition: L1MuGMTReadoutRecord.cc:151
L1GtFdlWord::setGtTechnicalTriggerWordWord64
void setGtTechnicalTriggerWordWord64(cms_uint64_t &word64, const int iWord)
Definition: L1GtFdlWord.cc:259
L1MuGMTReadoutRecord
Definition: L1MuGMTReadoutRecord.h:44
L1MuGMTReadoutRecord::getBxInEvent
int getBxInEvent() const
Definition: L1MuGMTReadoutRecord.h:63
L1GTDigiToRaw::packGmtCollection
unsigned int packGmtCollection(unsigned char *ptrGt, L1MuGMTReadoutCollection const *digis)
pack the GMT collection using packGMT (GMT record packing)
Definition: L1GTDigiToRaw.cc:630
w
const double w
Definition: UKUtility.cc:23
L1MuGMTReadoutRecord::getBxNr
int getBxNr() const
get counters
Definition: L1MuGMTReadoutRecord.h:61
L1GtPsbWord::setBxNrWord64
void setBxNrWord64(cms_uint64_t &word64, int iWord)
Definition: L1GtPsbWord.cc:158
L1GtfeWord::setSetupVersionWord64
void setSetupVersionWord64(cms_uint64_t &word64, int iWord)
Definition: L1GtfeWord.cc:166
edm::ESHandle
Definition: DTSurvey.h:22
L1GtfeWord::setBoardIdWord64
void setBoardIdWord64(cms_uint64_t &word64, int iWord)
Definition: L1GtfeWord.cc:116
GMT
Definition: L1GtDefinitions.h:27
L1GtFdlWord::setPhysicsDeclaredWord64
void setPhysicsDeclaredWord64(cms_uint64_t &word64, const int iWord)
Definition: L1GtFdlWord.cc:477
L1GTDigiToRaw::m_daqGtInputToken
const edm::EDGetTokenT< L1GlobalTriggerReadoutRecord > m_daqGtInputToken
input tag for GT DAQ record
Definition: L1GTDigiToRaw.h:87
L1GtFdlWord.h
L1GtPsbWord::print
void print(std::ostream &myCout) const
pretty print
Definition: L1GtPsbWord.cc:348
L1GTDigiToRaw::L1GTDigiToRaw
L1GTDigiToRaw(const edm::ParameterSet &)
constructor(s)
Definition: L1GTDigiToRaw.cc:57
L1TcsWord::getSize
const unsigned int getSize() const
get the size of the TCS block in GT EVM record (in multiple of 8 bits)
Definition: L1TcsWord.h:197
L1GtfeWord::getSize
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
evf::compute_crc
unsigned short compute_crc(unsigned char *buffer, unsigned int bufSize)
Definition: CRC16.h:46
edm::LogWarning
Definition: MessageLogger.h:141
L1GtFdlWord::setBxInEventWord64
void setBxInEventWord64(cms_uint64_t &word64, const int iWord)
Definition: L1GtFdlWord.cc:194
L1GtfeWord::setTotalTriggerNrWord64
void setTotalTriggerNrWord64(cms_uint64_t &word64, int iWord)
Definition: L1GtfeWord.cc:233
L1GtBoard.h
HLT_2018_cff.InputTag
InputTag
Definition: HLT_2018_cff.py:79016
LogDebug
#define LogDebug(id)
Definition: MessageLogger.h:670
MessageDrop.h
edm::ParameterSet
Definition: ParameterSet.h:36
L1GTDigiToRaw.h
FEDTrailer
Definition: FEDTrailer.h:14
L1GlobalTriggerReadoutSetup.h
L1GtFdlWord::setEventNrWord64
void setEventNrWord64(cms_uint64_t &word64, const int iWord)
Definition: L1GtFdlWord.cc:218
L1MuGMTReadoutRecord::getGMTFwdCands
std::vector< L1MuGMTExtendedCand > getGMTFwdCands() const
get GMT forward candidates vector
Definition: L1MuGMTReadoutRecord.cc:128
L1GTDigiToRaw::packGMT
unsigned int packGMT(L1MuGMTReadoutRecord const &, unsigned char *)
pack a GMT record
Definition: L1GTDigiToRaw.cc:648
L1MuGMTReadoutRecord::getBrlRPCCands
std::vector< L1MuRegionalCand > getBrlRPCCands() const
get barrel RPC candidates vector
Definition: L1MuGMTReadoutRecord.cc:162
L1MuGMTReadoutCollection::getRecord
L1MuGMTReadoutRecord const & getRecord(int bx=0) const
Definition: L1MuGMTReadoutCollection.h:55
L1GtFdlWord
Definition: L1GtFdlWord.h:29
L1GlobalTriggerReadoutRecord::print
void print(std::ostream &myCout) const
pretty print the content of a L1GlobalTriggerReadoutRecord
Definition: L1GlobalTriggerReadoutRecord.cc:515
L1GlobalTriggerReadoutRecord::gtfeWord
const L1GtfeWord gtfeWord() const
get / set GTFE word (record) in the GT readout record
Definition: L1GlobalTriggerReadoutRecord.cc:367
L1GtFdlWord::setBxNrWord64
void setBxNrWord64(cms_uint64_t &word64, const int iWord)
Definition: L1GtFdlWord.cc:207
createfilelist.int
int
Definition: createfilelist.py:10
iEvent
int iEvent
Definition: GenABIO.cc:224
L1GtfeWord::setActiveBoardsWord64
void setActiveBoardsWord64(cms_uint64_t &word64, int iWord)
Definition: L1GtfeWord.cc:191
L1GtFwd.h
L1GTDigiToRaw::m_muGmtInputToken
const edm::EDGetTokenT< L1MuGMTReadoutCollection > m_muGmtInputToken
input tag for GMT record
Definition: L1GTDigiToRaw.h:90
FEDRawDataCollection.h
L1GTDigiToRaw::m_muGmtInputTag
const edm::InputTag m_muGmtInputTag
Definition: L1GTDigiToRaw.h:92
L1GTDigiToRaw::packTrailer
void packTrailer(unsigned char *, unsigned char *, int)
pack trailer word
Definition: L1GTDigiToRaw.cc:745
L1GTDigiToRaw::m_totalBxInEvent
int m_totalBxInEvent
total Bx's in the event, obtained from GTFE block
Definition: L1GTDigiToRaw.h:98
cms_uint64_t
unsigned long long cms_uint64_t
Definition: typedefs.h:17
cms_uint16_t
unsigned short cms_uint16_t
Definition: typedefs.h:13
L1MuGMTReadoutRecord::getGMTCands
std::vector< L1MuGMTExtendedCand > getGMTCands() const
get GMT candidates vector
Definition: L1MuGMTReadoutRecord.cc:93
edm::EventSetup
Definition: EventSetup.h:57
L1MuGMTReadoutRecord::getGMTBrlCands
std::vector< L1MuGMTExtendedCand > getGMTBrlCands() const
get GMT barrel candidates vector
Definition: L1MuGMTReadoutRecord.cc:116
FEDTrailer::set
static void set(unsigned char *trailer, uint32_t lenght, uint16_t crc, uint8_t evt_stat, uint8_t tts, bool moreTrailers=false)
Set all fields in the trailer.
Definition: FEDTrailer.cc:31
get
#define get
L1GTDigiToRaw::m_isDebugEnabled
bool m_isDebugEnabled
Definition: L1GTDigiToRaw.h:111
L1GtBoardMaps.h
L1GtfeWord.h
FEDRawData::size
size_t size() const
Lenght of the data buffer in bytes.
Definition: FEDRawData.h:45
SeedStopReason::SIZE
L1GtFdlWord::setGtDecisionWordExtendedWord64
void setGtDecisionWordExtendedWord64(cms_uint64_t &word64, const int iWord)
Definition: L1GtFdlWord.cc:446
TCS
Definition: L1GtDefinitions.h:27
L1GtFdlWord::setLocalBxNrWord64
void setLocalBxNrWord64(cms_uint64_t &word64, const int iWord)
Definition: L1GtFdlWord.cc:560
L1GtFdlWord::setGtDecisionWordAWord64
void setGtDecisionWordAWord64(cms_uint64_t &word64, const int iWord)
Definition: L1GtFdlWord.cc:361
L1MuGMTReadoutCollection
Definition: L1MuGMTReadoutCollection.h:39
L1GTDigiToRaw::m_maxBxInEvent
int m_maxBxInEvent
Definition: L1GTDigiToRaw.h:106
L1GtPsbWord::setBDataWord64
void setBDataWord64(cms_uint64_t &word64, int iWord)
Definition: L1GtPsbWord.cc:295
L1MuGMTReadoutRecord::getBCERR
int getBCERR() const
Definition: L1MuGMTReadoutRecord.h:65
eostools.move
def move(src, dest)
Definition: eostools.py:511
L1GTDigiToRaw::m_daqGtFedId
int m_daqGtFedId
Definition: L1GTDigiToRaw.h:84
L1GtfeWord::recordLength1
const cms_uint16_t recordLength1() const
get/set record length for alternative 1
Definition: L1GtfeWord.h:71
L1GtFdlWord::getSize
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
FEDHeader::set
static void set(unsigned char *header, uint8_t triggerType, uint32_t lvl1ID, uint16_t bxID, uint16_t sourceID, uint8_t version=0, bool moreHeaders=false)
Set all fields in the header.
Definition: FEDHeader.cc:25
FEDRawData::resize
void resize(size_t newsize)
Definition: FEDRawData.cc:28
L1GtFdlWord::print
void print(std::ostream &myCout) const
pretty print the content of a L1GtFdlWord
Definition: L1GtFdlWord.cc:595
EventSetup.h
L1GtfeWord::setBxNrWord64
void setBxNrWord64(cms_uint64_t &word64, int iWord)
Definition: L1GtfeWord.cc:153
L1GtBoardMaps::gtBoardMaps
const std::vector< L1GtBoard > & gtBoardMaps() const
get / set / print the L1 GT board map
Definition: L1GtBoardMaps.h:43
edm::isDebugEnabled
bool isDebugEnabled()
Definition: MessageLogger.cc:71
L1GTDigiToRaw::produce
void produce(edm::Event &, const edm::EventSetup &) override
loop over events
Definition: L1GTDigiToRaw.cc:90
LogTrace
#define LogTrace(id)
Definition: MessageLogger.h:671
createTree.pp
pp
Definition: createTree.py:17
L1GtBoardMapsRcd
Definition: L1GtBoardMapsRcd.h:39
TIM
Definition: L1GtDefinitions.h:27
edm::HandleBase::isValid
bool isValid() const
Definition: HandleBase.h:70
FEDHeader
Definition: FEDHeader.h:14
edm::Event
Definition: Event.h:73
L1MuGMTExtendedCand.h
FEDHeader.h
L1GtfeWord::altNrBxBoard
const cms_uint16_t altNrBxBoard() const
get/set alternative for number of BX per board
Definition: L1GtfeWord.h:134
L1GtFdlWord::setFinalORWord64
void setFinalORWord64(cms_uint64_t &word64, const int iWord)
Definition: L1GtFdlWord.cc:525
TauDecayModes.dec
dec
Definition: TauDecayModes.py:143
L1GTDigiToRaw::packFDL
void packFDL(const edm::EventSetup &, unsigned char *, L1GtFdlWord &)
pack FDL blocks for various bunch crosses
Definition: L1GTDigiToRaw.cc:530
L1GtFdlWord::setGtPrescaleFactorIndexAlgoWord64
void setGtPrescaleFactorIndexAlgoWord64(cms_uint64_t &word64, const int iWord)
Definition: L1GtFdlWord.cc:503
L1GlobalTriggerReadoutRecord::gtFdlWord
const L1GtFdlWord gtFdlWord(int bxInEventValue) const
get / set FDL word (record) in the GT readout record
Definition: L1GlobalTriggerReadoutRecord.cc:372
L1GlobalTriggerReadoutRecord.h
L1GtBoardMapsRcd.h
L1GTDigiToRaw::m_daqGtInputTag
const edm::InputTag m_daqGtInputTag
Definition: L1GTDigiToRaw.h:91
CRC16.h
FEDTrailer.h