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

◆ pattern_ref_t

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

Definition at line 10 of file PatternRecognition.h.

Member Function Documentation

◆ configure()

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 simKBmtfDigis_cfi::bx, bx_, bxWindow_, configure_details(), makeMuonMisalignmentScenario::endcap, endcap_, maxRoadsPerZone_, pattDefinitions_, hgcalTBTopologyTester_cfi::sector, sector_, symPattDefinitions_, useSecondEarliest_, useSymPatterns_, verbose, and verbose_.

Referenced by SectorProcessor::process_single_bx().

21  {
22  verbose_ = verbose;
23  endcap_ = endcap;
24  sector_ = sector;
25  bx_ = bx;
26 
27  bxWindow_ = bxWindow;
28  pattDefinitions_ = pattDefinitions;
29  symPattDefinitions_ = symPattDefinitions;
30  useSymPatterns_ = useSymPatterns;
31  maxRoadsPerZone_ = maxRoadsPerZone;
32  useSecondEarliest_ = useSecondEarliest;
33 
35 }
bool verbose
std::vector< std::string > pattDefinitions_
std::vector< std::string > symPattDefinitions_

◆ configure_details()

void PatternRecognition::configure_details ( )

Definition at line 37 of file PatternRecognition.cc.

References bxWindow_, gather_cfg::cout, emtf_assert, mps_fire::i, pattDefinitions_, topSingleLeptonDQM_PU_cfi::pattern, patterns_, alignCSCRings::s, symPattDefinitions_, useSymPatterns_, and verbose_.

Referenced by configure().

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

◆ is_zone_empty()

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 270 of file PatternRecognition.cc.

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

Referenced by process().

272  {
273  int izone = zone - 1;
274  int num_conv_hits = 0;
275  int num_patts = 0;
276 
277  std::deque<EMTFHitCollection>::const_iterator ext_conv_hits_it = extended_conv_hits.begin();
278  std::deque<EMTFHitCollection>::const_iterator ext_conv_hits_end = extended_conv_hits.end();
279 
280  for (; ext_conv_hits_it != ext_conv_hits_end; ++ext_conv_hits_it) {
281  EMTFHitCollection::const_iterator conv_hits_it = ext_conv_hits_it->begin();
282  EMTFHitCollection::const_iterator conv_hits_end = ext_conv_hits_it->end();
283 
284  for (; conv_hits_it != conv_hits_end; ++conv_hits_it) {
285  emtf_assert(conv_hits_it->PC_segment() <=
286  4); // With 2 unique LCTs per chamber, 4 possible strip/wire combinations
287 
288  if (conv_hits_it->Subsystem() == L1TMuon::kRPC)
289  continue; // Don't use RPC hits for pattern formation
290 
291  if (conv_hits_it->Subsystem() == L1TMuon::kGEM)
292  continue; // Don't use GEM hits for pattern formation
293 
294  if (conv_hits_it->Zone_code() & (1 << izone)) { // hit belongs to this zone
295  num_conv_hits += 1;
296  }
297  } // end loop over conv_hits
298  } // end loop over extended_conv_hits
299 
300  std::map<pattern_ref_t, int>::const_iterator patt_lifetime_map_it = patt_lifetime_map.begin();
301  std::map<pattern_ref_t, int>::const_iterator patt_lifetime_map_end = patt_lifetime_map.end();
302 
303  for (; patt_lifetime_map_it != patt_lifetime_map_end; ++patt_lifetime_map_it) {
304  if (patt_lifetime_map_it->first.at(0) == zone) {
305  num_patts += 1;
306  }
307  } // end loop over patt_lifetime_map
308 
309  return (num_conv_hits == 0) && (num_patts == 0);
310 }
#define emtf_assert(expr)
Definition: DebugTools.h:18

◆ make_zone_image()

void PatternRecognition::make_zone_image ( int  zone,
const std::deque< EMTFHitCollection > &  extended_conv_hits,
PhiMemoryImage image 
) const

Definition at line 312 of file PatternRecognition.cc.

References triggerObjects_cff::bit, L1TMuon::kGEM, L1TMuon::kRPC, pixelTopology::layer, and PhiMemoryImage::set_bit().

Referenced by process().

