CMS 3D CMS Logo

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

#include <PrimitiveMatching.h>

Public Types

typedef EMTFHitCollection::const_iterator hit_ptr_t
 
typedef std::pair< int, hit_ptr_thit_sort_pair_t
 

Public Member Functions

void configure (int verbose, int endcap, int sector, int bx, bool fixZonePhi, bool useNewZones, bool bugSt2PhDiff, bool bugME11Dupes)
 
void insert_hits (hit_ptr_t conv_hit_ptr, const EMTFHitCollection &conv_hits, EMTFTrack &track) const
 
void process (const std::deque< EMTFHitCollection > &extended_conv_hits, const emtf::zone_array< EMTFRoadCollection > &zone_roads, emtf::zone_array< EMTFTrackCollection > &zone_tracks) const
 
void process_single_zone_station (int zone, int station, const EMTFRoadCollection &roads, const EMTFHitCollection &conv_hits, std::vector< hit_sort_pair_t > &phi_differences) const
 

Private Attributes

bool bugME11Dupes_
 
bool bugSt2PhDiff_
 
int bx_
 
int endcap_
 
bool fixZonePhi_
 
int sector_
 
bool useNewZones_
 
int verbose_
 

Detailed Description

Definition at line 6 of file PrimitiveMatching.h.

Member Typedef Documentation

◆ hit_ptr_t

typedef EMTFHitCollection::const_iterator PrimitiveMatching::hit_ptr_t

Definition at line 8 of file PrimitiveMatching.h.

◆ hit_sort_pair_t

Definition at line 9 of file PrimitiveMatching.h.

Member Function Documentation

◆ configure()

void PrimitiveMatching::configure ( int  verbose,
int  endcap,
int  sector,
int  bx,
bool  fixZonePhi,
bool  useNewZones,
bool  bugSt2PhDiff,
bool  bugME11Dupes 
)

◆ insert_hits()

void PrimitiveMatching::insert_hits ( hit_ptr_t  conv_hit_ptr,
const EMTFHitCollection conv_hits,
EMTFTrack track 
) const

Definition at line 434 of file PrimitiveMatching.cc.

References bugME11Dupes_, l1t::EMTFHit::BX(), emtf_assert, l1t::EMTFHit::Is_RPC(), L1TMuon::kCSC, l1t::EMTFHit::Pattern(), l1t::EMTFHit::PC_chamber(), l1t::EMTFHit::PC_station(), l1t::EMTFHit::Phi_fp(), l1t::EMTFHit::Ring(), l1t::EMTFHit::Roll(), l1t::EMTFHit::set_theta_fp(), l1t::EMTFHit::Strip(), l1t::EMTFHit::Strip_hi(), l1t::EMTFHit::Strip_low(), l1t::EMTFHit::Subsystem(), l1t::EMTFHit::Theta_fp(), and HLT_2024v13_cff::track.

Referenced by process().

