File indexing completed on 2024-04-06 12:20:48
0001 #include "L1Trigger/L1TMuon/interface/MicroGMTCancelOutUnit.h"
0002 #include "L1Trigger/L1TMuon/interface/GMTInternalMuon.h"
0003 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0004
0005 namespace l1t {
0006 MicroGMTCancelOutUnit::MicroGMTCancelOutUnit() {}
0007
0008 MicroGMTCancelOutUnit::~MicroGMTCancelOutUnit() {}
0009
0010 void MicroGMTCancelOutUnit::initialise(L1TMuonGlobalParamsHelper* microGMTParamsHelper) {
0011 int fwVersion = microGMTParamsHelper->fwVersion();
0012 m_boPosMatchQualLUT = l1t::MicroGMTMatchQualLUTFactory::create(
0013 microGMTParamsHelper->bOPosMatchQualLUT(), cancel_t::omtf_bmtf_pos, fwVersion);
0014 m_boNegMatchQualLUT = l1t::MicroGMTMatchQualLUTFactory::create(
0015 microGMTParamsHelper->bONegMatchQualLUT(), cancel_t::omtf_bmtf_neg, fwVersion);
0016 m_foPosMatchQualLUT = l1t::MicroGMTMatchQualLUTFactory::create(
0017 microGMTParamsHelper->fOPosMatchQualLUT(), cancel_t::omtf_emtf_pos, fwVersion);
0018 m_foNegMatchQualLUT = l1t::MicroGMTMatchQualLUTFactory::create(
0019 microGMTParamsHelper->fONegMatchQualLUT(), cancel_t::omtf_emtf_neg, fwVersion);
0020 m_ovlPosSingleMatchQualLUT = l1t::MicroGMTMatchQualLUTFactory::create(
0021 microGMTParamsHelper->ovlPosSingleMatchQualLUT(), cancel_t::omtf_omtf_pos, fwVersion);
0022 m_ovlNegSingleMatchQualLUT = l1t::MicroGMTMatchQualLUTFactory::create(
0023 microGMTParamsHelper->ovlNegSingleMatchQualLUT(), cancel_t::omtf_omtf_neg, fwVersion);
0024 m_fwdPosSingleMatchQualLUT = l1t::MicroGMTMatchQualLUTFactory::create(
0025 microGMTParamsHelper->fwdPosSingleMatchQualLUT(), cancel_t::emtf_emtf_pos, fwVersion);
0026 m_fwdNegSingleMatchQualLUT = l1t::MicroGMTMatchQualLUTFactory::create(
0027 microGMTParamsHelper->fwdNegSingleMatchQualLUT(), cancel_t::emtf_emtf_neg, fwVersion);
0028
0029 m_lutDict[tftype::omtf_neg + tftype::bmtf * 10] = m_boNegMatchQualLUT;
0030 m_lutDict[tftype::omtf_pos + tftype::bmtf * 10] = m_boPosMatchQualLUT;
0031 m_lutDict[tftype::omtf_pos + tftype::omtf_pos * 10] = m_ovlPosSingleMatchQualLUT;
0032 m_lutDict[tftype::omtf_neg + tftype::omtf_neg * 10] = m_ovlNegSingleMatchQualLUT;
0033 m_lutDict[tftype::emtf_pos + tftype::emtf_pos * 10] = m_fwdPosSingleMatchQualLUT;
0034 m_lutDict[tftype::emtf_neg + tftype::emtf_neg * 10] = m_fwdNegSingleMatchQualLUT;
0035 m_lutDict[tftype::omtf_pos + tftype::emtf_pos * 10] = m_foPosMatchQualLUT;
0036 m_lutDict[tftype::omtf_neg + tftype::emtf_neg * 10] = m_foNegMatchQualLUT;
0037 }
0038
0039 void MicroGMTCancelOutUnit::setCancelOutBits(GMTInternalWedges& wedges, tftype trackFinder, cancelmode mode) {
0040 std::vector<std::shared_ptr<GMTInternalMuon>> coll1;
0041 coll1.reserve(3);
0042 std::vector<std::shared_ptr<GMTInternalMuon>> coll2;
0043 coll2.reserve(3);
0044 int maxWedges = 6;
0045 if (trackFinder == bmtf) {
0046 maxWedges = 12;
0047 }
0048 for (int currentWedge = 0; currentWedge < maxWedges; ++currentWedge) {
0049 for (const auto& mu : wedges.at(currentWedge)) {
0050 coll1.push_back(mu);
0051 }
0052
0053 int neighbourWedge = (currentWedge + 1) % maxWedges;
0054 for (const auto& mu : wedges.at(neighbourWedge)) {
0055 coll2.push_back(mu);
0056 }
0057 if (mode == cancelmode::coordinate) {
0058 getCoordinateCancelBits(coll2, coll1);
0059 } else {
0060 getTrackAddrCancelBits(mode, coll1, coll2);
0061 }
0062
0063 coll1.clear();
0064 coll2.clear();
0065 }
0066 }
0067
0068 void MicroGMTCancelOutUnit::setCancelOutBitsOverlapBarrel(GMTInternalWedges& omtfSectors,
0069 GMTInternalWedges& bmtfWedges,
0070 cancelmode mode) {
0071
0072 std::vector<std::shared_ptr<GMTInternalMuon>> coll1;
0073 coll1.reserve(3);
0074
0075 std::vector<std::shared_ptr<GMTInternalMuon>> coll2;
0076 coll2.reserve(12);
0077
0078 for (int currentSector = 0; currentSector < 6; ++currentSector) {
0079 for (const auto& omtfMuon : omtfSectors.at(currentSector)) {
0080 coll1.push_back(omtfMuon);
0081 }
0082
0083
0084
0085
0086 for (int i = 0; i < 4; ++i) {
0087 int currentWedge = (currentSector * 2 + i) % 12;
0088 for (const auto& bmtfMuon : bmtfWedges.at(currentWedge)) {
0089 coll2.push_back(bmtfMuon);
0090 }
0091 }
0092 if (mode == cancelmode::coordinate) {
0093 getCoordinateCancelBits(coll1, coll2);
0094 } else {
0095 getTrackAddrCancelBits(mode, coll1, coll2);
0096 }
0097 coll1.clear();
0098 coll2.clear();
0099 }
0100 }
0101
0102 void MicroGMTCancelOutUnit::setCancelOutBitsOverlapEndcap(GMTInternalWedges& omtfSectors,
0103 GMTInternalWedges& emtfSectors,
0104 cancelmode mode) {
0105
0106 std::vector<std::shared_ptr<GMTInternalMuon>> coll1;
0107 coll1.reserve(3);
0108
0109 std::vector<std::shared_ptr<GMTInternalMuon>> coll2;
0110 coll2.reserve(9);
0111
0112 for (int curOmtfSector = 0; curOmtfSector < 6; ++curOmtfSector) {
0113 for (const auto& omtfMuon : omtfSectors.at(curOmtfSector)) {
0114 coll1.push_back(omtfMuon);
0115 }
0116
0117
0118
0119
0120 for (int i = 0; i < 3; ++i) {
0121
0122 int curEmtfSector = ((curOmtfSector + 5) + i) % 6;
0123 for (const auto& emtfMuon : emtfSectors.at(curEmtfSector)) {
0124 coll2.push_back(emtfMuon);
0125 }
0126 }
0127 if (mode == cancelmode::coordinate) {
0128 getCoordinateCancelBits(coll1, coll2);
0129 } else {
0130 getTrackAddrCancelBits(mode, coll1, coll2);
0131 }
0132 coll1.clear();
0133 coll2.clear();
0134 }
0135 }
0136
0137 void MicroGMTCancelOutUnit::getCoordinateCancelBits(std::vector<std::shared_ptr<GMTInternalMuon>>& coll1,
0138 std::vector<std::shared_ptr<GMTInternalMuon>>& coll2) {
0139 if (coll1.empty() || coll2.empty()) {
0140 return;
0141 }
0142 tftype coll1TfType = (*coll1.begin())->trackFinderType();
0143 tftype coll2TfType = (*coll2.begin())->trackFinderType();
0144 if (coll2TfType != tftype::bmtf && coll1TfType % 2 != coll2TfType % 2) {
0145 edm::LogError("Detector side mismatch")
0146 << "Overlap-Endcap cancel out between positive and negative detector side attempted. Check eta assignment. "
0147 "OMTF candidate: TF type: "
0148 << coll1TfType << ", hwEta: " << (*coll1.begin())->hwEta() << ". EMTF candidate: TF type: " << coll2TfType
0149 << ", hwEta: " << (*coll2.begin())->hwEta() << ". TF type even: pos. side; odd: neg. side." << std::endl;
0150 return;
0151 }
0152
0153 MicroGMTMatchQualLUT* matchLUT = m_lutDict.at(coll1TfType + coll2TfType * 10).get();
0154
0155 for (auto mu_w1 = coll1.begin(); mu_w1 != coll1.end(); ++mu_w1) {
0156 int etaFine1 = (*mu_w1)->hwHF();
0157
0158 if (coll1TfType == tftype::emtf_pos || coll1TfType == tftype::emtf_neg) {
0159 etaFine1 = 1;
0160 }
0161 for (auto mu_w2 = coll2.begin(); mu_w2 != coll2.end(); ++mu_w2) {
0162 int etaFine2 = (*mu_w2)->hwHF();
0163
0164 if (coll2TfType == tftype::emtf_pos || coll2TfType == tftype::emtf_neg) {
0165 etaFine2 = 1;
0166 }
0167
0168 int etaFine = (int)(etaFine1 > 0 && etaFine2 > 0);
0169
0170
0171 int dPhiMask = (1 << matchLUT->getDeltaPhiWidth()) - 1;
0172 int dEtaMask = (1 << matchLUT->getDeltaEtaWidth()) - 1;
0173
0174 int dPhi = (*mu_w1)->hwGlobalPhi() - (*mu_w2)->hwGlobalPhi();
0175 dPhi = std::abs(dPhi);
0176 if (dPhi > 338)
0177 dPhi -= 576;
0178 dPhi = std::abs(dPhi);
0179 int dEta = std::abs((*mu_w1)->hwEta() - (*mu_w2)->hwEta());
0180
0181
0182
0183 if (dEta <= dEtaMask && dPhi <= dPhiMask) {
0184 int match = matchLUT->lookup(etaFine, dEta & dEtaMask, dPhi & dPhiMask);
0185 if (match == 1) {
0186 if ((*mu_w1)->hwQual() > (*mu_w2)->hwQual()) {
0187 (*mu_w2)->setHwCancelBit(1);
0188 } else {
0189 (*mu_w1)->setHwCancelBit(1);
0190 }
0191 }
0192 }
0193 }
0194 }
0195 }
0196
0197 void MicroGMTCancelOutUnit::getTrackAddrCancelBits(cancelmode mode,
0198 std::vector<std::shared_ptr<GMTInternalMuon>>& coll1,
0199 std::vector<std::shared_ptr<GMTInternalMuon>>& coll2) {
0200 if (coll1.empty() || coll2.empty()) {
0201 return;
0202 }
0203
0204 if ((*coll1.begin())->trackFinderType() == tftype::bmtf && (*coll2.begin())->trackFinderType() == tftype::bmtf) {
0205 if (mode == cancelmode::tracks) {
0206 getTrackAddrCancelBitsOrigBMTF(coll1, coll2);
0207 } else if (mode == cancelmode::kftracks) {
0208 getTrackAddrCancelBitsKfBMTF(coll1, coll2);
0209 }
0210
0211 } else if (((*coll1.begin())->trackFinderType() == tftype::emtf_pos &&
0212 (*coll2.begin())->trackFinderType() == tftype::emtf_pos) ||
0213 ((*coll1.begin())->trackFinderType() == tftype::emtf_neg &&
0214 (*coll2.begin())->trackFinderType() == tftype::emtf_neg)) {
0215 for (auto mu_s1 = coll1.begin(); mu_s1 != coll1.end(); ++mu_s1) {
0216 std::map<int, int> trkAddr_s1 = (*mu_s1)->origin().trackAddress();
0217 int me1_ch_s1 = trkAddr_s1[l1t::RegionalMuonCand::emtfAddress::kME1Ch];
0218 int me2_ch_s1 = trkAddr_s1[l1t::RegionalMuonCand::emtfAddress::kME2Ch];
0219 int me3_ch_s1 = trkAddr_s1[l1t::RegionalMuonCand::emtfAddress::kME3Ch];
0220 int me4_ch_s1 = trkAddr_s1[l1t::RegionalMuonCand::emtfAddress::kME4Ch];
0221 if (me1_ch_s1 + me2_ch_s1 + me3_ch_s1 + me4_ch_s1 == 0) {
0222 continue;
0223 }
0224 int me1_seg_s1 = trkAddr_s1[l1t::RegionalMuonCand::emtfAddress::kME1Seg];
0225 int me2_seg_s1 = trkAddr_s1[l1t::RegionalMuonCand::emtfAddress::kME2Seg];
0226 int me3_seg_s1 = trkAddr_s1[l1t::RegionalMuonCand::emtfAddress::kME3Seg];
0227 int me4_seg_s1 = trkAddr_s1[l1t::RegionalMuonCand::emtfAddress::kME4Seg];
0228 for (auto mu_s2 = coll2.begin(); mu_s2 != coll2.end(); ++mu_s2) {
0229 std::map<int, int> trkAddr_s2 = (*mu_s2)->origin().trackAddress();
0230 int me1_ch_s2 = trkAddr_s2[l1t::RegionalMuonCand::emtfAddress::kME1Ch];
0231 int me2_ch_s2 = trkAddr_s2[l1t::RegionalMuonCand::emtfAddress::kME2Ch];
0232 int me3_ch_s2 = trkAddr_s2[l1t::RegionalMuonCand::emtfAddress::kME3Ch];
0233 int me4_ch_s2 = trkAddr_s2[l1t::RegionalMuonCand::emtfAddress::kME4Ch];
0234 if (me1_ch_s2 + me2_ch_s2 + me3_ch_s2 + me4_ch_s2 == 0) {
0235 continue;
0236 }
0237 int me1_seg_s2 = trkAddr_s2[l1t::RegionalMuonCand::emtfAddress::kME1Seg];
0238 int me2_seg_s2 = trkAddr_s2[l1t::RegionalMuonCand::emtfAddress::kME2Seg];
0239 int me3_seg_s2 = trkAddr_s2[l1t::RegionalMuonCand::emtfAddress::kME3Seg];
0240 int me4_seg_s2 = trkAddr_s2[l1t::RegionalMuonCand::emtfAddress::kME4Seg];
0241
0242 int nMatchedStations = 0;
0243 if (me1_ch_s2 != 0 && me1_ch_s1 == me1_ch_s2 + 3 && me1_seg_s1 == me1_seg_s2) {
0244 ++nMatchedStations;
0245 }
0246 if (me2_ch_s2 != 0 && me2_ch_s1 == me2_ch_s2 + 2 && me2_seg_s1 == me2_seg_s2) {
0247 ++nMatchedStations;
0248 }
0249 if (me3_ch_s2 != 0 && me3_ch_s1 == me3_ch_s2 + 2 && me3_seg_s1 == me3_seg_s2) {
0250 ++nMatchedStations;
0251 }
0252 if (me4_ch_s2 != 0 && me4_ch_s1 == me4_ch_s2 + 2 && me4_seg_s1 == me4_seg_s2) {
0253 ++nMatchedStations;
0254 }
0255
0256
0257 if (nMatchedStations > 0) {
0258 if ((*mu_s1)->origin().hwQual() >= (*mu_s2)->origin().hwQual()) {
0259 (*mu_s2)->setHwCancelBit(1);
0260 } else {
0261 (*mu_s1)->setHwCancelBit(1);
0262 }
0263 }
0264 }
0265 }
0266 } else {
0267 edm::LogError("Cancel out not implemented")
0268 << "Address based cancel out is currently only implemented for the barrel track finder.";
0269 }
0270 }
0271
0272 void MicroGMTCancelOutUnit::getTrackAddrCancelBitsOrigBMTF(std::vector<std::shared_ptr<GMTInternalMuon>>& coll1,
0273 std::vector<std::shared_ptr<GMTInternalMuon>>& coll2) {
0274 for (auto mu_w1 = coll1.begin(); mu_w1 != coll1.end(); ++mu_w1) {
0275 std::map<int, int> trkAddr_w1 = (*mu_w1)->origin().trackAddress();
0276 int wheelNum_w1 = trkAddr_w1[l1t::RegionalMuonCand::bmtfAddress::kWheelNum];
0277 int wheelSide_w1 = trkAddr_w1[l1t::RegionalMuonCand::bmtfAddress::kWheelSide];
0278 std::vector<int> stations_w1;
0279 stations_w1.push_back(trkAddr_w1[l1t::RegionalMuonCand::bmtfAddress::kStat1]);
0280 stations_w1.push_back(trkAddr_w1[l1t::RegionalMuonCand::bmtfAddress::kStat2]);
0281 stations_w1.push_back(trkAddr_w1[l1t::RegionalMuonCand::bmtfAddress::kStat3]);
0282 stations_w1.push_back(trkAddr_w1[l1t::RegionalMuonCand::bmtfAddress::kStat4]);
0283
0284
0285 for (auto mu_w2 = coll2.begin(); mu_w2 != coll2.end(); ++mu_w2) {
0286 std::map<int, int> trkAddr_w2 = (*mu_w2)->origin().trackAddress();
0287 int wheelNum_w2 = trkAddr_w2[l1t::RegionalMuonCand::bmtfAddress::kWheelNum];
0288 int wheelSide_w2 = trkAddr_w2[l1t::RegionalMuonCand::bmtfAddress::kWheelSide];
0289 std::vector<int> stations_w2;
0290 stations_w2.push_back(trkAddr_w2[l1t::RegionalMuonCand::bmtfAddress::kStat1]);
0291 stations_w2.push_back(trkAddr_w2[l1t::RegionalMuonCand::bmtfAddress::kStat2]);
0292 stations_w2.push_back(trkAddr_w2[l1t::RegionalMuonCand::bmtfAddress::kStat3]);
0293 stations_w2.push_back(trkAddr_w2[l1t::RegionalMuonCand::bmtfAddress::kStat4]);
0294
0295
0296 int nMatchedStations = 0;
0297
0298 for (int i = 1; i < 4; ++i) {
0299 if (wheelSide_w1 == wheelSide_w2) {
0300 if (wheelNum_w1 == wheelNum_w2) {
0301 if ((stations_w1[i] == 0x0 && stations_w2[i] == 0x2) ||
0302 (stations_w1[i] == 0x1 && stations_w2[i] == 0x3) ||
0303 (stations_w1[i] == 0x4 && stations_w2[i] == 0x0) ||
0304 (stations_w1[i] == 0x5 && stations_w2[i] == 0x1) ||
0305 (stations_w1[i] == 0x8 && stations_w2[i] == 0xA) ||
0306 (stations_w1[i] == 0x9 && stations_w2[i] == 0xB) ||
0307 (stations_w1[i] == 0xC && stations_w2[i] == 0x8) ||
0308 (stations_w1[i] == 0xD && stations_w2[i] == 0x9)) {
0309 ++nMatchedStations;
0310 }
0311 } else if (wheelNum_w1 == wheelNum_w2 - 1) {
0312 if ((stations_w1[i] == 0x0 && stations_w2[i] == 0xA) ||
0313 (stations_w1[i] == 0x1 && stations_w2[i] == 0xB) ||
0314 (stations_w1[i] == 0x4 && stations_w2[i] == 0x8) ||
0315 (stations_w1[i] == 0x5 && stations_w2[i] == 0x9)) {
0316 ++nMatchedStations;
0317 }
0318 } else if (wheelNum_w1 == wheelNum_w2 + 1) {
0319 if ((stations_w1[i] == 0x8 && stations_w2[i] == 0x2) ||
0320 (stations_w1[i] == 0x9 && stations_w2[i] == 0x3) ||
0321 (stations_w1[i] == 0xC && stations_w2[i] == 0x0) ||
0322 (stations_w1[i] == 0xD && stations_w2[i] == 0x1)) {
0323 ++nMatchedStations;
0324 }
0325 }
0326 } else {
0327 if (wheelNum_w1 == 0 &&
0328 wheelNum_w2 == 0) {
0329 if ((stations_w1[i] == 0x8 && stations_w2[i] == 0xA) ||
0330 (stations_w1[i] == 0x9 && stations_w2[i] == 0xB) ||
0331 (stations_w1[i] == 0xC && stations_w2[i] == 0x8) ||
0332 (stations_w1[i] == 0xD && stations_w2[i] == 0x9)) {
0333 ++nMatchedStations;
0334 }
0335 }
0336 }
0337 }
0338
0339 if (nMatchedStations > 0) {
0340 if ((*mu_w1)->origin().hwQual() >= (*mu_w2)->origin().hwQual()) {
0341 (*mu_w2)->setHwCancelBit(1);
0342 } else {
0343 (*mu_w1)->setHwCancelBit(1);
0344 }
0345 }
0346 }
0347 }
0348 }
0349
0350 void MicroGMTCancelOutUnit::getTrackAddrCancelBitsKfBMTF(std::vector<std::shared_ptr<GMTInternalMuon>>& coll1,
0351 std::vector<std::shared_ptr<GMTInternalMuon>>& coll2) {
0352 for (auto mu_w1 = coll1.begin(); mu_w1 != coll1.end(); ++mu_w1) {
0353 std::map<int, int> trkAddr_w1 = (*mu_w1)->origin().trackAddress();
0354 int wheelNum_w1 = trkAddr_w1[l1t::RegionalMuonCand::bmtfAddress::kWheelNum];
0355 int wheelSide_w1 = trkAddr_w1[l1t::RegionalMuonCand::bmtfAddress::kWheelSide];
0356 std::vector<int> stations_w1;
0357 stations_w1.push_back(trkAddr_w1[l1t::RegionalMuonCand::bmtfAddress::kStat1]);
0358 stations_w1.push_back(trkAddr_w1[l1t::RegionalMuonCand::bmtfAddress::kStat2]);
0359 stations_w1.push_back(trkAddr_w1[l1t::RegionalMuonCand::bmtfAddress::kStat3]);
0360 stations_w1.push_back(trkAddr_w1[l1t::RegionalMuonCand::bmtfAddress::kStat4]);
0361
0362
0363
0364 for (auto mu_w2 = coll2.begin(); mu_w2 != coll2.end(); ++mu_w2) {
0365 std::map<int, int> trkAddr_w2 = (*mu_w2)->origin().trackAddress();
0366 int wheelNum_w2 = trkAddr_w2[l1t::RegionalMuonCand::bmtfAddress::kWheelNum];
0367 int wheelSide_w2 = trkAddr_w2[l1t::RegionalMuonCand::bmtfAddress::kWheelSide];
0368 std::vector<int> stations_w2;
0369 stations_w2.push_back(trkAddr_w2[l1t::RegionalMuonCand::bmtfAddress::kStat1]);
0370 stations_w2.push_back(trkAddr_w2[l1t::RegionalMuonCand::bmtfAddress::kStat2]);
0371 stations_w2.push_back(trkAddr_w2[l1t::RegionalMuonCand::bmtfAddress::kStat3]);
0372 stations_w2.push_back(trkAddr_w2[l1t::RegionalMuonCand::bmtfAddress::kStat4]);
0373
0374
0375
0376 int nMatchedStations = 0;
0377
0378 for (int i = 0; i < 3; ++i) {
0379 if (wheelSide_w1 == wheelSide_w2) {
0380 if (wheelNum_w1 == wheelNum_w2) {
0381 if ((stations_w1[i] == 0x2 && stations_w2[i] == 0x0) ||
0382 (stations_w1[i] == 0x3 && stations_w2[i] == 0x1) ||
0383 (stations_w1[i] == 0x0 && stations_w2[i] == 0x4) ||
0384 (stations_w1[i] == 0x1 && stations_w2[i] == 0x5) ||
0385 (stations_w1[i] == 0xA && stations_w2[i] == 0x8) ||
0386 (stations_w1[i] == 0xB && stations_w2[i] == 0x9) ||
0387 (stations_w1[i] == 0x8 && stations_w2[i] == 0xC) ||
0388 (stations_w1[i] == 0x9 && stations_w2[i] == 0xD)) {
0389 ++nMatchedStations;
0390 }
0391 } else if (wheelNum_w1 == wheelNum_w2 - 1) {
0392 if ((stations_w1[i] == 0xA && stations_w2[i] == 0x0) ||
0393 (stations_w1[i] == 0xB && stations_w2[i] == 0x1) ||
0394 (stations_w1[i] == 0x8 && stations_w2[i] == 0x4) ||
0395 (stations_w1[i] == 0x9 && stations_w2[i] == 0x5)) {
0396 ++nMatchedStations;
0397 }
0398 } else if (wheelNum_w1 == wheelNum_w2 + 1) {
0399 if ((stations_w1[i] == 0x2 && stations_w2[i] == 0x8) ||
0400 (stations_w1[i] == 0x3 && stations_w2[i] == 0x9) ||
0401 (stations_w1[i] == 0x0 && stations_w2[i] == 0xC) ||
0402 (stations_w1[i] == 0x1 && stations_w2[i] == 0xD)) {
0403 ++nMatchedStations;
0404 }
0405 }
0406 } else {
0407 if (wheelNum_w1 == 0 && wheelNum_w2 == 1) {
0408 if ((stations_w1[i] == 0xA && stations_w2[i] == 0x0) ||
0409 (stations_w1[i] == 0xB && stations_w2[i] == 0x1) ||
0410 (stations_w1[i] == 0x8 && stations_w2[i] == 0x4) ||
0411 (stations_w1[i] == 0x9 && stations_w2[i] == 0x5)) {
0412 ++nMatchedStations;
0413 }
0414 } else if (wheelNum_w1 == 1 && wheelNum_w2 == 0) {
0415 if ((stations_w1[i] == 0x2 && stations_w2[i] == 0x8) ||
0416 (stations_w1[i] == 0x3 && stations_w2[i] == 0x9) ||
0417 (stations_w1[i] == 0x0 && stations_w2[i] == 0xC) ||
0418 (stations_w1[i] == 0x1 && stations_w2[i] == 0xD)) {
0419 ++nMatchedStations;
0420 }
0421 }
0422 }
0423 }
0424
0425 if (nMatchedStations > 0) {
0426 if ((*mu_w1)->origin().hwQual() >= (*mu_w2)->origin().hwQual()) {
0427 (*mu_w2)->setHwCancelBit(1);
0428 } else {
0429 (*mu_w1)->setHwCancelBit(1);
0430 }
0431 }
0432 }
0433 }
0434 }
0435
0436 }