Back to home page

Project CMSSW displayed by LXR

 
 

    


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

0001 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0002 #include "FWCore/Framework/interface/Event.h"
0003 #include "EventFilter/L1TRawToDigi/plugins/PackerFactory.h"
0004 
0005 #include "L1Trigger/L1TMuon/interface/RegionalMuonRawDigiTranslator.h"
0006 #include "GMTTokens.h"
0007 #include "RegionalMuonGMTPacker.h"
0008 
0009 namespace l1t {
0010   namespace stage2 {
0011     Blocks RegionalMuonGMTPacker::pack(const edm::Event& event, const PackerTokens* toks) {
0012       GMTObjectMap bmtfObjMap;
0013       GMTObjectMap omtfObjMap;
0014       GMTObjectMap emtfObjMap;
0015       auto const bmtfToken = static_cast<const GMTTokens*>(toks)->getRegionalMuonCandTokenBMTF();
0016       auto const omtfToken = static_cast<const GMTTokens*>(toks)->getRegionalMuonCandTokenOMTF();
0017       auto const emtfToken = static_cast<const GMTTokens*>(toks)->getRegionalMuonCandTokenEMTF();
0018 
0019       // First we put the muons in our object map.
0020       std::pair<int, int> const bmtfMuonBx = getMuons(bmtfObjMap, event, bmtfToken);
0021       std::pair<int, int> const omtfMuonBx = getMuons(omtfObjMap, event, omtfToken);
0022       std::pair<int, int> const emtfMuonBx = getMuons(emtfObjMap, event, emtfToken);
0023 
0024       // Then the showers (We don't expect to have shower data from BMTF and OMTF -- at the moment, at least)
0025       std::pair<int, int> emtfMuonShowerBx{0, 0};
0026       if (useEmtfNominalTightShowers_ || useEmtfLooseShowers_) {
0027         auto const emtfShowerToken = static_cast<const GMTTokens*>(toks)->getRegionalMuonShowerTokenEMTF();
0028         emtfMuonShowerBx = getMuonShowers(emtfObjMap, event, emtfShowerToken);
0029       }
0030 
0031       Blocks blocks;
0032 
0033       // Pack the muons and showers for each TF in blocks
0034       packTF(bmtfObjMap, bmtfMuonBx.first, bmtfMuonBx.second, 0, 0, blocks);
0035       packTF(omtfObjMap, omtfMuonBx.first, omtfMuonBx.second, 0, 0, blocks);
0036       packTF(emtfObjMap, emtfMuonBx.first, emtfMuonBx.second, emtfMuonShowerBx.first, emtfMuonShowerBx.second, blocks);
0037 
0038       return blocks;
0039     }
0040 
0041     std::pair<int, int> RegionalMuonGMTPacker::getMuonShowers(
0042         GMTObjectMap& objMap,
0043         const edm::Event& event,
0044         const edm::EDGetTokenT<RegionalMuonShowerBxCollection>& tfShowerToken) {
0045       edm::Handle<RegionalMuonShowerBxCollection> muonShowers;
0046       event.getByToken(tfShowerToken, muonShowers);
0047       for (int bx = muonShowers->getFirstBX(); bx <= muonShowers->getLastBX(); ++bx) {
0048         for (auto muShower = muonShowers->begin(bx); muShower != muonShowers->end(bx); ++muShower) {
0049           objMap[bx][muShower->link()].shower = *muShower;
0050         }
0051       }
0052       return std::make_pair(muonShowers->getFirstBX(), muonShowers->getLastBX());
0053     }
0054 
0055     std::pair<int, int> RegionalMuonGMTPacker::getMuons(GMTObjectMap& objMap,
0056                                                         const edm::Event& event,
0057                                                         const edm::EDGetTokenT<RegionalMuonCandBxCollection>& tfToken) {
0058       edm::Handle<RegionalMuonCandBxCollection> muons;
0059       event.getByToken(tfToken, muons);
0060       for (int bx = muons->getFirstBX(); bx <= muons->getLastBX(); ++bx) {
0061         for (auto mu = muons->begin(bx); mu != muons->end(bx); ++mu) {
0062           objMap[bx][mu->link()].mus.push_back(*mu);
0063         }
0064       }
0065       return std::make_pair(muons->getFirstBX(), muons->getLastBX());
0066     }
0067 
0068     void RegionalMuonGMTPacker::packTF(const GMTObjectMap& objMap,
0069                                        const int firstMuonBx,
0070                                        const int lastMuonBx,
0071                                        const int firstMuonShowerBx,
0072                                        const int lastMuonShowerBx,
0073                                        Blocks& blocks) {
0074       const auto firstBx{std::min(firstMuonShowerBx, firstMuonBx)};
0075       const auto lastBx{std::max(lastMuonShowerBx, lastMuonBx)};
0076       const auto nBx{lastBx - firstBx + 1};
0077 
0078       PayloadMap payloadMap;
0079 
0080       unsigned bxCtr = 0;
0081       for (int bx{firstBx}; bx < lastBx + 1; ++bx, ++bxCtr) {
0082         if (objMap.count(bx) > 0) {
0083           for (const auto& linkMap : objMap.at(bx)) {
0084             const auto linkTimes2{linkMap.first * 2};
0085             const auto gmtObjects{linkMap.second};
0086 
0087             // If the payload map key is new reserve the payload size.
0088             if (payloadMap.count(linkTimes2) == 0) {
0089               payloadMap[linkTimes2].reserve(wordsPerBx_ * nBx);
0090               // If there was no muon on the link of this muon in previous
0091               // BX the payload up to this BX must be filled with zeros.
0092               if (bxCtr > 0) {
0093                 while (payloadMap[linkTimes2].size() < bxCtr * wordsPerBx_) {
0094                   payloadMap[linkTimes2].push_back(0);
0095                 }
0096               }
0097             }
0098 
0099             if (gmtObjects.mus.size() > 3) {
0100               edm::LogError("L1T") << "Muon collection for link " << linkMap.first << " has " << gmtObjects.mus.size()
0101                                    << " entries, but 3 is the maximum!";
0102             }
0103 
0104             std::array<uint32_t, 6> buf{};  // Making sure contents of buf are initialised to 0.
0105             size_t frameIdx{0};
0106             for (const auto& mu : gmtObjects.mus) {
0107               // Fill the muon in the payload for this link.
0108               uint32_t msw{0};
0109               uint32_t lsw{0};
0110 
0111               RegionalMuonRawDigiTranslator::generatePackedDataWords(
0112                   mu, lsw, msw, isKbmtf_, useOmtfDisplacementInfo_, useEmtfDisplacementInfo_);
0113 
0114               buf.at(frameIdx++) = lsw;
0115               buf.at(frameIdx++) = msw;
0116             }
0117             // Add shower bits to the payload buffer.
0118             RegionalMuonRawDigiTranslator::generatePackedShowerPayload(
0119                 gmtObjects.shower, buf, useEmtfNominalTightShowers_, useEmtfLooseShowers_);
0120 
0121             payloadMap[linkTimes2].insert(
0122                 payloadMap[linkTimes2].end(), std::move_iterator(buf.begin()), std::move_iterator(buf.end()));
0123           }
0124         }
0125         // We now loop over all channels in the payload map and make sure that they are filled up to the current BX
0126         // If they are not, we fill them with zeros
0127         for (auto& kv : payloadMap) {
0128           while (kv.second.size() < (bxCtr + 1) * wordsPerBx_) {
0129             kv.second.push_back(0);
0130           }
0131         }
0132       }
0133 
0134       // push everything in the blocks vector
0135       for (auto& kv : payloadMap) {
0136         blocks.push_back(Block(kv.first, kv.second));
0137       }
0138     }
0139 
0140   }  // namespace stage2
0141 }  // namespace l1t
0142 
0143 DEFINE_L1T_PACKER(l1t::stage2::RegionalMuonGMTPacker);