436  {
437  EMTFHitCollection::const_iterator conv_hits_it = conv_hits.begin();
438  EMTFHitCollection::const_iterator conv_hits_end = conv_hits.end();
439 
440  const bool is_csc_me11 = (conv_hit_ptr->Subsystem() == L1TMuon::kCSC) && (conv_hit_ptr->Station() == 1) &&
441  (conv_hit_ptr->Ring() == 1 || conv_hit_ptr->Ring() == 4);
442 
443  // Find all possible duplicated hits, insert them
444  for (; conv_hits_it != conv_hits_end; ++conv_hits_it) {
445  const EMTFHit& conv_hit_i = *conv_hits_it;
446  const EMTFHit& conv_hit_j = *conv_hit_ptr;
447 
448  // All these must match: [bx_history][station][chamber][segment]
449  if ((conv_hit_i.Subsystem() == conv_hit_j.Subsystem()) && (conv_hit_i.PC_station() == conv_hit_j.PC_station()) &&
450  (conv_hit_i.PC_chamber() == conv_hit_j.PC_chamber()) &&
451  (conv_hit_i.Ring() == conv_hit_j.Ring()) && // because of ME1/1
452  (conv_hit_i.Strip() == conv_hit_j.Strip()) &&
453  //(conv_hit_i.Wire() == conv_hit_j.Wire()) &&
454  (conv_hit_i.Pattern() == conv_hit_j.Pattern()) && (conv_hit_i.BX() == conv_hit_j.BX()) &&
455  ((conv_hit_i.Is_RPC() == false) ||
456  ((conv_hit_i.Strip_low() == conv_hit_j.Strip_low()) && (conv_hit_i.Strip_hi() == conv_hit_j.Strip_hi()) &&
457  (conv_hit_i.Roll() == conv_hit_j.Roll()) && (conv_hit_i.Phi_fp() == conv_hit_j.Phi_fp()) &&
458  (conv_hit_i.Theta_fp() == conv_hit_j.Theta_fp()))) &&
459  true) {
460  // All duplicates with the same strip but different wire must have same phi_fp
461  emtf_assert(conv_hit_i.Phi_fp() == conv_hit_j.Phi_fp());
462 
463  track.push_Hit(conv_hit_i);
464 
465  } else if ((bugME11Dupes_ &&
466  is_csc_me11) && // if reproduce ME1/1 theta duplication bug, do not check 'ring', 'strip' and 'pattern'
467  (conv_hit_i.Subsystem() == conv_hit_j.Subsystem()) &&
468  (conv_hit_i.PC_station() == conv_hit_j.PC_station()) &&
469  (conv_hit_i.PC_chamber() == conv_hit_j.PC_chamber()) &&
470  //(conv_hit_i.Ring() == conv_hit_j.Ring()) && // because of ME1/1
471  //(conv_hit_i.Strip() == conv_hit_j.Strip()) &&
472  //(conv_hit_i.Wire() == conv_hit_j.Wire()) &&
473  //(conv_hit_i.Pattern() == conv_hit_j.Pattern()) &&
474  (conv_hit_i.BX() == conv_hit_j.BX()) &&
475  //(conv_hit_i.Strip_low() == conv_hit_j.Strip_low()) && // For RPC clusters
476  //(conv_hit_i.Strip_hi() == conv_hit_j.Strip_hi()) && // For RPC clusters
477  //(conv_hit_i.Roll() == conv_hit_j.Roll()) && // For RPC clusters
478  true) {
479  // Dirty hack
480  EMTFHit tmp_hit = conv_hit_j;
481  tmp_hit.set_theta_fp(conv_hit_i.Theta_fp());
482  track.push_Hit(tmp_hit);
483  }
484  }
485 
486  // Sort by station
487  struct {
488  typedef EMTFHit value_type;
489  bool operator()(const value_type& lhs, const value_type& rhs) const { return lhs.Station() < rhs.Station(); }
490  } less_station_cmp;
491 
492  EMTFHitCollection tmp_hits = track.Hits();
493  std::stable_sort(tmp_hits.begin(), tmp_hits.end(), less_station_cmp);
494  track.set_Hits(tmp_hits);
495 }
int PC_chamber() const
Definition: EMTFHit.h:228
int Pattern() const
Definition: EMTFHit.h:243
int Phi_fp() const
Definition: EMTFHit.h:276
l1t::EMTFHitCollection EMTFHitCollection
Definition: Common.h:23
void set_theta_fp(int bits)
Definition: EMTFHit.h:191
int Roll() const
Definition: EMTFHit.h:223
int Strip_hi() const
Definition: EMTFHit.h:232
int BX() const
Definition: EMTFHit.h:274
int Theta_fp() const
Definition: EMTFHit.h:277
int Strip() const
Definition: EMTFHit.h:231
bool Is_RPC() const
Definition: EMTFHit.h:299
int PC_station() const
Definition: EMTFHit.h:227
#define emtf_assert(expr)
Definition: DebugTools.h:18
int Subsystem() const
Definition: EMTFHit.h:211
int Ring() const
Definition: EMTFHit.h:214
int Strip_low() const
Definition: EMTFHit.h:233

