CMS 3D CMS Logo

List of all members | Public Types | Public Member Functions | Private Attributes
PatternRecognition Class Reference

#include <PatternRecognition.h>

Public Types

typedef std::array< int, 3 > pattern_ref_t
 

Public Member Functions

void configure (int verbose, int endcap, int sector, int bx, int bxWindow, const std::vector< std::string > &pattDefinitions, const std::vector< std::string > &symPattDefinitions, bool useSymPatterns, int maxRoadsPerZone, bool useSecondEarliest)
 
void configure_details ()
 
bool is_zone_empty (int zone, const std::deque< EMTFHitCollection > &extended_conv_hits, const std::map< pattern_ref_t, int > &patt_lifetime_map) const
 
void make_zone_image (int zone, const std::deque< EMTFHitCollection > &extended_conv_hits, PhiMemoryImage &image) const
 
void process (const std::deque< EMTFHitCollection > &extended_conv_hits, std::map< pattern_ref_t, int > &patt_lifetime_map, emtf::zone_array< EMTFRoadCollection > &zone_roads) const
 
void process_single_zone (int zone, PhiMemoryImage cloned_image, std::map< pattern_ref_t, int > &patt_lifetime_map, EMTFRoadCollection &roads) const
 
void sort_single_zone (EMTFRoadCollection &roads) const
 

Private Attributes

int bx_
 
int bxWindow_
 
int endcap_
 
int maxRoadsPerZone_
 
std::vector< std::string > pattDefinitions_
 
std::vector< PhiMemoryImagepatterns_
 
int sector_
 
std::vector< std::string > symPattDefinitions_
 
bool useSecondEarliest_
 
bool useSymPatterns_
 
int verbose_
 

Detailed Description

Definition at line 7 of file PatternRecognition.h.

Member Typedef Documentation

typedef std::array<int, 3> PatternRecognition::pattern_ref_t

Definition at line 10 of file PatternRecognition.h.

Member Function Documentation

void PatternRecognition::configure ( int  verbose,
int  endcap,
int  sector,
int  bx,
int  bxWindow,
const std::vector< std::string > &  pattDefinitions,
const std::vector< std::string > &  symPattDefinitions,
bool  useSymPatterns,
int  maxRoadsPerZone,
bool  useSecondEarliest 
)

Definition at line 11 of file PatternRecognition.cc.

References l1GtPatternGenerator_cfi::bx, bx_, bxWindow_, configure_details(), makeMuonMisalignmentScenario::endcap, endcap_, maxRoadsPerZone_, pattDefinitions_, sector_, symPattDefinitions_, useSecondEarliest_, useSymPatterns_, verbose, and verbose_.

Referenced by SectorProcessor::process_single_bx().

20  {
21  verbose_ = verbose;
22  endcap_ = endcap;
23  sector_ = sector;
24  bx_ = bx;
25 
26  bxWindow_ = bxWindow;
27  pattDefinitions_ = pattDefinitions;
28  symPattDefinitions_ = symPattDefinitions;
29  useSymPatterns_ = useSymPatterns;
30  maxRoadsPerZone_ = maxRoadsPerZone;
31  useSecondEarliest_ = useSecondEarliest;
32 
34 }
std::vector< std::string > pattDefinitions_
static int verbose
std::vector< std::string > symPattDefinitions_
void PatternRecognition::configure_details ( )

Definition at line 36 of file PatternRecognition.cc.

References gather_cfg::cout, mps_fire::i, pattDefinitions_, topSingleLeptonDQM_PU_cfi::pattern, patterns_, PhiMemoryImage::rotr(), alignCSCRings::s, PhiMemoryImage::set_bit(), PhiMemoryImage::set_straightness(), symPattDefinitions_, useSymPatterns_, and verbose_.

Referenced by configure().

