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

typedef EMTFHitCollection::const_iterator PrimitiveMatching::hit_ptr_t

Definition at line 8 of file PrimitiveMatching.h.

Definition at line 9 of file PrimitiveMatching.h.

Member Function Documentation

void PrimitiveMatching::configure ( int  verbose,
int  endcap,
int  sector,
int  bx,
bool  fixZonePhi,
bool  useNewZones,
bool  bugSt2PhDiff,
bool  bugME11Dupes 
)
void PrimitiveMatching::insert_hits ( hit_ptr_t  conv_hit_ptr,
const EMTFHitCollection conv_hits,
EMTFTrack track 
) const

Definition at line 456 of file PrimitiveMatching.cc.

References bugME11Dupes_, l1t::EMTFHit::BX(), l1t::EMTFTrack::Hits(), l1t::EMTFHit::Is_RPC(), L1TMuon::TriggerPrimitive::kCSC, l1t::EMTFHit::Pattern(), l1t::EMTFHit::PC_chamber(), l1t::EMTFHit::PC_station(), l1t::EMTFHit::Phi_fp(), l1t::EMTFTrack::push_Hit(), l1t::EMTFHit::Ring(), l1t::EMTFHit::Roll(), l1t::EMTFTrack::set_Hits(), l1t::EMTFHit::set_theta_fp(), l1t::EMTFHit::Strip(), l1t::EMTFHit::Strip_hi(), l1t::EMTFHit::Strip_low(), l1t::EMTFHit::Subsystem(), and l1t::EMTFHit::Theta_fp().

Referenced by process().

458  {
459  EMTFHitCollection::const_iterator conv_hits_it = conv_hits.begin();
460  EMTFHitCollection::const_iterator conv_hits_end = conv_hits.end();
461 
462  const bool is_csc_me11 = (conv_hit_ptr->Subsystem() == TriggerPrimitive::kCSC) && (conv_hit_ptr->Station() == 1) &&
463  (conv_hit_ptr->Ring() == 1 || conv_hit_ptr->Ring() == 4);
464 
465  // Find all possible duplicated hits, insert them
466  for (; conv_hits_it != conv_hits_end; ++conv_hits_it) {
467  const EMTFHit& conv_hit_i = *conv_hits_it;
468  const EMTFHit& conv_hit_j = *conv_hit_ptr;
469 
470  // All these must match: [bx_history][station][chamber][segment]
471  if ((conv_hit_i.Subsystem() == conv_hit_j.Subsystem()) && (conv_hit_i.PC_station() == conv_hit_j.PC_station()) &&
472  (conv_hit_i.PC_chamber() == conv_hit_j.PC_chamber()) &&
473  (conv_hit_i.Ring() == conv_hit_j.Ring()) && // because of ME1/1
474  (conv_hit_i.Strip() == conv_hit_j.Strip()) &&
475  //(conv_hit_i.Wire() == conv_hit_j.Wire()) &&
476  (conv_hit_i.Pattern() == conv_hit_j.Pattern()) && (conv_hit_i.BX() == conv_hit_j.BX()) &&
477  ((conv_hit_i.Is_RPC() == false) ||
478  ((conv_hit_i.Strip_low() == conv_hit_j.Strip_low()) && (conv_hit_i.Strip_hi() == conv_hit_j.Strip_hi()) &&
479  (conv_hit_i.Roll() == conv_hit_j.Roll()) && (conv_hit_i.Phi_fp() == conv_hit_j.Phi_fp()) &&
480  (conv_hit_i.Theta_fp() == conv_hit_j.Theta_fp()))) &&
481  true) {
482  // All duplicates with the same strip but different wire must have same phi_fp
483  if (not(conv_hit_i.Phi_fp() == conv_hit_j.Phi_fp())) {
484  edm::LogError("L1T") << "conv_hit_i.Phi_fp() = " << conv_hit_i.Phi_fp()
485  << ", conv_hit_j.Phi_fp() = " << conv_hit_j.Phi_fp();
486  return;
487  }
488 
489  track.push_Hit(conv_hit_i);
490 
491  } else if ((bugME11Dupes_ &&
492  is_csc_me11) && // if reproduce ME1/1 theta duplication bug, do not check 'ring', 'strip' and 'pattern'
493  (conv_hit_i.Subsystem() == conv_hit_j.Subsystem()) &&
494  (conv_hit_i.PC_station() == conv_hit_j.PC_station()) &&
495  (conv_hit_i.PC_chamber() == conv_hit_j.PC_chamber()) &&
496  //(conv_hit_i.Ring() == conv_hit_j.Ring()) && // because of ME1/1
497  //(conv_hit_i.Strip() == conv_hit_j.Strip()) &&
498  //(conv_hit_i.Wire() == conv_hit_j.Wire()) &&
499  //(conv_hit_i.Pattern() == conv_hit_j.Pattern()) &&
500  (conv_hit_i.BX() == conv_hit_j.BX()) &&
501  //(conv_hit_i.Strip_low() == conv_hit_j.Strip_low()) && // For RPC clusters
502  //(conv_hit_i.Strip_hi() == conv_hit_j.Strip_hi()) && // For RPC clusters
503  //(conv_hit_i.Roll() == conv_hit_j.Roll()) && // For RPC clusters
504  true) {
505  // Dirty hack
506  EMTFHit tmp_hit = conv_hit_j;
507  tmp_hit.set_theta_fp(conv_hit_i.Theta_fp());
508  track.push_Hit(tmp_hit);
509  }
510  }
511 
512  // Sort by station
513  struct {
514  typedef EMTFHit value_type;
515  bool operator()(const value_type& lhs, const value_type& rhs) const { return lhs.Station() < rhs.Station(); }
516  } less_station_cmp;
517 
518  EMTFHitCollection tmp_hits = track.Hits();
519  std::stable_sort(tmp_hits.begin(), tmp_hits.end(), less_station_cmp);
520  track.set_Hits(tmp_hits);
521 }
int Strip_hi() const
Definition: EMTFHit.h:208
int Subsystem() const
Definition: EMTFHit.h:244
int Strip() const
Definition: EMTFHit.h:207
int Phi_fp() const
Definition: EMTFHit.h:219
l1t::EMTFHitCollection EMTFHitCollection
Definition: Common.h:25
int Roll() const
Definition: EMTFHit.h:199
void set_theta_fp(int bits)
Definition: EMTFHit.h:162
int PC_station() const
Definition: EMTFHit.h:203
int Strip_low() const
Definition: EMTFHit.h:209
int BX() const
Definition: EMTFHit.h:217
int Ring() const
Definition: EMTFHit.h:190
int PC_chamber() const
Definition: EMTFHit.h:204
EMTFHitCollection Hits() const
Definition: EMTFTrack.h:107
void push_Hit(const EMTFHit &hit)
Definition: EMTFTrack.h:85
void set_Hits(const EMTFHitCollection &hits)
Definition: EMTFTrack.h:96
int Pattern() const
Definition: EMTFHit.h:212
int Theta_fp() const
Definition: EMTFHit.h:220
int Is_RPC() const
Definition: EMTFHit.h:242
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 30 of file PrimitiveMatching.cc.