◆ process()

void PrimitiveMatching::process ( const std::deque< EMTFHitCollection > &  extended_conv_hits,
const emtf::zone_array< EMTFRoadCollection > &  zone_roads,
emtf::zone_array< EMTFTrackCollection > &  zone_tracks 
) const

Definition at line 31 of file PrimitiveMatching.cc.

References b1, l1t::EMTFHit::BT_segment(), l1t::EMTFRoad::BX(), l1t::EMTFHit::BX(), bx_, gather_cfg::cout, emtf_assert, l1t::EMTFRoad::Endcap(), fixZonePhi_, l1t::EMTFHit::FS_segment(), insert_hits(), l1t::EMTFRoad::Key_zhit(), emtf::NUM_STATIONS, emtf::NUM_ZONES, process_single_zone_station(), l1t::EMTFRoad::Quality_code(), l1t::EMTFRoad::Sector(), l1t::EMTFRoad::Sector_idx(), l1t::EMTFHit::set_bt_segment(), l1t::EMTFHit::set_fs_segment(), to_hex(), HLT_2024v13_cff::track, DiMuonV_cfg::tracks, verbose_, l1t::EMTFRoad::Winner(), and l1t::EMTFRoad::Zone().

Referenced by SectorProcessor::process_single_bx().

33  {
34  // Function to update fs_history encoded in fs_segment
35  auto update_fs_history = [](int fs_segment, int this_bx, int hit_bx) {
36  // 0 for current BX, 1 for previous BX, 2 for BX before that
37  int fs_history = this_bx - hit_bx;
38  fs_segment |= ((fs_history & 0x3) << 4);
39  return fs_segment;
40  };
41 
42  // Function to update bt_history encoded in bt_segment
43  auto update_bt_history = [](int bt_segment, int this_bx, int hit_bx) {
44  // 0 for current BX, 1 for previous BX, 2 for BX before that
45  int bt_history = this_bx - hit_bx;
46  bt_segment |= ((bt_history & 0x3) << 5);
47  return bt_segment;
48  };
49 
50  // Exit if no roads
51  int num_roads = 0;
52  for (const auto& roads : zone_roads)
53  num_roads += roads.size();
54  bool early_exit = (num_roads == 0);
55 
56  if (early_exit)
57  return;
58 
59  if (verbose_ > 0) { // debug
60  for (const auto& roads : zone_roads) {
61  for (const auto& road : roads) {
62  std::cout << "pattern on match input: z: " << road.Zone() - 1 << " r: " << road.Winner()
63  << " ph_num: " << road.Key_zhit() << " ph_q: " << to_hex(road.Quality_code())
64  << " ly: " << to_binary(road.Layer_code(), 3) << " str: " << to_binary(road.Straightness(), 3)
65  << std::endl;
66  }
67  }
68  }
69 
70  // Organize converted hits by (zone, station)
71  std::array<EMTFHitCollection, emtf::NUM_ZONES * emtf::NUM_STATIONS> zs_conv_hits;
72 
73  bool use_fs_zone_code = true; // use zone code as in firmware find_segment module
74 
75  std::deque<EMTFHitCollection>::const_iterator ext_conv_hits_it = extended_conv_hits.begin();
76  std::deque<EMTFHitCollection>::const_iterator ext_conv_hits_end = extended_conv_hits.end();
77 
78  for (; ext_conv_hits_it != ext_conv_hits_end; ++ext_conv_hits_it) {
79  EMTFHitCollection::const_iterator conv_hits_it = ext_conv_hits_it->begin();
80  EMTFHitCollection::const_iterator conv_hits_end = ext_conv_hits_it->end();
81 
82  for (; conv_hits_it != conv_hits_end; ++conv_hits_it) {
83  int istation = conv_hits_it->Station() - 1;
84  int zone_code = conv_hits_it->Zone_code(); // decide based on original zone code
85  if (use_fs_zone_code)
86  zone_code = conv_hits_it->FS_zone_code(); // decide based on new zone code
87 
88  // A hit can go into multiple zones
89  for (int izone = 0; izone < emtf::NUM_ZONES; ++izone) {
90  if (!zone_roads.at(izone).empty()) {
91  if (zone_code & (1 << izone)) {
92  const int zs = (izone * emtf::NUM_STATIONS) + istation;
93  zs_conv_hits.at(zs).push_back(*conv_hits_it);
94 
95  // Update fs_history and bt_history depending on the processor BX
96  // This update only goes into the hits associated to a track, it does not affect the original hit collection
97  EMTFHit& conv_hit = zs_conv_hits.at(zs).back(); // pass by reference
98  int old_fs_segment = conv_hit.FS_segment();
99  int new_fs_segment = update_fs_history(old_fs_segment, bx_, conv_hit.BX());
100  conv_hit.set_fs_segment(new_fs_segment);
101 
102  int old_bt_segment = conv_hit.BT_segment();
103  int new_bt_segment = update_bt_history(old_bt_segment, bx_, conv_hit.BX());
104  conv_hit.set_bt_segment(new_bt_segment);
105  }
106  }
107  }
108 
109  } // end loop over conv_hits
110  } // end loop over extended_conv_hits
111 
112  if (verbose_ > 1) { // debug
113  for (int izone = 0; izone < emtf::NUM_ZONES; ++izone) {
114  for (int istation = 0; istation < emtf::NUM_STATIONS; ++istation) {
115  const int zs = (izone * emtf::NUM_STATIONS) + istation;
116  for (const auto& conv_hit : zs_conv_hits.at(zs)) {
117  std::cout << "z: " << izone << " st: " << istation + 1 << " cscid: " << conv_hit.CSC_ID()
118  << " ph_zone_phi: " << conv_hit.Zone_hit() << " ph_low_prec: " << (conv_hit.Zone_hit() << 5)
119  << " ph_high_prec: " << conv_hit.Phi_fp()
120  << " ph_high_low_diff: " << (conv_hit.Phi_fp() - (conv_hit.Zone_hit() << 5)) << std::endl;
121  }
122  }
123  }
124  }
125 
126  // Keep the best phi difference for every road by (zone, station)
127  std::array<std::vector<hit_sort_pair_t>, emtf::NUM_ZONES * emtf::NUM_STATIONS> zs_phi_differences;
128 
129  // Get the best-matching hits by comparing phi difference between
130  // pattern and segment
131  for (int izone = 0; izone < emtf::NUM_ZONES; ++izone) {
132  for (int istation = 0; istation < emtf::NUM_STATIONS; ++istation) {
133  const int zs = (izone * emtf::NUM_STATIONS) + istation;
134 
135  // This leaves zone_roads.at(izone) and zs_conv_hits.at(zs) unchanged
136  // zs_phi_differences.at(zs) gets filled with a pair of <phi_diff, conv_hit> for the
137  // conv_hit with the lowest phi_diff from the pattern in this station and zone
139  izone + 1, istation + 1, zone_roads.at(izone), zs_conv_hits.at(zs), zs_phi_differences.at(zs));
140  emtf_assert(zone_roads.at(izone).size() == zs_phi_differences.at(zs).size());
141  } // end loop over stations
142  } // end loop over zones
143 
144  if (verbose_ > 1) { // debug
145  for (int izone = 0; izone < emtf::NUM_ZONES; ++izone) {
146  const auto& roads = zone_roads.at(izone);
147  for (unsigned iroad = 0; iroad < roads.size(); ++iroad) {
148  const auto& road = roads.at(iroad);
149  for (int istation = 0; istation < emtf::NUM_STATIONS; ++istation) {
150  const int zs = (izone * emtf::NUM_STATIONS) + istation;
151  int ph_diff = zs_phi_differences.at(zs).at(iroad).first;
152  std::cout << "find seg: z: " << road.Zone() - 1 << " r: " << road.Winner() << " st: " << istation
153  << " ph_diff: " << ph_diff << std::endl;
154  }
155  }
156  }
157  }
158 
159  // Build all tracks in each zone
160  for (int izone = 0; izone < emtf::NUM_ZONES; ++izone) {
161  const EMTFRoadCollection& roads = zone_roads.at(izone);
162 
163  for (unsigned iroad = 0; iroad < roads.size(); ++iroad) {
164  const EMTFRoad& road = roads.at(iroad);
165 
166  // Create a track
168  track.set_endcap(road.Endcap());
169  track.set_sector(road.Sector());
170  track.set_sector_idx(road.Sector_idx());
171  track.set_bx(road.BX());
172  track.set_zone(road.Zone());
173  track.set_ph_num(road.Key_zhit());
174  track.set_ph_q(road.Quality_code());
175  track.set_rank(road.Quality_code());
176  track.set_winner(road.Winner());
177 
178  track.clear_Hits();
179 
180  // Insert hits
181  for (int istation = 0; istation < emtf::NUM_STATIONS; ++istation) {
182  const int zs = (izone * emtf::NUM_STATIONS) + istation;
183 
184  const EMTFHitCollection& conv_hits = zs_conv_hits.at(zs);
185  int ph_diff = zs_phi_differences.at(zs).at(iroad).first;
186  hit_ptr_t conv_hit_ptr = zs_phi_differences.at(zs).at(iroad).second;
187 
188  if (ph_diff != invalid_ph_diff) {
189  // Inserts the conv_hit with the lowest phi_diff, as well as its duplicate
190  // (same strip and phi, different wire and theta), if a duplicate exists
191  insert_hits(conv_hit_ptr, conv_hits, track);
192  }
193  }
194 
195  if (fixZonePhi_) {
196  emtf_assert(!track.Hits().empty());
197  }
198 
199  // Output track
200  zone_tracks.at(izone).push_back(track);
201 
202  } // end loop over roads
203  } // end loop over zones
204 
205  if (verbose_ > 0) { // debug
206  for (const auto& tracks : zone_tracks) {
207  for (const auto& track : tracks) {
208  for (const auto& hit : track.Hits()) {
209  std::cout << "match seg: z: " << track.Zone() - 1 << " pat: " << track.Winner() << " st: " << hit.Station()
210  << " vi: " << to_binary(0b1, 2) << " hi: " << ((hit.FS_segment() >> 4) & 0x3)
211  << " ci: " << ((hit.FS_segment() >> 1) & 0x7) << " si: " << (hit.FS_segment() & 0x1)
212  << " ph: " << hit.Phi_fp() << " th: " << hit.Theta_fp() << std::endl;
213  }
214  }
215  }
216  }
217 }
int Endcap() const
Definition: EMTFRoad.h:38
static char to_hex(unsigned int i)
Definition: types.cc:27
constexpr int NUM_ZONES
Definition: Common.h:54
int BT_segment() const
Definition: EMTFHit.h:283
int Phi_fp() const
Definition: EMTFHit.h:276
l1t::EMTFHitCollection EMTFHitCollection
Definition: Common.h:23
int CSC_ID() const
Definition: EMTFHit.h:221
int Winner() const
Definition: EMTFRoad.h:48
void set_bt_segment(int bits)
Definition: EMTFHit.h:197
l1t::EMTFRoadCollection EMTFRoadCollection
Definition: Common.h:25
int Sector() const
Definition: EMTFRoad.h:39
int BX() const
Definition: EMTFHit.h:274
EMTFHitCollection::const_iterator hit_ptr_t
int Sector_idx() const
Definition: EMTFRoad.h:40
void set_fs_segment(int bits)
Definition: EMTFHit.h:194
void process_single_zone_station(int zone, int station, const EMTFRoadCollection &roads, const EMTFHitCollection &conv_hits, std::vector< hit_sort_pair_t > &phi_differences) const
int Zone_hit() const
Definition: EMTFHit.h:278
#define emtf_assert(expr)
Definition: DebugTools.h:18
int BX() const
Definition: EMTFRoad.h:41
constexpr int NUM_STATIONS
Definition: Common.h:58
int Key_zhit() const
Definition: EMTFRoad.h:43
int Zone() const
Definition: EMTFRoad.h:42
void insert_hits(hit_ptr_t conv_hit_ptr, const EMTFHitCollection &conv_hits, EMTFTrack &track) const
int FS_segment() const
Definition: EMTFHit.h:280
static constexpr float b1
int Quality_code() const
Definition: EMTFRoad.h:47