314  {
315  int izone = zone - 1;
316 
317  std::deque<EMTFHitCollection>::const_iterator ext_conv_hits_it = extended_conv_hits.begin();
318  std::deque<EMTFHitCollection>::const_iterator ext_conv_hits_end = extended_conv_hits.end();
319 
320  for (; ext_conv_hits_it != ext_conv_hits_end; ++ext_conv_hits_it) {
321  EMTFHitCollection::const_iterator conv_hits_it = ext_conv_hits_it->begin();
322  EMTFHitCollection::const_iterator conv_hits_end = ext_conv_hits_it->end();
323 
324  for (; conv_hits_it != conv_hits_end; ++conv_hits_it) {
325  if (conv_hits_it->Subsystem() == L1TMuon::kRPC)
326  continue; // Don't use RPC hits for pattern formation
327 
328  if (conv_hits_it->Subsystem() == L1TMuon::kGEM)
329  continue; // Don't use GEM hits for pattern formation
330 
331  if (conv_hits_it->Zone_code() & (1 << izone)) { // hit belongs to this zone
332  unsigned int layer = conv_hits_it->Station() - 1;
333  unsigned int bit = conv_hits_it->Zone_hit();
334  image.set_bit(layer, bit);
335  }
336  } // end loop over conv_hits
337  } // end loop over extended_conv_hits
338 }
void set_bit(unsigned int layer, unsigned int bit)
constexpr std::array< uint8_t, layerIndexSize< TrackerTraits > > layer

◆ process()

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 181 of file PatternRecognition.cc.

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

Referenced by SectorProcessor::process_single_bx().

183  {
184  // Exit if no hits
185  int num_conv_hits = 0;
186  for (const auto& conv_hits : extended_conv_hits)
187  num_conv_hits += conv_hits.size();
188  bool early_exit = (num_conv_hits == 0) && (patt_lifetime_map.empty());
189 
190  if (early_exit)
191  return;
192 
193  if (verbose_ > 0) { // debug
194  for (const auto& conv_hits : extended_conv_hits) {
195  for (const auto& conv_hit : conv_hits) {
196  if (conv_hit.Subsystem() == L1TMuon::kCSC) {
197  std::cout << "CSC hit st: " << conv_hit.PC_station() << " ch: " << conv_hit.PC_chamber()
198  << " ph: " << conv_hit.Phi_fp() << " th: " << conv_hit.Theta_fp() << " strip: " << conv_hit.Strip()
199  << " wire: " << conv_hit.Wire() << " cpat: " << conv_hit.Pattern()
200  << " zone_hit: " << conv_hit.Zone_hit() << " zone_code: " << conv_hit.Zone_code()
201  << " bx: " << conv_hit.BX() << std::endl;
202  }
203  }
204  }
205 
206  for (const auto& conv_hits : extended_conv_hits) {
207  for (const auto& conv_hit : conv_hits) {
208  if (conv_hit.Subsystem() == L1TMuon::kRPC) {
209  std::cout << "RPC hit st: " << conv_hit.PC_station() << " ch: " << conv_hit.PC_chamber()
210  << " ph>>2: " << (conv_hit.Phi_fp() >> 2) << " th>>2: " << (conv_hit.Theta_fp() >> 2)
211  << " strip: " << conv_hit.Strip() << " roll: " << conv_hit.Roll() << " cpat: " << conv_hit.Pattern()
212  << " bx: " << conv_hit.BX() << 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() == L1TMuon::kGEM) {
220  std::cout << "GEM hit st: " << conv_hit.PC_station() << " ch: " << conv_hit.PC_chamber()
221  << " ph: " << conv_hit.Phi_fp() << " th: " << conv_hit.Theta_fp() << " strip: " << conv_hit.Strip()
222  << " roll: " << conv_hit.Roll() << " cpat: " << conv_hit.Pattern() << " bx: " << conv_hit.BX()
223  << std::endl;
224  }
225  }
226  }
227  } // end debug
228 
229  // Perform pattern recognition in each zone
231 
232  for (int izone = 0; izone < emtf::NUM_ZONES; ++izone) {
233  // Skip the zone if no hits and no patterns
234  if (is_zone_empty(izone + 1, extended_conv_hits, patt_lifetime_map))
235  continue;
236 
237  // Make zone images
238  make_zone_image(izone + 1, extended_conv_hits, zone_images.at(izone));
239 
240  // Detect patterns
241  process_single_zone(izone + 1, zone_images.at(izone), patt_lifetime_map, zone_roads.at(izone));
242  }
243 
244  if (verbose_ > 2) { // debug
245  for (int izone = emtf::NUM_ZONES; izone >= 1; --izone) {
246  std::cout << "zone: " << izone << std::endl;
247  std::cout << zone_images.at(izone - 1) << std::endl;
248  }
249  //for (const auto& kv : patt_lifetime_map) {
250  // std::cout << "zone: " << kv.first.at(0) << " izhit: " << kv.first.at(1) << " ipatt: " << kv.first.at(2) << " lifetime: " << kv.second << std::endl;
251  //}
252  }
253 
254  if (verbose_ > 0) { // debug
255  for (const auto& roads : zone_roads) {
256  for (const auto& road : reversed(roads)) {
257  std::cout << "pattern: z: " << road.Zone() - 1 << " ph: " << road.Key_zhit()
258  << " q: " << to_hex(road.Quality_code()) << " ly: " << to_binary(road.Layer_code(), 3)
259  << " str: " << to_binary(road.Straightness(), 3) << " bx: " << road.BX() << std::endl;
260  }
261  }
262  }
263 
264  // Sort patterns and select best three patterns in each zone
265  for (int izone = 0; izone < emtf::NUM_ZONES; ++izone) {
266  sort_single_zone(zone_roads.at(izone));
267  }
268 }
static char to_hex(unsigned int i)
Definition: types.cc:26
void sort_single_zone(EMTFRoadCollection &roads) const
constexpr int NUM_ZONES
Definition: Common.h:54
void process_single_zone(int zone, PhiMemoryImage cloned_image, std::map< pattern_ref_t, int > &patt_lifetime_map, EMTFRoadCollection &roads) const
std::array< T, NUM_ZONES > zone_array
Definition: Common.h:65
void make_zone_image(int zone, const std::deque< EMTFHitCollection > &extended_conv_hits, PhiMemoryImage &image) const
bool is_zone_empty(int zone, const std::deque< EMTFHitCollection > &extended_conv_hits, const std::map< pattern_ref_t, int > &patt_lifetime_map) const