References l1t::EMTFHit::BT_segment(), l1t::EMTFRoad::BX(), l1t::EMTFHit::BX(), bx_, l1t::EMTFTrack::clear_Hits(), gather_cfg::cout, l1t::EMTFRoad::Endcap(), fixZonePhi_, l1t::EMTFHit::FS_segment(), l1t::EMTFTrack::Hits(), 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::EMTFTrack::set_bx(), l1t::EMTFTrack::set_endcap(), l1t::EMTFHit::set_fs_segment(), l1t::EMTFTrack::set_ph_num(), l1t::EMTFTrack::set_ph_q(), l1t::EMTFTrack::set_rank(), l1t::EMTFTrack::set_sector(), l1t::EMTFTrack::set_sector_idx(), l1t::EMTFTrack::set_winner(), l1t::EMTFTrack::set_zone(), to_hex(), HLT_2018_cff::track, PDWG_EXOHSCP_cff::tracks, verbose_, l1t::EMTFRoad::Winner(), and l1t::EMTFRoad::Zone().

Referenced by SectorProcessor::process_single_bx().

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

References a, funct::abs(), b, electrons_cff::bool, bugSt2PhDiff_, HltBtagPostValidation_cff::c, fixZonePhi_, L1TMuon::TriggerPrimitive::kCSC, alignCSCRings::r, findQualityFiles::rr, and useNewZones_.

Referenced by process().

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

Member Data Documentation

bool PrimitiveMatching::bugME11Dupes_
private

Definition at line 36 of file PrimitiveMatching.h.

Referenced by configure(), and insert_hits().

bool PrimitiveMatching::bugSt2PhDiff_
private

Definition at line 36 of file PrimitiveMatching.h.

Referenced by configure(), and process_single_zone_station().

int PrimitiveMatching::bx_
private

Definition at line 33 of file PrimitiveMatching.h.

Referenced by configure(), and process().

int PrimitiveMatching::endcap_
private

Definition at line 33 of file PrimitiveMatching.h.

Referenced by configure().

bool PrimitiveMatching::fixZonePhi_
private

Definition at line 35 of file PrimitiveMatching.h.

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

int PrimitiveMatching::sector_
private

Definition at line 33 of file PrimitiveMatching.h.

Referenced by configure().

bool PrimitiveMatching::useNewZones_
private

Definition at line 35 of file PrimitiveMatching.h.

Referenced by configure(), and process_single_zone_station().

int PrimitiveMatching::verbose_
private

Definition at line 33 of file PrimitiveMatching.h.

Referenced by configure(), and process().