◆ process_single_zone_station()

void PrimitiveMatching::process_single_zone_station ( int  zone,
int  station,
const EMTFRoadCollection roads,
const EMTFHitCollection conv_hits,
std::vector< hit_sort_pair_t > &  phi_differences 
) const

Definition at line 219 of file PrimitiveMatching.cc.

References a, funct::abs(), b, nano_mu_local_reco_cff::bool, bugSt2PhDiff_, HltBtagPostValidation_cff::c, emtf_assert, fixZonePhi_, L1TMuon::kCSC, alignCSCRings::r, findQualityFiles::rr, relativeConstraints::station, and useNewZones_.

Referenced by process().

223  {
224  // max phi difference between pattern and segment
225  // This doesn't depend on the pattern straightness - any hit within the max phi difference may match
226  int max_ph_diff = (station == 1) ? 15 : 7;
227  //int bw_ph_diff = (station == 1) ? 5 : 4; // ph difference bit width
228  //int invalid_ph_diff = (station == 1) ? 31 : 15; // invalid difference
229 
230  if (fixZonePhi_) {
231  if (station == 1) {
232  max_ph_diff = 496; // width of pattern in ME1 + rounding error 15*32+16
233  //bw_ph_diff = 9;
234  //invalid_ph_diff = 0x1ff;
235  } else if (station == 2) {
236  if (bugSt2PhDiff_)
237  max_ph_diff = 16; // just rounding error for ME2 (pattern must match ME2 hit phi if there was one)
238  else
239  max_ph_diff = 240; // same as ME3,4
240  //bw_ph_diff = 5;
241  //invalid_ph_diff = 0x1f;
242  } else {
243  max_ph_diff = 240; // width of pattern in ME3,4 + rounding error 7*32+16
244  //bw_ph_diff = 8;
245  //invalid_ph_diff = 0xff;
246  }
247  }
248 
249  auto abs_diff = [](int a, int b) { return std::abs(a - b); };
250 
251  // Simple sort by ph_diff
252  struct {
253  typedef hit_sort_pair_t value_type;
254  bool operator()(const value_type& lhs, const value_type& rhs) const { return lhs.first <= rhs.first; }
255  } less_ph_diff_cmp;
256 
257  // Emulation of FW sorting with 3-way comparator
258  struct {
259  typedef hit_sort_pair_t value_type;
260  int operator()(const value_type& a, const value_type& b, const value_type& c) const {
261  int r = 0;
262  r |= bool(a.first <= b.first);
263  r <<= 1;
264  r |= bool(b.first <= c.first);
265  r <<= 1;
266  r |= bool(c.first <= a.first);
267 
268  int rr = 0;
269  switch (r) {
270  //case 0b000 : rr = 3; break; // invalid
271  case 0b001:
272  rr = 2;
273  break; // c
274  case 0b010:
275  rr = 1;
276  break; // b
277  case 0b011:
278  rr = 1;
279  break; // b
280  case 0b100:
281  rr = 0;
282  break; // a
283  case 0b101:
284  rr = 2;
285  break; // c
286  case 0b110:
287  rr = 0;
288  break; // a
289  //case 0b111 : rr = 0; break; // invalid
290  default:
291  rr = 0;
292  break;
293  }
294  return rr;
295  }
296  } less_ph_diff_cmp3;
297 
298  // ___________________________________________________________________________
299  // For each road, find the segment with min phi difference in every station
300 
301  EMTFRoadCollection::const_iterator roads_it = roads.begin();
302  EMTFRoadCollection::const_iterator roads_end = roads.end();
303 
304  for (; roads_it != roads_end; ++roads_it) {
305  int ph_pat = roads_it->Key_zhit(); // pattern key phi value
306  int ph_q = roads_it->Quality_code(); // pattern quality code
307  emtf_assert(ph_pat >= 0 && ph_q > 0);
308 
309  if (fixZonePhi_) {
310  ph_pat <<= 5; // add missing 5 lower bits to pattern phi
311  }
312 
313  std::vector<hit_sort_pair_t> tmp_phi_differences;
314 
315  EMTFHitCollection::const_iterator conv_hits_it = conv_hits.begin();
316  EMTFHitCollection::const_iterator conv_hits_end = conv_hits.end();
317 
318  for (; conv_hits_it != conv_hits_end; ++conv_hits_it) {
319  int ph_seg = conv_hits_it->Phi_fp(); // ph from segments
320  int ph_seg_red = ph_seg >> (bw_fph - bpow - 1); // remove unused low bits
321  emtf_assert(ph_seg >= 0);
322 
323  if (fixZonePhi_) {
324  ph_seg_red = ph_seg; // use full-precision phi
325  }
326 
327  // Get abs phi difference
328  int ph_diff = abs_diff(ph_pat, ph_seg_red);
329  if (ph_diff > max_ph_diff)
330  ph_diff = invalid_ph_diff; // difference is too high, cannot be the same pattern
331 
332  if (ph_diff != invalid_ph_diff)
333  tmp_phi_differences.push_back(std::make_pair(ph_diff, conv_hits_it)); // make a key-value pair
334  }
335 
336  // _________________________________________________________________________
337  // Sort to find the segment with min phi difference
338 
339  if (!tmp_phi_differences.empty()) {
340  // Because the sorting is sensitive to FW ordering, use the exact FW sorting.
341  // This implementation still slightly differs from FW because I prefer to
342  // use a sorting function that is as generic as possible.
343  bool use_fw_sorting = true;
344 
345  if (useNewZones_)
346  use_fw_sorting = false;
347 
348  if (use_fw_sorting) {
349  // zone_cham = 4 for [fs_01, fs_02, fs_03, fs_11], or 7 otherwise
350  // tot_diff = 27 or 45 in FW; it is 27 or 54 in the C++ merge_sort3 impl
351  const int max_drift = 3; // should use bxWindow from the config
352  const int zone_cham = ((zone == 1 && (2 <= station && station <= 4)) || (zone == 2 && station == 2)) ? 4 : 7;
353  const int seg_ch = 2;
354  const int tot_diff =
355  (max_drift * zone_cham * seg_ch) + ((zone_cham == 4) ? 3 : 12); // provide padding for 3-input comparators
356 
357  std::vector<hit_sort_pair_t> fw_sort_array(tot_diff, std::make_pair(invalid_ph_diff, conv_hits_end));
358 
359  // FW doesn't check if the hit is CSC or RPC
360  std::vector<hit_sort_pair_t>::const_iterator phdiffs_it = tmp_phi_differences.begin();
361  std::vector<hit_sort_pair_t>::const_iterator phdiffs_end = tmp_phi_differences.end();
362 
363  for (; phdiffs_it != phdiffs_end; ++phdiffs_it) {
364  //int ph_diff = phdiffs_it->first;
365  int fs_segment = phdiffs_it->second->FS_segment();
366 
367  // Calculate the index to put into the fw_sort_array
368  int fs_history = ((fs_segment >> 4) & 0x3);
369  int fs_chamber = ((fs_segment >> 1) & 0x7);
370  fs_segment = (fs_segment & 0x1);
371  unsigned fw_sort_array_index = (fs_history * zone_cham * seg_ch) + (fs_chamber * seg_ch) + fs_segment;
372 
373  emtf_assert(fs_history < max_drift && fs_chamber < zone_cham && fs_segment < seg_ch);
374  emtf_assert(fw_sort_array_index < fw_sort_array.size());
375  fw_sort_array.at(fw_sort_array_index) = *phdiffs_it;
376  }
377 
378  // Debug
379  //std::cout << "phdiffs" << std::endl;
380  //for (unsigned i = 0; i < fw_sort_array.size(); ++i)
381  // std::cout << fw_sort_array.at(i).first << " ";
382  //std::cout << std::endl;
383 
384  // Debug
385  //std::cout << "Before sort" << std::endl;
386  //for (unsigned i = 0; i < fw_sort_array.size(); ++i)
387  // std::cout << fw_sort_array.at(i).second->FS_segment() << " ";
388  //std::cout << std::endl;
389 
390  // Find the best phi difference according to FW sorting
391  //merge_sort3(fw_sort_array.begin(), fw_sort_array.end(), less_ph_diff_cmp, less_ph_diff_cmp3);
392  merge_sort3_with_hint(fw_sort_array.begin(),
393  fw_sort_array.end(),
394  less_ph_diff_cmp,
395  less_ph_diff_cmp3,
396  ((tot_diff == 54) ? tot_diff / 2 : tot_diff / 3));
397 
398  // Store the best phi difference
399  phi_differences.push_back(fw_sort_array.front());
400 
401  // Debug
402  //std::cout << "After sort" << std::endl;
403  //for (unsigned i = 0; i < fw_sort_array.size(); ++i)
404  // std::cout << fw_sort_array.at(i).second->FS_segment() << " ";
405  //std::cout << std::endl;
406 
407  } else { // use C++ sorting
408  struct {
409  typedef hit_sort_pair_t value_type;
410  bool operator()(const value_type& lhs, const value_type& rhs) const {
411  // If different types, prefer CSC over RPC; else prefer the closer hit in dPhi
412  if (lhs.second->Subsystem() != rhs.second->Subsystem())
413  return (lhs.second->Subsystem() == L1TMuon::kCSC);
414  else
415  return lhs.first <= rhs.first;
416  }
417  } tmp_less_ph_diff_cmp;
418 
419  // Find best phi difference
420  std::stable_sort(tmp_phi_differences.begin(), tmp_phi_differences.end(), tmp_less_ph_diff_cmp);
421 
422  // Store the best phi difference
423  phi_differences.push_back(tmp_phi_differences.front());
424  }
425 
426  } else {
427  // No segment found
428  phi_differences.push_back(std::make_pair(invalid_ph_diff, conv_hits_end)); // make a key-value pair
429  }
430 
431  } // end loop over roads
432 }
std::pair< int, hit_ptr_t > hit_sort_pair_t
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
#define emtf_assert(expr)
Definition: DebugTools.h:18
double b
Definition: hdecay.h:120
double a
Definition: hdecay.h:121

