Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2022-02-08 06:28:04

0001 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0002 #include "TMath.h"
0003 #include "L1Trigger/L1TMuon/interface/MuonRawDigiTranslator.h"
0004 
0005 void l1t::MuonRawDigiTranslator::fillMuon(Muon& mu,
0006                                           uint32_t raw_data_spare,
0007                                           uint32_t raw_data_00_31,
0008                                           uint32_t raw_data_32_63,
0009                                           int fed,
0010                                           unsigned int fw,
0011                                           int muInBx) {
0012   // Need the hw charge to properly compute dPhi
0013   mu.setHwCharge((raw_data_32_63 >> chargeShift_) & 0x1);
0014 
0015   // The position of the eta and phi coordinates in the RAW data changed between the 2016 run and the 2017 run.
0016   // Eta and phi at the muon system are replaced by eta and phi at the vertex
0017   // Eta and phi at the muon system are moved to spare bits
0018   // In Run-3 we have displacement information.
0019   // To make room for these data the raw eta value was moved to the second "spare" word which we will have to treat separately
0020   // The uGMT (FED 1402) or uGT (FED 1404) FW versions are used to determine the era.
0021   if ((fed == 1402 && fw < 0x4010000) || (fed == 1404 && fw < 0x10A6)) {
0022     fillMuonCoordinates2016(mu, raw_data_00_31, raw_data_32_63);
0023   } else if ((fed == 1402 && fw < 0x6000000) || (fed == 1404 && fw < 0x1120)) {
0024     fillMuonCoordinatesFrom2017(mu, raw_data_00_31, raw_data_32_63);
0025   } else if ((fed == 1402 && fw == 0x6000001) || (fed == 1404 && fw < 0x1130)) {
0026     // We're unpacking data from the November MWGR where the raw eta values were shifted by one bit.
0027     fillMuonQuantitiesRun3(mu, raw_data_spare, raw_data_00_31, raw_data_32_63, muInBx, true);
0028   } else {
0029     fillMuonQuantitiesRun3(mu, raw_data_spare, raw_data_00_31, raw_data_32_63, muInBx, false);
0030   }
0031 
0032   // Fill pT, qual, iso, charge, index bits, coordinates at vtx
0033   fillMuonStableQuantities(mu, raw_data_00_31, raw_data_32_63);
0034 }
0035 
0036 void l1t::MuonRawDigiTranslator::fillIntermediateMuon(Muon& mu,
0037                                                       uint32_t raw_data_00_31,
0038                                                       uint32_t raw_data_32_63,
0039                                                       unsigned int fw) {
0040   // Need the hw charge to properly compute dPhi
0041   mu.setHwCharge((raw_data_32_63 >> chargeShift_) & 0x1);
0042 
0043   if (fw < 0x4010000) {
0044     fillMuonCoordinates2016(mu, raw_data_00_31, raw_data_32_63);
0045   } else if (fw < 0x6000000) {
0046     fillMuonCoordinatesFrom2017(mu, raw_data_00_31, raw_data_32_63);
0047   } else {
0048     fillIntermediateMuonQuantitiesRun3(mu, raw_data_00_31, raw_data_32_63);
0049   }
0050 
0051   // Fill pT, qual, iso, charge, index bits,  phys. coordinates at vtx & unconstrained pT
0052   fillMuonStableQuantities(mu, raw_data_00_31, raw_data_32_63);
0053 }
0054 
0055 void l1t::MuonRawDigiTranslator::fillMuonStableQuantities(Muon& mu, uint32_t raw_data_00_31, uint32_t raw_data_32_63) {
0056   mu.setHwPt((raw_data_00_31 >> ptShift_) & ptMask_);
0057   mu.setHwQual((raw_data_00_31 >> qualShift_) & qualMask_);
0058   mu.setHwIso((raw_data_32_63 >> isoShift_) & isoMask_);
0059   // charge is coded as -1^chargeBit
0060   mu.setHwChargeValid((raw_data_32_63 >> chargeValidShift_) & 0x1);
0061   mu.setTfMuonIndex((raw_data_32_63 >> tfMuonIndexShift_) & tfMuonIndexMask_);
0062   if (mu.hwChargeValid()) {
0063     mu.setCharge(1 - 2 * mu.hwCharge());
0064   } else {
0065     mu.setCharge(0);
0066   }
0067 
0068   math::PtEtaPhiMLorentzVector vec{(mu.hwPt() - 1) * 0.5, mu.hwEta() * 0.010875, mu.hwPhi() * 0.010908, 0.0};
0069   mu.setP4(vec);
0070   // generate a muon at the vertex to extract the physical eta and phi coordinates
0071   math::PtEtaPhiMLorentzVector vecAtVtx{
0072       (mu.hwPt() - 1) * 0.5, mu.hwEtaAtVtx() * 0.010875, mu.hwPhiAtVtx() * 0.010908, 0.0};
0073   Muon muAtVtx;
0074   muAtVtx.setP4(vecAtVtx);
0075   mu.setEtaAtVtx(muAtVtx.eta());
0076   mu.setPhiAtVtx(muAtVtx.phi());
0077 
0078   int hwPtUnconstrained{mu.hwPtUnconstrained()};
0079   mu.setPtUnconstrained(
0080       hwPtUnconstrained == 0 ? 0 : (hwPtUnconstrained - 1));  // Don't want negative pT, unconstr. pT has LSB of 1 GeV.
0081 }
0082 
0083 void l1t::MuonRawDigiTranslator::fillMuon(
0084     Muon& mu, uint32_t raw_data_spare, uint64_t dataword, int fed, unsigned int fw, int muInBx) {
0085   fillMuon(
0086       mu, raw_data_spare, (uint32_t)(dataword & 0xFFFFFFFF), (uint32_t)((dataword >> 32) & 0xFFFFFFFF), fed, fw, muInBx);
0087 }
0088 
0089 void l1t::MuonRawDigiTranslator::fillMuonCoordinates2016(Muon& mu, uint32_t raw_data_00_31, uint32_t raw_data_32_63) {
0090   // coordinates at the muon system are in 2016 where in 2017 eta and phi at the vertex are
0091   mu.setHwEta(calcHwEta(raw_data_00_31, absEtaAtVtxShift_, etaAtVtxSignShift_));
0092   mu.setHwPhi((raw_data_00_31 >> phiAtVtxShift_) & phiMask_);
0093 
0094   // set the coordiantes at vertex to be the same as the coordinates at the muon system
0095   mu.setHwEtaAtVtx(mu.hwEta());
0096   mu.setHwPhiAtVtx(mu.hwPhi());
0097   // deltas are 0
0098   mu.setHwDEtaExtra(0);
0099   mu.setHwDPhiExtra(0);
0100 }
0101 
0102 void l1t::MuonRawDigiTranslator::fillMuonCoordinatesFrom2017(Muon& mu,
0103                                                              uint32_t raw_data_00_31,
0104                                                              uint32_t raw_data_32_63) {
0105   // coordinates at the muon system
0106   mu.setHwEta(calcHwEta(raw_data_32_63, absEtaShift_, etaSignShift_));
0107   mu.setHwPhi((raw_data_32_63 >> phiShift_) & phiMask_);
0108 
0109   // coordinates at the vertex
0110   mu.setHwEtaAtVtx(calcHwEta(raw_data_00_31, absEtaAtVtxShift_, etaAtVtxSignShift_));
0111   mu.setHwPhiAtVtx((raw_data_00_31 >> phiAtVtxShift_) & phiMask_);
0112   // deltas
0113   mu.setHwDEtaExtra(mu.hwEtaAtVtx() - mu.hwEta());
0114   int dPhi = mu.hwPhiAtVtx() - mu.hwPhi();
0115   if (mu.hwCharge() == 1 && dPhi > 0) {
0116     dPhi -= 576;
0117   } else if (mu.hwCharge() == 0 && dPhi < 0) {
0118     dPhi += 576;
0119   }
0120   mu.setHwDPhiExtra(dPhi);
0121 }
0122 
0123 void l1t::MuonRawDigiTranslator::fillMuonQuantitiesRun3(Muon& mu,
0124                                                         uint32_t raw_data_spare,
0125                                                         uint32_t raw_data_00_31,
0126                                                         uint32_t raw_data_32_63,
0127                                                         int muInBx,
0128                                                         bool wasSpecialMWGR /*= false*/) {
0129   unsigned absEtaMu1Shift{absEtaMu1Shift_};
0130   unsigned etaMu1SignShift{etaMu1SignShift_};
0131   unsigned absEtaMu2Shift{absEtaMu2Shift_};
0132   unsigned etaMu2SignShift{etaMu2SignShift_};
0133 
0134   // Adjust if we're unpacking data from the November 2020 MWGR.
0135   if (wasSpecialMWGR) {
0136     --absEtaMu1Shift;
0137     --etaMu1SignShift;
0138     --absEtaMu2Shift;
0139     --etaMu2SignShift;
0140   }
0141   // coordinates at the muon system
0142   // Where to find the raw eta depends on which muon we're looking at
0143   if (muInBx == 1) {
0144     mu.setHwEta(calcHwEta(raw_data_spare, absEtaMu1Shift, etaMu1SignShift));
0145   } else if (muInBx == 2) {
0146     mu.setHwEta(calcHwEta(raw_data_spare, absEtaMu2Shift, etaMu2SignShift));
0147   } else {
0148     edm::LogWarning("L1T") << "Received invalid muon id " << muInBx << ". Cannot fill eta value in the muon system.";
0149   }
0150   mu.setHwPhi((raw_data_32_63 >> phiShift_) & phiMask_);
0151 
0152   // coordinates at the vertex
0153   mu.setHwEtaAtVtx(calcHwEta(raw_data_00_31, absEtaAtVtxShift_, etaAtVtxSignShift_));
0154   mu.setHwPhiAtVtx((raw_data_00_31 >> phiAtVtxShift_) & phiMask_);
0155   // deltas
0156   mu.setHwDEtaExtra(mu.hwEtaAtVtx() - mu.hwEta());
0157   int dPhi = mu.hwPhiAtVtx() - mu.hwPhi();
0158   if (mu.hwCharge() == 1 && dPhi > 0) {
0159     dPhi -= 576;
0160   } else if (mu.hwCharge() == 0 && dPhi < 0) {
0161     dPhi += 576;
0162   }
0163   mu.setHwDPhiExtra(dPhi);
0164 
0165   // displacement information
0166   mu.setHwDXY((raw_data_32_63 >> dxyShift_) & dxyMask_);
0167   mu.setHwPtUnconstrained((raw_data_32_63 >> ptUnconstrainedShift_) & ptUnconstrainedMask_);
0168 }
0169 
0170 void l1t::MuonRawDigiTranslator::fillIntermediateMuonQuantitiesRun3(Muon& mu,
0171                                                                     uint32_t raw_data_00_31,
0172                                                                     uint32_t raw_data_32_63) {
0173   fillMuonCoordinatesFrom2017(mu, raw_data_00_31, raw_data_32_63);
0174 
0175   // displacement information
0176   mu.setHwDXY((raw_data_32_63 >> dxyShift_) & dxyMask_);
0177   mu.setHwPtUnconstrained((raw_data_00_31 >> ptUnconstrainedIntermedidateShift_) & ptUnconstrainedMask_);
0178 }
0179 
0180 void l1t::MuonRawDigiTranslator::generatePackedMuonDataWords(const Muon& mu,
0181                                                              uint32_t& raw_data_spare,
0182                                                              uint32_t& raw_data_00_31,
0183                                                              uint32_t& raw_data_32_63,
0184                                                              const int fedID,
0185                                                              const int fwID,
0186                                                              const int muInBx) {
0187   int abs_eta = mu.hwEta();
0188   if (abs_eta < 0) {
0189     abs_eta += (1 << (etaSignShift_ - absEtaShift_));
0190   }
0191   int abs_eta_at_vtx = mu.hwEtaAtVtx();
0192   if (abs_eta_at_vtx < 0) {
0193     abs_eta_at_vtx += (1 << (etaAtVtxSignShift_ - absEtaAtVtxShift_));
0194   }
0195   if ((fedID == 1402 && fwID < 0x4010000) || (fedID == 1404 && fwID < 0x10A6)) {
0196     // For 2016 the non-extrapolated coordiantes were in the place that are now occupied by the extrapolated quantities.
0197     raw_data_spare = 0;
0198     raw_data_00_31 = (mu.hwPt() & ptMask_) << ptShift_ | (mu.hwQual() & qualMask_) << qualShift_ |
0199                      (abs_eta & absEtaMask_) << absEtaAtVtxShift_ | (mu.hwEta() < 0) << etaAtVtxSignShift_ |
0200                      (mu.hwPhi() & phiMask_) << phiAtVtxShift_;
0201     raw_data_32_63 = mu.hwCharge() << chargeShift_ | mu.hwChargeValid() << chargeValidShift_ |
0202                      (mu.tfMuonIndex() & tfMuonIndexMask_) << tfMuonIndexShift_ | (mu.hwIso() & isoMask_) << isoShift_;
0203   } else if ((fedID == 1402 && fwID < 0x6000000) || (fedID == 1404 && fwID < 0x1120)) {
0204     raw_data_spare = 0;
0205     raw_data_00_31 = (mu.hwPt() & ptMask_) << ptShift_ | (mu.hwQual() & qualMask_) << qualShift_ |
0206                      (abs_eta_at_vtx & absEtaMask_) << absEtaAtVtxShift_ | (mu.hwEtaAtVtx() < 0) << etaAtVtxSignShift_ |
0207                      (mu.hwPhiAtVtx() & phiMask_) << phiAtVtxShift_;
0208 
0209     raw_data_32_63 = mu.hwCharge() << chargeShift_ | mu.hwChargeValid() << chargeValidShift_ |
0210                      (mu.tfMuonIndex() & tfMuonIndexMask_) << tfMuonIndexShift_ | (mu.hwIso() & isoMask_) << isoShift_ |
0211                      (abs_eta & absEtaMask_) << absEtaShift_ | (mu.hwEta() < 0) << etaSignShift_ |
0212                      (mu.hwPhi() & phiMask_) << phiShift_;
0213   } else if ((fedID == 1402 && fwID == 0x6000001) ||
0214              (fedID == 1404 && fwID < 0x1130)) {  // This allows us to unpack data taken in the November 2020 MWGR.
0215     generatePackedMuonDataWordsRun3(
0216         mu, abs_eta, abs_eta_at_vtx, raw_data_spare, raw_data_00_31, raw_data_32_63, muInBx, true);
0217   } else {
0218     generatePackedMuonDataWordsRun3(
0219         mu, abs_eta, abs_eta_at_vtx, raw_data_spare, raw_data_00_31, raw_data_32_63, muInBx, false);
0220   }
0221 }
0222 
0223 void l1t::MuonRawDigiTranslator::generatePackedMuonDataWordsRun3(const Muon& mu,
0224                                                                  const int abs_eta,
0225                                                                  const int abs_eta_at_vtx,
0226                                                                  uint32_t& raw_data_spare,
0227                                                                  uint32_t& raw_data_00_31,
0228                                                                  uint32_t& raw_data_32_63,
0229                                                                  const int muInBx,
0230                                                                  const bool wasSpecialMWGR /*= false*/) {
0231   int absEtaShiftRun3{0}, etaSignShiftRun3{0};
0232   if (muInBx == 1) {
0233     absEtaShiftRun3 = absEtaMu1Shift_;
0234     etaSignShiftRun3 = etaMu1SignShift_;
0235   } else if (muInBx == 2) {
0236     absEtaShiftRun3 = absEtaMu2Shift_;
0237     etaSignShiftRun3 = etaMu2SignShift_;
0238   }
0239 
0240   // Adjust if we're packing the November 2020 MWGR
0241   if (wasSpecialMWGR && (muInBx == 1 || muInBx == 2)) {
0242     --absEtaShiftRun3;
0243     --etaSignShiftRun3;
0244   }
0245 
0246   raw_data_spare = (abs_eta & absEtaMask_) << absEtaShiftRun3 | (mu.hwEta() < 0) << etaSignShiftRun3;
0247   raw_data_00_31 = (mu.hwPt() & ptMask_) << ptShift_ | (mu.hwQual() & qualMask_) << qualShift_ |
0248                    (abs_eta_at_vtx & absEtaMask_) << absEtaAtVtxShift_ | (mu.hwEtaAtVtx() < 0) << etaAtVtxSignShift_ |
0249                    (mu.hwPhiAtVtx() & phiMask_) << phiAtVtxShift_;
0250   raw_data_32_63 = mu.hwCharge() << chargeShift_ | mu.hwChargeValid() << chargeValidShift_ |
0251                    (mu.tfMuonIndex() & tfMuonIndexMask_) << tfMuonIndexShift_ | (mu.hwIso() & isoMask_) << isoShift_ |
0252                    (mu.hwPhi() & phiMask_) << phiShift_ |
0253                    (mu.hwPtUnconstrained() & ptUnconstrainedMask_) << ptUnconstrainedShift_ |
0254                    (mu.hwDXY() & dxyMask_) << dxyShift_;
0255 }
0256 
0257 void l1t::MuonRawDigiTranslator::generate64bitDataWord(
0258     const Muon& mu, uint32_t& raw_data_spare, uint64_t& dataword, int fedId, int fwId, int muInBx) {
0259   uint32_t lsw;
0260   uint32_t msw;
0261 
0262   generatePackedMuonDataWords(mu, raw_data_spare, lsw, msw, fedId, fwId, muInBx);
0263   dataword = (((uint64_t)msw) << 32) + lsw;
0264 }
0265 
0266 bool l1t::MuonRawDigiTranslator::showerFired(uint32_t shower_word, int fedId, unsigned int fwId) {
0267   if ((fedId == 1402 && fwId >= 0x7000000) || (fedId == 1404 && fwId >= 0x00010f01)) {
0268     return ((shower_word >> showerShift_) & 1) == 1;
0269   }
0270   return false;
0271 }
0272 
0273 std::array<uint32_t, 4> l1t::MuonRawDigiTranslator::getPackedShowerDataWords(const MuonShower& shower,
0274                                                                              const int fedId,
0275                                                                              const unsigned int fwId) {
0276   std::array<uint32_t, 4> res{};
0277   if ((fedId == 1402 && fwId >= 0x7000000) || (fedId == 1404 && fwId >= 0x00010f01)) {
0278     res.at(0) = shower.isOneNominalInTime() ? (1 << showerShift_) : 0;
0279     res.at(1) = shower.isOneTightInTime() ? (1 << showerShift_) : 0;
0280   }
0281   return res;
0282 }
0283 
0284 int l1t::MuonRawDigiTranslator::calcHwEta(const uint32_t& raw,
0285                                           const unsigned absEtaShift,
0286                                           const unsigned etaSignShift) {
0287   // eta is coded as two's complement
0288   int abs_eta = (raw >> absEtaShift) & absEtaMask_;
0289   if ((raw >> etaSignShift) & 0x1) {
0290     return abs_eta - (1 << (etaSignShift - absEtaShift));
0291   } else {
0292     return abs_eta;
0293   }
0294 }