36  {
37  patterns_.clear();
38 
39  // Parse pattern definitions
40  if (!useSymPatterns_) {
41  // Normal patterns
42  for (const auto& s : pattDefinitions_) {
43  const std::vector<std::string>& tokens = split_string(s, ',', ':'); // split by comma or colon
44  if (not(tokens.size() == 9)) // want to find 9 numbers
45  {
46  edm::LogError("L1T") << "tokens.size() = " << tokens.size();
47  return;
48  }
49 
50  std::vector<std::string>::const_iterator tokens_it = tokens.begin();
51 
52  // Get the 9 integers
53  // straightness, hits in ME1, hits in ME2, hits in ME3, hits in ME4
54  int straightness = std::stoi(*tokens_it++);
55  int st1_max = std::stoi(*tokens_it++);
56  int st1_min = std::stoi(*tokens_it++);
57  int st2_max = std::stoi(*tokens_it++);
58  int st2_min = std::stoi(*tokens_it++);
59  int st3_max = std::stoi(*tokens_it++);
60  int st3_min = std::stoi(*tokens_it++);
61  int st4_max = std::stoi(*tokens_it++);
62  int st4_min = std::stoi(*tokens_it++);
63 
64  // There can only be one zone hit in the key station in the pattern
65  // and it has to be this magic number
66  if (not(st2_max == padding_w_st3 && st2_min == padding_w_st3)) {
67  edm::LogError("L1T") << "st2_max = " << st2_max << ", padding_w_st3 = " << padding_w_st3
68  << ", st2_min = " << st2_min << ", padding_w_st3 = " << padding_w_st3;
69  return;
70  }
71 
72  // There is extra "padding" in st1 w.r.t st2,3,4
73  // Add the extra padding to st2,3,4
74  st2_max += padding_extra_w_st1;
75  st2_min += padding_extra_w_st1;
76  st3_max += padding_extra_w_st1;
77  st3_min += padding_extra_w_st1;
78  st4_max += padding_extra_w_st1;
79  st4_min += padding_extra_w_st1;
80 
81  // Create a pattern
83  pattern.set_straightness(straightness);
84  int i = 0;
85 
86  for (i = st1_min; i <= st1_max; i++)
87  pattern.set_bit(0, i);
88  for (i = st2_min; i <= st2_max; i++)
89  pattern.set_bit(1, i);
90  for (i = st3_min; i <= st3_max; i++)
91  pattern.set_bit(2, i);
92  for (i = st4_min; i <= st4_max; i++)
93  pattern.set_bit(3, i);
94 
95  // Remove the extra padding
96  pattern.rotr(padding_extra_w_st1);
97  patterns_.push_back(pattern);
98  }
99  if (not(patterns_.size() == pattDefinitions_.size())) {
100  edm::LogError("L1T") << "patterns_.size() = " << patterns_.size()
101  << ", pattDefinitions_.size() = " << pattDefinitions_.size();
102  return;
103  }
104 
105  } else {
106  // Symmetrical patterns
107  for (const auto& s : symPattDefinitions_) {
108  const std::vector<std::string>& tokens = split_string(s, ',', ':'); // split by comma or colon
109  if (not(tokens.size() == 17)) // want to find 17 numbers
110  {
111  edm::LogError("L1T") << "tokens.size() = " << tokens.size();
112  return;
113  }
114 
115  std::vector<std::string>::const_iterator tokens_it = tokens.begin();
116 
117  // Get the 17 integers
118  // straightness, hits in ME1, hits in ME2, hits in ME3, hits in ME4
119  int straightness = std::stoi(*tokens_it++);
120  int st1_max1 = std::stoi(*tokens_it++);
121  int st1_min1 = std::stoi(*tokens_it++);
122  int st1_max2 = std::stoi(*tokens_it++);
123  int st1_min2 = std::stoi(*tokens_it++);
124  int st2_max1 = std::stoi(*tokens_it++);
125  int st2_min1 = std::stoi(*tokens_it++);
126  int st2_max2 = std::stoi(*tokens_it++);
127  int st2_min2 = std::stoi(*tokens_it++);
128  int st3_max1 = std::stoi(*tokens_it++);
129  int st3_min1 = std::stoi(*tokens_it++);
130  int st3_max2 = std::stoi(*tokens_it++);
131  int st3_min2 = std::stoi(*tokens_it++);
132  int st4_max1 = std::stoi(*tokens_it++);
133  int st4_min1 = std::stoi(*tokens_it++);
134  int st4_max2 = std::stoi(*tokens_it++);
135  int st4_min2 = std::stoi(*tokens_it++);
136 
137  // There can only be one zone hit in the key station in the pattern
138  // and it has to be this magic number
139  if (not(st2_max1 == padding_w_st3 && st2_min1 == padding_w_st3)) {
140  edm::LogError("L1T") << "st2_max1 = " << st2_max1 << ", padding_w_st3 = " << padding_w_st3
141  << ", st2_min1 = " << st2_min1 << ", padding_w_st3 = " << padding_w_st3;
142  return;
143  }
144  if (not(st2_max2 == padding_w_st3 && st2_min2 == padding_w_st3)) {
145  edm::LogError("L1T") << "st2_max2 = " << st2_max2 << ", padding_w_st3 = " << padding_w_st3
146  << ", st2_min2 = " << st2_min2 << ", padding_w_st3 = " << padding_w_st3;
147  return;
148  }
149 
150  // There is extra "padding" in st1 w.r.t st2,3,4
151  // Add the extra padding to st2,3,4
152  st2_max1 += padding_extra_w_st1;
153  st2_min1 += padding_extra_w_st1;
154  st2_max2 += padding_extra_w_st1;
155  st2_min2 += padding_extra_w_st1;
156  st3_max1 += padding_extra_w_st1;
157  st3_min1 += padding_extra_w_st1;
158  st3_max2 += padding_extra_w_st1;
159  st3_min2 += padding_extra_w_st1;
160  st4_max1 += padding_extra_w_st1;
161  st4_min1 += padding_extra_w_st1;
162  st4_max2 += padding_extra_w_st1;
163  st4_min2 += padding_extra_w_st1;
164 
165  // Create a pattern
167  pattern.set_straightness(straightness);
168  int i = 0;
169 
170  for (i = st1_min1; i <= st1_max1; i++)
171  pattern.set_bit(0, i);
172  for (i = st1_min2; i <= st1_max2; i++)
173  pattern.set_bit(0, i);
174  for (i = st2_min1; i <= st2_max1; i++)
175  pattern.set_bit(1, i);
176  for (i = st2_min2; i <= st2_max2; i++)
177  pattern.set_bit(1, i);
178  for (i = st3_min1; i <= st3_max1; i++)
179  pattern.set_bit(2, i);
180  for (i = st3_min2; i <= st3_max2; i++)
181  pattern.set_bit(2, i);
182  for (i = st4_min1; i <= st4_max1; i++)
183  pattern.set_bit(3, i);
184  for (i = st4_min2; i <= st4_max2; i++)
185  pattern.set_bit(3, i);
186 
187  // Remove the extra padding
188  pattern.rotr(padding_extra_w_st1);
189  patterns_.push_back(pattern);
190  }
191  if (not(patterns_.size() == symPattDefinitions_.size())) {
192  edm::LogError("L1T") << "patterns_.size() = " << patterns_.size()
193  << ", symPattDefinitions_.size() = " << symPattDefinitions_.size();
194  return;
195  }
196  }
197 
198  if (verbose_ > 2) { // debug
199  for (const auto& pattern : patterns_) {
200  std::cout << "Pattern straightness: " << pattern.get_straightness() << " image: " << std::endl;
201  std::cout << pattern << std::endl;
202  }
203  }
204 }
void set_straightness(int s)
void set_bit(unsigned int layer, unsigned int bit)
std::vector< PhiMemoryImage > patterns_
std::vector< std::string > pattDefinitions_
int get_straightness() const
std::vector< std::string > symPattDefinitions_
void rotr(unsigned int n)
bool PatternRecognition::is_zone_empty ( int  zone,
const std::deque< EMTFHitCollection > &  extended_conv_hits,
const std::map< pattern_ref_t, int > &  patt_lifetime_map 
) const

