Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-11-15 23:40:41

0001 //-------------------------------------------------
0002 //
0003 //   Class: L1MuBMMuonSorter
0004 //
0005 //   Description: BM Muon Sorter
0006 //
0007 //
0008 //
0009 //   Author :
0010 //   N. Neumeister            CERN EP
0011 //   J. Troconiz              UAM Madrid
0012 //
0013 //--------------------------------------------------
0014 
0015 //-----------------------
0016 // This Class's Header --
0017 //-----------------------
0018 
0019 #include "L1Trigger/L1TMuonBarrel/interface/L1MuBMMuonSorter.h"
0020 
0021 //---------------
0022 // C++ Headers --
0023 //---------------
0024 
0025 #include <iostream>
0026 #include <algorithm>
0027 
0028 //-------------------------------
0029 // Collaborating Class Headers --
0030 //-------------------------------
0031 
0032 #include "L1Trigger/L1TMuonBarrel/interface/L1MuBMTFConfig.h"
0033 #include "L1Trigger/L1TMuonBarrel/src/L1MuBMWedgeSorter.h"
0034 #include "L1Trigger/L1TMuonBarrel/interface/L1MuBMTrackFinder.h"
0035 
0036 #include "DataFormats/L1TMuon/interface/BMTF/L1MuBMSecProcId.h"
0037 #include "DataFormats/L1TMuon/interface/L1MuBMTrack.h"
0038 
0039 using namespace std;
0040 
0041 // --------------------------------
0042 //       class L1MuBMMuonSorter
0043 //---------------------------------
0044 
0045 //----------------
0046 // Constructors --
0047 //----------------
0048 
0049 L1MuBMMuonSorter::L1MuBMMuonSorter(const L1MuBMTrackFinder& tf) : m_tf(tf), m_TrackCands() { m_TrackCands.reserve(4); }
0050 
0051 //--------------
0052 // Destructor --
0053 //--------------
0054 
0055 L1MuBMMuonSorter::~L1MuBMMuonSorter() {}
0056 
0057 //--------------
0058 // Operations --
0059 //--------------
0060 
0061 //
0062 // run BM Muon Sorter
0063 //
0064 void L1MuBMMuonSorter::run() {
0065   // get track candidates from Wedge Sorters
0066   vector<L1MuBMTrack*> mycands;
0067   mycands.reserve(24);
0068 
0069   for (int wedge = 0; wedge < 12; wedge++) {
0070     vector<const L1MuBMTrack*> wscand = m_tf.ws(wedge)->tracks();
0071     vector<const L1MuBMTrack*>::iterator iter = wscand.begin();
0072     while (iter != wscand.end()) {
0073       if (*iter && !(*iter)->empty())
0074         mycands.push_back(const_cast<L1MuBMTrack*>(*iter));
0075       iter++;
0076     }
0077   }
0078 
0079   // print input data
0080   if (m_tf.config().Debug(4)) {
0081     cout << "BM Muon Sorter input: " << mycands.size() << endl;
0082     vector<L1MuBMTrack*>::const_iterator iter;
0083     for (iter = mycands.begin(); iter != mycands.end(); iter++) {
0084       if (*iter)
0085         (*iter)->print();
0086     }
0087   }
0088 
0089   // run Cancel Out Logic
0090   runCOL(mycands);
0091 
0092   // remove disabled candidates
0093   vector<L1MuBMTrack*>::iterator it = mycands.begin();
0094   while (it != mycands.end()) {
0095     if (*it && (*it)->empty()) {
0096       mycands.erase(it);
0097       it = mycands.begin();
0098       continue;
0099     }
0100     it++;
0101   }
0102 
0103   // sort pt and quality
0104   stable_sort(mycands.begin(), mycands.end(), L1MuBMTrack::rank);
0105 
0106   // copy the best 4 candidates
0107   int number_of_tracks = 0;
0108   vector<L1MuBMTrack*>::const_iterator iter1 = mycands.begin();
0109   while (iter1 != mycands.end()) {
0110     if (*iter1 && number_of_tracks < 4) {
0111       m_TrackCands.push_back(*iter1);
0112       number_of_tracks++;
0113     }
0114     iter1++;
0115   }
0116 }
0117 
0118 //
0119 // reset BM Muon Sorter
0120 //
0121 void L1MuBMMuonSorter::reset() {
0122   m_TrackCands.clear();
0123   vector<const L1MuBMTrack*>::iterator iter;
0124   for (iter = m_TrackCands.begin(); iter != m_TrackCands.end(); iter++) {
0125     *iter = nullptr;
0126   }
0127 }
0128 
0129 //
0130 // print candidates found in the BM Muon Sorter
0131 //
0132 void L1MuBMMuonSorter::print() const {
0133   cout << endl;
0134   cout << "Muon candidates found by the barrel MTTF : " << numberOfTracks() << endl;
0135   vector<const L1MuBMTrack*>::const_iterator iter = m_TrackCands.begin();
0136   while (iter != m_TrackCands.end()) {
0137     if (*iter)
0138       cout << *(*iter) << endl;
0139     iter++;
0140   }
0141   cout << endl;
0142 }
0143 
0144 //
0145 // Cancel Out Logic for BM Muon Sorter
0146 //
0147 void L1MuBMMuonSorter::runCOL(vector<L1MuBMTrack*>& cands) const {
0148   // compare candidates which were found in nearby sectors and wheels
0149   // if 2 candidates have at least one track segment in common
0150   // disable the one with lower quality
0151   // compare addresses from stations 2, 3 and 4
0152 
0153   typedef vector<L1MuBMTrack*>::iterator TI;
0154   for (TI iter1 = cands.begin(); iter1 != cands.end(); iter1++) {
0155     if (*iter1 == nullptr)
0156       continue;
0157     if ((*iter1)->empty())
0158       continue;
0159     L1MuBMSecProcId sp1 = (*iter1)->spid();
0160     int qual1 = (*iter1)->quality();
0161     for (TI iter2 = cands.begin(); iter2 != cands.end(); iter2++) {
0162       if (*iter2 == nullptr)
0163         continue;
0164       if (*iter1 == *iter2)
0165         continue;
0166       if ((*iter2)->empty())
0167         continue;
0168       L1MuBMSecProcId sp2 = (*iter2)->spid();
0169       int qual2 = (*iter2)->quality();
0170       if (sp1 == sp2)
0171         continue;
0172       int topology = neighbour(sp1, sp2);
0173       if (topology == -1)
0174         continue;
0175       int countTS = 0;
0176       for (int stat = 2; stat <= 4; stat++) {
0177         int adr1 = (*iter1)->address(stat);
0178         int adr2 = (*iter2)->address(stat);
0179         if (adr1 == 15 || adr2 == 15)
0180           continue;
0181         switch (topology) {
0182           case 1: {
0183             if (adr1 > 7)
0184               continue;
0185             if (adr2 > 3 && adr2 < 8)
0186               continue;
0187             int adr_shift = (adr2 > 7) ? -8 : 4;
0188             if (adr1 == adr2 + adr_shift)
0189               countTS++;
0190             break;
0191           }
0192           case 2: {
0193             if (adr2 > 7)
0194               continue;
0195             if (adr1 > 3 && adr1 < 8)
0196               continue;
0197             int adr_shift = (adr2 > 3) ? -4 : 8;
0198             if (adr1 == adr2 + adr_shift)
0199               countTS++;
0200             break;
0201           }
0202           case 3: {
0203             if ((adr1 == 6 && adr2 == 0) || (adr1 == 7 && adr2 == 1) || (adr1 == 2 && adr2 == 8) ||
0204                 (adr1 == 3 && adr2 == 9))
0205               countTS++;
0206             break;
0207           }
0208           case 4: {
0209             if ((adr1 == 2 && adr2 == 4) || (adr1 == 3 && adr2 == 5) || (adr1 == 10 && adr2 == 0) ||
0210                 (adr1 == 11 && adr2 == 1))
0211               countTS++;
0212             break;
0213           }
0214           case 5: {
0215             if ((adr1 == 0 && adr2 == 8) || (adr1 == 1 && adr2 == 9) || (adr1 == 4 && adr2 == 0) ||
0216                 (adr1 == 5 && adr2 == 1))
0217               countTS++;
0218             break;
0219           }
0220           case 6: {
0221             if ((adr1 == 0 && adr2 == 4) || (adr1 == 1 && adr2 == 5) || (adr1 == 8 && adr2 == 0) ||
0222                 (adr1 == 9 && adr2 == 1))
0223               countTS++;
0224             break;
0225           }
0226           default:
0227             break;
0228         }
0229       }
0230       if (countTS > 0) {
0231         if (qual1 < qual2) {
0232           if (m_tf.config().Debug(5)) {
0233             cout << "Muon Sorter cancel : ";
0234             (*iter1)->print();
0235           }
0236           (*iter1)->disable();
0237           break;
0238         } else {
0239           if (m_tf.config().Debug(5)) {
0240             cout << "Muon Sorter cancel : ";
0241             (*iter2)->print();
0242           }
0243           (*iter2)->disable();
0244         }
0245       }
0246     }
0247   }
0248 
0249   // if two candidates have exactly the same phi and eta values
0250   // remove the one with lower rank
0251 
0252   for (TI iter1 = cands.begin(); iter1 != cands.end(); iter1++) {
0253     if (*iter1 == nullptr)
0254       continue;
0255     if ((*iter1)->empty())
0256       continue;
0257     int phi1 = (*iter1)->phi();
0258     int pt1 = (*iter1)->pt();
0259     int qual1 = (*iter1)->quality();
0260     for (TI iter2 = cands.begin(); iter2 != cands.end(); iter2++) {
0261       if (*iter2 == nullptr)
0262         continue;
0263       if (*iter1 == *iter2)
0264         continue;
0265       if ((*iter2)->empty())
0266         continue;
0267       int phi2 = (*iter2)->phi();
0268       int pt2 = (*iter2)->pt();
0269       int qual2 = (*iter2)->quality();
0270       int w1 = (*iter1)->getStartTSphi().wheel();
0271       int w2 = (*iter2)->getStartTSphi().wheel();
0272       int phidiff = (phi2 - phi1) % 144;
0273       if (phidiff >= 72)
0274         phidiff -= 144;
0275       if (phidiff < -72)
0276         phidiff += 144;
0277       if (abs(phidiff) < 2 && (w1 == w2)) {
0278         int rank1 = 10 * pt1 + qual1;
0279         int rank2 = 10 * pt2 + qual2;
0280         if (m_tf.config().Debug(5)) {
0281           cout << "========================================" << endl;
0282           cout << " special cancellation : " << endl;
0283           (*iter1)->print();
0284           if (rank1 < rank2)
0285             cout << "cancelled" << endl;
0286           (*iter2)->print();
0287           if (rank1 >= rank2)
0288             cout << "cancelled" << endl;
0289           cout << "========================================" << endl;
0290         }
0291         if (rank1 >= rank2)
0292           (*iter2)->disable();
0293         if (rank1 < rank2) {
0294           (*iter1)->disable();
0295           break;
0296         }
0297       }
0298     }
0299   }
0300 }
0301 
0302 //
0303 // find out if two Sector Processors are neighbours
0304 //
0305 int L1MuBMMuonSorter::neighbour(const L1MuBMSecProcId& spid1, const L1MuBMSecProcId& spid2) {
0306   // definition of valid topologies:
0307 
0308   //              E T A
0309   //        -----------------
0310   //   +
0311   //        ---               ---
0312   //   |   | 2 |             | 2 |
0313   // P |   |___|             |___|
0314   //   |    ---    ---    ---        ---
0315   // H |   | 1 |  | 1 |  | 1 |      | 1 |
0316   //   |   |___|  |___|  |___|      |___|
0317   // I |           ---                   ---
0318   //   |          | 2 |                 | 2 |
0319   //              |___|                 |___|
0320   //   -
0321   // result: 1      2        3          4         5    6  otherwise : -1
0322 
0323   int topology = -1;
0324 
0325   int sector1 = spid1.sector();
0326   int wheel1 = spid1.wheel();
0327 
0328   int sector2 = spid2.sector();
0329   int wheel2 = spid2.wheel();
0330 
0331   int sectordiff = (sector2 - sector1) % 12;
0332   if (sectordiff >= 6)
0333     sectordiff -= 12;
0334   if (sectordiff < -6)
0335     sectordiff += 12;
0336 
0337   if (abs(sectordiff) == 1) {
0338     if (wheel1 == wheel2)
0339       topology = (sectordiff > 0) ? 1 : 2;
0340     if (wheel1 == +1 && wheel2 == -1)
0341       topology = (sectordiff > 0) ? 5 : 6;
0342     if ((wheel1 == -2 && wheel2 == -3) || (wheel1 == -1 && wheel2 == -2) || (wheel1 == +1 && wheel2 == +2) ||
0343         (wheel1 == +2 && wheel2 == +3))
0344       topology = (sectordiff > 0) ? 3 : 4;
0345   }
0346 
0347   return topology;
0348 }