Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-07-30 05:19:49

0001 #include "EventFilter/L1TRawToDigi/plugins/PackerFactory.h"
0002 
0003 #include "GMTTokens.h"
0004 #include "MuonPacker.h"
0005 
0006 namespace l1t {
0007   namespace stage2 {
0008     Blocks MuonPacker::pack(const edm::Event& event, const PackerTokens* toks) {
0009       GMTOutputObjectMap gmtObjMap;
0010       std::pair<int, int> muonBx = getMuons(gmtObjMap, event, static_cast<const CommonTokens*>(toks)->getMuonToken());
0011       std::pair<int, int> muonShowerBx{0, 0};
0012       if (MuonRawDigiTranslator::isFwVersionWithShowers(fedId_, fwId_)) {
0013         muonShowerBx = getMuonShowers(gmtObjMap, event, static_cast<const CommonTokens*>(toks)->getMuonShowerToken());
0014       }
0015 
0016       PayloadMap payloadMap;
0017 
0018       packBx(gmtObjMap, muonBx.first, muonBx.second, muonShowerBx.first, muonShowerBx.second, payloadMap);
0019 
0020       Blocks blocks;
0021       // push everything in the blocks vector
0022       for (auto& kv : payloadMap) {
0023         blocks.push_back(Block(kv.first, kv.second));
0024       }
0025       return blocks;
0026     }
0027 
0028     std::pair<int, int> MuonPacker::getMuonShowers(GMTOutputObjectMap& objMap,
0029                                                    const edm::Event& event,
0030                                                    const edm::EDGetTokenT<MuonShowerBxCollection>& showerToken) {
0031       edm::Handle<MuonShowerBxCollection> muonShowers;
0032       event.getByToken(showerToken, muonShowers);
0033       for (int bx = muonShowers->getFirstBX(); bx <= muonShowers->getLastBX(); ++bx) {
0034         if (muonShowers->size(bx) > 0) {
0035           objMap[bx].shower = muonShowers->at(bx, 0);  // At most one shower per BX.
0036         }
0037       }
0038       return std::make_pair(muonShowers->getFirstBX(), muonShowers->getLastBX());
0039     }
0040 
0041     std::pair<int, int> MuonPacker::getMuons(GMTOutputObjectMap& objMap,
0042                                              const edm::Event& event,
0043                                              const edm::EDGetTokenT<MuonBxCollection>& muonToken) {
0044       edm::Handle<MuonBxCollection> muons;
0045       event.getByToken(muonToken, muons);
0046       for (int bx = muons->getFirstBX(); bx <= muons->getLastBX(); ++bx) {
0047         objMap[bx] = GMTObjects();
0048         for (auto mu = muons->begin(bx); mu != muons->end(bx); ++mu) {
0049           objMap[bx].mus.push_back(*mu);
0050         }
0051       }
0052       return std::make_pair(muons->getFirstBX(), muons->getLastBX());
0053     }
0054 
0055     void MuonPacker::packBx(const GMTOutputObjectMap& objMap,
0056                             const int firstMuonBx,
0057                             const int lastMuonBx,
0058                             const int firstMuonShowerBx,
0059                             const int lastMuonShowerBx,
0060                             PayloadMap& payloadMap) {
0061       const auto firstBx{std::min(firstMuonShowerBx, firstMuonBx)};
0062       const auto lastBx{std::max(lastMuonShowerBx, lastMuonBx)};
0063 
0064       for (int bx{firstBx}; bx < lastBx + 1; ++bx) {
0065         // the first word in every BX and every block id is 0
0066         for (unsigned int blkId = b1_; blkId < b1_ + 7; blkId += 2) {
0067           payloadMap[blkId].push_back(0);
0068         }
0069 
0070         unsigned int blkId = b1_;
0071         uint32_t mu1_shared_word{0};
0072         uint32_t mu2_shared_word{0};
0073         uint32_t mu1_msw{0};
0074         uint32_t mu2_msw{0};
0075         uint32_t mu1_lsw{0};
0076         uint32_t mu2_lsw{0};
0077         auto mu{objMap.at(bx).mus.begin()};  // Need to get the first muon of that bx from the object map
0078         std::array<std::array<uint32_t, 4>, 2> const showerWords{
0079             MuonRawDigiTranslator::getPackedShowerDataWords(objMap.at(bx).shower, fedId_, fwId_)};
0080         // Slightly convoluted logic to account for the Run-3 muon readout record:
0081         // To make space for displacement information we moved the raw
0082         // (i.e. non-extrapolated) eta value to the second "spare" word
0083         // in the block which we call "shared word". So the logic below
0084         // needs to be aware if it is operating on the first or second
0085         // muon in the block in order to place the eta value in the right
0086         // place in the shared word. Additionally the logic needs to
0087         // wait for the second muon in the block before filling the
0088         // payload map because the shared word goes in first.
0089         for (int muCtr = 1; muCtr <= 8; ++muCtr) {
0090           if (mu != objMap.at(bx).mus.end()) {
0091             MuonRawDigiTranslator::generatePackedMuonDataWords(
0092                 *mu, mu2_shared_word, mu2_lsw, mu2_msw, fedId_, fwId_, 2 - (muCtr % 2));
0093             ++mu;
0094           }
0095 
0096           // If we're remaining in the current block the muon we just packed is the first one in the block.
0097           // If not we add both muons to the payload map and go to the next block.
0098           if (muCtr % 2 == 1) {
0099             mu1_shared_word = mu2_shared_word;
0100             mu1_lsw = mu2_lsw;
0101             mu1_msw = mu2_msw;
0102             mu1_msw |= showerWords.at(0).at(muCtr / 2);
0103           } else {
0104             mu2_msw |= showerWords.at(1).at(muCtr / 2 - 1);
0105             payloadMap[blkId].push_back(mu1_shared_word | mu2_shared_word);
0106             payloadMap[blkId].push_back(mu1_lsw);
0107             payloadMap[blkId].push_back(mu1_msw);
0108             payloadMap[blkId].push_back(mu2_lsw);
0109             payloadMap[blkId].push_back(mu2_msw);
0110 
0111             blkId += 2;
0112 
0113             mu1_shared_word = 0;
0114             mu1_lsw = 0;
0115             mu1_msw = 0;
0116           }
0117           mu2_shared_word = 0;
0118           mu2_lsw = 0;
0119           mu2_msw = 0;
0120         }
0121       }
0122     }
0123   }  // namespace stage2
0124 }  // namespace l1t
0125 
0126 DEFINE_L1T_PACKER(l1t::stage2::GTMuonPacker);
0127 DEFINE_L1T_PACKER(l1t::stage2::GMTMuonPacker);