CMS 3D CMS Logo

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