Back to home page

Project CMSSW displayed by LXR

 
 

    


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

0001 #include "FWCore/Framework/interface/Event.h"
0002 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0003 #include "EventFilter/L1TRawToDigi/plugins/UnpackerFactory.h"
0004 
0005 #include "L1Trigger/L1TMuon/interface/MuonRawDigiTranslator.h"
0006 
0007 #include "GMTCollections.h"
0008 #include "IntermediateMuonUnpacker.h"
0009 
0010 namespace l1t {
0011   namespace stage2 {
0012     IntermediateMuonUnpacker::IntermediateMuonUnpacker() : res1_(nullptr), res2_(nullptr), coll1Cnt_(0) {}
0013 
0014     bool IntermediateMuonUnpacker::unpack(const Block& block, UnpackerCollections* coll) {
0015       LogDebug("L1T") << "Block ID  = " << block.header().getID() << " size = " << block.header().getSize();
0016       // process only if there is a payload
0017       // If all BX block were zero suppressed the block header size is 0.
0018       if (block.header().getSize() < 1) {
0019         return true;
0020       }
0021 
0022       auto payload = block.payload();
0023 
0024       int nBX, firstBX, lastBX;
0025       // Check if per BX zero suppression was enabled
0026       bool bxZsEnabled = ((block.header().getFlags() >> bxzs_enable_shift_) & 0x1) == 1;
0027       // Calculate the total number of BXs
0028       if (bxZsEnabled) {
0029         BxBlockHeader bxHeader(payload.at(0));
0030         nBX = bxHeader.getTotalBx();
0031       } else {
0032         nBX = int(ceil(block.header().getSize() / nWords_));
0033       }
0034       getBXRange(nBX, firstBX, lastBX);
0035 
0036       // decide which collections to use according to the link ID
0037       unsigned int linkId = (block.header().getID() - 1) / 2;
0038       // Intermediate muons come on uGMT output links 24-31.
0039       // Each link can transmit 3 muons and we receive 4 intermediate muons from
0040       // EMTF/OMTF on each detector side and 8 intermediate muons from BMTF.
0041       // Therefore, the muon at a certain position on a link has to be filled
0042       // in a specific collection. The order is from links 24-31:
0043       // 4 muons from EMTF pos, 4 from OMTF pos, 8 from BMTF, 4 from OMTF neg,
0044       // and 4 from EMTF neg.
0045       switch (linkId) {
0046         case 24:
0047           res1_ = static_cast<GMTCollections*>(coll)->getImdMuonsEMTFPos();
0048           res2_ = static_cast<GMTCollections*>(coll)->getImdMuonsEMTFPos();
0049           coll1Cnt_ = 3;
0050           break;
0051         case 25:
0052           res1_ = static_cast<GMTCollections*>(coll)->getImdMuonsEMTFPos();
0053           res2_ = static_cast<GMTCollections*>(coll)->getImdMuonsOMTFPos();
0054           coll1Cnt_ = 1;
0055           break;
0056         case 26:
0057           res1_ = static_cast<GMTCollections*>(coll)->getImdMuonsOMTFPos();
0058           res2_ = static_cast<GMTCollections*>(coll)->getImdMuonsBMTF();
0059           coll1Cnt_ = 2;
0060           break;
0061         case 27:
0062           res1_ = static_cast<GMTCollections*>(coll)->getImdMuonsBMTF();
0063           res2_ = static_cast<GMTCollections*>(coll)->getImdMuonsBMTF();
0064           coll1Cnt_ = 3;
0065           break;
0066         case 28:
0067           res1_ = static_cast<GMTCollections*>(coll)->getImdMuonsBMTF();
0068           res2_ = static_cast<GMTCollections*>(coll)->getImdMuonsBMTF();
0069           coll1Cnt_ = 3;
0070           break;
0071         case 29:
0072           res1_ = static_cast<GMTCollections*>(coll)->getImdMuonsBMTF();
0073           res2_ = static_cast<GMTCollections*>(coll)->getImdMuonsOMTFNeg();
0074           coll1Cnt_ = 1;
0075           break;
0076         case 30:
0077           res1_ = static_cast<GMTCollections*>(coll)->getImdMuonsOMTFNeg();
0078           res2_ = static_cast<GMTCollections*>(coll)->getImdMuonsEMTFNeg();
0079           coll1Cnt_ = 2;
0080           break;
0081         case 31:
0082           res1_ = static_cast<GMTCollections*>(coll)->getImdMuonsEMTFNeg();
0083           res2_ = static_cast<GMTCollections*>(coll)->getImdMuonsEMTFNeg();
0084           coll1Cnt_ = 3;
0085           break;
0086         default:
0087           edm::LogWarning("L1T") << "Block ID " << block.header().getID()
0088                                  << " not associated with intermediate muons. Skip.";
0089           return false;
0090       }
0091       res1_->setBXRange(firstBX, lastBX);
0092       res2_->setBXRange(firstBX, lastBX);
0093       LogDebug("L1T") << "nBX = " << nBX << " first BX = " << firstBX << " lastBX = " << lastBX;
0094 
0095       // Get the BX blocks and unpack them
0096       auto bxBlocks = block.getBxBlocks(nWords_, bxZsEnabled);
0097       for (const auto& bxBlock : bxBlocks) {
0098         unpackBx(bxBlock.header().getBx(), bxBlock.payload());
0099       }
0100       return true;
0101     }
0102 
0103     void IntermediateMuonUnpacker::unpackBx(int bx, const std::vector<uint32_t>& payload, unsigned int startIdx) {
0104       unsigned int i = startIdx;
0105       // Check if there are enough words left in the payload
0106       if (i + nWords_ <= payload.size()) {
0107         unsigned int muonCnt = 0;
0108         for (unsigned nWord = 0; nWord < nWords_; nWord += 2, ++muonCnt) {
0109           uint32_t raw_data_00_31 = payload[i++];
0110           uint32_t raw_data_32_63 = payload[i++];
0111           LogDebug("L1T") << "raw_data_00_31 = 0x" << hex << raw_data_00_31 << " raw_data_32_63 = 0x" << raw_data_32_63;
0112           // skip empty muons (hwPt == 0)
0113           if (((raw_data_00_31 >> l1t::MuonRawDigiTranslator::ptShift_) & l1t::MuonRawDigiTranslator::ptMask_) == 0) {
0114             LogDebug("L1T") << "Muon hwPt zero. Skip.";
0115             continue;
0116           }
0117 
0118           Muon mu;
0119 
0120           // The intermediate muons of the uGMT (FED number 1402) do not
0121           // have coordinates estimated at the vertex in the RAW data.
0122           // The corresponding bits are set to zero.
0123           MuonRawDigiTranslator::fillIntermediateMuon(mu, raw_data_00_31, raw_data_32_63, getAlgoVersion());
0124 
0125           LogDebug("L1T") << "Mu" << nWord / 2 << ": eta " << mu.hwEta() << " phi " << mu.hwPhi() << " pT " << mu.hwPt()
0126                           << " iso " << mu.hwIso() << " qual " << mu.hwQual() << " charge " << mu.hwCharge()
0127                           << " charge valid " << mu.hwChargeValid();
0128 
0129           if (muonCnt < coll1Cnt_) {
0130             res1_->push_back(bx, mu);
0131           } else {
0132             res2_->push_back(bx, mu);
0133           }
0134         }
0135       } else {
0136         edm::LogWarning("L1T") << "Only " << payload.size() - i << " 32 bit words in this BX but " << nWords_
0137                                << " are required. Not unpacking the data for BX " << bx << ".";
0138       }
0139     }
0140 
0141   }  // namespace stage2
0142 }  // namespace l1t
0143 
0144 DEFINE_L1T_UNPACKER(l1t::stage2::IntermediateMuonUnpacker);