Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-12-17 02:41:12

0001 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0002 #include "FWCore/Utilities/interface/Exception.h"
0003 #include "EventFilter/L1TRawToDigi/plugins/UnpackerFactory.h"
0004 
0005 #include "L1Trigger/L1TMuon/interface/RegionalMuonRawDigiTranslator.h"
0006 #include "RegionalMuonGMTUnpacker.h"
0007 
0008 namespace l1t {
0009   namespace stage2 {
0010     bool RegionalMuonGMTUnpacker::unpack(const Block& block, UnpackerCollections* coll) {
0011       unsigned int blockId = block.header().getID();
0012       LogDebug("L1T") << "Block ID  = " << blockId << " size = " << block.header().getSize();
0013       // Process only if there is a payload.
0014       // If all BX block were zero suppressed the block header size is 0.
0015       if (block.header().getSize() < 1) {
0016         return true;
0017       }
0018 
0019       auto payload = block.payload();
0020 
0021       int nBX, firstBX, lastBX;
0022       // Check if per BX zero suppression was enabled
0023       bool bxZsEnabled = ((block.header().getFlags() >> bxzs_enable_shift_) & 0x1) == 1;
0024       // Calculate the total number of BXs
0025       if (bxZsEnabled) {
0026         BxBlockHeader bxHeader(payload.at(0));
0027         nBX = bxHeader.getTotalBx();
0028       } else {
0029         nBX = int(ceil(block.header().getSize() / nWords_));
0030       }
0031       getBXRange(nBX, firstBX, lastBX);
0032 
0033       // decide which collection to use according to the link ID
0034       unsigned int linkId = blockId / 2;
0035       int processor;
0036       RegionalMuonCandBxCollection* regionalMuonCollection;
0037       RegionalMuonShowerBxCollection* regionalMuonShowerCollection = nullptr;
0038       tftype trackFinder;
0039       if (linkId > 47 && linkId < 60) {
0040         regionalMuonCollection = static_cast<GMTCollections*>(coll)->getRegionalMuonCandsBMTF();
0041         trackFinder = tftype::bmtf;
0042         processor = linkId - 48;
0043       } else if (linkId > 41 && linkId < 66) {
0044         regionalMuonCollection = static_cast<GMTCollections*>(coll)->getRegionalMuonCandsOMTF();
0045         if (linkId < 48) {
0046           trackFinder = tftype::omtf_pos;
0047           processor = linkId - 42;
0048         } else {
0049           trackFinder = tftype::omtf_neg;
0050           processor = linkId - 60;
0051         }
0052       } else if (linkId > 35 && linkId < 72) {
0053         regionalMuonCollection = static_cast<GMTCollections*>(coll)->getRegionalMuonCandsEMTF();
0054         regionalMuonShowerCollection = static_cast<GMTCollections*>(coll)->getRegionalMuonShowersEMTF();
0055         if (linkId < 42) {
0056           trackFinder = tftype::emtf_pos;
0057           processor = linkId - 36;
0058         } else {
0059           trackFinder = tftype::emtf_neg;
0060           processor = linkId - 66;
0061         }
0062       } else {
0063         edm::LogError("L1T") << "No TF muon expected for link " << linkId;
0064         return false;
0065       }
0066       regionalMuonCollection->setBXRange(firstBX, lastBX);
0067       if (regionalMuonShowerCollection) {
0068         regionalMuonShowerCollection->setBXRange(firstBX, lastBX);
0069       }
0070       LogDebug("L1T") << "nBX = " << nBX << " first BX = " << firstBX << " lastBX = " << lastBX;
0071 
0072       // Get the BX blocks and unpack them
0073       auto bxBlocks = block.getBxBlocks(nWords_, bxZsEnabled);
0074       for (const auto& bxBlock : bxBlocks) {
0075         // Throw an exception if finding a corrupt BX header with out of range BX numbers
0076         const auto bx = bxBlock.header().getBx();
0077         if (bx < firstBX || bx > lastBX) {
0078           throw cms::Exception("CorruptData") << "Corrupt RAW data from AMC " << block.amc().getAMCNumber()
0079                                               << ". BX number " << bx << " in BX header is outside of the BX range ["
0080                                               << firstBX << "," << lastBX << "] defined in the block header.";
0081         }
0082         // Check if there are enough words left in the BX block payload
0083         auto bxPayload = bxBlock.payload();
0084         if (nWords_ <= bxPayload.size()) {
0085           for (unsigned nWord = 0; nWord < nWords_; nWord += 2) {
0086             uint32_t raw_data_00_31 = bxPayload[nWord];
0087             uint32_t raw_data_32_63 = bxPayload[nWord + 1];
0088             LogDebug("L1T") << "raw_data_00_31 = 0x" << hex << setw(8) << setfill('0') << raw_data_00_31
0089                             << " raw_data_32_63 = 0x" << setw(8) << setfill('0') << raw_data_32_63;
0090             // skip empty muons (hwPt == 0)
0091             if (((raw_data_00_31 >> l1t::RegionalMuonRawDigiTranslator::ptShift_) &
0092                  l1t::RegionalMuonRawDigiTranslator::ptMask_) == 0) {
0093               LogDebug("L1T") << "Muon hwPt zero. Skip.";
0094               continue;
0095             }
0096             // Detect and ignore comma events
0097             if (raw_data_00_31 == 0x505050bc || raw_data_32_63 == 0x505050bc) {
0098               edm::LogWarning("L1T") << "Comma detected in raw data stream. Orbit number: "
0099                                      << block.amc().getOrbitNumber() << ", BX ID: " << block.amc().getBX()
0100                                      << ", BX: " << bx << ", linkId: " << linkId << ", Raw data: 0x" << hex << setw(8)
0101                                      << setfill('0') << raw_data_32_63 << setw(8) << setfill('0') << raw_data_00_31
0102                                      << dec << ". Skip.";
0103               continue;
0104             }
0105 
0106             RegionalMuonCand mu;
0107             mu.setMuIdx(nWord / 2);
0108 
0109             RegionalMuonRawDigiTranslator::fillRegionalMuonCand(mu,
0110                                                                 raw_data_00_31,
0111                                                                 raw_data_32_63,
0112                                                                 processor,
0113                                                                 trackFinder,
0114                                                                 isKbmtf_,
0115                                                                 useOmtfDisplacementInfo_,
0116                                                                 useEmtfDisplacementInfo_);
0117 
0118             LogDebug("L1T") << "Mu" << nWord / 2 << ": eta " << mu.hwEta() << " phi " << mu.hwPhi() << " pT "
0119                             << mu.hwPt() << " qual " << mu.hwQual() << " sign " << mu.hwSign() << " sign valid "
0120                             << mu.hwSignValid() << " unconstrained pT " << mu.hwPtUnconstrained();
0121 
0122             regionalMuonCollection->push_back(bx, mu);
0123           }
0124           // Fill RegionalMuonShower objects. For this we need to look at all six words together.
0125           RegionalMuonShower muShower;
0126           if (RegionalMuonRawDigiTranslator::fillRegionalMuonShower(
0127                   muShower, bxPayload, processor, trackFinder, useEmtfNominalTightShowers_, useEmtfLooseShowers_) and
0128               regionalMuonShowerCollection) {
0129             regionalMuonShowerCollection->push_back(bx, muShower);
0130           }
0131         } else {
0132           unsigned int nWords =
0133               nWords_;  // This seems unnecessary but it prevents an 'undefined reference' linker error that occurs when using nWords_ directly with LogWarning.
0134           edm::LogWarning("L1T") << "Only " << bxPayload.size() << " 32 bit words in this BX but " << nWords
0135                                  << " are required. Not unpacking the data for BX " << bx << ".";
0136         }
0137       }
0138       return true;
0139     }
0140   }  // namespace stage2
0141 }  // namespace l1t
0142 
0143 DEFINE_L1T_UNPACKER(l1t::stage2::RegionalMuonGMTUnpacker);