CMS 3D CMS Logo

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