File indexing completed on 2024-04-06 12:10:52
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/MuonRawDigiTranslator.h"
0006
0007 #include "MuonUnpacker.h"
0008
0009 namespace l1t {
0010 namespace stage2 {
0011 MuonUnpacker::MuonUnpacker() : muonCollection_(nullptr), muonShowerCollection_(nullptr), muonCopy_(0) {}
0012
0013 bool MuonUnpacker::unpack(const Block& block, UnpackerCollections* coll) {
0014 LogDebug("L1T") << "Block ID = " << block.header().getID() << " size = " << block.header().getSize();
0015
0016
0017 if (block.header().getSize() < 1) {
0018 return true;
0019 }
0020
0021 auto payload = block.payload();
0022
0023 int nBX, firstBX, lastBX;
0024
0025 bool bxZsEnabled = ((block.header().getFlags() >> bxzs_enable_shift_) & 0x1) == 1;
0026
0027 if (bxZsEnabled) {
0028 BxBlockHeader bxHeader(payload.at(0));
0029 nBX = bxHeader.getTotalBx();
0030 } else {
0031 nBX = int(ceil(block.header().getSize() / nWords_));
0032 }
0033 getBXRange(nBX, firstBX, lastBX);
0034
0035
0036 muonCollection_ = static_cast<L1TObjectCollections*>(coll)->getMuons(muonCopy_);
0037 muonCollection_->setBXRange(firstBX, lastBX);
0038
0039 muonShowerCollection_ = static_cast<L1TObjectCollections*>(coll)->getMuonShowers(muonCopy_);
0040 muonShowerCollection_->setBXRange(firstBX, lastBX);
0041
0042 LogDebug("L1T") << "nBX = " << nBX << " first BX = " << firstBX << " lastBX = " << lastBX;
0043
0044
0045 auto bxBlocks = block.getBxBlocks(nWords_, bxZsEnabled);
0046 for (const auto& bxBlock : bxBlocks) {
0047
0048 const auto bx = bxBlock.header().getBx();
0049 if (bx < firstBX || bx > lastBX) {
0050 throw cms::Exception("CorruptData")
0051 << "Corrupt RAW data from FED " << fed_ << ", AMC " << block.amc().getAMCNumber() << ". BX number " << bx
0052 << " in BX header is outside of the BX range [" << firstBX << "," << lastBX
0053 << "] defined in the block header.";
0054 }
0055 unpackBx(bx, bxBlock.payload(), block.header().getID());
0056 }
0057 return true;
0058 }
0059
0060 void MuonUnpacker::unpackBx(int bx,
0061 const std::vector<uint32_t>& payload,
0062 unsigned int blockID,
0063 unsigned int startIdx) {
0064 unsigned int i = startIdx + 2;
0065
0066 if (startIdx + nWords_ <= payload.size()) {
0067
0068
0069
0070
0071
0072 int link_offset{0};
0073 if (fed_ == 1402) {
0074 link_offset = 1;
0075 }
0076 unsigned linkID{(blockID - link_offset) / 2};
0077
0078
0079
0080
0081
0082 MuonShower shower;
0083 if (!muonShowerCollection_->isEmpty(bx)) {
0084 shower = muonShowerCollection_->at(bx, 0);
0085 muonShowerCollection_->erase(bx, 0);
0086 }
0087 if (linkID == 0) {
0088 shower.setOneNominalInTime(l1t::MuonRawDigiTranslator::showerFired(payload[i + 1], fed_, getAlgoVersion()));
0089
0090 if (fed_ == 1402 && getAlgoVersion() == l1t::MuonRawDigiTranslator::kUgmtFwVersionShowersFrom2023) {
0091 shower.setTwoLooseDiffSectorsInTime(
0092 l1t::MuonRawDigiTranslator::showerFired(payload[i + 3], fed_, getAlgoVersion()));
0093 }
0094 } else if (linkID ==
0095 1) {
0096 shower.setOneTightInTime(l1t::MuonRawDigiTranslator::showerFired(payload[i + 1], fed_, getAlgoVersion()));
0097
0098 if (!(fed_ == 1402 && getAlgoVersion() == l1t::MuonRawDigiTranslator::kUgmtFwVersionShowersFrom2023)) {
0099 shower.setTwoLooseDiffSectorsInTime(
0100 l1t::MuonRawDigiTranslator::showerFired(payload[i + 3], fed_, getAlgoVersion()));
0101 }
0102 }
0103
0104 if (shower.isValid()) {
0105 muonShowerCollection_->push_back(bx, shower);
0106 }
0107
0108 for (unsigned nWord = 2; nWord < nWords_; nWord += 2) {
0109 uint32_t raw_data_spare = payload[startIdx + 1];
0110 uint32_t raw_data_00_31 = payload[i++];
0111 uint32_t raw_data_32_63 = payload[i++];
0112 LogDebug("L1T") << "raw_data_spare = 0x" << hex << raw_data_spare << " raw_data_00_31 = 0x" << raw_data_00_31
0113 << " raw_data_32_63 = 0x" << raw_data_32_63;
0114
0115 if (((raw_data_00_31 >> l1t::MuonRawDigiTranslator::ptShift_) & l1t::MuonRawDigiTranslator::ptMask_) == 0) {
0116 LogDebug("L1T") << "Muon hwPt zero. Skip.";
0117 continue;
0118 }
0119
0120 Muon mu;
0121
0122 MuonRawDigiTranslator::fillMuon(
0123 mu, raw_data_spare, raw_data_00_31, raw_data_32_63, fed_, getAlgoVersion(), nWord / 2);
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 muonCollection_->push_back(bx, mu);
0130 }
0131 } else {
0132 edm::LogWarning("L1T") << "Only " << payload.size() - i << " 32 bit words in this BX but " << nWords_
0133 << " are required. Not unpacking the data for BX " << bx << ".";
0134 }
0135 }
0136 }
0137 }
0138
0139 DEFINE_L1T_UNPACKER(l1t::stage2::MuonUnpacker);