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 8 of file PatternRecognition.h.

Member Typedef Documentation

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

Definition at line 11 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 12 of file PatternRecognition.cc.

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

Referenced by SectorProcessor::process_single_bx().

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

Definition at line 33 of file PatternRecognition.cc.

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

Referenced by configure().

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

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

Referenced by process().

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

Definition at line 329 of file PatternRecognition.cc.

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

Referenced by process().

333  {
334  int izone = zone-1;
335 
336  std::deque<EMTFHitCollection>::const_iterator ext_conv_hits_it = extended_conv_hits.begin();
337  std::deque<EMTFHitCollection>::const_iterator ext_conv_hits_end = extended_conv_hits.end();
338 
339  for (; ext_conv_hits_it != ext_conv_hits_end; ++ext_conv_hits_it) {
340  EMTFHitCollection::const_iterator conv_hits_it = ext_conv_hits_it->begin();
341  EMTFHitCollection::const_iterator conv_hits_end = ext_conv_hits_it->end();
342 
343  for (; conv_hits_it != conv_hits_end; ++conv_hits_it) {
344  if (conv_hits_it->Subsystem() == TriggerPrimitive::kRPC)
345  continue; // Don't use RPC hits for pattern formation
346 
347  if (conv_hits_it->Subsystem() == TriggerPrimitive::kGEM)
348  continue; // Don't use GEM hits for pattern formation
349 
350  if (conv_hits_it->Zone_code() & (1 << izone)) { // hit belongs to this zone
351  unsigned int layer = conv_hits_it->Station() - 1;
352  unsigned int bit = conv_hits_it->Zone_hit();
353  image.set_bit(layer, bit);
354  }
355  } // end loop over conv_hits
356  } // end loop over extended_conv_hits
357 }
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 187 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().

191  {
192  // Exit if no hits
193  int num_conv_hits = 0;
194  for (const auto& conv_hits : extended_conv_hits)
195  num_conv_hits += conv_hits.size();
196  bool early_exit = (num_conv_hits == 0) && (patt_lifetime_map.empty());
197 
198  if (early_exit)
199  return;
200 
201 
202  if (verbose_ > 0) { // debug
203  for (const auto& conv_hits : extended_conv_hits) {
204  for (const auto& conv_hit : conv_hits) {
205  if (conv_hit.Subsystem() == TriggerPrimitive::kCSC) {
206  std::cout << "CSC hit st: " << conv_hit.PC_station() << " ch: " << conv_hit.PC_chamber()
207  << " ph: " << conv_hit.Phi_fp() << " th: " << conv_hit.Theta_fp()
208  << " ph_hit: " << (1ul<<conv_hit.Ph_hit()) << " phzvl: " << conv_hit.Phzvl()
209  << " strip: " << conv_hit.Strip() << " wire: " << conv_hit.Wire() << " cpat: " << conv_hit.Pattern()
210  << " zone_hit: " << conv_hit.Zone_hit() << " zone_code: " << conv_hit.Zone_code()
211  << " bx: " << conv_hit.BX()
212  << std::endl;
213  }
214  }
215  }
216 
217  for (const auto& conv_hits : extended_conv_hits) {
218  for (const auto& conv_hit : conv_hits) {
219  if (conv_hit.Subsystem() == TriggerPrimitive::kRPC) {
220  std::cout << "RPC hit st: " << conv_hit.PC_station() << " ch: " << conv_hit.PC_chamber()
221  << " ph>>2: " << (conv_hit.Phi_fp()>>2) << " th>>2: " << (conv_hit.Theta_fp()>>2)
222  << " strip: " << conv_hit.Strip() << " roll: " << conv_hit.Roll() << " cpat: " << conv_hit.Pattern()
223  << " bx: " << conv_hit.BX()
224  << std::endl;
225  }
226  }
227  }
228 
229  for (const auto& conv_hits : extended_conv_hits) {
230  for (const auto& conv_hit : conv_hits) {
231  if (conv_hit.Subsystem() == TriggerPrimitive::kGEM) {
232  std::cout << "GEM hit st: " << conv_hit.PC_station() << " ch: " << conv_hit.PC_chamber()
233  << " ph: " << conv_hit.Phi_fp() << " th: " << conv_hit.Theta_fp()
234  << " strip: " << conv_hit.Strip() << " roll: " << conv_hit.Roll() << " cpat: " << conv_hit.Pattern()
235  << " bx: " << conv_hit.BX()
236  << std::endl;
237  }
238  }
239  }
240  } // end debug
241 
242  // Perform pattern recognition in each zone
244 
245  for (int izone = 0; izone < emtf::NUM_ZONES; ++izone) {
246  // Skip the zone if no hits and no patterns
247  if (is_zone_empty(izone+1, extended_conv_hits, patt_lifetime_map))
248  continue;
249 
250  // Make zone images
251  make_zone_image(izone+1, extended_conv_hits, zone_images.at(izone));
252 
253  // Detect patterns
254  process_single_zone(izone+1, zone_images.at(izone), patt_lifetime_map, zone_roads.at(izone));
255  }
256 
257  if (verbose_ > 2) { // debug
258  for (int izone = emtf::NUM_ZONES; izone >= 1; --izone) {
259  std::cout << "zone: " << izone << std::endl;
260  std::cout << zone_images.at(izone-1) << std::endl;
261  }
262  //for (const auto& kv : patt_lifetime_map) {
263  // std::cout << "zone: " << kv.first.at(0) << " izhit: " << kv.first.at(1) << " ipatt: " << kv.first.at(2) << " lifetime: " << kv.second << std::endl;
264  //}
265  }
266 
267  if (verbose_ > 0) { // debug
268  for (const auto& roads : zone_roads) {
269  for (const auto& road : reversed(roads)) {
270  std::cout << "pattern: z: " << road.Zone()-1 << " ph: " << road.Key_zhit()
271  << " q: " << to_hex(road.Quality_code()) << " ly: " << to_binary(road.Layer_code(), 3)
272  << " str: " << to_binary(road.Straightness(), 3) << " bx: " << road.BX()
273  << std::endl;
274  }
275  }
276  }
277 
278  // Sort patterns and select best three patterns in each zone
279  for (int izone = 0; izone < emtf::NUM_ZONES; ++izone) {
280  sort_single_zone(zone_roads.at(izone));
281  }
282 
283 }
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 359 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().

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