Definition at line 296 of file PatternRecognition.cc.

References L1TMuon::TriggerPrimitive::kGEM, and L1TMuon::TriggerPrimitive::kRPC.

Referenced by process().

298  {
299  int izone = zone - 1;
300  int num_conv_hits = 0;
301  int num_patts = 0;
302 
303  std::deque<EMTFHitCollection>::const_iterator ext_conv_hits_it = extended_conv_hits.begin();
304  std::deque<EMTFHitCollection>::const_iterator ext_conv_hits_end = extended_conv_hits.end();
305 
306  for (; ext_conv_hits_it != ext_conv_hits_end; ++ext_conv_hits_it) {
307  EMTFHitCollection::const_iterator conv_hits_it = ext_conv_hits_it->begin();
308  EMTFHitCollection::const_iterator conv_hits_end = ext_conv_hits_it->end();
309 
310  for (; conv_hits_it != conv_hits_end; ++conv_hits_it) {
311  if (not(conv_hits_it->PC_segment() <= 4)) // With 2 unique LCTs per chamber, 4 possible strip/wire combinations
312  {
313  edm::LogError("L1T") << "conv_hits_it->PC_segment() = " << conv_hits_it->PC_segment();
314  return true;
315  }
316 
317  if (conv_hits_it->Subsystem() == TriggerPrimitive::kRPC)
318  continue; // Don't use RPC hits for pattern formation
319 
320  if (conv_hits_it->Subsystem() == TriggerPrimitive::kGEM)
321  continue; // Don't use GEM hits for pattern formation
322 
323  if (conv_hits_it->Zone_code() & (1 << izone)) { // hit belongs to this zone
324  num_conv_hits += 1;
325  }
326  } // end loop over conv_hits
327  } // end loop over extended_conv_hits
328 
329  std::map<pattern_ref_t, int>::const_iterator patt_lifetime_map_it = patt_lifetime_map.begin();
330  std::map<pattern_ref_t, int>::const_iterator patt_lifetime_map_end = patt_lifetime_map.end();
331 
332  for (; patt_lifetime_map_it != patt_lifetime_map_end; ++patt_lifetime_map_it) {
333  if (patt_lifetime_map_it->first.at(0) == zone) {
334  num_patts += 1;
335  }
336  } // end loop over patt_lifetime_map
337 
338  return (num_conv_hits == 0) && (num_patts == 0);
339 }
void PatternRecognition::make_zone_image ( int  zone,
const std::deque< EMTFHitCollection > &  extended_conv_hits,
PhiMemoryImage image 
) const

