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),
65  m_epid(id),
66  m_foundPattern(0),
67  m_tseta(15),
68  m_DTDigiToken(iC.consumes<L1MuDTChambThContainer>(m_tf.config()->getDTDigiInputTag())),
69  theEtaToken(iC.esConsumes()),
70  theQualToken(iC.esConsumes()),
71  theMsksToken(iC.esConsumes()) {
72  m_tseta.reserve(15);
73 }
74 
75 //--------------
76 // Destructor --
77 //--------------
78 
80 
81 //--------------
82 // Operations --
83 //--------------
84 
85 //
86 // run Eta Processor
87 //
89  if (m_tf.config()->getEtaTF()) {
90  receiveData(bx, e, c);
92  }
93 
96 
97  assign();
98 }
99 
100 //
101 // reset Eta Processor
102 //
104  vector<const L1MuDTTrackSegEta*>::iterator iter = m_tseta.begin();
105  while (iter != m_tseta.end()) {
106  if (*iter) {
107  delete *iter;
108  *iter = nullptr;
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] = nullptr;
121  m_TracKCand[i] = nullptr;
122  }
123 
124  m_foundPattern.clear();
125 
126  m_mask = true;
127 }
128 
129 //
130 // print track candidates found in Eta Processor
131 //
133  bool empty1 = true;
134  for (int i = 0; i < 15; i++) {
135  empty1 &= (m_tseta[i] == nullptr || m_tseta[i]->empty());
136  }
137 
138  bool empty2 = true;
139  for (int i = 0; i < 12; i++) {
140  empty2 &= (m_address[i] == 0);
141  }
142 
143  if (!empty1 || !empty2) {
144  cout << "Eta processor " << m_epid << " : " << endl;
145 
146  // print local pattern
147  if (!empty1) {
148  cout << "Local pattern : " << endl;
149  for (int i = 0; i < 15; i++) {
150  if ((i + 5) % 5 == 0)
151  cout << "station " << m_tseta[i]->station() << " : ";
152  bitset<7> pos(m_tseta[i]->position());
153  bitset<7> qua(m_tseta[i]->quality());
154  for (int j = 6; j >= 0; j--) {
155  cout << pos[j] + qua[j];
156  }
157  cout << " ";
158  if ((i + 1) % 5 == 0)
159  cout << endl;
160  }
161  cout << "Found patterns :" << endl;
162  vector<int>::const_iterator iter;
163  for (iter = m_foundPattern.begin(); iter != m_foundPattern.end(); iter++) {
165  int qualitycode = p.quality();
166  cout << "ID = " << setw(4) << p.id() << " "
167  << "eta = " << setw(3) << p.eta() << " "
168  << "quality = " << setw(2) << qualitycode << " (" << quality(qualitycode, 1) << " "
169  << quality(qualitycode, 2) << " " << quality(qualitycode, 3) << ")";
170  for (int i = 0; i < 12; i++) {
171  if (m_pattern[i] == p.id())
172  cout << " <--";
173  }
174  cout << endl;
175  }
176  }
177 
178  cout << "Received addresses : " << endl;
179  for (int i = 0; i < 12; i++)
180  cout << setw(3) << m_address[i] << " ";
181  cout << endl;
182 
183  if (!empty1) {
184  cout << "Matched patterns : " << endl;
185  for (int i = 0; i < 12; i++) {
186  if (m_fine[i]) {
188  int fineeta = p.eta();
189  int coarseeta = theQualPatternLUT->getCoarseEta(i / 2 + 1, m_address[i]);
190  cout << "Index = " << setw(2) << i << ", "
191  << "address = " << setw(2) << m_address[i] << " --> "
192  << "pattern = " << setw(4) << m_pattern[i] << " "
193  << "eta (coarse) = " << setw(3) << coarseeta << " "
194  << "eta (fine) = " << setw(3) << fineeta << " "
195  << "quality = " << setw(2) << p.quality() << endl;
196  }
197  }
198  }
199 
200  cout << "Eta values and fine bits : " << endl;
201  for (int i = 0; i < 12; i++)
202  cout << setw(3) << m_eta[i] << " ";
203  cout << endl;
204  for (int i = 0; i < 12; i++)
205  cout << setw(3) << m_fine[i] << " ";
206  cout << endl;
207  }
208 }
209 
210 //
211 // receive data ( 15*3 DTBX eta trigger primitives )
212 //
214  msks = c.getHandle(theMsksToken);
215 
217  e.getByToken(m_DTDigiToken, dttrig);
218 
219  // const int bx_offset = dttrig->correctBX();
220  int bx_offset = 0;
221  bx = bx + bx_offset;
222 
223  //
224  // get 5*3 eta track segments
225  //
226  int sector = m_epid;
227  for (int stat = 1; stat <= 3; stat++) {
228  for (int wheel = -2; wheel <= 2; wheel++) {
229  L1MuDTChambThDigi const* tseta = dttrig->chThetaSegm(wheel, stat, sector, bx);
230  bitset<7> pos;
231  bitset<7> qual;
232 
233  int lwheel = wheel + 1;
234  if (wheel < 0)
235  lwheel = wheel - 1;
236 
237  bool masked = false;
238  if (stat == 1)
239  masked = msks->get_etsoc_chdis_st1(lwheel, sector);
240  if (stat == 2)
241  masked = msks->get_etsoc_chdis_st2(lwheel, sector);
242  if (stat == 3)
243  masked = msks->get_etsoc_chdis_st3(lwheel, sector);
244 
245  if (!masked)
246  m_mask = false;
247 
248  if (tseta && !masked) {
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))
253  pos.set(6 - i);
254  if (tseta->quality(i))
255  qual.set(6 - i);
256  }
257  } else {
258  for (int i = 0; i < 7; i++) {
259  if (tseta->position(i))
260  pos.set(i);
261  if (tseta->quality(i))
262  qual.set(i);
263  }
264  }
265  }
266 
267  const L1MuDTTrackSegEta* tmpts =
268  new L1MuDTTrackSegEta(wheel, sector, stat, pos.to_ulong(), qual.to_ulong(), bx - bx_offset);
269  m_tseta.push_back(tmpts);
270  }
271  }
272 }
273 
274 //
275 // receive track addresses from 6 Sector Processors
276 //
278  // get track address code of all track segments
279  // 6*2 times 5 bits; valid range [1-22]
280 
281  int sector = m_epid;
282 
283  int i = 0;
284  for (int wheel = -3; wheel <= 3; wheel++) {
285  if (wheel == 0)
286  continue;
287  L1MuDTSecProcId tmpspid(wheel, sector);
288  for (int number = 0; number < 2; number++) {
289  const L1MuDTTrack* cand = m_tf.sp(tmpspid)->track(number);
290  const L1MuDTTrack* canD = m_tf.sp(tmpspid)->tracK(number);
291  if (cand) {
292  m_address[i] = cand->address().trackAddressCode();
293  if (!cand->empty()) {
294  m_TrackCand[i] = const_cast<L1MuDTTrack*>(cand);
295  m_TracKCand[i] = const_cast<L1MuDTTrack*>(canD);
296  }
297  i++;
298  }
299  }
300  }
301 }
302 
303 //
304 // run Eta Track Finder (ETF)
305 //
307  theEtaPatternLUT = c.getHandle(theEtaToken);
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)
315  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  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)
332  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)
339  good &= qual.test(bin - 1);
340  }
341 
342  if (good)
343  m_foundPattern.push_back(pattern.id());
344 
345  it++;
346  }
347 }
348 
349 //
350 // run Eta Matching Unit (EMU)
351 //
353  theQualPatternLUT = c.getHandle(theQualToken);
354 
355  // loop over all addresses
356  for (int i = 0; i < 12; i++) {
357  int adr = m_address[i];
358  if (adr == 0)
359  continue;
360  int sp = i / 2 + 1; //sector processor [1,6]
361 
362  // assign coarse eta value
363  if (!m_mask)
364  m_eta[i] = theQualPatternLUT->getCoarseEta(sp, adr);
365  if (m_eta[i] == 99)
366  m_eta[i] = 32;
367  if (m_eta[i] > 31)
368  m_eta[i] -= 64;
369  m_eta[i] += 32;
370 
371  if (m_foundPattern.empty())
372  continue;
373 
374  // get list of qualified patterns ordered by quality
375  // and compare with found patterns
376  const vector<short>& qualifiedPatterns = theQualPatternLUT->getQualifiedPatterns(sp, adr);
377  vector<short>::const_iterator iter;
378  vector<int>::const_iterator f_iter;
379  for (iter = qualifiedPatterns.begin(); iter != qualifiedPatterns.end(); iter++) {
380  f_iter = find(m_foundPattern.begin(), m_foundPattern.end(), (*iter));
381  // found
382  if (f_iter != m_foundPattern.end()) {
383  const L1MuDTEtaPattern p = theEtaPatternLUT->getPattern(*f_iter);
384  // assign fine eta value
385  m_fine[i] = true;
386  m_eta[i] = p.eta(); // improved eta
387  if (m_eta[i] == 99)
388  m_eta[i] = 32;
389  if (m_eta[i] > 31)
390  m_eta[i] -= 64;
391  m_eta[i] += 32;
392  m_pattern[i] = (*f_iter);
393  break;
394  }
395  }
396  }
397 
398  // if both tracks from one sector processor deliver the same track address
399  // both tracks get only a coarse eta value!
400 
401  // loop over sector processors
402  for (int i = 0; i < 6; i++) {
403  int idx1 = 2 * i;
404  int idx2 = 2 * i + 1;
405  int adr1 = m_address[idx1];
406  int adr2 = m_address[idx2];
407  if (adr1 == 0 || adr2 == 0)
408  continue;
409  if (adr1 == adr2 && !m_mask) {
410  // both tracks get coarse (default) eta value
411  m_eta[idx1] = theQualPatternLUT->getCoarseEta(i + 1, adr1);
412  if (m_eta[idx1] == 99)
413  m_eta[idx1] = 32;
414  if (m_eta[idx1] > 31)
415  m_eta[idx1] -= 64;
416  m_eta[idx1] += 32;
417  m_pattern[idx1] = 0;
418  m_fine[idx1] = false;
419  m_eta[idx2] = theQualPatternLUT->getCoarseEta(i + 1, adr2);
420  if (m_eta[idx2] == 99)
421  m_eta[idx2] = 32;
422  if (m_eta[idx2] > 31)
423  m_eta[idx2] -= 64;
424  m_eta[idx2] += 32;
425  m_pattern[idx2] = 0;
426  m_fine[idx2] = false;
427  }
428  }
429 }
430 
431 //
432 // assign values to track candidates
433 //
435  for (int i = 0; i < 12; i++) {
436  if (m_TrackCand[i]) {
437  if (m_eta[i] != 99) {
438  m_TrackCand[i]->setEta(m_eta[i]);
439  m_TracKCand[i]->setEta(m_eta[i]);
440  } else {
441  // if ( i/2 != 2 ) cerr << "L1MuDTEtaProcessor: assign invalid eta" << " " << m_address[i] << endl;
442  }
443  if (m_fine[i]) {
446  // find all contributing track segments
448  vector<const L1MuDTTrackSegEta*> TSeta;
449  const L1MuDTTrackSegEta* ts = nullptr;
450  for (int stat = 0; stat < 3; stat++) {
451  int wh = p.wheel(stat + 1);
452  int pos = p.position(stat + 1);
453  if (pos == 0)
454  continue;
455  ts = m_tseta[wh + 2 + stat * 5];
456  TSeta.push_back(ts);
457  }
458  m_TrackCand[i]->setTSeta(TSeta);
459  m_TracKCand[i]->setTSeta(TSeta);
460  }
461  }
462  }
463 }
464 
465 //
466 // get quality: id [0,26], stat [1,3]
467 //
469  // quality codes as defined in CMS Note 2001/027
470  // This QualityPatterns are used to have a defined Quality-Identifier for
471  // all possible found tracks.
472  // Therefore three integer numbers ( Station 1, 2, 3 from left to right )
473  // can have numbers like 0, 1 or 2
474  // 0 ... no hit is given
475  // 1 ... a LTRG is given
476  // 2 ... a HTRG is given
477 
478  const int qualcode[27][3] = {{0, 0, 0}, {1, 0, 0}, {0, 1, 0}, {0, 0, 1}, {2, 0, 0}, {0, 2, 0}, {0, 0, 2},
479  {1, 1, 0}, {1, 0, 1}, {0, 1, 1}, {2, 1, 0}, {1, 2, 0}, {2, 0, 1}, {1, 0, 2},
480  {0, 2, 1}, {0, 1, 2}, {2, 2, 0}, {2, 0, 2}, {0, 2, 2}, {1, 1, 1}, {2, 1, 1},
481  {1, 2, 1}, {1, 1, 2}, {2, 2, 1}, {2, 1, 2}, {1, 2, 2}, {2, 2, 2}};
482 
483  return qualcode[id][stat - 1];
484 }
void setFineEtaBit()
set fine eta bit
Definition: L1MuDTTrack.h:141
L1MuDTEtaProcessor(const L1MuDTTrackFinder &, int id, edm::ConsumesCollector &&iC)
constructor
void runEtaTrackFinder(const edm::EventSetup &c)
run Eta Track Finder (ETF)
ESGetTokenH3DDVariant esConsumes(std::string const &Record, edm::ConsumesCollector &)
Definition: DeDxTools.cc:283
LUT::const_iterator ETFLut_iter
const L1MuDTTrackFinder & m_tf
L1MuDTChambThDigi const * chThetaSegm(int wheel, int stat, int sect, int bx) const
bool get_etsoc_chdis_st2(int wh, int sc) const
virtual ~L1MuDTEtaProcessor()
destructor
edm::ESGetToken< L1MuDTEtaPatternLut, L1MuDTEtaPatternLutRcd > theEtaToken
edm::ESGetToken< L1MuDTTFMasks, L1MuDTTFMasksRcd > theMsksToken
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] ...
L1MuDTTrack * m_TracKCand[12]
void assign()
assign eta and etaFineBit
void setTSeta(const std::vector< const L1MuDTTrackSegEta *> &tsList)
set eta track segments used to form the muon candidate
Definition: L1MuDTTrack.cc:158
static int quality(int id, int stat)
get quality code; id [0,26], stat [1,3]
const L1MuDTTrack * tracK(int id) const
return pointer to muon candidate, index [0,1]
int position(const int i) const
edm::ESHandle< L1MuDTTFMasks > msks
Definition: config.py:1
L1MuDTEtaPattern getPattern(int id) const
get pattern with a given ID
void find(edm::Handle< EcalRecHitCollection > &hits, DetId thisDet, std::vector< EcalRecHitCollection::const_iterator > &hit, bool debug=false)
Definition: FindCaloHit.cc:19
bool get_etsoc_chdis_st1(int wh, int sc) const
int id() const
return Eta Processor identifier (0-11)
void setEta(int eta)
set eta-code of muon candidate
Definition: L1MuDTTrack.cc:114
virtual void run(int bx, const edm::Event &e, const edm::EventSetup &c)
run the Eta Processor
edm::ESHandle< L1MuDTEtaPatternLut > theEtaPatternLUT
std::vector< const L1MuDTTrackSegEta * > m_tseta
int getCoarseEta(int sp, int adr) const
get coarse eta value for a given sector processor [1-6] and address [1-22]
const L1MuDTSectorProcessor * sp(const L1MuDTSecProcId &) const
get a pointer to a Sector Processor
edm::ESGetToken< L1MuDTQualPatternLut, L1MuDTQualPatternLutRcd > theQualToken
void receiveAddresses()
receive addresses (from 6 Sector Processors)
bool get_etsoc_chdis_st3(int wh, int sc) const
void runEtaMatchingUnit(const edm::EventSetup &c)
run Eta Matching Unit (EMU)
std::vector< int > m_foundPattern
auto const good
min quality of good
void receiveData(int bx, const edm::Event &e, const edm::EventSetup &c)
receive data (eta trigger primitives)
static L1MuDTTFConfig * config()
return configuration
virtual void reset()
reset the Eta Processor
void print() const
print muon candidates found by the Eta Processor
static int position[264][3]
Definition: ReadPGInfo.cc:289
int quality(const int i) const
edm::ESHandle< L1MuDTQualPatternLut > theQualPatternLUT
bool getEtaTF() const
ETFLut_iter begin() const
return iterator which points to the first entry of the LUT
L1MuDTTrack * m_TrackCand[12]
ETFLut_iter end() const
return iterator which points to the one-past-last entry of the LUT
edm::EDGetTokenT< L1MuDTChambThContainer > m_DTDigiToken
const L1MuDTTrack * track(int id) const
return pointer to muon candidate, index [0,1]