Definition at line 537 of file PatternRecognition.cc.

References maxRoadsPerZone_, and gen::n.

Referenced by process().

537  {
538  // First, order by key_zhit (highest to lowest)
539  struct {
540  typedef EMTFRoad value_type;
541  bool operator()(const value_type& lhs, const value_type& rhs) const {
542  return lhs.Key_zhit() > rhs.Key_zhit();
543  }
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; return; }
565 
566  // Assign the winner variable
567  for (unsigned iroad = 0; iroad < roads.size(); ++iroad) {
568  roads.at(iroad).set_winner( iroad );
569  }
570 }

Member Data Documentation

int PatternRecognition::bx_
private

Definition at line 51 of file PatternRecognition.h.

Referenced by configure(), and process_single_zone().

int PatternRecognition::bxWindow_
private

Definition at line 53 of file PatternRecognition.h.

Referenced by configure(), and process_single_zone().

int PatternRecognition::endcap_
private

Definition at line 51 of file PatternRecognition.h.

Referenced by configure(), and process_single_zone().

int PatternRecognition::maxRoadsPerZone_
private

Definition at line 56 of file PatternRecognition.h.

Referenced by configure(), and sort_single_zone().

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

Definition at line 54 of file PatternRecognition.h.

Referenced by configure(), and configure_details().

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

Definition at line 59 of file PatternRecognition.h.

Referenced by configure_details(), and process_single_zone().

int PatternRecognition::sector_
private

Definition at line 51 of file PatternRecognition.h.

Referenced by configure(), and process_single_zone().

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

Definition at line 54 of file PatternRecognition.h.

Referenced by configure(), and configure_details().

bool PatternRecognition::useSecondEarliest_
private

Definition at line 57 of file PatternRecognition.h.

Referenced by configure(), and process_single_zone().

bool PatternRecognition::useSymPatterns_
private

Definition at line 55 of file PatternRecognition.h.

Referenced by configure(), and configure_details().

int PatternRecognition::verbose_
private

Definition at line 51 of file PatternRecognition.h.

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