Definition at line 341 of file PatternRecognition.cc.

References L1TMuon::TriggerPrimitive::kGEM, L1TMuon::TriggerPrimitive::kRPC, and PhiMemoryImage::set_bit().

Referenced by process().

343  {
344  int izone = zone - 1;
345 
346  std::deque<EMTFHitCollection>::const_iterator ext_conv_hits_it = extended_conv_hits.begin();
347  std::deque<EMTFHitCollection>::const_iterator ext_conv_hits_end = extended_conv_hits.end();
348 
349  for (; ext_conv_hits_it != ext_conv_hits_end; ++ext_conv_hits_it) {
350  EMTFHitCollection::const_iterator conv_hits_it = ext_conv_hits_it->begin();
351  EMTFHitCollection::const_iterator conv_hits_end = ext_conv_hits_it->end();
352 
353  for (; conv_hits_it != conv_hits_end; ++conv_hits_it) {
354  if (conv_hits_it->Subsystem() == TriggerPrimitive::kRPC)
355  continue; // Don't use RPC hits for pattern formation
356 
357  if (conv_hits_it->Subsystem() == TriggerPrimitive::kGEM)
358  continue; // Don't use GEM hits for pattern formation
359 
360  if (conv_hits_it->Zone_code() & (1 << izone)) { // hit belongs to this zone
361  unsigned int layer = conv_hits_it->Station() - 1;
362  unsigned int bit = conv_hits_it->Zone_hit();
363  image.set_bit(layer, bit);
364  }
365  } // end loop over conv_hits
366  } // end loop over extended_conv_hits
367 }
void set_bit(unsigned int layer, unsigned int bit)
void PatternRecognition::process ( const std::deque< EMTFHitCollection > &  extended_conv_hits,
std::map< pattern_ref_t, int > &  patt_lifetime_map,
emtf::zone_array< EMTFRoadCollection > &  zone_roads 
) const

Definition at line 206 of file PatternRecognition.cc.

References gather_cfg::cout, is_zone_empty(), L1TMuon::TriggerPrimitive::kCSC, L1TMuon::TriggerPrimitive::kGEM, L1TMuon::TriggerPrimitive::kRPC, make_zone_image(), emtf::NUM_ZONES, process_single_zone(), sort_single_zone(), to_hex(), and verbose_.

Referenced by SectorProcessor::process_single_bx().

