Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:04:29

0001 /**
0002  * \class L1GtfeExtWord
0003  *
0004  *
0005  * Description: L1 Global Trigger - GTFE words in the readout record.
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 "DataFormats/L1GlobalTrigger/interface/L1GtfeExtWord.h"
0017 
0018 // system include files
0019 #include <iomanip>
0020 #include <cstdint>
0021 
0022 // user include files
0023 #include "FWCore/Utilities/interface/EDMException.h"
0024 
0025 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0026 #include "FWCore/MessageLogger/interface/MessageDrop.h"
0027 
0028 #include "DataFormats/L1GlobalTrigger/interface/L1GlobalTriggerReadoutSetupFwd.h"
0029 #include "DataFormats/L1GlobalTrigger/interface/L1GlobalTriggerReadoutSetup.h"
0030 
0031 // constructors
0032 
0033 // empty constructor, all members set to zero;
0034 L1GtfeExtWord::L1GtfeExtWord() : L1GtfeWord(), m_bstSource(0) {
0035   // empty
0036 }
0037 
0038 // all members set to zero, m_bst has bstSizeBytes zero elements
0039 L1GtfeExtWord::L1GtfeExtWord(int bstSizeBytes) : L1GtfeWord(), m_bstSource(0) { m_bst.resize(bstSizeBytes); }
0040 
0041 // constructor from unpacked values, m_bst size taken from bstValue
0042 L1GtfeExtWord::L1GtfeExtWord(cms_uint16_t boardIdValue,
0043                              cms_uint16_t recordLength1Value,
0044                              cms_uint16_t recordLengthValue,
0045                              cms_uint16_t bxNrValue,
0046                              cms_uint32_t setupVersionValue,
0047                              cms_uint16_t activeBoardsValue,
0048                              cms_uint16_t altNrBxBoardValue,
0049                              cms_uint32_t totalTriggerNrValue,  // end of L1GtfeWord
0050                              const std::vector<cms_uint16_t>& bstValue,
0051                              cms_uint16_t bstSourceValue)
0052     : L1GtfeWord(boardIdValue,
0053                  recordLength1Value,
0054                  recordLengthValue,
0055                  bxNrValue,
0056                  setupVersionValue,
0057                  activeBoardsValue,
0058                  altNrBxBoardValue,
0059                  totalTriggerNrValue),
0060       m_bst(bstValue),
0061       m_bstSource(bstSourceValue)
0062 
0063 {
0064   // empty
0065 }
0066 
0067 // destructor
0068 L1GtfeExtWord::~L1GtfeExtWord() {
0069   // empty now
0070 }
0071 
0072 // equal operator
0073 bool L1GtfeExtWord::operator==(const L1GtfeExtWord& result) const {
0074   // base class
0075 
0076   const L1GtfeWord gtfeResult = result;
0077   const L1GtfeWord gtfeThis = *this;
0078 
0079   if (gtfeThis != gtfeResult) {
0080     return false;
0081   }
0082 
0083   //
0084 
0085   for (unsigned int iB = 0; iB < m_bst.size(); ++iB) {
0086     if (m_bst[iB] != result.m_bst[iB]) {
0087       return false;
0088     }
0089   }
0090 
0091   if (m_bstSource != result.m_bstSource) {
0092     return false;
0093   }
0094 
0095   // all members identical
0096   return true;
0097 }
0098 
0099 // unequal operator
0100 bool L1GtfeExtWord::operator!=(const L1GtfeExtWord& result) const { return !(result == *this); }
0101 
0102 // methods
0103 
0104 const cms_uint64_t L1GtfeExtWord::gpsTime() const {
0105   cms_uint64_t gpst = 0ULL;
0106 
0107   // return 0 if BST message too small
0108   int bstSize = m_bst.size();
0109   if (GpsTimeLastBlock >= bstSize) {
0110     return gpst;
0111   }
0112 
0113   for (int iB = GpsTimeFirstBlock; iB <= GpsTimeLastBlock; ++iB) {
0114     // keep capitalization for similarity with other functions
0115     const int scaledIB = iB - GpsTimeFirstBlock;
0116     const int BstShift = BstBitSize * scaledIB;
0117 
0118     gpst = gpst | ((static_cast<cms_uint64_t>(m_bst[iB])) << BstShift);
0119   }
0120 
0121   return gpst;
0122 }
0123 
0124 void L1GtfeExtWord::setGpsTime(const cms_uint64_t gpsTimeValue) {
0125   // return if BST message too small
0126   int bstSize = m_bst.size();
0127   if (GpsTimeLastBlock >= bstSize) {
0128     edm::LogError("L1GtfeExtWord") << "Error: BST message length " << bstSize
0129                                    << " smaller than the required GpsTimeLastBlock " << GpsTimeLastBlock
0130                                    << "\n Cannot set GpsTime" << std::endl;
0131 
0132     return;
0133   }
0134 
0135   for (int iB = GpsTimeFirstBlock; iB <= GpsTimeLastBlock; ++iB) {
0136     // keep capitalization for similarity with other functions
0137     const int scaledIB = iB - GpsTimeFirstBlock;
0138     const int BstShift = BstBitSize * scaledIB;
0139     const cms_uint64_t BstMask = 0x0000000000000000ULL | (BstBlockMask << BstShift);
0140 
0141     m_bst[iB] = static_cast<cms_uint16_t>((gpsTimeValue & BstMask) >> BstShift);
0142 
0143     //LogTrace("L1GtfeExtWord")
0144     //<< "BstShift: value [dec] = " << BstShift << "\n"
0145     //<< "BstBlockMask: value [hex] = "  << std::hex << BstBlockMask << "\n"
0146     //<< "BstMask: value [hex] = "<< BstMask << std::dec
0147     //<< std::endl;
0148 
0149     //LogTrace("L1GtfeExtWord")
0150     //<< "BST block " << iB << ": value [hex] = " << std::hex << m_bst[iB] << std::dec
0151     //<< std::endl;
0152   }
0153 }
0154 
0155 const cms_uint16_t L1GtfeExtWord::bstMasterStatus() const {
0156   cms_uint16_t bms = 0;
0157 
0158   // return 0 if BST message too small
0159   int bstSize = m_bst.size();
0160   if (BstMasterStatusLastBlock >= bstSize) {
0161     return bms;
0162   }
0163 
0164   for (int iB = BstMasterStatusFirstBlock; iB <= BstMasterStatusLastBlock; ++iB) {
0165     // keep capitalization for similarity with other functions
0166     const int scaledIB = iB - BstMasterStatusFirstBlock;
0167     const int BstShift = BstBitSize * scaledIB;
0168 
0169     bms = bms | (m_bst[iB] << BstShift);
0170   }
0171 
0172   return bms;
0173 }
0174 
0175 const cms_uint32_t L1GtfeExtWord::turnCountNumber() const {
0176   cms_uint32_t tcn = 0;
0177 
0178   // return 0 if BST message too small
0179   int bstSize = m_bst.size();
0180   if (TurnCountNumberLastBlock >= bstSize) {
0181     return tcn;
0182   }
0183 
0184   for (int iB = TurnCountNumberFirstBlock; iB <= TurnCountNumberLastBlock; ++iB) {
0185     // keep capitalization for similarity with other functions
0186     const int scaledIB = iB - TurnCountNumberFirstBlock;
0187     const int BstShift = BstBitSize * scaledIB;
0188 
0189     tcn = tcn | ((static_cast<cms_uint32_t>(m_bst[iB])) << BstShift);
0190   }
0191 
0192   return tcn;
0193 }
0194 
0195 const cms_uint32_t L1GtfeExtWord::lhcFillNumber() const {
0196   cms_uint32_t lhcfn = 0;
0197 
0198   // return 0 if BST message too small
0199   int bstSize = m_bst.size();
0200   if (LhcFillNumberLastBlock >= bstSize) {
0201     return lhcfn;
0202   }
0203 
0204   for (int iB = LhcFillNumberFirstBlock; iB <= LhcFillNumberLastBlock; ++iB) {
0205     // keep capitalization for similarity with other functions
0206     const int scaledIB = iB - LhcFillNumberFirstBlock;
0207     const int BstShift = BstBitSize * scaledIB;
0208 
0209     lhcfn = lhcfn | ((static_cast<cms_uint32_t>(m_bst[iB])) << BstShift);
0210   }
0211 
0212   return lhcfn;
0213 }
0214 
0215 const cms_uint16_t L1GtfeExtWord::beamMode() const {
0216   cms_uint16_t bm = 0;
0217 
0218   // return 0 if BST message too small
0219   int bstSize = m_bst.size();
0220   if (BeamModeLastBlock >= bstSize) {
0221     return bm;
0222   }
0223 
0224   for (int iB = BeamModeFirstBlock; iB <= BeamModeLastBlock; ++iB) {
0225     // keep capitalization for similarity with other functions
0226     const int scaledIB = iB - BeamModeFirstBlock;
0227     const int BstShift = BstBitSize * scaledIB;
0228 
0229     bm = bm | (m_bst[iB] << BstShift);
0230   }
0231 
0232   return bm;
0233 }
0234 
0235 const cms_uint16_t L1GtfeExtWord::particleTypeBeam1() const {
0236   cms_uint16_t ptb = 0;
0237 
0238   // return 0 if BST message too small
0239   int bstSize = m_bst.size();
0240   if (ParticleTypeBeam1LastBlock >= bstSize) {
0241     return ptb;
0242   }
0243 
0244   for (int iB = ParticleTypeBeam1FirstBlock; iB <= ParticleTypeBeam1LastBlock; ++iB) {
0245     // keep capitalization for similarity with other functions
0246     const int scaledIB = iB - ParticleTypeBeam1FirstBlock;
0247     const int BstShift = BstBitSize * scaledIB;
0248 
0249     ptb = ptb | (m_bst[iB] << BstShift);
0250   }
0251 
0252   return ptb;
0253 }
0254 
0255 const cms_uint16_t L1GtfeExtWord::particleTypeBeam2() const {
0256   cms_uint16_t ptb = 0;
0257 
0258   // return 0 if BST message too small
0259   int bstSize = m_bst.size();
0260   if (ParticleTypeBeam2LastBlock >= bstSize) {
0261     return ptb;
0262   }
0263 
0264   for (int iB = ParticleTypeBeam2FirstBlock; iB <= ParticleTypeBeam2LastBlock; ++iB) {
0265     // keep capitalization for similarity with other functions
0266     const int scaledIB = iB - ParticleTypeBeam2FirstBlock;
0267     const int BstShift = BstBitSize * scaledIB;
0268 
0269     ptb = ptb | (m_bst[iB] << BstShift);
0270   }
0271 
0272   return ptb;
0273 }
0274 
0275 const cms_uint16_t L1GtfeExtWord::beamMomentum() const {
0276   cms_uint16_t bm = 0;
0277 
0278   // return 0 if BST message too small
0279   int bstSize = m_bst.size();
0280   if (BeamMomentumLastBlock >= bstSize) {
0281     return bm;
0282   }
0283 
0284   for (int iB = BeamMomentumFirstBlock; iB <= BeamMomentumLastBlock; ++iB) {
0285     // keep capitalization for similarity with other functions
0286     const int scaledIB = iB - BeamMomentumFirstBlock;
0287     const int BstShift = BstBitSize * scaledIB;
0288 
0289     bm = bm | (m_bst[iB] << BstShift);
0290   }
0291 
0292   return bm;
0293 }
0294 
0295 const cms_uint32_t L1GtfeExtWord::totalIntensityBeam1() const {
0296   cms_uint32_t tib = 0;
0297 
0298   // return 0 if BST message too small
0299   int bstSize = m_bst.size();
0300   if (TotalIntensityBeam1LastBlock >= bstSize) {
0301     return tib;
0302   }
0303 
0304   for (int iB = TotalIntensityBeam1FirstBlock; iB <= TotalIntensityBeam1LastBlock; ++iB) {
0305     // keep capitalization for similarity with other functions
0306     const int scaledIB = iB - TotalIntensityBeam1FirstBlock;
0307     const int BstShift = BstBitSize * scaledIB;
0308 
0309     tib = tib | ((static_cast<cms_uint32_t>(m_bst[iB])) << BstShift);
0310   }
0311 
0312   return tib;
0313 }
0314 
0315 const cms_uint32_t L1GtfeExtWord::totalIntensityBeam2() const {
0316   cms_uint32_t tib = 0;
0317 
0318   // return 0 if BST message too small
0319   int bstSize = m_bst.size();
0320   if (TotalIntensityBeam2LastBlock >= bstSize) {
0321     return tib;
0322   }
0323 
0324   for (int iB = TotalIntensityBeam2FirstBlock; iB <= TotalIntensityBeam2LastBlock; ++iB) {
0325     // keep capitalization for similarity with other functions
0326     const int scaledIB = iB - TotalIntensityBeam2FirstBlock;
0327     const int BstShift = BstBitSize * scaledIB;
0328 
0329     tib = tib | ((static_cast<cms_uint32_t>(m_bst[iB])) << BstShift);
0330   }
0331 
0332   return tib;
0333 }
0334 
0335 // get/set BST for block iB
0336 const uint16_t L1GtfeExtWord::bst(int iB) const {
0337   int NumberBstBlocks = m_bst.size();
0338 
0339   if (iB < 0 || iB >= NumberBstBlocks) {
0340     throw cms::Exception("BstIndexError")
0341         << "\nError: index for BST array out of range. Allowed range: [0, " << NumberBstBlocks << ") " << std::endl;
0342 
0343   } else {
0344     return m_bst[iB];
0345   }
0346 }
0347 
0348 void L1GtfeExtWord::setBst(const uint16_t bstVal, const int iB) {
0349   int NumberBstBlocks = m_bst.size();
0350 
0351   if (iB < 0 || iB >= NumberBstBlocks) {
0352     throw cms::Exception("BstIndexError")
0353         << "\nError: index for BST array out of range. Allowed range: [0, " << NumberBstBlocks << ") " << std::endl;
0354 
0355   } else {
0356     m_bst[iB] = bstVal;
0357   }
0358 }
0359 
0360 // set the BST block for index iB from a 64-bits word
0361 void L1GtfeExtWord::setBst(const cms_uint64_t& word64, const int iB) {
0362   // keep capitalization for similarity with other functions //FIXME check it again
0363   const int scaledIB = iB % (sizeof(word64) * 8 / BstBitSize);
0364   const int BstShift = BstBitSize * scaledIB;
0365   const cms_uint64_t BstMask = 0x0000000000000000ULL | (BstBlockMask << BstShift);
0366 
0367   m_bst[iB] = static_cast<cms_uint16_t>((word64 & BstMask) >> BstShift);
0368 }
0369 
0370 // set the BST block in a 64-bits word, having the index iWord
0371 // in the GTFE raw record
0372 void L1GtfeExtWord::setBstWord64(cms_uint64_t& word64, int iB, int iWord) {
0373   // keep capitalization for similarity with other functions
0374   const int scaledIB = iB % (sizeof(word64) * 8 / BstBitSize);
0375   const int BstShift = BstBitSize * scaledIB;
0376   const int BstWord = iB / (sizeof(word64) * 8 / BstBitSize) + BstFirstWord;
0377 
0378   if (iWord == BstWord) {
0379     word64 = word64 | (static_cast<cms_uint64_t>(m_bst[iB]) << BstShift);
0380   }
0381 }
0382 
0383 // set the hex message indicating the source of BST message from a 64-bits word
0384 void L1GtfeExtWord::setBstSource(const cms_uint64_t& word64) {
0385   m_bstSource = (word64 & BstSourceMask) >> BstSourceShift;
0386 }
0387 
0388 // set hex message indicating the source of BST message in a 64-bits word,
0389 // having the index iWord in the GTFE raw record
0390 void L1GtfeExtWord::setBstSourceWord64(cms_uint64_t& word64, const int iWord) {
0391   // BST always in the last word of GTFE extended - size must be correct!
0392   int gtfeSize = this->getSize();
0393 
0394   int BstSourceWord = gtfeSize / 8 - 1;  // counting starts at 0
0395 
0396   if (iWord == BstSourceWord) {
0397     word64 = word64 | (static_cast<cms_uint64_t>(m_bstSource) << BstSourceShift);
0398   }
0399 }
0400 
0401 // get the size of the GTFE block in GT EVM record (in multiple of 8 bits)
0402 const unsigned int L1GtfeExtWord::getSize() const {
0403   L1GtfeWord gtfeWord;
0404   unsigned int gtfeSize = gtfeWord.getSize();
0405 
0406   unsigned int gtfeExtSize;
0407 
0408   // 2 bytes to write if real BST message or simulated BST message
0409   unsigned int bytesBstWriter = 2;
0410 
0411   // size of BST block, using rounded 64-bit words (8 bytes per 64-bit word)
0412 
0413   unsigned int bstSize = m_bst.size();
0414 
0415   if ((bstSize + bytesBstWriter) % 8 == 0) {
0416     gtfeExtSize = gtfeSize + bstSize + bytesBstWriter;
0417   } else {
0418     gtfeExtSize = gtfeSize + bstSize + bytesBstWriter + (8 - (bstSize + bytesBstWriter) % 8);
0419   }
0420 
0421   return gtfeExtSize;
0422 }
0423 
0424 // resize the BST vector to get the right size of the block
0425 void L1GtfeExtWord::resize(int bstSizeBytes) { m_bst.resize(bstSizeBytes); }
0426 
0427 // reset the content of a L1GtfeExtWord
0428 void L1GtfeExtWord::reset() {
0429   L1GtfeWord::reset();
0430   m_bst.clear();
0431 }
0432 
0433 // pretty print the content of a L1GtfeWord
0434 void L1GtfeExtWord::print(std::ostream& myCout) const {
0435   myCout << "\n L1GtfeExtWord::print \n" << std::endl;
0436 
0437   unsigned int sizeW64 = 64;
0438   unsigned int dataBlocksPerLine = sizeW64 / 8;  // 8x8 bits per line
0439 
0440   L1GtfeWord::print(myCout);
0441 
0442   unsigned int numberBstBlocks = m_bst.size();
0443 
0444   myCout << "\n  BST ";
0445 
0446   if (numberBstBlocks == 0) {
0447     myCout << "\n  BST source [hex]: " << std::hex << std::setw(4) << std::setfill('0') << m_bstSource
0448            << std::setfill(' ') << std::dec << std::endl;
0449 
0450     return;
0451   }
0452 
0453   for (unsigned int iB = 0; iB < numberBstBlocks; iB += dataBlocksPerLine) {
0454     myCout << "\n" << std::hex << " hex: ";
0455 
0456     for (unsigned int jB = iB; jB < dataBlocksPerLine + iB; ++jB) {
0457       if (jB >= numberBstBlocks) {
0458         break;
0459       }
0460 
0461       myCout << std::setw(2) << std::setfill('0') << m_bst[jB] << "   " << std::setfill(' ');
0462     }
0463 
0464     myCout << "\n" << std::dec << " dec: ";
0465 
0466     for (unsigned int jB = iB; jB < dataBlocksPerLine + iB; ++jB) {
0467       if (jB >= numberBstBlocks) {
0468         break;
0469       }
0470 
0471       myCout << std::setw(3) << std::setfill('0') << m_bst[jB] << "  " << std::setfill(' ');
0472     }
0473 
0474     myCout << std::endl;
0475   }
0476 
0477   myCout << "\n  BST source [hex]: " << std::hex << std::setw(4) << std::setfill('0') << m_bstSource
0478          << std::setfill(' ') << std::dec << std::endl;
0479 }
0480 
0481 void L1GtfeExtWord::unpack(const unsigned char* gtfePtr) {
0482   LogDebug("L1GtfeExtWord") << "\nUnpacking GTFE block.\n" << std::endl;
0483 
0484   L1GtfeWord::unpack(gtfePtr);
0485 
0486   // TODO make BlockSize protected & use friends instead of creating L1GtfeWord?
0487   L1GtfeWord gtfeWord;
0488   const unsigned char* gtfeExtPtr = gtfePtr + gtfeWord.getSize();
0489 
0490   const cms_uint64_t* payload = reinterpret_cast<cms_uint64_t const*>(gtfeExtPtr);
0491 
0492   int BlockSizeExt = this->getSize() / 8;
0493   int NumberBstBlocks = m_bst.size();
0494 
0495   if (edm::isDebugEnabled()) {
0496     for (int iWord = BstFirstWord; iWord < BlockSizeExt; ++iWord) {
0497       int jWord = iWord - BstFirstWord;
0498       LogTrace("L1GtfeExtWord") << std::setw(4) << iWord << "  " << std::hex << std::setfill('0') << std::setw(16)
0499                                 << payload[jWord] << std::dec << std::setfill(' ') << std::endl;
0500     }
0501   }
0502 
0503   int blocksPerWord = sizeof(cms_uint64_t) * 8 / BstBitSize;
0504 
0505   for (int iB = 0; iB < NumberBstBlocks; ++iB) {
0506     // keep capitalization for similarity with other functions
0507     int BstWord = iB / blocksPerWord;
0508 
0509     setBst(payload[BstWord], iB);
0510   }
0511 }
0512 
0513 // static class members
0514 
0515 // block description in the raw GT record
0516 
0517 // index of first word for BST blocks
0518 const int L1GtfeExtWord::BstFirstWord = 2;
0519 
0520 // size in bits for a BST block
0521 const int L1GtfeExtWord::BstBitSize = 8;
0522 
0523 // BST block mask, correlated with the number of bits of a block
0524 // 8 bit = 0xFF
0525 const cms_uint64_t L1GtfeExtWord::BstBlockMask = 0xFFULL;
0526 
0527 // BST blocks: conversion to defined quantities (LHC-BOB-ES-0001)
0528 
0529 const int L1GtfeExtWord::GpsTimeFirstBlock = 0;
0530 const int L1GtfeExtWord::GpsTimeLastBlock = 7;
0531 
0532 const int L1GtfeExtWord::BstMasterStatusFirstBlock = 17;
0533 const int L1GtfeExtWord::BstMasterStatusLastBlock = 17;
0534 
0535 const int L1GtfeExtWord::TurnCountNumberFirstBlock = 18;
0536 const int L1GtfeExtWord::TurnCountNumberLastBlock = 21;
0537 
0538 const int L1GtfeExtWord::LhcFillNumberFirstBlock = 22;
0539 const int L1GtfeExtWord::LhcFillNumberLastBlock = 25;
0540 
0541 const int L1GtfeExtWord::BeamModeFirstBlock = 26;
0542 const int L1GtfeExtWord::BeamModeLastBlock = 27;
0543 
0544 const int L1GtfeExtWord::ParticleTypeBeam1FirstBlock = 28;
0545 const int L1GtfeExtWord::ParticleTypeBeam1LastBlock = 28;
0546 
0547 const int L1GtfeExtWord::ParticleTypeBeam2FirstBlock = 29;
0548 const int L1GtfeExtWord::ParticleTypeBeam2LastBlock = 29;
0549 
0550 const int L1GtfeExtWord::BeamMomentumFirstBlock = 30;
0551 const int L1GtfeExtWord::BeamMomentumLastBlock = 31;
0552 
0553 const int L1GtfeExtWord::TotalIntensityBeam1FirstBlock = 32;
0554 const int L1GtfeExtWord::TotalIntensityBeam1LastBlock = 35;
0555 
0556 const int L1GtfeExtWord::TotalIntensityBeam2FirstBlock = 36;
0557 const int L1GtfeExtWord::TotalIntensityBeam2LastBlock = 39;
0558 
0559 // BST
0560 const cms_uint64_t L1GtfeExtWord::BstSourceMask = 0xFFFF000000000000ULL;
0561 const int L1GtfeExtWord::BstSourceShift = 48;