Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:19:42

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