Member Data Documentation

◆ bugME11Dupes_

bool PrimitiveMatching::bugME11Dupes_
private

Definition at line 36 of file PrimitiveMatching.h.

Referenced by configure(), and insert_hits().

◆ bugSt2PhDiff_

bool PrimitiveMatching::bugSt2PhDiff_
private

Definition at line 36 of file PrimitiveMatching.h.

Referenced by configure(), and process_single_zone_station().

◆ bx_

int PrimitiveMatching::bx_
private

Definition at line 33 of file PrimitiveMatching.h.

Referenced by configure(), and process().

◆ endcap_

int PrimitiveMatching::endcap_
private

Definition at line 33 of file PrimitiveMatching.h.

Referenced by configure().

◆ fixZonePhi_

bool PrimitiveMatching::fixZonePhi_
private

Definition at line 35 of file PrimitiveMatching.h.

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

◆ sector_

int PrimitiveMatching::sector_
private

Definition at line 33 of file PrimitiveMatching.h.

Referenced by configure().

◆ useNewZones_

bool PrimitiveMatching::useNewZones_
private

Definition at line 35 of file PrimitiveMatching.h.

Referenced by configure(), and process_single_zone_station().

◆ verbose_

int PrimitiveMatching::verbose_
private

Definition at line 33 of file PrimitiveMatching.h.

Referenced by configure(), and process().