CMS 3D CMS Logo

L1MuDTEtaProcessor.cc
Go to the documentation of this file.
1 //-------------------------------------------------
2 //
3 // Class: L1MuDTEtaProcessor
4 //
5 // Description: Eta Processor
6 //
7 // An Eta Processor consists of :
8 // a receiver unit,
9 // one Eta Track Finder (ETF) and
10 // one Eta Matching Unit (EMU)
11 //
12 //
13 // Author :
14 // N. Neumeister CERN EP
15 // J. Troconiz UAM Madrid
16 //
17 //--------------------------------------------------
18 
19 //-----------------------
20 // This Class's Header --
21 //-----------------------
22 
24 
25 //---------------
26 // C++ Headers --
27 //---------------
28 
29 #include <iostream>
30 #include <iomanip>
31 #include <bitset>
32 
33 //-------------------------------
34 // Collaborating Class Headers --
35 //-------------------------------
36 
52 
53 using namespace std;
54 
55 // --------------------------------
56 // class L1MuDTEtaProcessor
57 //---------------------------------
58 
59 //----------------
60 // Constructors --
61 //----------------
62 
64  m_tf(tf), m_epid(id), m_foundPattern(0), m_tseta(15),
65  m_DTDigiToken(iC.consumes<L1MuDTChambThContainer>(m_tf.config()->getDTDigiInputTag())) {
66 
67  m_tseta.reserve(15);
68 
69 }
70 
71 
72 //--------------
73 // Destructor --
74 //--------------
75 
77 
78 
79 //--------------
80 // Operations --
81 //--------------
82 
83 //
84 // run Eta Processor
85 //
86 void L1MuDTEtaProcessor::run(int bx, const edm::Event& e, const edm::EventSetup& c) {
87 
88  if ( m_tf.config()->getEtaTF() ) {
89  receiveData(bx,e,c);
91  }
92 
95 
96  assign();
97 
98 }
99 
100 
101 //
102 // reset Eta Processor
103 //
105 
106  vector<const L1MuDTTrackSegEta*>::iterator iter = m_tseta.begin();
107  while ( iter != m_tseta.end() ) {
108  if ( *iter ) {
109  delete *iter;
110  *iter = nullptr;
111  }
112  iter++;
113  }
114 
115  m_tseta.clear();
116 
117  for ( int i = 0; i < 12; i++ ) {
118  m_eta[i] = 99;
119  m_fine[i] = false;
120  m_pattern[i] = 0;
121  m_address[i] = 0;
122  m_TrackCand[i] = nullptr;
123  m_TracKCand[i] = nullptr;
124  }
125 
126  m_foundPattern.clear();
127 
128  m_mask = true;
129 
130 }
131 
132 
133 //
134 // print track candidates found in Eta Processor
135 //
137 
138  bool empty1 = true;
139  for ( int i = 0; i < 15; i++ ) {
140  empty1 &= ( m_tseta[i] == nullptr || m_tseta[i]->empty() );
141  }
142 
143  bool empty2 = true;
144  for ( int i = 0; i < 12; i++ ) {
145  empty2 &= ( m_address[i] == 0 );
146  }
147 
148  if ( !empty1 || !empty2 ) {
149  cout << "Eta processor " << m_epid << " : " << endl;
150 
151  // print local pattern
152  if ( !empty1 ) {
153  cout << "Local pattern : " << endl;
154  for ( int i = 0; i < 15; i++ ) {
155  if ( (i+5)%5 == 0 ) cout << "station " << m_tseta[i]->station() << " : ";
156  bitset<7> pos(m_tseta[i]->position());
157  bitset<7> qua(m_tseta[i]->quality());
158  for ( int j = 6; j >= 0; j-- ) {
159  cout << pos[j]+qua[j];
160  }
161  cout << " ";
162  if ( (i+1)%5 == 0 ) cout << endl;
163  }
164  cout << "Found patterns :" << endl;
165  vector<int>::const_iterator iter;
166  for ( iter = m_foundPattern.begin(); iter != m_foundPattern.end(); iter++ ) {
168  int qualitycode = p.quality();
169  cout << "ID = " << setw(4) << p.id() << " "
170  << "eta = " << setw(3) << p.eta() << " "
171  << "quality = " << setw(2) << qualitycode << " ("
172  << quality(qualitycode,1) << " "
173  << quality(qualitycode,2) << " "
174  << quality(qualitycode,3) << ")";
175  for ( int i = 0; i < 12; i++ ) {
176  if ( m_pattern[i] == p.id() ) cout << " <--";
177  }
178  cout << endl;
179  }
180  }
181 
182  cout << "Received addresses : " << endl;
183  for ( int i = 0; i < 12; i++ ) cout << setw(3) << m_address[i] << " ";
184  cout << endl;
185 
186  if ( !empty1 ) {
187  cout << "Matched patterns : " << endl;
188  for ( int i = 0; i < 12; i++ ) {
189  if ( m_fine[i] ) {
191  int fineeta = p.eta();
192  int coarseeta = theQualPatternLUT->getCoarseEta(i/2+1,m_address[i]);
193  cout << "Index = " << setw(2) << i << ", "
194  << "address = " << setw(2) << m_address[i] << " --> "
195  << "pattern = " << setw(4) << m_pattern[i] << " "
196  << "eta (coarse) = " << setw(3) << coarseeta << " "
197  << "eta (fine) = " << setw(3) << fineeta << " "
198  << "quality = " << setw(2) << p.quality() << endl;
199  }
200  }
201  }
202 
203  cout << "Eta values and fine bits : " << endl;
204  for ( int i = 0; i < 12; i++ ) cout << setw(3) << m_eta[i] << " ";
205  cout << endl;
206  for ( int i = 0; i < 12; i++ ) cout << setw(3) << m_fine[i] << " ";
207  cout << endl;
208  }
209 
210 }
211 
212 
213 //
214 // receive data ( 15*3 DTBX eta trigger primitives )
215 //
217 
218  c.get< L1MuDTTFMasksRcd >().get( msks );
219 
221  e.getByToken(m_DTDigiToken,dttrig);
222 
223  // const int bx_offset = dttrig->correctBX();
224  int bx_offset=0;
225  bx = bx + bx_offset;
226 
227  //
228  // get 5*3 eta track segments
229  //
230  int sector = m_epid;
231  for ( int stat = 1; stat <= 3; stat++ ) {
232  for ( int wheel = -2; wheel <= 2; wheel++ ) {
233  L1MuDTChambThDigi const* tseta = dttrig->chThetaSegm(wheel,stat,sector,bx);
234  bitset<7> pos;
235  bitset<7> qual;
236 
237  int lwheel = wheel+1;
238  if ( wheel < 0 ) lwheel = wheel-1;
239 
240  bool masked = false;
241  if ( stat == 1 ) masked = msks->get_etsoc_chdis_st1(lwheel, sector);
242  if ( stat == 2 ) masked = msks->get_etsoc_chdis_st2(lwheel, sector);
243  if ( stat == 3 ) masked = msks->get_etsoc_chdis_st3(lwheel, sector);
244 
245  if ( !masked ) m_mask = false;
246 
247  if ( tseta && !masked ) {
248 
249  if ( wheel == -2 || wheel == -1 ||
250  ( wheel == 0 && (sector == 0 || sector == 3 || sector == 4 || sector == 7 || sector == 8 || sector == 11) ) ) {
251  for ( int i = 0; i < 7; i++ ) {
252  if ( tseta->position(i) ) pos.set(6-i);
253  if ( tseta->quality(i) ) qual.set(6-i);
254  }
255  } else {
256  for ( int i = 0; i < 7; i++ ) {
257  if ( tseta->position(i) ) pos.set(i);
258  if ( tseta->quality(i) ) qual.set(i);
259  }
260  }
261  }
262 
263  const L1MuDTTrackSegEta* tmpts = new L1MuDTTrackSegEta(wheel,sector,stat,pos.to_ulong(),qual.to_ulong(),bx-bx_offset);
264  m_tseta.push_back(tmpts);
265  }
266  }
267 
268 }
269 
270 
271 //
272 // receive track addresses from 6 Sector Processors
273 //
275 
276  // get track address code of all track segments
277  // 6*2 times 5 bits; valid range [1-22]
278 
279  int sector = m_epid;
280 
281  int i = 0;
282  for ( int wheel = -3; wheel <= 3; wheel++ ) {
283  if ( wheel == 0 ) continue;
284  L1MuDTSecProcId tmpspid(wheel,sector);
285  for ( int number = 0; number < 2; number++ ) {
286  const L1MuDTTrack* cand = m_tf.sp(tmpspid)->track(number);
287  const L1MuDTTrack* canD = m_tf.sp(tmpspid)->tracK(number);
288  if ( cand ) {
289  m_address[i] = cand->address().trackAddressCode();
290  if ( !cand->empty() ) {
291  m_TrackCand[i] = const_cast<L1MuDTTrack*>(cand);
292  m_TracKCand[i] = const_cast<L1MuDTTrack*>(canD);
293  }
294  i++;
295  }
296  }
297  }
298 
299 }
300 
301 
302 //
303 // run Eta Track Finder (ETF)
304 //
306 
308 
309  // check if there are any data
310  bool empty = true;
311  for ( int i = 0; i < 15; i++ ) {
312  empty &= m_tseta[i]->empty();
313  }
314  if ( empty ) return;
315 
316  // Pattern comparator:
317  // loop over all patterns and compare with local chamber pattern
318  // result : list of valid pattern IDs ( m_foundPattern )
320  while ( it != theEtaPatternLUT->end() ) {
321 
322  const L1MuDTEtaPattern pattern = (*it).second;
323  int qualitycode = pattern.quality();
324 
325  bool good = true;
326 
327  for ( int station = 0; station < 3; station++) {
328  int q = quality(qualitycode,station+1);
329  int wheel = pattern.wheel(station+1);
330  int bin = pattern.position(station+1);
331  if ( bin == 0 ) continue;
332  bitset<7> pos = m_tseta[wheel+2 + station*5]->position();
333  bitset<7> qual = m_tseta[wheel+2 + station*5]->quality();
334  // compare position
335  good &= pos.test(bin-1);
336  // compare quality
337  if ( q == 2 ) good &= qual.test(bin-1);
338  }
339 
340  if ( good ) m_foundPattern.push_back(pattern.id());
341 
342  it++;
343 
344  }
345 
346 }
347 
348 
349 //
350 // run Eta Matching Unit (EMU)
351 //
353 
355 
356  // loop over all addresses
357  for ( int i = 0; i < 12; i++ ) {
358 
359  int adr = m_address[i];
360  if ( adr == 0 ) continue;
361  int sp = i/2 + 1; //sector processor [1,6]
362 
363  // assign coarse eta value
364  if ( !m_mask ) m_eta[i] = theQualPatternLUT->getCoarseEta(sp,adr);
365  if ( m_eta[i] == 99 ) m_eta[i] = 32;
366  if ( m_eta[i] > 31 ) m_eta[i] -= 64;
367  m_eta[i] += 32;
368 
369  if ( m_foundPattern.empty() ) continue;
370 
371  // get list of qualified patterns ordered by quality
372  // and compare with found patterns
373  const vector<short>& qualifiedPatterns = theQualPatternLUT->getQualifiedPatterns(sp,adr);
374  vector<short>::const_iterator iter;
375  vector<int>::const_iterator f_iter;
376  for ( iter = qualifiedPatterns.begin(); iter != qualifiedPatterns.end(); iter++ ) {
377  f_iter = find(m_foundPattern.begin(),m_foundPattern.end(),(*iter));
378  // found
379  if ( f_iter != m_foundPattern.end() ) {
380  const L1MuDTEtaPattern p = theEtaPatternLUT->getPattern(*f_iter);
381  // assign fine eta value
382  m_fine[i] = true;
383  m_eta[i] = p.eta(); // improved eta
384  if ( m_eta[i] == 99 ) m_eta[i] = 32;
385  if ( m_eta[i] > 31 ) m_eta[i] -= 64;
386  m_eta[i] += 32;
387  m_pattern[i] = (*f_iter);
388  break;
389  }
390  }
391 
392  }
393 
394  // if both tracks from one sector processor deliver the same track address
395  // both tracks get only a coarse eta value!
396 
397  // loop over sector processors
398  for ( int i = 0; i < 6; i++ ) {
399  int idx1 = 2*i;
400  int idx2 = 2*i+1;
401  int adr1 = m_address[idx1];
402  int adr2 = m_address[idx2];
403  if ( adr1 == 0 || adr2 == 0 ) continue;
404  if ( adr1 == adr2 && !m_mask ) {
405  // both tracks get coarse (default) eta value
406  m_eta[idx1] = theQualPatternLUT->getCoarseEta(i+1,adr1);
407  if ( m_eta[idx1] == 99 ) m_eta[idx1] = 32;
408  if ( m_eta[idx1] > 31 ) m_eta[idx1] -= 64;
409  m_eta[idx1] += 32;
410  m_pattern[idx1] = 0;
411  m_fine[idx1] = false;
412  m_eta[idx2] = theQualPatternLUT->getCoarseEta(i+1,adr2);
413  if ( m_eta[idx2] == 99 ) m_eta[idx2] = 32;
414  if ( m_eta[idx2] > 31 ) m_eta[idx2] -= 64;
415  m_eta[idx2] += 32;
416  m_pattern[idx2] = 0;
417  m_fine[idx2] = false;
418  }
419  }
420 
421 }
422 
423 
424 //
425 // assign values to track candidates
426 //
428 
429  for ( int i = 0; i < 12; i++ ) {
430  if ( m_TrackCand[i] ) {
431  if ( m_eta[i] != 99 ) {
432  m_TrackCand[i]->setEta(m_eta[i]);
433  m_TracKCand[i]->setEta(m_eta[i]);
434  }
435  else {
436  // if ( i/2 != 2 ) cerr << "L1MuDTEtaProcessor: assign invalid eta" << " " << m_address[i] << endl;
437  }
438  if ( m_fine[i] ) {
441  // find all contributing track segments
443  vector<const L1MuDTTrackSegEta*> TSeta;
444  const L1MuDTTrackSegEta* ts = nullptr;
445  for ( int stat = 0; stat < 3; stat++ ) {
446  int wh = p.wheel(stat+1);
447  int pos = p.position(stat+1);
448  if ( pos == 0 ) continue;
449  ts = m_tseta[wh+2 + stat*5];
450  TSeta.push_back(ts);
451  }
452  m_TrackCand[i]->setTSeta(TSeta);
453  m_TracKCand[i]->setTSeta(TSeta);
454  }
455  }
456  }
457 
458 }
459 
460 
461 //
462 // get quality: id [0,26], stat [1,3]
463 //
465 
466  // quality codes as defined in CMS Note 2001/027
467  // This QualityPatterns are used to have a defined Quality-Identifier for
468  // all possible found tracks.
469  // Therefore three integer numbers ( Station 1, 2, 3 from left to right )
470  // can have numbers like 0, 1 or 2
471  // 0 ... no hit is given
472  // 1 ... a LTRG is given
473  // 2 ... a HTRG is given
474 
475  const int qualcode[27][3] = { {0,0,0},{1,0,0},{0,1,0},{0,0,1},{2,0,0},
476  {0,2,0},{0,0,2},{1,1,0},{1,0,1},{0,1,1},
477  {2,1,0},{1,2,0},{2,0,1},{1,0,2},{0,2,1},
478  {0,1,2},{2,2,0},{2,0,2},{0,2,2},{1,1,1},
479  {2,1,1},{1,2,1},{1,1,2},{2,2,1},{2,1,2},
480  {1,2,2},{2,2,2} };
481 
482  return qualcode[id][stat-1];
483 
484 }
void setFineEtaBit()
set fine eta bit
Definition: L1MuDTTrack.h:143
L1MuDTEtaProcessor(const L1MuDTTrackFinder &, int id, edm::ConsumesCollector &&iC)
constructor
void runEtaTrackFinder(const edm::EventSetup &c)
run Eta Track Finder (ETF)
LUT::const_iterator ETFLut_iter
edm::ESHandle< L1MuDTEtaPatternLut > theEtaPatternLUT
const L1MuDTTrackFinder & m_tf
virtual ~L1MuDTEtaProcessor()
destructor
int quality() const
return quality
bool get_etsoc_chdis_st3(int wh, int sc) const
L1MuDTTrack * m_TracKCand[12]
void assign()
assign eta and etaFineBit
edm::ESHandle< L1MuDTQualPatternLut > theQualPatternLUT
L1MuDTTrack * tracK(int id) const
return pointer to muon candidate, index [0,1]
L1MuDTAddressArray address() const
get address-array for this muon candidate
Definition: L1MuDTTrack.h:95
bool getByToken(EDGetToken token, Handle< PROD > &result) const
Definition: Event.h:579
int trackAddressCode() const
get track address code (for eta track finder)
static int quality(int id, int stat)
get quality code; id [0,26], stat [1,3]
const L1MuDTSectorProcessor * sp(const L1MuDTSecProcId &) const
get a pointer to a Sector Processor
Definition: config.py:1
int position(int station) const
return position in station [1,3]
void find(edm::Handle< EcalRecHitCollection > &hits, DetId thisDet, std::vector< EcalRecHitCollection::const_iterator > &hit, bool debug=false)
Definition: FindCaloHit.cc:20
int quality(const int i) const
L1MuDTEtaPattern getPattern(int id) const
get pattern with a given ID
int id() const
return id
int position(const int i) const
void setEta(int eta)
set eta-code of muon candidate
Definition: L1MuDTTrack.cc:114
int eta() const
return eta
int getCoarseEta(int sp, int adr) const
get coarse eta value for a given sector processor [1-6] and address [1-22]
virtual void run(int bx, const edm::Event &e, const edm::EventSetup &c)
run the Eta Processor
void setTSeta(const std::vector< const L1MuDTTrackSegEta * > &tsList)
set eta track segments used to form the muon candidate
Definition: L1MuDTTrack.cc:183
std::vector< const L1MuDTTrackSegEta * > m_tseta
bool empty() const override
is it an empty muon candidate?
Definition: L1MuDTTrack.h:89
ETFLut_iter begin() const
return iterator which points to the first entry of the LUT
void receiveAddresses()
receive addresses (from 6 Sector Processors)
bool get_etsoc_chdis_st2(int wh, int sc) const
bin
set the eta bin as selection string.
int id() const
return Eta Processor identifier (0-11)
void runEtaMatchingUnit(const edm::EventSetup &c)
run Eta Matching Unit (EMU)
std::vector< int > m_foundPattern
void receiveData(int bx, const edm::Event &e, const edm::EventSetup &c)
receive data (eta trigger primitives)
bool getEtaTF() const
static L1MuDTTFConfig * config()
return configuration
L1MuDTChambThDigi const * chThetaSegm(int wheel, int stat, int sect, int bx) const
ETFLut_iter end() const
return iterator which points to the one-past-last entry of the LUT
virtual void reset()
reset the Eta Processor
static int position[264][3]
Definition: ReadPGInfo.cc:509
T get() const
Definition: EventSetup.h:68
int wheel(int station) const
return wheel number in station [1,3]
L1MuDTTrack * m_TrackCand[12]
bool get_etsoc_chdis_st1(int wh, int sc) const
edm::EDGetTokenT< L1MuDTChambThContainer > m_DTDigiToken
L1MuDTTrack * track(int id) const
return pointer to muon candidate, index [0,1]
const std::vector< short > & getQualifiedPatterns(int sp, int adr) const
get list of qualified patterns for a given sector processor [1-6] and address [1-22] ...
void print() const
print muon candidates found by the Eta Processor
edm::ESHandle< L1MuDTTFMasks > msks