208  {
209  // Exit if no hits
210  int num_conv_hits = 0;
211  for (const auto& conv_hits : extended_conv_hits)
212  num_conv_hits += conv_hits.size();
213  bool early_exit = (num_conv_hits == 0) && (patt_lifetime_map.empty());
214 
215  if (early_exit)
216  return;
217 
218  if (verbose_ > 0) { // debug
219  for (const auto& conv_hits : extended_conv_hits) {
220  for (const auto& conv_hit : conv_hits) {
221  if (conv_hit.Subsystem() == TriggerPrimitive::kCSC) {
222  std::cout << "CSC hit st: " << conv_hit.PC_station() << " ch: " << conv_hit.PC_chamber()
223  << " ph: " << conv_hit.Phi_fp() << " th: " << conv_hit.Theta_fp()
224  << " ph_hit: " << (1ul << conv_hit.Ph_hit()) << " phzvl: " << conv_hit.Phzvl()
225  << " strip: " << conv_hit.Strip() << " wire: " << conv_hit.Wire() << " cpat: " << conv_hit.Pattern()
226  << " zone_hit: " << conv_hit.Zone_hit() << " zone_code: " << conv_hit.Zone_code()
227  << " bx: " << conv_hit.BX() << std::endl;
228  }
229  }
230  }
231 
232  for (const auto& conv_hits : extended_conv_hits) {
233  for (const auto& conv_hit : conv_hits) {
234  if (conv_hit.Subsystem() == TriggerPrimitive::kRPC) {
235  std::cout << "RPC hit st: " << conv_hit.PC_station() << " ch: " << conv_hit.PC_chamber()
236  << " ph>>2: " << (conv_hit.Phi_fp() >> 2) << " th>>2: " << (conv_hit.Theta_fp() >> 2)
237  << " strip: " << conv_hit.Strip() << " roll: " << conv_hit.Roll() << " cpat: " << conv_hit.Pattern()
238  << " bx: " << conv_hit.BX() << std::endl;
239  }
240  }
241  }
242 
243  for (const auto& conv_hits : extended_conv_hits) {
244  for (const auto& conv_hit : conv_hits) {
245  if (conv_hit.Subsystem() == TriggerPrimitive::kGEM) {
246  std::cout << "GEM hit st: " << conv_hit.PC_station() << " ch: " << conv_hit.PC_chamber()
247  << " ph: " << conv_hit.Phi_fp() << " th: " << conv_hit.Theta_fp() << " strip: " << conv_hit.Strip()
248  << " roll: " << conv_hit.Roll() << " cpat: " << conv_hit.Pattern() << " bx: " << conv_hit.BX()
249  << std::endl;
250  }
251  }
252  }
253  } // end debug
254 
255  // Perform pattern recognition in each zone
257 
258  for (int izone = 0; izone < emtf::NUM_ZONES; ++izone) {
259  // Skip the zone if no hits and no patterns
260  if (is_zone_empty(izone + 1, extended_conv_hits, patt_lifetime_map))
261  continue;
262 
263  // Make zone images
264  make_zone_image(izone + 1, extended_conv_hits, zone_images.at(izone));
265 
266  // Detect patterns
267  process_single_zone(izone + 1, zone_images.at(izone), patt_lifetime_map, zone_roads.at(izone));
268  }
269 
270  if (verbose_ > 2) { // debug
271  for (int izone = emtf::NUM_ZONES; izone >= 1; --izone) {
272  std::cout << "zone: " << izone << std::endl;
273  std::cout << zone_images.at(izone - 1) << std::endl;
274  }
275  //for (const auto& kv : patt_lifetime_map) {
276  // std::cout << "zone: " << kv.first.at(0) << " izhit: " << kv.first.at(1) << " ipatt: " << kv.first.at(2) << " lifetime: " << kv.second << std::endl;
277  //}
278  }
279 
280  if (verbose_ > 0) { // debug
281  for (const auto& roads : zone_roads) {
282  for (const auto& road : reversed(roads)) {
283  std::cout << "pattern: z: " << road.Zone() - 1 << " ph: " << road.Key_zhit()
284  << " q: " << to_hex(road.Quality_code()) << " ly: " << to_binary(road.Layer_code(), 3)
285  << " str: " << to_binary(road.Straightness(), 3) << " bx: " << road.BX() << std::endl;
286  }
287  }
288  }
289 
290  // Sort patterns and select best three patterns in each zone
291  for (int izone = 0; izone < emtf::NUM_ZONES; ++izone) {
292  sort_single_zone(zone_roads.at(izone));
293  }
294 }
static char to_hex(unsigned int i)
Definition: types.cc:27
int NUM_ZONES
Definition: Common.h:67
void sort_single_zone(EMTFRoadCollection &roads) const
void process_single_zone(int zone, PhiMemoryImage cloned_image, std::map< pattern_ref_t, int > &patt_lifetime_map, EMTFRoadCollection &roads) const
void make_zone_image(int zone, const std::deque< EMTFHitCollection > &extended_conv_hits, PhiMemoryImage &image) const
std::array< T, NUM_ZONES > zone_array
Definition: Common.h:78
bool is_zone_empty(int zone, const std::deque< EMTFHitCollection > &extended_conv_hits, const std::map< pattern_ref_t, int > &patt_lifetime_map) const
void PatternRecognition::process_single_zone ( int  zone,
PhiMemoryImage  cloned_image,
std::map< pattern_ref_t, int > &  patt_lifetime_map,
EMTFRoadCollection roads 
) const

