CMS 3D CMS Logo

L1MuDTMuonSorter.cc
Go to the documentation of this file.
1 //-------------------------------------------------
2 //
3 // Class: L1MuDTMuonSorter
4 //
5 // Description: DT Muon Sorter
6 //
7 //
8 //
9 // Author :
10 // N. Neumeister CERN EP
11 // J. Troconiz UAM Madrid
12 //
13 //--------------------------------------------------
14 
15 //-----------------------
16 // This Class's Header --
17 //-----------------------
18 
20 
21 //---------------
22 // C++ Headers --
23 //---------------
24 
25 #include <iostream>
26 #include <algorithm>
27 
28 //-------------------------------
29 // Collaborating Class Headers --
30 //-------------------------------
31 
37 
38 using namespace std;
39 
40 // --------------------------------
41 // class L1MuDTMuonSorter
42 //---------------------------------
43 
44 //----------------
45 // Constructors --
46 //----------------
47 
49  m_tf(tf), m_TrackCands() {
50 
51  m_TrackCands.reserve(4);
52 
53 }
54 
55 
56 //--------------
57 // Destructor --
58 //--------------
59 
61 
62 }
63 
64 
65 //--------------
66 // Operations --
67 //--------------
68 
69 //
70 // run DT Muon Sorter
71 //
73 
74  // get track candidates from Wedge Sorters
75  vector<L1MuDTTrack*> mycands;
76  mycands.reserve(24);
77 
78  for ( int wedge = 0; wedge < 12; wedge++ ) {
79  vector<const L1MuDTTrack*> wscand = m_tf.ws(wedge)->tracks();
80  vector<const L1MuDTTrack*>::iterator iter = wscand.begin();
81  while ( iter != wscand.end() ) {
82  if ( *iter && !(*iter)->empty() )
83  mycands.push_back(const_cast<L1MuDTTrack*>(*iter) );
84  iter++;
85  }
86  }
87 
88  // print input data
89  if ( L1MuDTTFConfig::Debug(4) ) {
90  cout << "DT Muon Sorter input: "
91  << mycands.size() << endl;
92  vector<L1MuDTTrack*>::const_iterator iter;
93  for ( iter = mycands.begin(); iter != mycands.end(); iter++ ) {
94  if (*iter ) (*iter)->print();
95  }
96  }
97 
98  // run Cancel Out Logic
99  runCOL(mycands);
100 
101  // remove disabled candidates
102  vector<L1MuDTTrack*>::iterator it = mycands.begin();
103  while ( it != mycands.end() ) {
104  if ( *it && (*it)->empty() ) {
105  mycands.erase(it);
106  it = mycands.begin(); continue;
107  }
108  it++;
109  }
110 
111  // sort pt and quality
112  stable_sort( mycands.begin(), mycands.end(), L1MuDTTrack::rank );
113 
114  // copy the best 4 candidates
115  int number_of_tracks = 0;
116  vector<L1MuDTTrack*>::const_iterator iter1 = mycands.begin();
117  while ( iter1 != mycands.end() ) {
118  if ( *iter1 && number_of_tracks < 4 ) {
119  m_TrackCands.push_back(*iter1);
120  number_of_tracks++;
121  }
122  iter1++;
123  }
124 
125 }
126 
127 
128 //
129 // reset DT Muon Sorter
130 //
132 
133  m_TrackCands.clear();
134  vector<const L1MuDTTrack*>::iterator iter;
135  for ( iter = m_TrackCands.begin(); iter != m_TrackCands.end(); iter++ ) {
136  *iter = nullptr;
137  }
138 
139 }
140 
141 
142 //
143 // print candidates found in the DT Muon Sorter
144 //
146 
147  cout << endl;
148  cout << "Muon candidates found by the barrel MTTF : "
149  << numberOfTracks() << endl;
150  vector<const L1MuDTTrack*>::const_iterator iter = m_TrackCands.begin();
151  while ( iter != m_TrackCands.end() ) {
152  if ( *iter ) cout << *(*iter) << endl;
153  iter++;
154  }
155  cout << endl;
156 
157 }
158 
159 
160 //
161 // Cancel Out Logic for DT Muon Sorter
162 //
163 void L1MuDTMuonSorter::runCOL(vector<L1MuDTTrack*>& cands) const {
164 
165  // compare candidates which were found in nearby sectors and wheels
166  // if 2 candidates have at least one track segment in common
167  // disable the one with lower quality
168  // compare addresses from stations 2, 3 and 4
169 
170  typedef vector<L1MuDTTrack*>::iterator TI;
171  for ( TI iter1 = cands.begin(); iter1 != cands.end(); iter1++ ) {
172  if ( *iter1 == nullptr ) continue;
173  if ( (*iter1)->empty() ) continue;
174  L1MuDTSecProcId sp1 = (*iter1)->spid();
175  int qual1 = (*iter1)->quality();
176  for ( TI iter2 = cands.begin(); iter2 != cands.end(); iter2++ ) {
177  if ( *iter2 == nullptr ) continue;
178  if ( *iter1 == *iter2 ) continue;
179  if ( (*iter2)->empty() ) continue;
180  L1MuDTSecProcId sp2 = (*iter2)->spid();
181  int qual2 = (*iter2)->quality();
182  if (sp1 == sp2 ) continue;
183  int topology = neighbour(sp1,sp2);
184  if ( topology == -1 ) continue;
185  int countTS = 0;
186  for ( int stat = 2; stat <= 4; stat++ ) {
187  int adr1 = (*iter1)->address(stat);
188  int adr2 = (*iter2)->address(stat);
189  if ( adr1 == 15 || adr2 == 15 ) continue;
190  switch ( topology ) {
191  case 1 : {
192  if ( adr1 > 7 ) continue;
193  if ( adr2 > 3 && adr2 < 8 ) continue;
194  int adr_shift = ( adr2 > 7 ) ? -8 : 4;
195  if ( adr1 == adr2+adr_shift ) countTS++;
196  break;
197  }
198  case 2 : {
199  if ( adr2 > 7 ) continue;
200  if ( adr1 > 3 && adr1 < 8 ) continue;
201  int adr_shift = ( adr2 > 3 ) ? -4 : 8;
202  if ( adr1 == adr2+adr_shift ) countTS++;
203  break;
204  }
205  case 3 : {
206  if ( ( adr1 == 6 && adr2 == 0 ) ||
207  ( adr1 == 7 && adr2 == 1 ) ||
208  ( adr1 == 2 && adr2 == 8 ) ||
209  ( adr1 == 3 && adr2 == 9 ) ) countTS++;
210  break;
211  }
212  case 4 : {
213  if ( ( adr1 == 2 && adr2 == 4 ) ||
214  ( adr1 == 3 && adr2 == 5 ) ||
215  ( adr1 == 10 && adr2 == 0 ) ||
216  ( adr1 == 11 && adr2 == 1 ) ) countTS++;
217  break;
218  }
219  case 5 : {
220  if ( ( adr1 == 0 && adr2 == 8 ) ||
221  ( adr1 == 1 && adr2 == 9 ) ||
222  ( adr1 == 4 && adr2 == 0 ) ||
223  ( adr1 == 5 && adr2 == 1 ) ) countTS++;
224  break;
225  }
226  case 6 : {
227  if ( ( adr1 == 0 && adr2 == 4 ) ||
228  ( adr1 == 1 && adr2 == 5 ) ||
229  ( adr1 == 8 && adr2 == 0 ) ||
230  ( adr1 == 9 && adr2 == 1 ) ) countTS++;
231  break;
232  }
233  default : break;
234  }
235  }
236  if ( countTS > 0 ) {
237  if ( qual1 < qual2 ) {
238  if ( L1MuDTTFConfig::Debug(5) ) {
239  cout << "Muon Sorter cancel : "; (*iter1)->print();
240  }
241  (*iter1)->disable();
242  break;
243  }
244  else {
245  if ( L1MuDTTFConfig::Debug(5) ) {
246  cout << "Muon Sorter cancel : "; (*iter2)->print();
247  }
248  (*iter2)->disable();
249  }
250  }
251  }
252  }
253 
254 
255  // if two candidates have exactly the same phi and eta values
256  // remove the one with lower rank
257 
258  for ( TI iter1 = cands.begin(); iter1 != cands.end(); iter1++ ) {
259  if ( *iter1 == nullptr ) continue;
260  if ( (*iter1)->empty() ) continue;
261  int phi1 = (*iter1)->phi();
262  int pt1 = (*iter1)->pt();
263  int qual1 = (*iter1)->quality();
264  for ( TI iter2 = cands.begin(); iter2 != cands.end(); iter2++ ) {
265  if ( *iter2 == nullptr ) continue;
266  if ( *iter1 == *iter2 ) continue;
267  if ( (*iter2)->empty() ) continue;
268  int phi2 = (*iter2)->phi();
269  int pt2 = (*iter2)->pt();
270  int qual2 = (*iter2)->quality();
271  int w1 = (*iter1)->getStartTSphi().wheel();
272  int w2 = (*iter2)->getStartTSphi().wheel();
273  int phidiff = (phi2 - phi1)%144;
274  if ( phidiff >= 72 ) phidiff -= 144;
275  if ( phidiff < -72 ) phidiff += 144;
276  if ( abs(phidiff) < 2 && (w1 == w2) ) {
277  int rank1 = 10 * pt1 + qual1;
278  int rank2 = 10 * pt2 + qual2;
279  if ( L1MuDTTFConfig::Debug(5) ) {
280  cout << "========================================" << endl;
281  cout << " special cancellation : " << endl;
282  (*iter1)->print(); if ( rank1 < rank2 ) cout << "cancelled" << endl;
283  (*iter2)->print(); if ( rank1 >= rank2 ) cout << "cancelled" << endl;
284  cout << "========================================" << endl;
285  }
286  if ( rank1 >= rank2 ) (*iter2)->disable();
287  if ( rank1 < rank2 ) { (*iter1)->disable(); break; }
288  }
289  }
290  }
291 
292 }
293 
294 
295 //
296 // find out if two Sector Processors are neighbours
297 //
299  const L1MuDTSecProcId& spid2) {
300 
301  // definition of valid topologies:
302 
303  // E T A
304  // -----------------
305  // +
306  // --- ---
307  // | | 2 | | 2 |
308  // P | |___| |___|
309  // | --- --- --- ---
310  // H | | 1 | | 1 | | 1 | | 1 |
311  // | |___| |___| |___| |___|
312  // I | --- ---
313  // | | 2 | | 2 |
314  // |___| |___|
315  // -
316  // result: 1 2 3 4 5 6 otherwise : -1
317 
318  int topology = -1;
319 
320  int sector1 = spid1.sector();
321  int wheel1 = spid1.wheel();
322 
323  int sector2 = spid2.sector();
324  int wheel2 = spid2.wheel();
325 
326  int sectordiff = (sector2 - sector1)%12;
327  if ( sectordiff >= 6 ) sectordiff -= 12;
328  if ( sectordiff < -6 ) sectordiff += 12;
329 
330  if ( abs(sectordiff) == 1 ) {
331 
332  if ( wheel1 == wheel2 ) topology = (sectordiff > 0) ? 1 : 2;
333  if ( wheel1 == +1 && wheel2 == -1 ) topology = (sectordiff > 0) ? 5 : 6;
334  if ( ( wheel1 == -2 && wheel2 == -3 ) ||
335  ( wheel1 == -1 && wheel2 == -2 ) ||
336  ( wheel1 == +1 && wheel2 == +2 ) ||
337  ( wheel1 == +2 && wheel2 == +3 ) ) topology = (sectordiff > 0) ? 3 : 4;
338 
339  }
340 
341  return topology;
342 
343 }
common ppss p3p6s2 common epss epspn46 common const1 w2
Definition: inclppp.h:1
CaloTopology const * topology(0)
static bool rank(const L1MuDTTrack *first, const L1MuDTTrack *second)
define a rank for muon candidates
Definition: L1MuDTTrack.h:182
static int neighbour(const L1MuDTSecProcId &spid1, const L1MuDTSecProcId &spid2)
find out if two Sector Processors are neighbours
void print() const
print results after sorting
double phidiff(double phi)
Normalized difference in azimuthal angles to a range between .
Definition: fourvec.cc:230
void runCOL(std::vector< L1MuDTTrack * > &) const
run the Cancel Out Logic of the muon sorter
const std::vector< const L1MuDTTrack * > & tracks() const
return vector of muon candidates
int sector() const
return sector number
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
void run() override
run Muon Sorter
static bool Debug()
void reset() override
reset Muon Sorter
std::vector< const L1MuDTTrack * > m_TrackCands
int numberOfTracks() const
return number of found muon candidates after sorter
const L1MuDTTrackFinder & m_tf
L1MuDTMuonSorter(const L1MuDTTrackFinder &)
constructor
~L1MuDTMuonSorter() override
destructor
const L1MuDTWedgeSorter * ws(int id) const
get a pointer to a Wedge Sorter, index [0-11]
int wheel() const
return wheel number