File indexing completed on 2025-04-02 23:19:46
0001 #include "L1Trigger/Phase2L1GMT/interface/TPSAlgorithm.h"
0002
0003 using namespace Phase2L1GMT;
0004
0005 TPSAlgorithm::TPSAlgorithm(const edm::ParameterSet& iConfig) : verbose_(iConfig.getParameter<int>("verbose")) {}
0006
0007 std::vector<PreTrackMatchedMuon> TPSAlgorithm::processNonant(const std::vector<ConvertedTTTrack>& convertedTracks,
0008 const l1t::MuonStubRefVector& stubs) const {
0009 std::vector<PreTrackMatchedMuon> preMuons;
0010 for (const auto& track : convertedTracks) {
0011 PreTrackMatchedMuon mu = processTrack(track, stubs);
0012 if (mu.valid() && preMuons.size() < 16)
0013 preMuons.push_back(mu);
0014 }
0015 std::vector<PreTrackMatchedMuon> cleanedMuons = clean(preMuons);
0016 return cleanedMuons;
0017 }
0018
0019 std::vector<PreTrackMatchedMuon> TPSAlgorithm::cleanNeighbor(const std::vector<PreTrackMatchedMuon>& muons,
0020 const std::vector<PreTrackMatchedMuon>& muonsPrevious,
0021 const std::vector<PreTrackMatchedMuon>& muonsNext,
0022 bool equality) const {
0023 std::vector<PreTrackMatchedMuon> out;
0024
0025 if (muons.empty())
0026 return out;
0027
0028 if (verbose_ == 1) {
0029 edm::LogInfo("TPSAlgo") << "-----Cleaning Up Muons in the neighbours";
0030 edm::LogInfo("TPSAlgo") << "Before:";
0031 }
0032
0033 for (uint i = 0; i < muons.size(); ++i) {
0034 if (verbose_ == 1) {
0035 muons[i].print();
0036 }
0037 ap_uint<5> mask = 0x1f;
0038 for (uint j = 0; j < muonsPrevious.size(); ++j) {
0039 mask = mask & cleanMuon(muons[i], muonsPrevious[j], equality);
0040 }
0041 for (uint j = 0; j < muonsNext.size(); ++j) {
0042 mask = mask & cleanMuon(muons[i], muonsNext[j], equality);
0043 }
0044 if (mask) {
0045 if (verbose_ == 1)
0046 edm::LogInfo("TPSAlgo") << "kept";
0047 out.push_back(muons[i]);
0048 } else {
0049 if (verbose_ == 1)
0050 edm::LogInfo("TPSAlgo") << "discarded";
0051 }
0052 }
0053 return out;
0054 }
0055
0056 std::vector<l1t::TrackerMuon> TPSAlgorithm::convert(const std::vector<PreTrackMatchedMuon>& muons, uint maximum) const {
0057 std::vector<l1t::TrackerMuon> out;
0058 for (const auto& mu : muons) {
0059 if (out.size() == maximum)
0060 break;
0061 l1t::TrackerMuon muon(mu.trkPtr(), mu.charge(), mu.pt(), mu.eta(), mu.phi(), mu.z0(), mu.d0(), mu.quality());
0062 muon.setMuonRef(mu.muonRef());
0063 for (const auto& stub : mu.stubs())
0064 muon.addStub(stub);
0065
0066 uint matches = 0;
0067 uint mask = mu.matchMask();
0068
0069 for (uint i = 0; i < 10; i = i + 1) {
0070 if (mask & (1 << i))
0071 matches++;
0072 }
0073 muon.setNumberOfMatches(matches);
0074 out.push_back(muon);
0075
0076 if (verbose_ == 1) {
0077 edm::LogInfo("TPSAlgo") << "Final Muon:" << std::flush;
0078 muon.print();
0079 }
0080 }
0081 return out;
0082 }
0083
0084 void TPSAlgorithm::SetQualityBits(std::vector<l1t::TrackerMuon>& muons) const {
0085 for (auto& mu : muons) {
0086
0087 bool veryloose = mu.numberOfMatches() > 0;
0088 bool loose = mu.numberOfMatches() > 1;
0089 bool medium = mu.stubs().size() > 1;
0090 bool tight = mu.numberOfMatches() > 2;
0091 int qualbit = 0;
0092 qualbit = (veryloose << 0) | (loose << 1) | (medium << 2) | (tight << 3);
0093 mu.setHwQual(qualbit);
0094 }
0095 }
0096
0097 bool TPSAlgorithm::outputGT(std::vector<l1t::TrackerMuon>& muons) const {
0098 for (auto& mu : muons) {
0099 wordtype word1 = 0;
0100 wordtype word2 = 0;
0101
0102 int bstart = 0;
0103 bstart = wordconcat<wordtype>(word1, bstart, mu.hwPt(), BITSGTPT);
0104 bstart = wordconcat<wordtype>(word1, bstart, mu.hwPhi(), BITSGTPHI);
0105 bstart = wordconcat<wordtype>(word1, bstart, mu.hwEta(), BITSGTETA);
0106 bstart = wordconcat<wordtype>(word1, bstart, mu.hwZ0(), BITSGTZ0);
0107 wordconcat<wordtype>(word1, bstart, (mu.hwD0() >> 2), BITSGTD0);
0108
0109 bstart = 0;
0110 bstart = wordconcat<wordtype>(word2, bstart, mu.hwCharge(), 1);
0111 bstart = wordconcat<wordtype>(word2, bstart, mu.hwQual(), BITSGTQUAL);
0112 bstart = wordconcat<wordtype>(word2, bstart, mu.hwIso(), BITSGTISO);
0113 wordconcat<wordtype>(word2, bstart, mu.hwBeta(), BITSGTBETA);
0114
0115 std::array<uint64_t, 2> wordout = {{word1, word2}};
0116 mu.setWord(wordout);
0117 }
0118 return true;
0119 }
0120
0121 std::vector<l1t::TrackerMuon> TPSAlgorithm::sort(std::vector<l1t::TrackerMuon>& muons, uint maximum) const {
0122 if (muons.size() < 2)
0123 return muons;
0124
0125 std::sort(muons.begin(), muons.end(), [](l1t::TrackerMuon a, l1t::TrackerMuon b) { return a.hwPt() > b.hwPt(); });
0126 std::vector<l1t::TrackerMuon> out{muons.begin(), muons.begin() + (maximum < muons.size() ? maximum : muons.size())};
0127
0128 return out;
0129 }
0130
0131 propagation_t TPSAlgorithm::propagate(const ConvertedTTTrack& track, uint layer) const {
0132 static const std::array<const ap_uint<BITSPROPCOORD>*, 5> lt_prop1_coord1 = {
0133 {lt_prop1_coord1_0, lt_prop1_coord1_1, lt_prop1_coord1_2, lt_prop1_coord1_3, lt_prop1_coord1_4}};
0134 static const std::array<const ap_uint<BITSPROPCOORD>*, 5> lt_prop1_coord2 = {
0135 {lt_prop1_coord2_0, lt_prop1_coord2_1, lt_prop1_coord2_2, lt_prop1_coord2_3, lt_prop1_coord2_4}};
0136 static const std::array<const ap_uint<BITSPROPCOORD>*, 5> lt_prop2_coord1 = {
0137 {lt_prop2_coord1_0, lt_prop2_coord1_1, lt_prop2_coord1_2, lt_prop2_coord1_3, lt_prop2_coord1_4}};
0138 static const std::array<const ap_uint<BITSPROPCOORD>*, 5> lt_prop2_coord2 = {
0139 {lt_prop2_coord2_0, lt_prop2_coord2_1, lt_prop2_coord2_2, lt_prop2_coord2_3, lt_prop2_coord2_4}};
0140 static const std::array<const ap_uint<BITSPROPCOORD>*, 5> lt_prop3_coord1 = {
0141 {lt_prop3_coord1_0, lt_prop3_coord1_1, lt_prop3_coord1_2, lt_prop3_coord1_3, lt_prop3_coord1_4}};
0142 static const std::array<const ap_uint<BITSPROPCOORD>*, 5> lt_prop3_coord2 = {
0143 {lt_prop3_coord2_0, lt_prop3_coord2_1, lt_prop3_coord2_2, lt_prop3_coord2_3, lt_prop3_coord2_4}};
0144
0145 static const std::array<const ap_uint<BITSPROPSIGMACOORD_A>*, 5> lt_res0_coord1 = {
0146 {lt_res0_coord1_0, lt_res0_coord1_1, lt_res0_coord1_2, lt_res0_coord1_3, lt_res0_coord1_4}};
0147 static const std::array<const ap_uint<BITSPROPSIGMACOORD_B>*, 5> lt_res1_coord1 = {
0148 {lt_res1_coord1_0, lt_res1_coord1_1, lt_res1_coord1_2, lt_res1_coord1_3, lt_res1_coord1_4}};
0149 static const std::array<const ap_uint<BITSPROPSIGMACOORD_A>*, 5> lt_res0_coord2 = {
0150 {lt_res0_coord2_0, lt_res0_coord2_1, lt_res0_coord2_2, lt_res0_coord2_3, lt_res0_coord2_4}};
0151 static const std::array<const ap_uint<BITSPROPSIGMACOORD_B>*, 5> lt_res1_coord2 = {
0152 {lt_res1_coord2_0, lt_res1_coord2_1, lt_res1_coord2_2, lt_res1_coord2_3, lt_res1_coord2_4}};
0153
0154 static const std::array<const ap_uint<BITSPROPSIGMAETA_A>*, 5> lt_res0_eta1 = {
0155 {lt_res0_eta1_0, lt_res0_eta1_1, lt_res0_eta1_2, lt_res0_eta1_3, lt_res0_eta1_4}};
0156 static const std::array<const ap_uint<BITSPROPSIGMAETA_A>*, 5> lt_res1_eta1 = {
0157 {lt_res1_eta_0, lt_res1_eta_1, lt_res1_eta_2, lt_res1_eta_3, lt_res1_eta_4}};
0158
0159 static const std::array<const ap_uint<BITSPROPSIGMAETA_A>*, 5> lt_res0_eta2 = {
0160 {lt_res0_eta2_0, lt_res0_eta2_1, lt_res0_eta2_2, lt_res0_eta2_3, lt_res0_eta2_4}};
0161
0162 static const uint barrellimit[5] = {barrelLimit0_, barrelLimit1_, barrelLimit2_, barrelLimit3_, barrelLimit4_};
0163
0164 ap_uint<BITSPROPCOORD> prop1_coord1 = 0;
0165 ap_uint<BITSPROPCOORD> prop2_coord1 = 0;
0166 ap_uint<BITSPROPCOORD> prop3_coord1 = 0;
0167 ap_uint<BITSPROPCOORD> prop1_coord2 = 0;
0168 ap_uint<BITSPROPCOORD> prop2_coord2 = 0;
0169 ap_uint<BITSPROPCOORD> prop3_coord2 = 0;
0170 ap_uint<BITSPROPSIGMACOORD_A> res0_coord1 = 0;
0171 ap_uint<BITSPROPSIGMACOORD_B> res1_coord1 = 0;
0172 ap_uint<BITSPROPSIGMACOORD_A> res0_coord2 = 0;
0173 ap_uint<BITSPROPSIGMACOORD_B> res1_coord2 = 0;
0174 ap_uint<BITSPROPSIGMAETA_A> res0_eta1 = 0;
0175 ap_uint<BITSPROPSIGMAETA_B> res1_eta = 0;
0176 ap_uint<BITSPROPSIGMAETA_A> res0_eta2 = 0;
0177 ap_uint<1> is_barrel = 0;
0178
0179
0180 ap_int<BITSPROP + 2> dphi_c1 = 0;
0181 ap_int<BITSPROP + 2> dphi_c2 = 0;
0182
0183 uint reducedAbsEta = track.abseta() / 8;
0184
0185
0186 assert(layer < 5);
0187 prop1_coord1 = lt_prop1_coord1[layer][reducedAbsEta];
0188 prop2_coord1 = lt_prop2_coord1[layer][reducedAbsEta];
0189 prop3_coord1 = lt_prop3_coord1[layer][reducedAbsEta];
0190 prop1_coord2 = lt_prop1_coord2[layer][reducedAbsEta];
0191 prop2_coord2 = lt_prop2_coord2[layer][reducedAbsEta];
0192 prop3_coord2 = lt_prop3_coord2[layer][reducedAbsEta];
0193
0194 res0_coord1 = lt_res0_coord1[layer][reducedAbsEta];
0195 res1_coord1 = lt_res1_coord1[layer][reducedAbsEta];
0196 res0_coord2 = lt_res0_coord2[layer][reducedAbsEta];
0197 res1_coord2 = lt_res1_coord2[layer][reducedAbsEta];
0198 res0_eta1 = lt_res0_eta1[layer][reducedAbsEta];
0199 res1_eta = lt_res1_eta1[layer][reducedAbsEta];
0200 res0_eta2 = lt_res0_eta2[layer][reducedAbsEta];
0201 is_barrel = reducedAbsEta < barrellimit[layer] ? 1 : 0;
0202
0203
0204
0205
0206
0207 propagation_t out;
0208 ap_int<BITSTTCURV> k = track.curvature();
0209 ap_int<BITSPHI> phi = track.phi();
0210
0211 ap_uint<BITSTTCURV - 1> absK = 0;
0212 ap_uint<1> negativeCurv = 0;
0213 if (k < 0) {
0214 absK = ap_uint<BITSTTCURV - 1>(-k);
0215 negativeCurv = 1;
0216 } else {
0217 absK = ap_uint<BITSTTCURV - 1>(k);
0218 }
0219
0220 ap_uint<2 * BITSTTCURV - 2> k2All = k * k;
0221 ap_uint<BITSTTCURV2> k2 = k2All / 2;
0222
0223
0224
0225 ap_uint<BITSPROPCOORD + BITSTTCURV - 1> dphi_c1Full = prop1_coord1 * absK;
0226 dphi_c1 = dphi_c1Full >> BITSHIFTPROP1C1;
0227
0228 if (absK <= (1 << BITSHIFTCURVSCALEC1)) {
0229 ap_uint<BITSPROPCOORD + 2 * BITSTTCURV - 2> dphi2_c1Full = prop2_coord1 * k2;
0230 dphi_c1 += (dphi2_c1Full >> (BITSHIFTPROP2C1 - 1));
0231 } else {
0232 ap_uint<BITSPROPCOORD + 2 * BITSTTCURV - 2 + BITSHIFTCURVSCALEC1 + 1> dphi2A_c1Full = prop2_coord1 * absK;
0233 dphi_c1 += ((dphi2A_c1Full << (BITSHIFTCURVSCALEC1 + 1)) >> BITSHIFTPROP2C1);
0234 ap_uint<BITSPROPCOORD + 2 * BITSHIFTCURVSCALEC1> dphi2B_c1Full = prop2_coord1;
0235 dphi_c1 -= (dphi2B_c1Full << (2 * BITSHIFTCURVSCALEC1)) >> BITSHIFTPROP2C1;
0236
0237 ap_uint<BITSTTCURV2 + 1> k2pad = k2;
0238 ap_uint<BITSTTCURV - 1 + BITSHIFTCURVSCALEC1 + 1> absKpad = absK;
0239 ap_uint<BITSPROPCOORD + 2 * BITSTTCURV - 2> dphi3_c1Full =
0240 (k2pad << 1) + (1 << (2 * BITSHIFTCURVSCALEC1)) - (absKpad << (BITSHIFTCURVSCALEC1 + 1));
0241 dphi3_c1Full *= prop3_coord1;
0242 dphi_c1 += (dphi3_c1Full >> BITSHIFTPROP3C1);
0243 }
0244
0245 if (dphi_c1 > PROPMAX)
0246 dphi_c1 = PROPMAX;
0247
0248
0249 if (negativeCurv == 0)
0250 dphi_c1 = -dphi_c1;
0251
0252 out.coord1 = ((phi + dphi_c1) >> PHISHIFT);
0253
0254
0255
0256 ap_uint<BITSPROPCOORD + BITSTTCURV - 1> dphi_c2Full = prop1_coord2 * absK;
0257 dphi_c2 = dphi_c2Full >> BITSHIFTPROP1C2;
0258
0259 if (absK <= ((1 << (BITSHIFTCURVSCALEC2LEADS[layer])) - (1 << (BITSHIFTCURVSCALEC2CORRS[layer])))) {
0260 ap_uint<BITSPROPCOORD + 2 * BITSTTCURV - 2> dphi2_c2Full = prop2_coord2 * k2;
0261 dphi_c2 += (dphi2_c2Full >> (BITSHIFTPROP2C2 - 1));
0262 } else {
0263 ap_uint<BITSTTCURV2 + 1> k2pad = k2;
0264 ap_uint<BITSTTCURV - 1 + BITSTTCURV> absKpad = absK;
0265
0266 ap_uint<BITSPROPCOORD + 2 * BITSTTCURV - 2> dphi2_c2Full =
0267 (absKpad << (BITSHIFTCURVSCALEC2LEADS[layer] + 1)) - (1 << (2 * BITSHIFTCURVSCALEC2LEADS[layer]));
0268 if (BITSHIFTCURVSCALEC2CORRS[layer] != 0) {
0269 dphi2_c2Full += (1 << (BITSHIFTCURVSCALEC2LEADS[layer] + BITSHIFTCURVSCALEC2CORRS[layer] + 1));
0270 dphi2_c2Full -=
0271 ((absKpad << (BITSHIFTCURVSCALEC2CORRS[layer] + 1)) + (1 << (2 * BITSHIFTCURVSCALEC2CORRS[layer])));
0272 }
0273 dphi_c2 += (dphi2_c2Full >> BITSHIFTPROP2C2);
0274
0275 ap_uint<BITSPROPCOORD + 2 * BITSTTCURV - 2> dphi3_c2Full = (k2pad << 1) +
0276 (1 << (2 * BITSHIFTCURVSCALEC2LEADS[layer])) -
0277 (absKpad << (BITSHIFTCURVSCALEC2LEADS[layer] + 1));
0278 if (BITSHIFTCURVSCALEC2CORRS[layer] != 0) {
0279 dphi3_c2Full +=
0280 ((1 << (2 * BITSHIFTCURVSCALEC2CORRS[layer])) + (absKpad << (BITSHIFTCURVSCALEC2CORRS[layer] + 1)));
0281 dphi3_c2Full -= (1 << (BITSHIFTCURVSCALEC2LEADS[layer] + BITSHIFTCURVSCALEC2CORRS[layer] + 1));
0282 }
0283 dphi3_c2Full *= prop3_coord2;
0284 if (layer == 0 or layer == 4) {
0285 dphi_c2 += (dphi3_c2Full >> BITSHIFTPROP3C2);
0286 } else {
0287 dphi_c2 -= (dphi3_c2Full >> BITSHIFTPROP3C2);
0288 }
0289 }
0290
0291 if (dphi_c2 > PROPMAX)
0292 dphi_c2 = PROPMAX;
0293 else if (dphi_c2 < -PROPMAX)
0294 dphi_c2 = -PROPMAX;
0295
0296
0297 if (negativeCurv == 0)
0298 dphi_c2 = -dphi_c2;
0299
0300 if (is_barrel)
0301 out.coord2 = (dphi_c2 >> PHISHIFT);
0302 else
0303 out.coord2 = ((phi + dphi_c2) >> PHISHIFT);
0304
0305 ap_uint<BITSPROPSIGMACOORD_B + BITSTTCURV - 1> s1kFull = res1_coord1 * absK;
0306 ap_uint<BITSPROPSIGMACOORD_B + BITSTTCURV - 1 - BITSHIFTRES1> s1k = res0_coord1 + (s1kFull >> BITSHIFTRES1);
0307 s1k = s1k >> PHISHIFT;
0308 if (s1k >= SIGMAMAX)
0309 out.sigma_coord1 = SIGMAMAX;
0310 else if (s1k < SIGMAMIN)
0311 out.sigma_coord1 = SIGMAMIN;
0312 else
0313 out.sigma_coord1 = s1k;
0314
0315 ap_uint<BITSPROPSIGMACOORD_B + BITSTTCURV - 1> s2kFull = res1_coord2 * absK;
0316 ap_uint<BITSPROPSIGMACOORD_B + BITSTTCURV - 1 - BITSHIFTRES1> s2k = res0_coord2 + (s2kFull >> BITSHIFTRES1);
0317 s2k = s2k >> PHISHIFT;
0318 if (s2k >= SIGMAMAX)
0319 out.sigma_coord2 = SIGMAMAX;
0320 else if (s2k < SIGMAMIN)
0321 out.sigma_coord2 = SIGMAMIN;
0322 else
0323 out.sigma_coord2 = s2k;
0324
0325 ap_int<BITSETA> eta = track.eta();
0326 out.eta = eta / ETADIVIDER;
0327
0328
0329 ap_uint<BITSPROPSIGMAETA_B + BITSTTCURV2> resetak = (res1_eta * k2) >> 23;
0330 ap_ufixed<BITSSIGMAETA, BITSSIGMAETA, AP_TRN_ZERO, AP_SAT_SYM> sigma_eta1 = res0_eta1 + resetak;
0331 out.sigma_eta1 = ap_uint<BITSSIGMAETA>(sigma_eta1);
0332 ap_ufixed<BITSSIGMAETA, BITSSIGMAETA, AP_TRN_ZERO, AP_SAT_SYM> sigma_eta2 = res0_eta2 + resetak;
0333 out.sigma_eta2 = ap_uint<BITSSIGMAETA>(sigma_eta2);
0334
0335 out.valid = 1;
0336 out.is_barrel = is_barrel;
0337
0338 if (verbose_ == 1) {
0339 edm::LogInfo("TPSAlgo") << "Propagating to layer " << int(layer) << ":is barrel=" << out.is_barrel.to_int()
0340 << " coords=" << out.coord1.to_int() << "+-" << out.sigma_coord1.to_int() << " , "
0341 << out.coord2.to_int() << " +-" << out.sigma_coord2.to_int()
0342 << " etas = " << out.eta.to_int() << " +- " << out.sigma_eta1.to_int() << " +-"
0343 << out.sigma_eta2.to_int();
0344
0345 edm::LogInfo("TPSAlgo") << "----- breakout of sigma 1 : constant=" << res0_coord1.to_int()
0346 << " slope=" << res1_coord1.to_int() << " before division=" << s1k.to_int();
0347
0348 edm::LogInfo("TPSAlgo") << "----- breakout of sigma 2 : constant=" << res0_coord2.to_int()
0349 << " slope=" << res1_coord2.to_int() << " before division=" << s2k.to_int();
0350 }
0351 return out;
0352 }
0353
0354 ap_uint<BITSSIGMAETA + 1> TPSAlgorithm::deltaEta(const ap_int<BITSSTUBETA>& eta1,
0355 const ap_int<BITSSTUBETA>& eta2) const {
0356 ap_fixed<BITSSIGMAETA + 2, BITSSIGMAETA + 2, AP_TRN_ZERO, AP_SAT_SYM> dEta = eta1 - eta2;
0357 if (dEta < 0)
0358 return ap_uint<BITSSIGMAETA + 1>(-dEta);
0359 else
0360 return ap_uint<BITSSIGMAETA + 1>(dEta);
0361 }
0362
0363 ap_uint<BITSSIGMACOORD + 1> TPSAlgorithm::deltaCoord(const ap_int<BITSSTUBCOORD>& phi1,
0364 const ap_int<BITSSTUBCOORD>& phi2) const {
0365 ap_int<BITSSTUBCOORD> dPhiRoll = phi1 - phi2;
0366 ap_ufixed<BITSSIGMACOORD + 1, BITSSIGMACOORD + 1, AP_TRN_ZERO, AP_SAT_SYM> dPhi;
0367 if (dPhiRoll < 0)
0368 dPhi = ap_ufixed<BITSSIGMACOORD + 1, BITSSIGMACOORD + 1, AP_TRN_ZERO, AP_SAT_SYM>(-dPhiRoll);
0369 else
0370 dPhi = ap_ufixed<BITSSIGMACOORD + 1, BITSSIGMACOORD + 1, AP_TRN_ZERO, AP_SAT_SYM>(dPhiRoll);
0371
0372 return ap_uint<BITSSIGMACOORD + 1>(dPhi);
0373 }
0374
0375 match_t TPSAlgorithm::match(const propagation_t prop, const l1t::MuonStubRef& stub, uint trackID) const {
0376 if (verbose_ == 1) {
0377 edm::LogInfo("TPSAlgo") << "Matching to coord1=" << stub->coord1() << " coord2=" << stub->coord2()
0378 << " eta1=" << stub->eta1() << " eta2=" << stub->eta2();
0379
0380 stub->print();
0381 }
0382
0383 ap_uint<1> coord1Matched;
0384 ap_uint<BITSSIGMACOORD + 1> deltaCoord1 = deltaCoord(prop.coord1, stub->coord1());
0385 if (deltaCoord1 <= prop.sigma_coord1 && (stub->quality() & 0x1)) {
0386 coord1Matched = 1;
0387 } else {
0388 coord1Matched = 0;
0389 }
0390 if (verbose_ == 1)
0391 edm::LogInfo("TPSAlgo") << "Coord1 matched=" << coord1Matched.to_int() << " delta=" << deltaCoord1.to_int()
0392 << " res=" << prop.sigma_coord1.to_int();
0393
0394
0395 ap_uint<1> coord2Matched;
0396 ap_uint<BITSSIGMACOORD + 1> deltaCoord2 = deltaCoord(prop.coord2, stub->coord2());
0397 if (deltaCoord2 <= prop.sigma_coord2 && (stub->quality() & 0x2)) {
0398 coord2Matched = 1;
0399 } else {
0400 coord2Matched = 0;
0401 }
0402 if (verbose_ == 1)
0403 edm::LogInfo("TPSAlgo") << "Coord2 matched=" << coord2Matched.to_int() << " delta=" << deltaCoord2.to_int()
0404 << " res=" << prop.sigma_coord2.to_int();
0405
0406
0407
0408 ap_uint<1> eta1Matched;
0409
0410
0411
0412 ap_ufixed<BITSSIGMAETA, BITSSIGMAETA, AP_TRN_ZERO, AP_SAT_SYM> prop_sigma_eta1;
0413 if (stub->etaQuality() == 0)
0414 prop_sigma_eta1 = prop.sigma_eta1 + 6;
0415 else
0416 prop_sigma_eta1 = prop.sigma_eta1;
0417
0418 ap_uint<BITSSIGMAETA + 1> deltaEta1 = deltaEta(prop.eta, stub->eta1());
0419 if (deltaEta1 <= prop_sigma_eta1 && (stub->etaQuality() == 0 || (stub->etaQuality() & 0x1)))
0420 eta1Matched = 1;
0421 else
0422 eta1Matched = 0;
0423
0424 if (verbose_ == 1)
0425 edm::LogInfo("TPSAlgo") << "eta1 matched=" << eta1Matched.to_int() << " delta=" << deltaEta1.to_int()
0426 << " res=" << prop_sigma_eta1.to_int();
0427
0428
0429
0430 ap_uint<1> eta2Matched;
0431
0432 ap_uint<BITSSIGMAETA + 1> deltaEta2 = deltaEta(prop.eta, stub->eta2());
0433 if (deltaEta2 <= prop.sigma_eta2 && (stub->etaQuality() & 0x2))
0434 eta2Matched = 1;
0435 else
0436 eta2Matched = 0;
0437 match_t out;
0438 out.id = trackID;
0439
0440 if (verbose_ == 1)
0441 edm::LogInfo("TPSAlgo") << "eta2 matched=" << eta2Matched.to_int() << " delta=" << deltaEta2.to_int()
0442 << " res=" << prop.sigma_eta2.to_int();
0443
0444
0445
0446
0447 if (prop.is_barrel) {
0448 out.valid = (coord1Matched == 1 && (eta1Matched == 1 || eta2Matched == 1)) ? 1 : 0;
0449 if (out.valid == 0) {
0450 out.quality = 0;
0451 } else {
0452 out.quality = 32 - deltaCoord1 / 4;
0453 if (coord2Matched == 1) {
0454 out.quality += 32 - deltaCoord2 / 4;
0455 out.valid = 3;
0456 }
0457 }
0458 }
0459
0460 else {
0461 bool match1 = (coord1Matched == 1 && eta1Matched == 1);
0462 bool match2 = (coord2Matched == 1 && eta2Matched == 1);
0463 bool match3 =
0464 (coord1Matched == 1 && (eta1Matched || eta2Matched) && stub->etaQuality() == 3 && stub->quality() == 1);
0465 out.valid = (match1 || match2 || match3) ? 1 : 0;
0466 if (out.valid == 0)
0467 out.quality = 0;
0468 else {
0469 out.quality = 0;
0470 if (match1 || match3)
0471 out.quality += 32 - deltaCoord1 / 4;
0472 if (match2) {
0473 out.quality += 32 - deltaCoord2 / 4;
0474 if (match1 || match3)
0475 out.valid = 3;
0476 }
0477 }
0478 }
0479 if (verbose_ == 1)
0480 edm::LogInfo("TPSAlgo") << "GlobalMatchQuality = " << out.quality.to_int();
0481 out.stubRef = stub;
0482 return out;
0483 }
0484
0485 match_t TPSAlgorithm::propagateAndMatch(const ConvertedTTTrack& track,
0486 const l1t::MuonStubRef& stub,
0487 uint trackID) const {
0488 propagation_t prop = propagate(track, stub->tfLayer());
0489 return match(prop, stub, trackID);
0490 }
0491
0492 match_t TPSAlgorithm::getBest(const std::vector<match_t>& matches) const {
0493 match_t best = matches[0];
0494 for (const auto& m : matches) {
0495 if (m.quality > best.quality)
0496 best = m;
0497 }
0498
0499 return best;
0500 }
0501
0502 void TPSAlgorithm::matchingInfos(const std::vector<match_t>& matchInfo,
0503 PreTrackMatchedMuon& muon,
0504 ap_uint<BITSMATCHQUALITY>& quality) const {
0505 if (!matchInfo.empty()) {
0506 match_t b = getBest(matchInfo);
0507 if (b.valid != 0) {
0508 muon.addStub(b.stubRef, b.valid);
0509 if (b.isGlobal)
0510 muon.addMuonRef(b.muRef);
0511 quality += b.quality;
0512 }
0513 }
0514 }
0515
0516 PreTrackMatchedMuon TPSAlgorithm::processTrack(const ConvertedTTTrack& track,
0517 const l1t::MuonStubRefVector& stubs) const {
0518 std::array<std::vector<match_t>, 6> matchInfos;
0519
0520 if (verbose_ == 1 && !stubs.empty()) {
0521 edm::LogInfo("TPSAlgo") << "-----------processing new track----------";
0522 track.print();
0523 }
0524 for (const auto& stub : stubs) {
0525 match_t m = propagateAndMatch(track, stub, 0);
0526 if (m.valid != 0 && stub->tfLayer() < 6) {
0527 matchInfos[stub->tfLayer()].push_back(m);
0528 }
0529 }
0530
0531 ap_ufixed<6, 6, AP_TRN_ZERO, AP_SAT_SYM> ptPenalty = ap_ufixed<6, 6, AP_TRN_ZERO, AP_SAT_SYM>(track.pt() / 32);
0532
0533 ap_uint<BITSMATCHQUALITY> quality = 0;
0534 PreTrackMatchedMuon muon(track.charge(), track.pt(), track.eta(), track.phi(), track.z0(), track.d0());
0535
0536 for (auto&& m : matchInfos)
0537 matchingInfos(m, muon, quality);
0538
0539 muon.setOfflineQuantities(track.offline_pt(), track.offline_eta(), track.offline_phi());
0540 muon.setTrkPtr(track.trkPtr());
0541
0542 ap_uint<8> etaAddr = muon.eta() < 0 ? ap_uint<8>(-muon.eta() / 256) : ap_uint<8>((muon.eta()) / 256);
0543 ap_uint<8> ptAddr = muon.pt() > 4095 ? ap_uint<8>(15) : ap_uint<8>(muon.pt() / 256);
0544 ap_uint<8> addr = ptAddr | (etaAddr << 4);
0545 ap_uint<8> qualityCut = lt_tpsID[addr];
0546
0547 if (!muon.stubs().empty()) {
0548 muon.setValid(true);
0549 muon.setQuality(quality + ptPenalty);
0550 } else {
0551 muon.setValid(false);
0552 muon.setQuality(0);
0553 muon.resetGlobal();
0554 }
0555 if (verbose_ == 1)
0556 muon.print();
0557
0558 if (verbose_ == 1 && !stubs.empty()) {
0559
0560 edm::LogInfo("TPSAlgo") << "TPS " << track.trkPtr()->phiSector() << std::flush;
0561 track.printWord();
0562
0563 for (uint i = 0; i < 16; ++i) {
0564 if (stubs.size() > i) {
0565 edm::LogInfo("TPSAlgo") << "remember to implement printout of muon";
0566 } else {
0567 edm::LogInfo("TPSAlgo") << std::hex << std::setw(8) << 0 << std::flush;
0568 edm::LogInfo("TPSAlgo") << std::hex << std::setw(16) << 0x1ff000000000000 << std::flush;
0569 edm::LogInfo("TPSAlgo") << std::hex << std::setw(16) << 0x1ff000000000000 << std::flush;
0570 edm::LogInfo("TPSAlgo") << std::hex << std::setw(16) << 0x1ff000000000000 << std::flush;
0571 edm::LogInfo("TPSAlgo") << std::hex << std::setw(16) << 0x1ff000000000000 << std::flush;
0572 edm::LogInfo("TPSAlgo") << std::hex << std::setw(16) << 0x1ff000000000000 << std::flush;
0573 }
0574 }
0575 muon.printWord();
0576 edm::LogInfo("TPSAlgo") << std::endl;
0577 }
0578
0579 return muon;
0580 }
0581
0582 ap_uint<5> TPSAlgorithm::cleanMuon(const PreTrackMatchedMuon& mu, const PreTrackMatchedMuon& other, bool eq) const {
0583 ap_uint<5> valid = 0;
0584 ap_uint<5> overlap = 0;
0585 constexpr int bittest = 0xfff;
0586 if (mu.stubID0() != bittest) {
0587 valid = valid | 0x1;
0588 if (mu.stubID0() == other.stubID0())
0589 overlap = overlap | 0x1;
0590 }
0591 if (mu.stubID1() != bittest) {
0592 valid = valid | 0x2;
0593 if (mu.stubID1() == other.stubID1())
0594 overlap = overlap | 0x2;
0595 }
0596 if (mu.stubID2() != bittest) {
0597 valid = valid | 0x4;
0598 if (mu.stubID2() == other.stubID2())
0599 overlap = overlap | 0x4;
0600 }
0601 if (mu.stubID3() != bittest) {
0602 valid = valid | 0x8;
0603 if (mu.stubID3() == other.stubID3())
0604 overlap = overlap | 0x8;
0605 }
0606 if (mu.stubID4() != bittest) {
0607 valid = valid | 0x10;
0608 if (mu.stubID4() == other.stubID4())
0609 overlap = overlap | 0x10;
0610 }
0611
0612 if (((mu.quality() < other.quality()) && (!eq)) || ((mu.quality() <= other.quality()) && (eq)))
0613 return valid & (~overlap);
0614 else
0615 return valid;
0616 }
0617
0618 std::vector<PreTrackMatchedMuon> TPSAlgorithm::clean(const std::vector<PreTrackMatchedMuon>& muons) const {
0619 std::vector<PreTrackMatchedMuon> out;
0620 if (muons.empty())
0621 return out;
0622 if (verbose_ == 1) {
0623 edm::LogInfo("TPSAlgo") << "-----Cleaning Up Muons in the same Nonant";
0624 edm::LogInfo("TPSAlgo") << "Before:";
0625 }
0626 for (uint i = 0; i < muons.size(); ++i) {
0627 if (verbose_ == 1)
0628 muons[i].print();
0629
0630 ap_uint<5> mask = 0x1f;
0631 for (uint j = 0; j < muons.size(); ++j) {
0632 if (i == j)
0633 continue;
0634 mask = mask & cleanMuon(muons[i], muons[j], false);
0635 }
0636 if (mask) {
0637 if (verbose_ == 1)
0638 edm::LogInfo("TPSAlgo") << "kept";
0639 out.push_back(muons[i]);
0640 } else {
0641 if (verbose_ == 1)
0642 edm::LogInfo("TPSAlgo") << "discarded";
0643 }
0644 }
0645 return out;
0646 }