Definition at line 369 of file PatternRecognition.cc.

References electrons_cff::bool, bx_, bxWindow_, endcap_, PhiMemoryImage::get_straightness(), cuy::ins, eostools::move(), emtf::NUM_ZONE_HITS, PhiMemoryImage::op_and(), patt, patterns_, PhiMemoryImage::rotl(), PhiMemoryImage::rotr(), sector_, l1t::EMTFRoad::set_bx(), l1t::EMTFRoad::set_endcap(), l1t::EMTFRoad::set_key_zhit(), l1t::EMTFRoad::set_layer_code(), l1t::EMTFRoad::set_pattern(), l1t::EMTFRoad::set_quality_code(), l1t::EMTFRoad::set_sector(), l1t::EMTFRoad::set_sector_idx(), l1t::EMTFRoad::set_straightness(), l1t::EMTFRoad::set_zone(), useSecondEarliest_, and x.

Referenced by process().

372  {
373  roads.clear();
374 
375  const int drift_time = bxWindow_ - 1;
376  const int npatterns = patterns_.size();
377 
378  // The zone hit image is rotated/shifted before comparing with patterns
379  // First, rotate left/shift up to the zone hit in the key station
380  cloned_image.rotl(padding_w_st3);
381 
382  for (int izhit = 0; izhit < emtf::NUM_ZONE_HITS; ++izhit) {
383  // The zone hit image is rotated/shift before comparing with patterns
384  // For every zone hit, rotate right/shift down by one
385  if (izhit > 0)
386  cloned_image.rotr(1);
387 
388  int max_quality_code = -1;
389  EMTFRoad tmp_road;
390 
391  // Compare with patterns
392  for (int ipatt = 0; ipatt < npatterns; ++ipatt) {
393  const PhiMemoryImage& patt = patterns_.at(ipatt);
394  const pattern_ref_t patt_ref = {{zone, izhit, ipatt}}; // due to GCC bug, use {{}} instead of {}
395  int straightness = patt.get_straightness();
396 
397  bool is_lifetime_up = false;
398 
399  int layer_code = patt.op_and(cloned_image); // kind of like AND operator
400  bool more_than_one = (layer_code != 0) && (layer_code != 1) && (layer_code != 2) && (layer_code != 4);
401  bool more_than_zero = (layer_code != 0);
402 
403  if (more_than_zero) {
404  // Insert this pattern
405  auto ins = patt_lifetime_map.insert({patt_ref, 0});
406 
407  if (!useSecondEarliest_) {
408  // Use earliest
409  auto patt_ins = ins.first; // iterator of patt_lifetime_map pointing to this pattern
410  bool patt_exists = !ins.second;
411 
412  if (patt_exists) { // if exists
413  if (patt_ins->second == drift_time) { // is lifetime up?
414  is_lifetime_up = true;
415  }
416  }
417  patt_ins->second += 1; // bx starts counting at any hit in the pattern, even single
418 
419  } else {
420  // Use 2nd earliest
421  auto patt_ins = ins.first; // iterator of patt_lifetime_map pointing to this pattern
422  int bx_shifter = patt_ins->second;
423  int bx2 = bool(bx_shifter & (1 << 2));
424  int bx1 = bool(bx_shifter & (1 << 1));
425  int bx0 = bool(bx_shifter & (1 << 0));
426 
427  // is lifetime up?
428  if (drift_time == 2 && bx2 == 0 && bx1 == 1) {
429  is_lifetime_up = true;
430  } else if (drift_time == 1 && bx1 == 0 && bx0 == 1) {
431  is_lifetime_up = true;
432  } else if (drift_time == 0) {
433  is_lifetime_up = true;
434  } else {
435  // The bx_shifter keeps track of a number of booleans from BX 0, 1, ..., drift_time.
436  if (not(drift_time == 2 || drift_time == 1 || drift_time == 0)) {
437  edm::LogError("L1T") << "drift_time = " << drift_time << ", not 0 or 1 or 2";
438  return;
439  }
440  }
441 
442  bx2 = bx1;
443  bx1 = bx0;
444  bx0 = more_than_zero; // put 1 in shifter when one layer is hit
445  bx_shifter = (bx2 << 2) | (bx1 << 1) | bx0;
446  patt_ins->second = bx_shifter;
447  }
448 
449  } else {
450  // Zero hit
451  patt_lifetime_map.erase(patt_ref); // erase if exists
452  }
453 
454  // If lifetime is up, and not single-layer hit patterns (stations 3&4 considered
455  // as a single layer), find quality of this pattern
456  if (is_lifetime_up && more_than_one) {
457  // This quality code scheme is giving almost-equal priority to
458  // more stations and better straightness
459  // Station 1 has higher weight, station 2 lower, stations 3&4 lowest
460  int quality_code =
461  ((((straightness >> 2) & 1) << 5) | (((straightness >> 1) & 1) << 3) | (((straightness >> 0) & 1) << 1) |
462  (((layer_code >> 2) & 1) << 4) | (((layer_code >> 1) & 1) << 2) | (((layer_code >> 0) & 1) << 0));
463 
464  // Create a road (fired pattern)
465  EMTFRoad road;
466  road.set_endcap((endcap_ == 1) ? 1 : -1);
467  road.set_sector(sector_);
468  road.set_sector_idx((endcap_ == 1) ? sector_ - 1 : sector_ + 5);
469  road.set_bx(bx_ - drift_time);
470 
471  road.set_zone(patt_ref.at(0));
472  road.set_key_zhit(patt_ref.at(1));
473  road.set_pattern(patt_ref.at(2));
474 
475  road.set_straightness(straightness);
476  road.set_layer_code(layer_code);
477  road.set_quality_code(quality_code);
478 
479  // Find max quality code in a given key_zhit
480  if (max_quality_code < quality_code) {
481  max_quality_code = quality_code;
482  tmp_road = std::move(road);
483  }
484  } // end if is_lifetime_up
485 
486  } // end loop over patterns
487 
488  // Output road
489  if (max_quality_code != -1) {
490  roads.push_back(tmp_road);
491  }
492 
493  } // end loop over zone hits
494 
495  // Ghost cancellation logic by considering neighbor patterns
496 
497  if (!roads.empty()) {
498  std::array<int, emtf::NUM_ZONE_HITS> quality_codes;
499  quality_codes.fill(0);
500 
501  EMTFRoadCollection::iterator roads_it = roads.begin();
502  EMTFRoadCollection::iterator roads_end = roads.end();
503 
504  for (; roads_it != roads_end; ++roads_it) {
505  quality_codes.at(roads_it->Key_zhit()) = roads_it->Quality_code();
506  }
507 
508  roads_it = roads.begin();
509  roads_end = roads.end();
510 
511  for (; roads_it != roads_end; ++roads_it) {
512  int izhit = roads_it->Key_zhit();
513 
514  // Center quality is the current one
515  int qc = quality_codes.at(izhit);
516 
517  // Left and right qualities are the neighbors
518  // Protect against the right end and left end special cases
519  int ql = (izhit == emtf::NUM_ZONE_HITS - 1) ? 0 : quality_codes.at(izhit + 1);
520  int qr = (izhit == 0) ? 0 : quality_codes.at(izhit - 1);
521 
522  // Cancellation conditions
523  if (qc <= ql || qc < qr) { // this pattern is lower quality than neighbors
524  roads_it->set_quality_code(0); // cancel
525  }
526  }
527  }
528 
529  // Erase roads with quality_code == 0
530  // using erase-remove idiom
531  struct {
532  typedef EMTFRoad value_type;
533  bool operator()(const value_type& x) const { return (x.Quality_code() == 0); }
534  } quality_code_zero_pred;
535 
536  roads.erase(std::remove_if(roads.begin(), roads.end(), quality_code_zero_pred), roads.end());
537 }
unsigned int op_and(const PhiMemoryImage &other) const
int NUM_ZONE_HITS
Definition: Common.h:68
std::vector< PhiMemoryImage > patterns_
void set_pattern(int bits)
Definition: EMTFRoad.h:32
void set_quality_code(int bits)
Definition: EMTFRoad.h:35
void set_key_zhit(int bits)
Definition: EMTFRoad.h:31
void set_zone(int bits)
Definition: EMTFRoad.h:30
ins
Definition: cuy.py:314
void set_sector(int bits)
Definition: EMTFRoad.h:27
void set_straightness(int bits)
Definition: EMTFRoad.h:33
int get_straightness() const
void rotr(unsigned int n)
void rotl(unsigned int n)
void set_endcap(int bits)
Definition: EMTFRoad.h:26
void set_bx(int bits)
Definition: EMTFRoad.h:29
void set_layer_code(int bits)
Definition: EMTFRoad.h:34
void set_sector_idx(int bits)
Definition: EMTFRoad.h:28
std::array< int, 3 > pattern_ref_t
def move(src, dest)
Definition: eostools.py:511
float patt[4][130000]
Definition: HijingWrapper.h:48
void PatternRecognition::sort_single_zone ( EMTFRoadCollection roads) const

