Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:10:46

0001 /**
0002  * \class L1GTEvmDigiToRaw
0003  *
0004  *
0005  * Description: generate raw data from digis.
0006  *
0007  * Implementation:
0008  *    <TODO: enter implementation details>
0009  *
0010  * \author: Vasile Mihai Ghete - HEPHY Vienna
0011  *
0012  *
0013  */
0014 
0015 // this class header
0016 #include "EventFilter/L1GlobalTriggerRawToDigi/interface/L1GTEvmDigiToRaw.h"
0017 
0018 // system include files
0019 #include <vector>
0020 #include <iostream>
0021 #include <iomanip>
0022 
0023 // user include files
0024 #include "DataFormats/FEDRawData/interface/FEDRawDataCollection.h"
0025 #include "DataFormats/FEDRawData/interface/FEDNumbering.h"
0026 
0027 #include "DataFormats/FEDRawData/interface/FEDHeader.h"
0028 #include "DataFormats/FEDRawData/interface/FEDTrailer.h"
0029 #include "FWCore/Utilities/interface/CRC16.h"
0030 
0031 #include "DataFormats/L1GlobalTrigger/interface/L1GlobalTriggerReadoutSetup.h"
0032 #include "DataFormats/L1GlobalTrigger/interface/L1GlobalTriggerEvmReadoutRecord.h"
0033 
0034 #include "DataFormats/L1GlobalTrigger/interface/L1GtfeWord.h"
0035 #include "DataFormats/L1GlobalTrigger/interface/L1GtfeExtWord.h"
0036 #include "DataFormats/L1GlobalTrigger/interface/L1TcsWord.h"
0037 #include "DataFormats/L1GlobalTrigger/interface/L1GtFdlWord.h"
0038 
0039 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0040 #include "FWCore/MessageLogger/interface/MessageDrop.h"
0041 
0042 #include "FWCore/Framework/interface/EventSetup.h"
0043 #include "FWCore/Framework/interface/ESHandle.h"
0044 
0045 #include "CondFormats/L1TObjects/interface/L1GtFwd.h"
0046 #include "CondFormats/L1TObjects/interface/L1GtBoard.h"
0047 
0048 #include "CondFormats/L1TObjects/interface/L1GtBoardMaps.h"
0049 #include "CondFormats/DataRecord/interface/L1GtBoardMapsRcd.h"
0050 
0051 // constructor(s)
0052 L1GTEvmDigiToRaw::L1GTEvmDigiToRaw(const edm::ParameterSet& pSet)
0053     : m_evmGtFedId(pSet.getUntrackedParameter<int>("EvmGtFedId", FEDNumbering::MINTriggerGTPFEDID)),
0054       m_evmGtInputToken(consumes<L1GlobalTriggerEvmReadoutRecord>(pSet.getParameter<edm::InputTag>("EvmGtInputTag"))),
0055       m_evmGtInputTag(pSet.getParameter<edm::InputTag>("EvmGtInputTag")),
0056       m_l1GtBMToken(esConsumes<L1GtBoardMaps, L1GtBoardMapsRcd>()),
0057       m_activeBoardsMaskGt(pSet.getParameter<unsigned int>("ActiveBoardsMask")),
0058       m_totalBxInEvent(0),
0059       m_minBxInEvent(0),
0060       m_maxBxInEvent(),
0061       m_verbosity(pSet.getUntrackedParameter<int>("Verbosity", 0)),
0062       m_isDebugEnabled(edm::isDebugEnabled())
0063 
0064 {
0065   LogDebug("L1GTEvmDigiToRaw") << "\nMask for active boards (hex format): " << std::hex
0066                                << std::setw(sizeof(m_activeBoardsMaskGt) * 2) << std::setfill('0')
0067                                << m_activeBoardsMaskGt << std::dec << std::setfill(' ')
0068                                << "\nInput tag for EVM GT record: " << m_evmGtInputTag
0069                                << "\nFED Id for EVM GT record: " << m_evmGtFedId << " \n"
0070                                << std::endl;
0071 
0072   //
0073   produces<FEDRawDataCollection>();
0074 }
0075 
0076 // member functions
0077 
0078 // method called to produce the data
0079 void L1GTEvmDigiToRaw::produce(edm::Event& iEvent, const edm::EventSetup& evSetup) {
0080   // define new FEDRawDataCollection
0081   // it contains ALL FEDs in an event
0082   std::unique_ptr<FEDRawDataCollection> allFedRawData(new FEDRawDataCollection);
0083 
0084   FEDRawData& gtRawData = allFedRawData->FEDData(m_evmGtFedId);
0085 
0086   // get records from EventSetup
0087 
0088   //  board maps
0089   edm::ESHandle<L1GtBoardMaps> l1GtBM = evSetup.getHandle(m_l1GtBMToken);
0090 
0091   const std::vector<L1GtBoard> boardMaps = l1GtBM->gtBoardMaps();
0092   int boardMapsSize = boardMaps.size();
0093 
0094   typedef std::vector<L1GtBoard>::const_iterator CItBoardMaps;
0095 
0096   // create an ordered vector for the GT EVM record
0097   // header (pos 0 in record) and trailer (last position in record)
0098   // not included, as they are not in board list
0099   std::vector<L1GtBoard> gtRecordMap;
0100   gtRecordMap.reserve(boardMapsSize);
0101 
0102   for (int iPos = 0; iPos < boardMapsSize; ++iPos) {
0103     for (CItBoardMaps itBoard = boardMaps.begin(); itBoard != boardMaps.end(); ++itBoard) {
0104       if (itBoard->gtPositionEvmRecord() == iPos) {
0105         gtRecordMap.push_back(*itBoard);
0106         break;
0107       }
0108     }
0109   }
0110 
0111   // get L1GlobalTriggerEvmReadoutRecord
0112   edm::Handle<L1GlobalTriggerEvmReadoutRecord> gtReadoutRecord;
0113   iEvent.getByToken(m_evmGtInputToken, gtReadoutRecord);
0114 
0115   if (!gtReadoutRecord.isValid()) {
0116     edm::LogWarning("L1GTEvmDigiToRaw") << "\nWarning: L1GlobalTriggerEvmReadoutRecord with input tag "
0117                                         << m_evmGtInputTag
0118                                         << "\nrequested in configuration, but not found in the event."
0119                                         << "\nQuit packing this event" << std::endl;
0120 
0121     // put the raw data in the event
0122     iEvent.put(std::move(allFedRawData));
0123 
0124     return;
0125   }
0126 
0127   if (m_verbosity && m_isDebugEnabled) {
0128     std::ostringstream myCoutStream;
0129     gtReadoutRecord->print(myCoutStream);
0130     LogTrace("L1GTEvmDigiToRaw") << "\n The following L1 GT EVM readout record will be packed.\n"
0131                                  << " Some boards could be disabled before packing,"
0132                                  << " see detailed board packing.\n"
0133                                  << myCoutStream.str() << "\n"
0134                                  << std::endl;
0135   }
0136 
0137   // get GTFE block
0138   L1GtfeExtWord gtfeBlock = gtReadoutRecord->gtfeWord();
0139 
0140   // get the number of Bx in the event for alternative 0 and alternative 1
0141   cms_uint16_t recordLength0 = gtfeBlock.recordLength();
0142   cms_uint16_t recordLength1 = gtfeBlock.recordLength1();
0143 
0144   // length of BST record (in bytes)
0145   m_bstLengthBytes = static_cast<int>(gtfeBlock.bstLengthBytes());
0146 
0147   // get list of active blocks from the GTFE block
0148   // and mask some blocks, if required
0149   // blocks not active are not written to the record
0150 
0151   cms_uint16_t activeBoardsGtInitial = gtfeBlock.activeBoards();
0152   cms_uint16_t altNrBxBoardInitial = gtfeBlock.altNrBxBoard();
0153 
0154   // mask some boards, if needed
0155 
0156   cms_uint16_t activeBoardsGt = activeBoardsGtInitial & m_activeBoardsMaskGt;
0157 
0158   if (m_verbosity && m_isDebugEnabled) {
0159     LogDebug("L1GTEvmDigiToRaw") << "\nActive boards before masking(hex format): " << std::hex
0160                                  << std::setw(sizeof(activeBoardsGtInitial) * 2) << std::setfill('0')
0161                                  << activeBoardsGtInitial << std::dec << std::setfill(' ')
0162                                  << "\nActive boards after masking(hex format):  " << std::hex
0163                                  << std::setw(sizeof(activeBoardsGt) * 2) << std::setfill('0') << activeBoardsGt
0164                                  << std::dec << std::setfill(' ') << " \n"
0165                                  << std::endl;
0166   }
0167 
0168   // get the size of the record
0169 
0170   unsigned int gtDataSize = 0;
0171 
0172   unsigned int headerSize = 8;
0173   gtDataSize += headerSize;
0174 
0175   for (CItBoardMaps itBoard = boardMaps.begin(); itBoard != boardMaps.end(); ++itBoard) {
0176     if (itBoard->gtBoardType() == GTFE) {
0177       gtDataSize += gtfeBlock.getSize();
0178       continue;
0179     }
0180 
0181     int iActiveBit = itBoard->gtBitEvmActiveBoards();
0182     bool activeBoardToPack = false;
0183 
0184     int altNrBxBoardVal = -1;
0185 
0186     if (iActiveBit >= 0) {
0187       activeBoardToPack = activeBoardsGt & (1 << iActiveBit);
0188 
0189       altNrBxBoardVal = (altNrBxBoardInitial & (1 << iActiveBit)) >> iActiveBit;
0190 
0191       if (altNrBxBoardVal == 1) {
0192         m_totalBxInEvent = recordLength1;
0193       } else if (altNrBxBoardVal == 0) {
0194         m_totalBxInEvent = recordLength0;
0195       } else {
0196         if (m_verbosity) {
0197           edm::LogWarning("L1GTEvmDigiToRaw")
0198               << "\n\nWARNING: Wrong value altNrBxBoardVal = " << altNrBxBoardVal << " for board " << std::hex
0199               << (itBoard->gtBoardId()) << std::dec << "\n  iActiveBit =            " << iActiveBit
0200               << "\n  altNrBxBoardInitial = 0x" << std::hex << altNrBxBoardInitial << std::dec
0201               << "\n  activeBoardsGt =      0x" << std::hex << activeBoardsGt << std::dec
0202               << "\n  activeBoardToPack =   " << activeBoardToPack << "\n Set altNrBxBoardVal tentatively to "
0203               << recordLength0 << "\n Job may crash or produce wrong results!\n\n"
0204               << std::endl;
0205         }
0206 
0207         m_totalBxInEvent = recordLength0;
0208       }
0209     } else {
0210       // board not in the ActiveBoards for the record
0211       continue;
0212     }
0213 
0214     if (activeBoardToPack) {
0215       switch (itBoard->gtBoardType()) {
0216         case GTFE: {
0217           // size already added;
0218         }
0219 
0220         break;
0221         case FDL: {
0222           L1GtFdlWord fdlBlock;
0223           gtDataSize += m_totalBxInEvent * fdlBlock.getSize();
0224         }
0225 
0226         break;
0227         case TCS: {
0228           L1TcsWord tcsBlock;
0229           gtDataSize += tcsBlock.getSize();
0230         }
0231 
0232         break;
0233         case TIM: {
0234           // not considered
0235         }
0236 
0237         break;
0238         default: {
0239           // do nothing, all blocks are given in GtBoardType enum
0240         }
0241 
0242         break;
0243       }
0244     }
0245   }
0246 
0247   unsigned int trailerSize = 8;
0248   gtDataSize += trailerSize;
0249 
0250   // resize, GT raw data record has variable length,
0251   // depending on active boards (read in GTFE)
0252   gtRawData.resize(gtDataSize);
0253 
0254   // ptrGt: pointer to the beginning of GT record in the raw data
0255 
0256   unsigned char* ptrGt = gtRawData.data();
0257   unsigned char* ptrGtBegin = gtRawData.data();
0258 
0259   if (m_verbosity && m_isDebugEnabled) {
0260     LogDebug("L1GTEvmDigiToRaw") << "\n Size of raw data: " << gtRawData.size() << "\n" << std::endl;
0261   }
0262 
0263   // ------- pack boards -------
0264 
0265   // pack header
0266   packHeader(ptrGt, iEvent);
0267   ptrGt += headerSize;  // advance with header size
0268 
0269   // loop over other blocks in the raw record, if they are active
0270 
0271   for (CItBoardMaps itBoard = gtRecordMap.begin(); itBoard != gtRecordMap.end(); ++itBoard) {
0272     if (itBoard->gtBoardType() == GTFE) {
0273       packGTFE(evSetup, ptrGt, gtfeBlock, activeBoardsGt);
0274 
0275       if (m_verbosity && m_isDebugEnabled) {
0276         std::ostringstream myCoutStream;
0277         gtfeBlock.print(myCoutStream);
0278         LogTrace("L1GTEvmDigiToRaw") << myCoutStream.str() << "\n" << std::endl;
0279       }
0280 
0281       ptrGt += gtfeBlock.getSize();  // advance with GTFE block size
0282 
0283       continue;
0284     }
0285 
0286     // pack modules other than GTFE if they are active
0287 
0288     int iActiveBit = itBoard->gtBitEvmActiveBoards();
0289     bool activeBoardToPack = false;
0290 
0291     int altNrBxBoardVal = -1;
0292 
0293     if (iActiveBit >= 0) {
0294       activeBoardToPack = activeBoardsGt & (1 << iActiveBit);
0295 
0296       altNrBxBoardVal = (altNrBxBoardInitial & (1 << iActiveBit)) >> iActiveBit;
0297 
0298       if (altNrBxBoardVal == 1) {
0299         m_totalBxInEvent = recordLength1;
0300       } else if (altNrBxBoardVal == 0) {
0301         m_totalBxInEvent = recordLength0;
0302       } else {
0303         if (m_verbosity) {
0304           edm::LogWarning("L1GTEvmDigiToRaw")
0305               << "\n\nWARNING: Wrong value altNrBxBoardVal = " << altNrBxBoardVal << " for board " << std::hex
0306               << (itBoard->gtBoardId()) << std::dec << "\n  iActiveBit =            " << iActiveBit
0307               << "\n  altNrBxBoardInitial = 0x" << std::hex << altNrBxBoardInitial << std::dec
0308               << "\n  activeBoardsGt =      0x" << std::hex << activeBoardsGt << std::dec
0309               << "\n  activeBoardToPack =   " << activeBoardToPack << "\n Set altNrBxBoardVal tentatively to "
0310               << recordLength0 << "\n Job may crash or produce wrong results!\n\n"
0311               << std::endl;
0312         }
0313 
0314         m_totalBxInEvent = recordLength0;
0315       }
0316 
0317       m_minBxInEvent = (m_totalBxInEvent + 1) / 2 - m_totalBxInEvent;
0318       m_maxBxInEvent = (m_totalBxInEvent + 1) / 2 - 1;
0319 
0320     } else {
0321       // board not in the ActiveBoards for the record
0322       continue;
0323     }
0324 
0325     if (activeBoardToPack) {
0326       if (m_verbosity && m_isDebugEnabled) {
0327         LogDebug("L1GTEvmDigiToRaw") << "\nBoard " << std::hex << "0x" << (itBoard->gtBoardId()) << std::dec
0328                                      << "\n  Number of bunch crosses in the record: " << m_totalBxInEvent << " = "
0329                                      << "[" << m_minBxInEvent << ", " << m_maxBxInEvent << "] BX\n"
0330                                      << std::endl;
0331       }
0332 
0333       // active board, pack it
0334       switch (itBoard->gtBoardType()) {
0335         case TCS: {
0336           L1TcsWord tcsBlock = gtReadoutRecord->tcsWord();
0337           packTCS(evSetup, ptrGt, tcsBlock);
0338 
0339           if (m_verbosity && m_isDebugEnabled) {
0340             std::ostringstream myCoutStream;
0341             tcsBlock.print(myCoutStream);
0342             LogTrace("L1GTEvmDigiToRaw") << myCoutStream.str() << "\n" << std::endl;
0343           }
0344 
0345           ptrGt += tcsBlock.getSize();  // advance with TCS block size
0346 
0347         } break;
0348         case FDL: {
0349           for (int iBxInEvent = m_minBxInEvent; iBxInEvent <= m_maxBxInEvent; ++iBxInEvent) {
0350             L1GtFdlWord fdlBlock = gtReadoutRecord->gtFdlWord(iBxInEvent);
0351             packFDL(evSetup, ptrGt, fdlBlock);
0352 
0353             if (m_verbosity && m_isDebugEnabled) {
0354               std::ostringstream myCoutStream;
0355               fdlBlock.print(myCoutStream);
0356               LogTrace("L1GTEvmDigiToRaw") << myCoutStream.str() << "\n" << std::endl;
0357             }
0358 
0359             ptrGt += fdlBlock.getSize();  // advance with FDL block size
0360           }
0361 
0362         } break;
0363         default: {
0364           // do nothing, all blocks are given in GtBoardType enum
0365           break;
0366         }
0367       }
0368     }
0369   }
0370 
0371   // pack trailer
0372   packTrailer(ptrGt, ptrGtBegin, gtDataSize);
0373 
0374   // put the raw data in the event
0375 
0376   iEvent.put(std::move(allFedRawData));
0377 }
0378 
0379 // pack header
0380 void L1GTEvmDigiToRaw::packHeader(unsigned char* ptrGt, edm::Event& iEvent) {
0381   // TODO FIXME where from to get all numbers?
0382 
0383   // Event Trigger type identifier
0384   int triggerTypeVal = 0;
0385 
0386   // Level-1 event number generated by the TTC system
0387   int lvl1IdVal = iEvent.id().event();
0388 
0389   // The bunch crossing number
0390   int bxCross = iEvent.bunchCrossing();
0391   cms_uint16_t bxCrossHw = 0;
0392   if ((bxCross & 0xFFF) == bxCross) {
0393     bxCrossHw = static_cast<cms_uint16_t>(bxCross);
0394   } else {
0395     bxCrossHw = 0;  // Bx number too large, set to 0!
0396     if (m_verbosity && m_isDebugEnabled) {
0397       LogDebug("L1GTEvmDigiToRaw") << "\nBunch cross number [hex] = " << std::hex << bxCross
0398                                    << "\n  larger than 12 bits. Set to 0! \n"
0399                                    << std::dec << std::endl;
0400     }
0401   }
0402   int bxIdVal = bxCrossHw;
0403 
0404   // Identifier of the FED
0405   int sourceIdVal = m_evmGtFedId;
0406 
0407   // Version identifier of the FED data format
0408   int versionVal = 0;
0409 
0410   // 0 -> the current header word is the last one.
0411   // 1-> other header words can follow
0412   // (always 1 for ECAL)
0413   bool moreHeadersVal = false;
0414 
0415   FEDHeader gtFEDHeader(ptrGt);
0416 
0417   gtFEDHeader.set(ptrGt, triggerTypeVal, lvl1IdVal, bxIdVal, sourceIdVal, versionVal, moreHeadersVal);
0418 }
0419 
0420 // pack the GTFE block
0421 void L1GTEvmDigiToRaw::packGTFE(const edm::EventSetup& evSetup,
0422                                 unsigned char* ptrGt,
0423                                 L1GtfeExtWord& gtfeBlock,
0424                                 cms_uint16_t activeBoardsGtValue) {
0425   if (m_verbosity && m_isDebugEnabled) {
0426     LogDebug("L1GTEvmDigiToRaw") << "\nPacking GTFE \n" << std::endl;
0427   }
0428 
0429   int uLength = L1GlobalTriggerReadoutSetup::UnitLength;
0430 
0431   // initialize the required number of word64
0432   int nrWord64 = gtfeBlock.getSize() / uLength;
0433   std::vector<cms_uint64_t> tmpWord64;
0434   tmpWord64.resize(nrWord64);
0435 
0436   for (int iWord = 0; iWord < nrWord64; ++iWord) {
0437     tmpWord64[iWord] = 0x0000000000000000ULL;
0438   }
0439 
0440   // fill the values in the words
0441   for (int iWord = 0; iWord < nrWord64; ++iWord) {
0442     gtfeBlock.setBoardIdWord64(tmpWord64[iWord], iWord);
0443     gtfeBlock.setRecordLength1Word64(tmpWord64[iWord], iWord);
0444     gtfeBlock.setRecordLengthWord64(tmpWord64[iWord], iWord);
0445     gtfeBlock.setBxNrWord64(tmpWord64[iWord], iWord);
0446     gtfeBlock.setSetupVersionWord64(tmpWord64[iWord], iWord);
0447     gtfeBlock.setActiveBoardsWord64(tmpWord64[iWord], iWord, activeBoardsGtValue);
0448     gtfeBlock.setAltNrBxBoardWord64(tmpWord64[iWord], iWord);
0449     gtfeBlock.setTotalTriggerNrWord64(tmpWord64[iWord], iWord);
0450 
0451     for (int iBst = 0; iBst < m_bstLengthBytes; ++iBst) {
0452       gtfeBlock.setBstWord64(tmpWord64[iWord], iBst, iWord);
0453     }
0454   }
0455 
0456   // put the words in the FED record
0457 
0458   cms_uint64_t* pw = reinterpret_cast<cms_uint64_t*>(const_cast<unsigned char*>(ptrGt));
0459 
0460   for (int iWord = 0; iWord < nrWord64; ++iWord) {
0461     *pw++ = tmpWord64[iWord];
0462 
0463     if (m_verbosity && m_isDebugEnabled) {
0464       LogTrace("L1GTEvmDigiToRaw") << std::setw(4) << iWord << "  " << std::hex << std::setfill('0') << std::setw(16)
0465                                    << tmpWord64[iWord] << std::dec << std::setfill(' ') << std::endl;
0466     }
0467   }
0468 }
0469 
0470 // pack the TCS block
0471 void L1GTEvmDigiToRaw::packTCS(const edm::EventSetup& evSetup, unsigned char* ptrGt, L1TcsWord& tcsBlock) {
0472   if (m_verbosity && m_isDebugEnabled) {
0473     LogDebug("L1GTEvmDigiToRaw") << "\nPacking TCS \n" << std::endl;
0474   }
0475 
0476   int uLength = L1GlobalTriggerReadoutSetup::UnitLength;
0477 
0478   // initialize the required number of word64
0479   int nrWord64 = tcsBlock.getSize() / uLength;
0480   std::vector<cms_uint64_t> tmpWord64;
0481   tmpWord64.resize(nrWord64);
0482 
0483   for (int iWord = 0; iWord < nrWord64; ++iWord) {
0484     tmpWord64[iWord] = 0x0000000000000000ULL;
0485   }
0486 
0487   // fill the values in the words
0488   for (int iWord = 0; iWord < nrWord64; ++iWord) {
0489     tcsBlock.setBoardIdWord64(tmpWord64[iWord], iWord);
0490     tcsBlock.setBxNrWord64(tmpWord64[iWord], iWord);
0491     tcsBlock.setDaqNrWord64(tmpWord64[iWord], iWord);
0492     tcsBlock.setTriggerTypeWord64(tmpWord64[iWord], iWord);
0493     tcsBlock.setStatusWord64(tmpWord64[iWord], iWord);
0494     tcsBlock.setLuminositySegmentNrWord64(tmpWord64[iWord], iWord);
0495 
0496     tcsBlock.setPartRunNrWord64(tmpWord64[iWord], iWord);
0497     tcsBlock.setAssignedPartitionsWord64(tmpWord64[iWord], iWord);
0498 
0499     tcsBlock.setPartTrigNrWord64(tmpWord64[iWord], iWord);
0500     tcsBlock.setEventNrWord64(tmpWord64[iWord], iWord);
0501 
0502     tcsBlock.setOrbitNrWord64(tmpWord64[iWord], iWord);
0503   }
0504 
0505   // put the words in the FED record
0506 
0507   cms_uint64_t* pw = reinterpret_cast<cms_uint64_t*>(const_cast<unsigned char*>(ptrGt));
0508 
0509   for (int iWord = 0; iWord < nrWord64; ++iWord) {
0510     *pw++ = tmpWord64[iWord];
0511 
0512     if (m_verbosity && m_isDebugEnabled) {
0513       LogTrace("L1GTEvmDigiToRaw") << std::setw(4) << iWord << "  " << std::hex << std::setfill('0') << std::setw(16)
0514                                    << tmpWord64[iWord] << std::dec << std::setfill(' ') << std::endl;
0515     }
0516   }
0517 }
0518 
0519 // pack the FDL block
0520 void L1GTEvmDigiToRaw::packFDL(const edm::EventSetup& evSetup, unsigned char* ptrGt, L1GtFdlWord& fdlBlock) {
0521   if (m_verbosity && m_isDebugEnabled) {
0522     LogDebug("L1GTEvmDigiToRaw") << "\nPacking FDL \n" << std::endl;
0523   }
0524 
0525   int uLength = L1GlobalTriggerReadoutSetup::UnitLength;
0526 
0527   // initialize the required number of word64
0528   int nrWord64 = fdlBlock.getSize() / uLength;
0529   std::vector<cms_uint64_t> tmpWord64;
0530   tmpWord64.resize(nrWord64);
0531 
0532   for (int iWord = 0; iWord < nrWord64; ++iWord) {
0533     tmpWord64[iWord] = 0x0000000000000000ULL;
0534   }
0535 
0536   // fill the values in the words
0537   for (int iWord = 0; iWord < nrWord64; ++iWord) {
0538     fdlBlock.setBoardIdWord64(tmpWord64[iWord], iWord);
0539     fdlBlock.setBxInEventWord64(tmpWord64[iWord], iWord);
0540     fdlBlock.setBxNrWord64(tmpWord64[iWord], iWord);
0541     fdlBlock.setEventNrWord64(tmpWord64[iWord], iWord);
0542 
0543     fdlBlock.setGtTechnicalTriggerWordWord64(tmpWord64[iWord], iWord);
0544 
0545     fdlBlock.setGtDecisionWordAWord64(tmpWord64[iWord], iWord);
0546     fdlBlock.setGtDecisionWordBWord64(tmpWord64[iWord], iWord);
0547 
0548     fdlBlock.setGtDecisionWordExtendedWord64(tmpWord64[iWord], iWord);
0549 
0550     fdlBlock.setPhysicsDeclaredWord64(tmpWord64[iWord], iWord);
0551     fdlBlock.setGtPrescaleFactorIndexTechWord64(tmpWord64[iWord], iWord);
0552     fdlBlock.setGtPrescaleFactorIndexAlgoWord64(tmpWord64[iWord], iWord);
0553     fdlBlock.setNoAlgoWord64(tmpWord64[iWord], iWord);
0554     fdlBlock.setFinalORWord64(tmpWord64[iWord], iWord);
0555 
0556     fdlBlock.setOrbitNrWord64(tmpWord64[iWord], iWord);
0557     fdlBlock.setLumiSegmentNrWord64(tmpWord64[iWord], iWord);
0558     fdlBlock.setLocalBxNrWord64(tmpWord64[iWord], iWord);
0559   }
0560 
0561   // put the words in the FED record
0562 
0563   cms_uint64_t* pw = reinterpret_cast<cms_uint64_t*>(const_cast<unsigned char*>(ptrGt));
0564 
0565   for (int iWord = 0; iWord < nrWord64; ++iWord) {
0566     *pw++ = tmpWord64[iWord];
0567 
0568     if (m_verbosity && m_isDebugEnabled) {
0569       LogTrace("L1GTEvmDigiToRaw") << std::setw(4) << iWord << "  " << std::hex << std::setfill('0') << std::setw(16)
0570                                    << tmpWord64[iWord] << std::dec << std::setfill(' ') << std::endl;
0571     }
0572   }
0573 }
0574 
0575 // pack trailer
0576 void L1GTEvmDigiToRaw::packTrailer(unsigned char* ptrGt, unsigned char* ptrGtBegin, int dataSize) {
0577   // TODO FIXME where from to get all numbers?
0578 
0579   // The length of the event fragment counted in 64-bit words including header and trailer
0580   int lengthVal = dataSize / 8;
0581 
0582   // Cyclic Redundancy Code of the event fragment including header and trailer
0583   int crcVal = evf::compute_crc(ptrGtBegin, dataSize);
0584 
0585   // Event fragment status information
0586   int evtStatusVal = 0;
0587 
0588   // Current value of the Trigger Throttling System bits.
0589   int ttsBitsVal = 0;
0590 
0591   // 0 -> the current trailer word is the last one.
0592   // 1-> other trailer words can follow
0593   // (always 0 for ECAL)
0594   bool moreTrailersVal = false;
0595 
0596   FEDTrailer gtFEDTrailer(ptrGt);
0597   gtFEDTrailer.set(ptrGt, lengthVal, crcVal, evtStatusVal, ttsBitsVal, moreTrailersVal);
0598 }
0599 
0600 // static class members