◆ process_single_zone()

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 340 of file PatternRecognition.cc.

References electrons_cff::bool, bx_, bxWindow_, endcap_, cuy::ins, emtf::NUM_ZONE_HITS, patt, patterns_, l1t::EMTFRoad::Quality_code(), 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().

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

◆ sort_single_zone()

void PatternRecognition::sort_single_zone ( EMTFRoadCollection roads) const

Definition at line 504 of file PatternRecognition.cc.

References emtf_assert, maxRoadsPerZone_, dqmiodumpmetadata::n, and jetUpdater_cfi::sort.

Referenced by process().

504  {
505  // First, order by key_zhit (highest to lowest)
506  struct {
507  typedef EMTFRoad value_type;
508  bool operator()(const value_type& lhs, const value_type& rhs) const { return lhs.Key_zhit() > rhs.Key_zhit(); }
509  } greater_zhit_cmp;
510 
511  std::sort(roads.begin(), roads.end(), greater_zhit_cmp);
512 
513  // Second, sort by quality_code (highest to lowest), but preserving the original order if qualities are equal
514  struct {
515  typedef EMTFRoad value_type;
516  bool operator()(const value_type& lhs, const value_type& rhs) const {
517  return lhs.Quality_code() > rhs.Quality_code();
518  }
519  } greater_quality_cmp;
520 
521  std::stable_sort(roads.begin(), roads.end(), greater_quality_cmp);
522 
523  // Finally, select 3 best
524  const size_t n = maxRoadsPerZone_;
525  if (roads.size() > n) {
526  roads.erase(roads.begin() + n, roads.end());
527  }
528  emtf_assert(roads.size() <= n);
529 
530  // Assign the winner variable
531  for (unsigned iroad = 0; iroad < roads.size(); ++iroad) {
532  roads.at(iroad).set_winner(iroad);
533  }
534 }
#define emtf_assert(expr)
Definition: DebugTools.h:18

Member Data Documentation

◆ bx_

int PatternRecognition::bx_
private

Definition at line 43 of file PatternRecognition.h.

Referenced by configure(), and process_single_zone().

◆ bxWindow_

int PatternRecognition::bxWindow_
private

Definition at line 45 of file PatternRecognition.h.

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

◆ endcap_

int PatternRecognition::endcap_
private

Definition at line 43 of file PatternRecognition.h.

Referenced by configure(), and process_single_zone().

◆ maxRoadsPerZone_

int PatternRecognition::maxRoadsPerZone_
private

Definition at line 48 of file PatternRecognition.h.

Referenced by configure(), and sort_single_zone().

◆ pattDefinitions_

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

Definition at line 46 of file PatternRecognition.h.

Referenced by configure(), and configure_details().

◆ patterns_

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

Definition at line 51 of file PatternRecognition.h.

Referenced by configure_details(), and process_single_zone().

◆ sector_

int PatternRecognition::sector_
private

Definition at line 43 of file PatternRecognition.h.

Referenced by configure(), and process_single_zone().

◆ symPattDefinitions_

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

Definition at line 46 of file PatternRecognition.h.

Referenced by configure(), and configure_details().

◆ useSecondEarliest_

bool PatternRecognition::useSecondEarliest_
private

Definition at line 49 of file PatternRecognition.h.

Referenced by configure(), and process_single_zone().

◆ useSymPatterns_

bool PatternRecognition::useSymPatterns_
private

Definition at line 47 of file PatternRecognition.h.

Referenced by configure(), and configure_details().

◆ verbose_

int PatternRecognition::verbose_
private

Definition at line 43 of file PatternRecognition.h.

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