Definition at line 539 of file PatternRecognition.cc.

References maxRoadsPerZone_, and dqmiodumpmetadata::n.

Referenced by process().

539  {
540  // First, order by key_zhit (highest to lowest)
541  struct {
542  typedef EMTFRoad value_type;
543  bool operator()(const value_type& lhs, const value_type& rhs) const { return lhs.Key_zhit() > rhs.Key_zhit(); }
544  } greater_zhit_cmp;
545 
546  std::sort(roads.begin(), roads.end(), greater_zhit_cmp);
547 
548  // Second, sort by quality_code (highest to lowest), but preserving the original order if qualities are equal
549  struct {
550  typedef EMTFRoad value_type;
551  bool operator()(const value_type& lhs, const value_type& rhs) const {
552  return lhs.Quality_code() > rhs.Quality_code();
553  }
554  } greater_quality_cmp;
555 
556  std::stable_sort(roads.begin(), roads.end(), greater_quality_cmp);
557 
558  // Finally, select 3 best
559  const size_t n = maxRoadsPerZone_;
560  if (roads.size() > n) {
561  roads.erase(roads.begin() + n, roads.end());
562  }
563  if (not(roads.size() <= n)) {
564  edm::LogError("L1T") << "roads.size() = " << roads.size() << ", n = " << n;
565  return;
566  }
567 
568  // Assign the winner variable
569  for (unsigned iroad = 0; iroad < roads.size(); ++iroad) {
570  roads.at(iroad).set_winner(iroad);
571  }
572 }

