Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2023-03-28 01:34: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;
0038       tftype trackFinder;
0039       if (linkId > 47 && linkId < 60) {
0040         regionalMuonCollection = static_cast<GMTCollections*>(coll)->getRegionalMuonCandsBMTF();
0041         regionalMuonShowerCollection =
0042             new RegionalMuonShowerBxCollection();  // To avoid warning re uninitialised collection
0043         trackFinder = tftype::bmtf;
0044         processor = linkId - 48;
0045       } else if (linkId > 41 && linkId < 66) {
0046         regionalMuonCollection = static_cast<GMTCollections*>(coll)->getRegionalMuonCandsOMTF();
0047         regionalMuonShowerCollection =
0048             new RegionalMuonShowerBxCollection();  // To avoid warning re uninitialised collection
0049         if (linkId < 48) {
0050           trackFinder = tftype::omtf_pos;
0051           processor = linkId - 42;
0052         } else {
0053           trackFinder = tftype::omtf_neg;
0054           processor = linkId - 60;
0055         }
0056       } else if (linkId > 35 && linkId < 72) {
0057         regionalMuonCollection = static_cast<GMTCollections*>(coll)->getRegionalMuonCandsEMTF();
0058         regionalMuonShowerCollection = static_cast<GMTCollections*>(coll)->getRegionalMuonShowersEMTF();
0059         if (linkId < 42) {
0060           trackFinder = tftype::emtf_pos;
0061           processor = linkId - 36;
0062         } else {
0063           trackFinder = tftype::emtf_neg;
0064           processor = linkId - 66;
0065         }
0066       } else {
0067         edm::LogError("L1T") << "No TF muon expected for link " << linkId;
0068         return false;
0069       }
0070       regionalMuonCollection->setBXRange(firstBX, lastBX);
0071       regionalMuonShowerCollection->setBXRange(firstBX, lastBX);
0072 
0073       LogDebug("L1T") << "nBX = " << nBX << " first BX = " << firstBX << " lastBX = " << lastBX;
0074 
0075       // Get the BX blocks and unpack them
0076       auto bxBlocks = block.getBxBlocks(nWords_, bxZsEnabled);
0077       for (const auto& bxBlock : bxBlocks) {
0078         // Throw an exception if finding a corrupt BX header with out of range BX numbers
0079         const auto bx = bxBlock.header().getBx();
0080         if (bx < firstBX || bx > lastBX) {
0081           throw cms::Exception("CorruptData") << "Corrupt RAW data from AMC " << block.amc().getAMCNumber()
0082                                               << ". BX number " << bx << " in BX header is outside of the BX range ["
0083                                               << firstBX << "," << lastBX << "] defined in the block header.";
0084         }
0085         // Check if there are enough words left in the BX block payload
0086         auto bxPayload = bxBlock.payload();
0087         if (nWords_ <= bxPayload.size()) {
0088           for (unsigned nWord = 0; nWord < nWords_; nWord += 2) {
0089             uint32_t raw_data_00_31 = bxPayload[nWord];
0090             uint32_t raw_data_32_63 = bxPayload[nWord + 1];
0091             LogDebug("L1T") << "raw_data_00_31 = 0x" << hex << setw(8) << setfill('0') << raw_data_00_31
0092                             << " raw_data_32_63 = 0x" << setw(8) << setfill('0') << raw_data_32_63;
0093             // skip empty muons (hwPt == 0)
0094             if (((raw_data_00_31 >> l1t::RegionalMuonRawDigiTranslator::ptShift_) &
0095                  l1t::RegionalMuonRawDigiTranslator::ptMask_) == 0) {
0096               LogDebug("L1T") << "Muon hwPt zero. Skip.";
0097               continue;
0098             }
0099             // Detect and ignore comma events
0100             if (raw_data_00_31 == 0x505050bc || raw_data_32_63 == 0x505050bc) {
0101               edm::LogWarning("L1T") << "Comma detected in raw data stream. Orbit number: "
0102                                      << block.amc().getOrbitNumber() << ", BX ID: " << block.amc().getBX()
0103                                      << ", BX: " << bx << ", linkId: " << linkId << ", Raw data: 0x" << hex << setw(8)
0104                                      << setfill('0') << raw_data_32_63 << setw(8) << setfill('0') << raw_data_00_31
0105                                      << dec << ". Skip.";
0106               continue;
0107             }
0108 
0109             RegionalMuonCand mu;
0110             mu.setMuIdx(nWord / 2);
0111 
0112             RegionalMuonRawDigiTranslator::fillRegionalMuonCand(
0113                 mu, raw_data_00_31, raw_data_32_63, processor, trackFinder, isKbmtf_, useEmtfDisplacementInfo_);
0114 
0115             LogDebug("L1T") << "Mu" << nWord / 2 << ": eta " << mu.hwEta() << " phi " << mu.hwPhi() << " pT "
0116                             << mu.hwPt() << " qual " << mu.hwQual() << " sign " << mu.hwSign() << " sign valid "
0117                             << mu.hwSignValid() << " unconstrained pT " << mu.hwPtUnconstrained();
0118 
0119             regionalMuonCollection->push_back(bx, mu);
0120           }
0121           // Fill RegionalMuonShower objects. For this we need to look at all six words together.
0122           RegionalMuonShower muShower;
0123           if (RegionalMuonRawDigiTranslator::fillRegionalMuonShower(
0124                   muShower, bxPayload, processor, trackFinder, useEmtfNominalTightShowers_, useEmtfLooseShowers_)) {
0125             regionalMuonShowerCollection->push_back(bx, muShower);
0126           }
0127         } else {
0128           unsigned int nWords =
0129               nWords_;  // This seems unnecessary but it prevents an 'undefined reference' linker error that occurs when using nWords_ directly with LogWarning.
0130           edm::LogWarning("L1T") << "Only " << bxPayload.size() << " 32 bit words in this BX but " << nWords
0131                                  << " are required. Not unpacking the data for BX " << bx << ".";
0132         }
0133       }
0134       return true;
0135     }
0136   }  // namespace stage2
0137 }  // namespace l1t
0138 
0139 DEFINE_L1T_UNPACKER(l1t::stage2::RegionalMuonGMTUnpacker);