CMS 3D CMS Logo

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