Member Data Documentation

int PatternRecognition::bx_
private

Definition at line 43 of file PatternRecognition.h.

Referenced by configure(), and process_single_zone().

int PatternRecognition::bxWindow_
private

Definition at line 45 of file PatternRecognition.h.

Referenced by configure(), and process_single_zone().

int PatternRecognition::endcap_
private

Definition at line 43 of file PatternRecognition.h.

Referenced by configure(), and process_single_zone().

int PatternRecognition::maxRoadsPerZone_
private

Definition at line 48 of file PatternRecognition.h.

Referenced by configure(), and sort_single_zone().

std::vector<std::string> PatternRecognition::pattDefinitions_
private

Definition at line 46 of file PatternRecognition.h.

Referenced by configure(), and configure_details().

std::vector<PhiMemoryImage> PatternRecognition::patterns_
private

Definition at line 51 of file PatternRecognition.h.

Referenced by configure_details(), and process_single_zone().

int PatternRecognition::sector_
private

Definition at line 43 of file PatternRecognition.h.

Referenced by configure(), and process_single_zone().

std::vector<std::string> PatternRecognition::symPattDefinitions_
private

Definition at line 46 of file PatternRecognition.h.

Referenced by configure(), and configure_details().

bool PatternRecognition::useSecondEarliest_
private

Definition at line 49 of file PatternRecognition.h.

Referenced by configure(), and process_single_zone().

bool PatternRecognition::useSymPatterns_
private

Definition at line 47 of file PatternRecognition.h.

Referenced by configure(), and configure_details().

int PatternRecognition::verbose_
private

Definition at line 43 of file PatternRecognition.h.

Referenced by configure(), configure_details(), and process().