Back to home page

Project CMSSW displayed by LXR

 
 

    


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

0001 /**
0002  * \class L1GTDigiToRaw
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 -  GT
0011  * \author: Ivan Mikulec       - HEPHY Vienna - GMT
0012  *
0013  *
0014  */
0015 
0016 // this class header
0017 #include "EventFilter/L1GlobalTriggerRawToDigi/interface/L1GTDigiToRaw.h"
0018 
0019 // system include files
0020 #include <vector>
0021 #include <iostream>
0022 #include <iomanip>
0023 
0024 // user include files
0025 #include "DataFormats/FEDRawData/interface/FEDRawDataCollection.h"
0026 #include "DataFormats/FEDRawData/interface/FEDNumbering.h"
0027 
0028 #include "DataFormats/FEDRawData/interface/FEDHeader.h"
0029 #include "DataFormats/FEDRawData/interface/FEDTrailer.h"
0030 #include "FWCore/Utilities/interface/CRC16.h"
0031 
0032 #include "DataFormats/L1GlobalTrigger/interface/L1GlobalTriggerReadoutSetup.h"
0033 #include "DataFormats/L1GlobalTrigger/interface/L1GlobalTriggerReadoutRecord.h"
0034 
0035 #include "DataFormats/L1GlobalTrigger/interface/L1GtfeWord.h"
0036 #include "DataFormats/L1GlobalTrigger/interface/L1GtFdlWord.h"
0037 #include "DataFormats/L1GlobalTrigger/interface/L1GtPsbWord.h"
0038 #include "DataFormats/L1GlobalTrigger/interface/L1TcsWord.h"
0039 
0040 #include "DataFormats/L1GlobalMuonTrigger/interface/L1MuRegionalCand.h"
0041 #include "DataFormats/L1GlobalMuonTrigger/interface/L1MuGMTExtendedCand.h"
0042 #include "DataFormats/L1GlobalMuonTrigger/interface/L1MuGMTReadoutCollection.h"
0043 
0044 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0045 #include "FWCore/MessageLogger/interface/MessageDrop.h"
0046 
0047 #include "FWCore/Framework/interface/EventSetup.h"
0048 #include "FWCore/Framework/interface/ESHandle.h"
0049 
0050 #include "CondFormats/L1TObjects/interface/L1GtFwd.h"
0051 #include "CondFormats/L1TObjects/interface/L1GtBoard.h"
0052 
0053 // constructor(s)
0054 L1GTDigiToRaw::L1GTDigiToRaw(const edm::ParameterSet& pSet)
0055     :
0056 
0057       m_daqGtFedId(pSet.getUntrackedParameter<int>("DaqGtFedId", FEDNumbering::MAXTriggerGTPFEDID)),
0058       m_daqGtInputToken(consumes<L1GlobalTriggerReadoutRecord>(pSet.getParameter<edm::InputTag>("DaqGtInputTag"))),
0059       m_muGmtInputToken(consumes<L1MuGMTReadoutCollection>(pSet.getParameter<edm::InputTag>("MuGmtInputTag"))),
0060       m_daqGtInputTag(pSet.getParameter<edm::InputTag>("DaqGtInputTag")),
0061       m_muGmtInputTag(pSet.getParameter<edm::InputTag>("MuGmtInputTag")),
0062       m_l1GtBMToken(esConsumes<L1GtBoardMaps, L1GtBoardMapsRcd>()),
0063       m_activeBoardsMaskGt(pSet.getParameter<unsigned int>("ActiveBoardsMask")),
0064       m_totalBxInEvent(0),
0065       m_minBxInEvent(0),
0066       m_maxBxInEvent(),
0067       m_verbosity(pSet.getUntrackedParameter<int>("Verbosity", 0)),
0068       m_isDebugEnabled(edm::isDebugEnabled())
0069 
0070 {
0071   if (m_verbosity && m_isDebugEnabled) {
0072     LogDebug("L1GTDigiToRaw") << "\nFED Id for DAQ GT record: " << m_daqGtFedId << " \n"
0073                               << "\nInput tag for DAQ GT record: " << m_daqGtInputTag << " \n"
0074                               << "\nInput tag for GMT record: " << m_muGmtInputTag << " \n"
0075                               << "\nMask for active boards (hex format): " << std::hex
0076                               << std::setw(sizeof(m_activeBoardsMaskGt) * 2) << std::setfill('0')
0077                               << m_activeBoardsMaskGt << std::dec << std::setfill(' ') << " \n"
0078                               << std::endl;
0079   }
0080 
0081   //
0082   produces<FEDRawDataCollection>();
0083 }
0084 
0085 // member functions
0086 
0087 // method called to produce the data
0088 void L1GTDigiToRaw::produce(edm::Event& iEvent, const edm::EventSetup& evSetup) {
0089   // define new FEDRawDataCollection
0090   // it contains ALL FEDs in an event
0091   std::unique_ptr<FEDRawDataCollection> allFedRawData(new FEDRawDataCollection);
0092 
0093   FEDRawData& gtRawData = allFedRawData->FEDData(m_daqGtFedId);
0094 
0095   // get records from EventSetup
0096 
0097   //  board maps
0098   edm::ESHandle<L1GtBoardMaps> l1GtBM = evSetup.getHandle(m_l1GtBMToken);
0099 
0100   const std::vector<L1GtBoard> boardMaps = l1GtBM->gtBoardMaps();
0101   int boardMapsSize = boardMaps.size();
0102 
0103   typedef std::vector<L1GtBoard>::const_iterator CItBoardMaps;
0104 
0105   // create an ordered vector for the GT DAQ record
0106   // header (pos 0 in record) and trailer (last position in record)
0107   // not included, as they are not in board list
0108   std::vector<L1GtBoard> gtRecordMap;
0109   gtRecordMap.reserve(boardMapsSize);
0110 
0111   for (int iPos = 0; iPos < boardMapsSize; ++iPos) {
0112     for (CItBoardMaps itBoard = boardMaps.begin(); itBoard != boardMaps.end(); ++itBoard) {
0113       if (itBoard->gtPositionDaqRecord() == iPos) {
0114         gtRecordMap.push_back(*itBoard);
0115         break;
0116       }
0117     }
0118   }
0119 
0120   // get L1GlobalTriggerReadoutRecord
0121   edm::Handle<L1GlobalTriggerReadoutRecord> gtReadoutRecord;
0122   iEvent.getByToken(m_daqGtInputToken, gtReadoutRecord);
0123 
0124   if (!gtReadoutRecord.isValid()) {
0125     if (m_verbosity) {
0126       edm::LogWarning("L1GTDigiToRaw") << "\nWarning: L1GlobalTriggerReadoutRecord with input tag " << m_daqGtInputTag
0127                                        << "\nrequested in configuration, but not found in the event."
0128                                        << "\nQuit packing this event" << std::endl;
0129     }
0130 
0131     // put the raw data in the event
0132     iEvent.put(std::move(allFedRawData));
0133 
0134     return;
0135   }
0136 
0137   if (m_verbosity && m_isDebugEnabled) {
0138     std::ostringstream myCoutStream;
0139     gtReadoutRecord->print(myCoutStream);
0140     LogTrace("L1GTDigiToRaw") << "\n The following L1 GT DAQ readout record will be packed.\n"
0141                               << " Some boards could be disabled before packing,"
0142                               << " see detailed board packing.\n"
0143                               << myCoutStream.str() << "\n"
0144                               << std::endl;
0145   }
0146 
0147   // get GTFE block
0148   L1GtfeWord gtfeBlock = gtReadoutRecord->gtfeWord();
0149 
0150   // get the number of Bx in the event for alternative 0 and alternative 1
0151   cms_uint16_t recordLength0 = gtfeBlock.recordLength();
0152   cms_uint16_t recordLength1 = gtfeBlock.recordLength1();
0153 
0154   // get list of active boards from the GTFE payload
0155   // and mask some boards, if required
0156   // boards not active are not written to the record
0157 
0158   cms_uint16_t activeBoardsGtInitial = gtfeBlock.activeBoards();
0159   cms_uint16_t altNrBxBoardInitial = gtfeBlock.altNrBxBoard();
0160 
0161   // mask some boards, if needed
0162 
0163   cms_uint16_t activeBoardsGt = activeBoardsGtInitial & m_activeBoardsMaskGt;
0164 
0165   if (m_verbosity && m_isDebugEnabled) {
0166     LogDebug("L1GTDigiToRaw") << "\nActive boards before masking(hex format): " << std::hex
0167                               << std::setw(sizeof(activeBoardsGtInitial) * 2) << std::setfill('0')
0168                               << activeBoardsGtInitial << std::dec << std::setfill(' ')
0169                               << "Active boards after masking(hex format):  " << std::hex
0170                               << std::setw(sizeof(activeBoardsGt) * 2) << std::setfill('0') << activeBoardsGt
0171                               << std::dec << std::setfill(' ') << " \n"
0172                               << std::endl;
0173   }
0174 
0175   // get the size of the record
0176 
0177   unsigned int gtDataSize = 0;
0178 
0179   unsigned int headerSize = 8;
0180   gtDataSize += headerSize;
0181 
0182   for (CItBoardMaps itBoard = boardMaps.begin(); itBoard != boardMaps.end(); ++itBoard) {
0183     if (itBoard->gtBoardType() == GTFE) {
0184       gtDataSize += gtfeBlock.getSize();
0185       continue;
0186     }
0187 
0188     int iActiveBit = itBoard->gtBitDaqActiveBoards();
0189     bool activeBoardToPack = false;
0190 
0191     int altNrBxBoardVal = -1;
0192 
0193     if (iActiveBit >= 0) {
0194       activeBoardToPack = activeBoardsGt & (1 << iActiveBit);
0195 
0196       altNrBxBoardVal = (altNrBxBoardInitial & (1 << iActiveBit)) >> iActiveBit;
0197 
0198       if (altNrBxBoardVal == 1) {
0199         m_totalBxInEvent = recordLength1;
0200       } else if (altNrBxBoardVal == 0) {
0201         m_totalBxInEvent = recordLength0;
0202       } else {
0203         if (m_verbosity) {
0204           edm::LogWarning("L1GTDigiToRaw")
0205               << "\n\nWARNING: Wrong value altNrBxBoardVal = " << altNrBxBoardVal << " for board " << std::hex
0206               << (itBoard->gtBoardId()) << std::dec << "\n  iActiveBit =            " << iActiveBit
0207               << "\n  altNrBxBoardInitial = 0x" << std::hex << altNrBxBoardInitial << std::dec
0208               << "\n  activeBoardsGt =      0x" << std::hex << activeBoardsGt << std::dec
0209               << "\n  activeBoardToPack =   " << activeBoardToPack << "\n Set altNrBxBoardVal tentatively to "
0210               << recordLength0 << "\n Job may crash or produce wrong results!\n\n"
0211               << std::endl;
0212         }
0213 
0214         m_totalBxInEvent = recordLength0;
0215       }
0216 
0217     } else {
0218       // board not in the ActiveBoards for the record
0219       continue;
0220     }
0221 
0222     if (activeBoardToPack) {
0223       switch (itBoard->gtBoardType()) {
0224         case GTFE: {
0225           // size already added;
0226         }
0227 
0228         break;
0229         case FDL: {
0230           L1GtFdlWord fdlBlock;
0231           gtDataSize += m_totalBxInEvent * fdlBlock.getSize();
0232         }
0233 
0234         break;
0235         case PSB: {
0236           L1GtPsbWord psbBlock;
0237           gtDataSize += m_totalBxInEvent * psbBlock.getSize();
0238         }
0239 
0240         break;
0241         case GMT: {
0242           // 17*64/8 TODO FIXME ask Ivan for a getSize() function for GMT record
0243           unsigned int gmtRecordSize = 136;
0244           unsigned int gmtCollSize = m_totalBxInEvent * gmtRecordSize;
0245           gtDataSize += gmtCollSize;
0246         }
0247 
0248         break;
0249         case TCS: {
0250           L1TcsWord tcsBlock;
0251           gtDataSize += tcsBlock.getSize();
0252         }
0253 
0254         break;
0255         case TIM: {
0256           // not considered
0257         }
0258 
0259         break;
0260         default: {
0261           // do nothing, all blocks are given in GtBoardType enum
0262         }
0263 
0264         break;
0265       }
0266     }
0267   }
0268 
0269   unsigned int trailerSize = 8;
0270   gtDataSize += trailerSize;
0271 
0272   // resize, GT raw data record has variable length,
0273   // depending on active boards (read in GTFE)
0274   gtRawData.resize(gtDataSize);
0275 
0276   // ptrGt: pointer to the beginning of GT record in the raw data
0277 
0278   unsigned char* ptrGt = gtRawData.data();
0279   unsigned char* ptrGtBegin = gtRawData.data();
0280 
0281   if (m_verbosity && m_isDebugEnabled) {
0282     LogDebug("L1GTDigiToRaw") << "\n Size of raw data: " << gtRawData.size() << "\n" << std::endl;
0283   }
0284 
0285   // ------- pack boards -------
0286 
0287   // pack header
0288   packHeader(ptrGt, iEvent);
0289   ptrGt += headerSize;  // advance with header size
0290 
0291   // loop over other blocks in the raw record, if they are active
0292 
0293   for (CItBoardMaps itBoard = gtRecordMap.begin(); itBoard != gtRecordMap.end(); ++itBoard) {
0294     if (itBoard->gtBoardType() == GTFE) {
0295       packGTFE(evSetup, ptrGt, gtfeBlock, activeBoardsGt);
0296 
0297       if (m_verbosity && m_isDebugEnabled) {
0298         std::ostringstream myCoutStream;
0299         gtfeBlock.print(myCoutStream);
0300         LogTrace("L1GTDigiToRaw") << myCoutStream.str() << "\n" << std::endl;
0301       }
0302 
0303       ptrGt += gtfeBlock.getSize();  // advance with GTFE block size
0304 
0305       continue;
0306     }
0307 
0308     // pack modules other than GTFE if they are active
0309 
0310     int iActiveBit = itBoard->gtBitDaqActiveBoards();
0311     bool activeBoardToPack = false;
0312 
0313     int altNrBxBoardVal = -1;
0314 
0315     if (iActiveBit >= 0) {
0316       activeBoardToPack = activeBoardsGt & (1 << iActiveBit);
0317 
0318       altNrBxBoardVal = (altNrBxBoardInitial & (1 << iActiveBit)) >> iActiveBit;
0319 
0320       if (altNrBxBoardVal == 1) {
0321         m_totalBxInEvent = recordLength1;
0322       } else if (altNrBxBoardVal == 0) {
0323         m_totalBxInEvent = recordLength0;
0324       } else {
0325         if (m_verbosity) {
0326           edm::LogWarning("L1GTDigiToRaw")
0327               << "\n\nWARNING: Wrong value altNrBxBoardVal = " << altNrBxBoardVal << " for board " << std::hex
0328               << (itBoard->gtBoardId()) << std::dec << "\n  iActiveBit =            " << iActiveBit
0329               << "\n  altNrBxBoardInitial = 0x" << std::hex << altNrBxBoardInitial << std::dec
0330               << "\n  activeBoardsGt =      0x" << std::hex << activeBoardsGt << std::dec
0331               << "\n  activeBoardToPack =   " << activeBoardToPack << "\n Set altNrBxBoardVal tentatively to "
0332               << recordLength0 << "\n Job may crash or produce wrong results!\n\n"
0333               << std::endl;
0334         }
0335 
0336         m_totalBxInEvent = recordLength0;
0337       }
0338 
0339       m_minBxInEvent = (m_totalBxInEvent + 1) / 2 - m_totalBxInEvent;
0340       m_maxBxInEvent = (m_totalBxInEvent + 1) / 2 - 1;
0341 
0342     } else {
0343       // board not in the ActiveBoards for the record
0344       continue;
0345     }
0346 
0347     if (activeBoardToPack) {
0348       if (m_verbosity && m_isDebugEnabled) {
0349         LogDebug("L1GTDigiToRaw") << "\nBoard " << std::hex << "0x" << (itBoard->gtBoardId()) << std::dec
0350                                   << "\n  Number of bunch crosses in the record: " << m_totalBxInEvent << " = "
0351                                   << "[" << m_minBxInEvent << ", " << m_maxBxInEvent << "] BX\n"
0352                                   << std::endl;
0353       }
0354 
0355       // active board, pack it
0356       switch (itBoard->gtBoardType()) {
0357         case FDL: {
0358           for (int iBxInEvent = m_minBxInEvent; iBxInEvent <= m_maxBxInEvent; ++iBxInEvent) {
0359             L1GtFdlWord fdlBlock = gtReadoutRecord->gtFdlWord(iBxInEvent);
0360             packFDL(evSetup, ptrGt, fdlBlock);
0361 
0362             if (m_verbosity && m_isDebugEnabled) {
0363               std::ostringstream myCoutStream;
0364               fdlBlock.print(myCoutStream);
0365               LogTrace("L1GTDigiToRaw") << myCoutStream.str() << "\n" << std::endl;
0366             }
0367 
0368             ptrGt += fdlBlock.getSize();  // advance with FDL block size
0369           }
0370 
0371         } break;
0372         case PSB: {
0373           if (m_verbosity && m_isDebugEnabled) {
0374             LogDebug("L1GTDigiToRaw") << "\nBoard of type " << itBoard->gtBoardName() << " with index "
0375                                       << itBoard->gtBoardIndex() << " and boardId " << std::hex << itBoard->gtBoardId()
0376                                       << std::dec << "\n"
0377                                       << std::endl;
0378           }
0379 
0380           for (int iBxInEvent = m_minBxInEvent; iBxInEvent <= m_maxBxInEvent; ++iBxInEvent) {
0381             L1GtPsbWord psbBlock = gtReadoutRecord->gtPsbWord(itBoard->gtBoardId(), iBxInEvent);
0382 
0383             packPSB(evSetup, ptrGt, psbBlock);
0384 
0385             if (m_verbosity && m_isDebugEnabled) {
0386               std::ostringstream myCoutStream;
0387               psbBlock.print(myCoutStream);
0388               LogTrace("L1GTDigiToRaw") << myCoutStream.str() << "\n" << std::endl;
0389             }
0390 
0391             ptrGt += psbBlock.getSize();  // advance with PSB block size
0392           }
0393 
0394         } break;
0395         case GMT: {
0396           // get GMT record TODO separate GMT record or via RefProd from GT record
0397           edm::Handle<L1MuGMTReadoutCollection> gmtrc_handle;
0398           iEvent.getByToken(m_muGmtInputToken, gmtrc_handle);
0399           if (!gmtrc_handle.isValid()) {
0400             if (m_verbosity) {
0401               edm::LogWarning("L1GTDigiToRaw")
0402                   << "\nWarning: L1MuGMTReadoutCollection with input tag " << m_muGmtInputTag
0403                   << "\nrequested in configuration, but not found in the event."
0404                   << "\nQuit packing this event" << std::endl;
0405             }
0406 
0407             std::unique_ptr<FEDRawDataCollection> allFedRawData(new FEDRawDataCollection);
0408 
0409             // put the raw data in the event
0410             iEvent.put(std::move(allFedRawData));
0411 
0412             return;
0413           }
0414 
0415           L1MuGMTReadoutCollection const* gmtrc = gmtrc_handle.product();
0416 
0417           // pack the GMT record
0418 
0419           unsigned int gmtCollSize = 0;
0420           gmtCollSize = packGmtCollection(ptrGt, gmtrc);
0421           ptrGt += gmtCollSize;  // advance with GMT collection size
0422 
0423         } break;
0424         default: {
0425           // do nothing, all blocks are given in GtBoardType enum
0426           break;
0427         }
0428       }
0429     }
0430   }
0431 
0432   // pack trailer
0433   packTrailer(ptrGt, ptrGtBegin, gtDataSize);
0434 
0435   // put the raw data in the event
0436   iEvent.put(std::move(allFedRawData));
0437 }
0438 
0439 // pack header
0440 void L1GTDigiToRaw::packHeader(unsigned char* ptrGt, edm::Event& iEvent) {
0441   // TODO FIXME where from to get all numbers?
0442 
0443   // Event Trigger type identifier
0444   int triggerTypeVal = 0;
0445 
0446   // Level-1 event number generated by the TTC system
0447   int lvl1IdVal = iEvent.id().event();
0448 
0449   // The bunch crossing number
0450   int bxCross = iEvent.bunchCrossing();
0451   cms_uint16_t bxCrossHw = 0;
0452   if ((bxCross & 0xFFF) == bxCross) {
0453     bxCrossHw = static_cast<cms_uint16_t>(bxCross);
0454   } else {
0455     bxCrossHw = 0;  // Bx number too large, set to 0!
0456     if (m_verbosity && m_isDebugEnabled) {
0457       LogDebug("L1GTDigiToRaw") << "\nBunch cross number [hex] = " << std::hex << bxCross
0458                                 << "\n  larger than 12 bits. Set to 0! \n"
0459                                 << std::dec << std::endl;
0460     }
0461   }
0462   int bxIdVal = bxCrossHw;
0463 
0464   // Identifier of the FED
0465   int sourceIdVal = m_daqGtFedId;
0466 
0467   // Version identifier of the FED data format
0468   int versionVal = 0;
0469 
0470   // 0 -> the current header word is the last one.
0471   // 1-> other header words can follow
0472   // (always 1 for ECAL)
0473   bool moreHeadersVal = false;
0474 
0475   FEDHeader gtFEDHeader(ptrGt);
0476 
0477   gtFEDHeader.set(ptrGt, triggerTypeVal, lvl1IdVal, bxIdVal, sourceIdVal, versionVal, moreHeadersVal);
0478 }
0479 
0480 // pack the GTFE block
0481 void L1GTDigiToRaw::packGTFE(const edm::EventSetup& evSetup,
0482                              unsigned char* ptrGt,
0483                              L1GtfeWord& gtfeBlock,
0484                              cms_uint16_t activeBoardsGtValue) {
0485   if (m_verbosity && m_isDebugEnabled) {
0486     LogDebug("L1GTDigiToRaw") << "\nPacking GTFE \n" << std::endl;
0487   }
0488 
0489   int uLength = L1GlobalTriggerReadoutSetup::UnitLength;
0490 
0491   // initialize the required number of word64
0492   int nrWord64 = gtfeBlock.getSize() / uLength;
0493   std::vector<cms_uint64_t> tmpWord64;
0494   tmpWord64.resize(nrWord64);
0495 
0496   for (int iWord = 0; iWord < nrWord64; ++iWord) {
0497     tmpWord64[iWord] = 0x0000000000000000ULL;
0498   }
0499 
0500   // fill the values in the words
0501   for (int iWord = 0; iWord < nrWord64; ++iWord) {
0502     gtfeBlock.setBoardIdWord64(tmpWord64[iWord], iWord);
0503     gtfeBlock.setRecordLength1Word64(tmpWord64[iWord], iWord);
0504     gtfeBlock.setRecordLengthWord64(tmpWord64[iWord], iWord);
0505     gtfeBlock.setBxNrWord64(tmpWord64[iWord], iWord);
0506     gtfeBlock.setSetupVersionWord64(tmpWord64[iWord], iWord);
0507     gtfeBlock.setActiveBoardsWord64(tmpWord64[iWord], iWord, activeBoardsGtValue);
0508     gtfeBlock.setAltNrBxBoardWord64(tmpWord64[iWord], iWord);
0509     gtfeBlock.setTotalTriggerNrWord64(tmpWord64[iWord], iWord);
0510   }
0511 
0512   // put the words in the FED record
0513 
0514   cms_uint64_t* pw = reinterpret_cast<cms_uint64_t*>(const_cast<unsigned char*>(ptrGt));
0515 
0516   for (int iWord = 0; iWord < nrWord64; ++iWord) {
0517     *pw++ = tmpWord64[iWord];
0518 
0519     if (m_verbosity && m_isDebugEnabled) {
0520       LogTrace("L1GTDigiToRaw") << std::setw(4) << iWord << "  " << std::hex << std::setfill('0') << std::setw(16)
0521                                 << tmpWord64[iWord] << std::dec << std::setfill(' ') << std::endl;
0522     }
0523   }
0524 }
0525 
0526 // pack the FDL block
0527 void L1GTDigiToRaw::packFDL(const edm::EventSetup& evSetup, unsigned char* ptrGt, L1GtFdlWord& fdlBlock) {
0528   if (m_verbosity && m_isDebugEnabled) {
0529     LogDebug("L1GTDigiToRaw") << "\nPacking FDL \n" << std::endl;
0530   }
0531 
0532   int uLength = L1GlobalTriggerReadoutSetup::UnitLength;
0533 
0534   // initialize the required number of word64
0535   int nrWord64 = fdlBlock.getSize() / uLength;
0536   std::vector<cms_uint64_t> tmpWord64;
0537   tmpWord64.resize(nrWord64);
0538 
0539   for (int iWord = 0; iWord < nrWord64; ++iWord) {
0540     tmpWord64[iWord] = 0x0000000000000000ULL;
0541   }
0542 
0543   // fill the values in the words
0544   for (int iWord = 0; iWord < nrWord64; ++iWord) {
0545     fdlBlock.setBoardIdWord64(tmpWord64[iWord], iWord);
0546     fdlBlock.setBxInEventWord64(tmpWord64[iWord], iWord);
0547     fdlBlock.setBxNrWord64(tmpWord64[iWord], iWord);
0548     fdlBlock.setEventNrWord64(tmpWord64[iWord], iWord);
0549 
0550     fdlBlock.setGtTechnicalTriggerWordWord64(tmpWord64[iWord], iWord);
0551 
0552     fdlBlock.setGtDecisionWordAWord64(tmpWord64[iWord], iWord);
0553     fdlBlock.setGtDecisionWordBWord64(tmpWord64[iWord], iWord);
0554 
0555     fdlBlock.setGtDecisionWordExtendedWord64(tmpWord64[iWord], iWord);
0556 
0557     fdlBlock.setPhysicsDeclaredWord64(tmpWord64[iWord], iWord);
0558     fdlBlock.setGtPrescaleFactorIndexTechWord64(tmpWord64[iWord], iWord);
0559     fdlBlock.setGtPrescaleFactorIndexAlgoWord64(tmpWord64[iWord], iWord);
0560     fdlBlock.setNoAlgoWord64(tmpWord64[iWord], iWord);
0561     fdlBlock.setFinalORWord64(tmpWord64[iWord], iWord);
0562 
0563     fdlBlock.setOrbitNrWord64(tmpWord64[iWord], iWord);
0564     fdlBlock.setLumiSegmentNrWord64(tmpWord64[iWord], iWord);
0565     fdlBlock.setLocalBxNrWord64(tmpWord64[iWord], iWord);
0566   }
0567 
0568   // put the words in the FED record
0569 
0570   cms_uint64_t* pw = reinterpret_cast<cms_uint64_t*>(const_cast<unsigned char*>(ptrGt));
0571 
0572   for (int iWord = 0; iWord < nrWord64; ++iWord) {
0573     *pw++ = tmpWord64[iWord];
0574 
0575     if (m_verbosity && m_isDebugEnabled) {
0576       LogTrace("L1GTDigiToRaw") << std::setw(4) << iWord << "  " << std::hex << std::setfill('0') << std::setw(16)
0577                                 << tmpWord64[iWord] << std::dec << std::setfill(' ') << std::endl;
0578     }
0579   }
0580 }
0581 
0582 // pack the PSB block
0583 void L1GTDigiToRaw::packPSB(const edm::EventSetup& evSetup, unsigned char* ptrGt, L1GtPsbWord& psbBlock) {
0584   if (m_verbosity && m_isDebugEnabled) {
0585     LogDebug("L1GTDigiToRaw") << "\nPacking PSB \n" << std::endl;
0586   }
0587 
0588   int uLength = L1GlobalTriggerReadoutSetup::UnitLength;
0589 
0590   // initialize the required number of word64
0591   int nrWord64 = psbBlock.getSize() / uLength;
0592   std::vector<cms_uint64_t> tmpWord64;
0593   tmpWord64.resize(nrWord64);
0594 
0595   for (int iWord = 0; iWord < nrWord64; ++iWord) {
0596     tmpWord64[iWord] = 0x0000000000000000ULL;
0597   }
0598 
0599   // fill the values in the words
0600   for (int iWord = 0; iWord < nrWord64; ++iWord) {
0601     psbBlock.setBoardIdWord64(tmpWord64[iWord], iWord);
0602     psbBlock.setBxInEventWord64(tmpWord64[iWord], iWord);
0603     psbBlock.setBxNrWord64(tmpWord64[iWord], iWord);
0604     psbBlock.setEventNrWord64(tmpWord64[iWord], iWord);
0605 
0606     psbBlock.setADataWord64(tmpWord64[iWord], iWord);
0607     psbBlock.setBDataWord64(tmpWord64[iWord], iWord);
0608 
0609     psbBlock.setLocalBxNrWord64(tmpWord64[iWord], iWord);
0610   }
0611 
0612   // put the words in the FED record
0613 
0614   cms_uint64_t* pw = reinterpret_cast<cms_uint64_t*>(const_cast<unsigned char*>(ptrGt));
0615 
0616   for (int iWord = 0; iWord < nrWord64; ++iWord) {
0617     *pw++ = tmpWord64[iWord];
0618 
0619     if (m_verbosity && m_isDebugEnabled) {
0620       LogTrace("L1GTDigiToRaw") << std::setw(4) << iWord << "  " << std::hex << std::setfill('0') << std::setw(16)
0621                                 << tmpWord64[iWord] << std::dec << std::setfill(' ') << std::endl;
0622     }
0623   }
0624 }
0625 
0626 // pack the GMT collection using packGMT (GMT record packing)
0627 unsigned int L1GTDigiToRaw::packGmtCollection(unsigned char* ptrGt, L1MuGMTReadoutCollection const* digis) {
0628   if (m_verbosity && m_isDebugEnabled) {
0629     LogDebug("L1GTDigiToRaw") << "\nPacking GMT collection \n" << std::endl;
0630   }
0631 
0632   unsigned gmtsize = 0;
0633 
0634   // loop range: int m_totalBxInEvent is normally even (L1A-1, L1A, L1A+1, with L1A = 0)
0635   for (int iBxInEvent = m_minBxInEvent; iBxInEvent <= m_maxBxInEvent; ++iBxInEvent) {
0636     L1MuGMTReadoutRecord const& gmtrr = digis->getRecord(iBxInEvent);
0637     gmtsize = packGMT(gmtrr, ptrGt);
0638     ptrGt += gmtsize;
0639   }
0640 
0641   return m_totalBxInEvent * gmtsize;
0642 }
0643 
0644 // pack a GMT record
0645 unsigned L1GTDigiToRaw::packGMT(L1MuGMTReadoutRecord const& gmtrr, unsigned char* chp) {
0646   const unsigned SIZE = 136;
0647   const unsigned boardId = 0xdd12;
0648   memset(chp, 0, SIZE);
0649 
0650   unsigned* p = (unsigned*)chp;
0651 
0652   // event number + bcerr
0653   *p++ = (gmtrr.getEvNr() & 0xffffff) | ((gmtrr.getBCERR() & 0xff) << 24);
0654   // bx number, bx in event, length(?), board-id(?)
0655   *p++ = (gmtrr.getBxNr() & 0xfff) | ((gmtrr.getBxInEvent() & 0xf) << 12) | (boardId << 16);
0656 
0657   std::vector<L1MuRegionalCand> vrc;
0658   std::vector<L1MuRegionalCand>::const_iterator irc;
0659   unsigned* pp = p;
0660 
0661   vrc = gmtrr.getDTBXCands();
0662   pp = p;
0663   for (irc = vrc.begin(); irc != vrc.end(); irc++) {
0664     *pp++ = (*irc).getDataWord();
0665   }
0666   p += 4;
0667 
0668   vrc = gmtrr.getBrlRPCCands();
0669   pp = p;
0670   for (irc = vrc.begin(); irc != vrc.end(); irc++) {
0671     *pp++ = (*irc).getDataWord();
0672   }
0673   p += 4;
0674 
0675   vrc = gmtrr.getCSCCands();
0676   pp = p;
0677   for (irc = vrc.begin(); irc != vrc.end(); irc++) {
0678     *pp++ = (*irc).getDataWord();
0679   }
0680   p += 4;
0681 
0682   vrc = gmtrr.getFwdRPCCands();
0683   pp = p;
0684   for (irc = vrc.begin(); irc != vrc.end(); irc++) {
0685     *pp++ = (*irc).getDataWord();
0686   }
0687   p += 4;
0688 
0689   // the regional candidates are written to the record with inverted Pt and qual bits
0690   pp = p - 16;
0691   for (int i = 0; i < 16; i++) {
0692     unsigned w = *pp;
0693     *pp++ = (w & 0xffff00ff) | ((~w) & 0x0000ff00);
0694   }
0695 
0696   std::vector<L1MuGMTExtendedCand> vgc;
0697   std::vector<L1MuGMTExtendedCand>::const_iterator igc;
0698 
0699   vgc = gmtrr.getGMTBrlCands();
0700   pp = p;
0701   for (igc = vgc.begin(); igc != vgc.end(); igc++) {
0702     *pp++ = (*igc).getDataWord();
0703   }
0704   p += 4;
0705 
0706   vgc = gmtrr.getGMTFwdCands();
0707   pp = p;
0708   for (igc = vgc.begin(); igc != vgc.end(); igc++) {
0709     *pp++ = (*igc).getDataWord();
0710   }
0711   p += 4;
0712 
0713   vgc = gmtrr.getGMTCands();
0714   pp = p;
0715   for (igc = vgc.begin(); igc != vgc.end(); igc++) {
0716     *pp++ = (*igc).getDataWord();
0717   }
0718   p += 4;
0719 
0720   unsigned char* chpp;
0721 
0722   vgc = gmtrr.getGMTBrlCands();
0723   chpp = (unsigned char*)p;
0724   for (igc = vgc.begin(); igc != vgc.end(); igc++) {
0725     *chpp++ = (*igc).rank();
0726   }
0727   p++;
0728 
0729   vgc = gmtrr.getGMTFwdCands();
0730   chpp = (unsigned char*)p;
0731   for (igc = vgc.begin(); igc != vgc.end(); igc++) {
0732     *chpp++ = (*igc).rank();
0733   }
0734   p++;
0735 
0736   return SIZE;
0737 }
0738 
0739 unsigned int L1GTDigiToRaw::flipPtQ(unsigned int w) { return ((w & 0xffff00ff) | ((~w) & 0x0000ff00)); }
0740 
0741 // pack trailer
0742 void L1GTDigiToRaw::packTrailer(unsigned char* ptrGt, unsigned char* ptrGtBegin, int dataSize) {
0743   // TODO FIXME where from to get all numbers?
0744 
0745   // The length of the event fragment counted in 64-bit words including header and trailer
0746   int lengthVal = dataSize / 8;
0747 
0748   // Cyclic Redundancy Code of the event fragment including header and trailer
0749   int crcVal = evf::compute_crc(ptrGtBegin, dataSize);
0750 
0751   // Event fragment status information
0752   int evtStatusVal = 0;
0753 
0754   // Current value of the Trigger Throttling System bits.
0755   int ttsBitsVal = 0;
0756 
0757   // 0 -> the current trailer word is the last one.
0758   // 1-> other trailer words can follow
0759   // (always 0 for ECAL)
0760   bool moreTrailersVal = false;
0761 
0762   FEDTrailer gtFEDTrailer(ptrGt);
0763   gtFEDTrailer.set(ptrGt, lengthVal, crcVal, evtStatusVal, ttsBitsVal, moreTrailersVal);
0764 }
0765 
0766 // static class members