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

Member Typedef Documentation

typedef EMTFHitCollection::const_iterator PrimitiveMatching::hit_ptr_t

Definition at line 9 of file PrimitiveMatching.h.

Definition at line 10 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 441 of file PrimitiveMatching.cc.

References bugME11Dupes_, l1t::EMTFHit::BX(), l1t::EMTFTrack::Hits(), 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::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().

444  {
445  EMTFHitCollection::const_iterator conv_hits_it = conv_hits.begin();
446  EMTFHitCollection::const_iterator conv_hits_end = conv_hits.end();
447 
448  const bool is_csc_me11 = (conv_hit_ptr->Subsystem() == TriggerPrimitive::kCSC) &&
449  (conv_hit_ptr->Station() == 1) && (conv_hit_ptr->Ring() == 1 || conv_hit_ptr->Ring() == 4);
450 
451  // Find all possible duplicated hits, insert them
452  for (; conv_hits_it != conv_hits_end; ++conv_hits_it) {
453  const EMTFHit& conv_hit_i = *conv_hits_it;
454  const EMTFHit& conv_hit_j = *conv_hit_ptr;
455 
456  // All these must match: [bx_history][station][chamber][segment]
457  if (
458  (conv_hit_i.Subsystem() == conv_hit_j.Subsystem()) &&
459  (conv_hit_i.PC_station() == conv_hit_j.PC_station()) &&
460  (conv_hit_i.PC_chamber() == conv_hit_j.PC_chamber()) &&
461  (conv_hit_i.Ring() == conv_hit_j.Ring()) && // because of ME1/1
462  (conv_hit_i.Strip() == conv_hit_j.Strip()) &&
463  //(conv_hit_i.Wire() == conv_hit_j.Wire()) &&
464  (conv_hit_i.Pattern() == conv_hit_j.Pattern()) &&
465  (conv_hit_i.BX() == conv_hit_j.BX()) &&
466  (conv_hit_i.Strip_low() == conv_hit_j.Strip_low()) && // For RPC clusters
467  (conv_hit_i.Strip_hi() == conv_hit_j.Strip_hi()) && // For RPC clusters
468  //(conv_hit_i.Roll() == conv_hit_j.Roll()) &&
469  true
470  ) {
471  // All duplicates with the same strip but different wire must have same phi_fp
472  if (not(conv_hit_i.Phi_fp() == conv_hit_j.Phi_fp()))
473  { edm::LogError("L1T") << "conv_hit_i.Phi_fp() = " << conv_hit_i.Phi_fp()
474  << ", conv_hit_j.Phi_fp() = " << conv_hit_j.Phi_fp(); return; }
475 
476  track.push_Hit( conv_hit_i );
477 
478  } else if (
479  (bugME11Dupes_ && is_csc_me11) && // if reproduce ME1/1 theta duplication bug, do not check 'ring', 'strip' and 'pattern'
480  (conv_hit_i.Subsystem() == conv_hit_j.Subsystem()) &&
481  (conv_hit_i.PC_station() == conv_hit_j.PC_station()) &&
482  (conv_hit_i.PC_chamber() == conv_hit_j.PC_chamber()) &&
483  //(conv_hit_i.Ring() == conv_hit_j.Ring()) && // because of ME1/1
484  //(conv_hit_i.Strip() == conv_hit_j.Strip()) &&
485  //(conv_hit_i.Wire() == conv_hit_j.Wire()) &&
486  //(conv_hit_i.Pattern() == conv_hit_j.Pattern()) &&
487  (conv_hit_i.BX() == conv_hit_j.BX()) &&
488  //(conv_hit_i.Strip_low() == conv_hit_j.Strip_low()) && // For RPC clusters
489  //(conv_hit_i.Strip_hi() == conv_hit_j.Strip_hi()) && // For RPC clusters
490  //(conv_hit_i.Roll() == conv_hit_j.Roll()) &&
491  true
492  ) {
493  // // All duplicates with the same strip but different wire must have same phi_fp
494  // if (not(conv_hit_i.Phi_fp() == conv_hit_j.Phi_fp()))
495  // { edm::LogError("L1T") << "conv_hit_i.Phi_fp() = " << conv_hit_i.Phi_fp()
496  // << ", conv_hit_j.Phi_fp() = " << conv_hit_j.Phi_fp(); return; }
497 
498  // track.push_Hit( conv_hit_i );
499 
500  // Dirty hack
501  EMTFHit tmp_hit = conv_hit_j;
502  tmp_hit.set_theta_fp( conv_hit_i.Theta_fp() );
503  track.push_Hit( tmp_hit );
504  }
505  }
506 
507  // Sort by station
508  struct {
509  typedef EMTFHit value_type;
510  bool operator()(const value_type& lhs, const value_type& rhs) const {
511  return lhs.Station() < rhs.Station();
512  }
513  } less_station_cmp;
514 
515  EMTFHitCollection tmp_hits = track.Hits();
516  std::stable_sort(tmp_hits.begin(), tmp_hits.end(), less_station_cmp);
517  track.set_Hits( tmp_hits );
518 }
int Strip_hi() const
Definition: EMTFHit.h:142
int Subsystem() const
Definition: EMTFHit.h:173
int Strip() const
Definition: EMTFHit.h:141
int Phi_fp() const
Definition: EMTFHit.h:153
void set_theta_fp(int bits)
Definition: EMTFHit.h:101
int PC_station() const
Definition: EMTFHit.h:137
int Strip_low() const
Definition: EMTFHit.h:143
int BX() const
Definition: EMTFHit.h:151
l1t::EMTFHitCollection EMTFHitCollection
Definition: Common.h:21
int Ring() const
Definition: EMTFHit.h:124
int PC_chamber() const
Definition: EMTFHit.h:138
EMTFHitCollection Hits() const
Definition: EMTFTrack.h:77
void push_Hit(const EMTFHit &hit)
Definition: EMTFTrack.h:59
void set_Hits(const EMTFHitCollection &hits)
Definition: EMTFTrack.h:66
int Pattern() const
Definition: EMTFHit.h:146
int Theta_fp() const
Definition: EMTFHit.h:154
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 28 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(), HiIsolationCommonParameters_cff::track, l1t::tracks, verbose_, l1t::EMTFRoad::Winner(), and l1t::EMTFRoad::Zone().

Referenced by ConfigBuilder.ConfigBuilder::addExtraStream(), ConfigBuilder.ConfigBuilder::completeInputCommand(), ConfigBuilder.ConfigBuilder::doNotInlineEventContent(), ConfigBuilder.ConfigBuilder.PrintAllModules::leave(), ConfigBuilder.ConfigBuilder::prepare(), ConfigBuilder.ConfigBuilder::prepare_ALCA(), ConfigBuilder.ConfigBuilder::prepare_DQM(), ConfigBuilder.ConfigBuilder::prepare_HLT(), ConfigBuilder.ConfigBuilder::prepare_LHE(), ConfigBuilder.ConfigBuilder::prepare_PATFILTER(), ConfigBuilder.ConfigBuilder::prepare_VALIDATION(), SectorProcessor::process_single_bx(), ConfigBuilder.ConfigBuilder::renameHLTprocessInSequence(), ConfigBuilder.ConfigBuilder::renameInputTagsInSequence(), and ConfigBuilder.ConfigBuilder::scheduleSequence().

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

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

Referenced by process().

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

Member Data Documentation

bool PrimitiveMatching::bugME11Dupes_
private

Definition at line 40 of file PrimitiveMatching.h.

Referenced by configure(), and insert_hits().

bool PrimitiveMatching::bugSt2PhDiff_
private

Definition at line 40 of file PrimitiveMatching.h.

Referenced by configure(), and process_single_zone_station().

int PrimitiveMatching::bx_
private

Definition at line 37 of file PrimitiveMatching.h.

Referenced by configure(), and process().

int PrimitiveMatching::endcap_
private

Definition at line 37 of file PrimitiveMatching.h.

Referenced by configure().

bool PrimitiveMatching::fixZonePhi_
private

Definition at line 39 of file PrimitiveMatching.h.

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

int PrimitiveMatching::sector_
private

Definition at line 37 of file PrimitiveMatching.h.

Referenced by configure().

bool PrimitiveMatching::useNewZones_
private

Definition at line 39 of file PrimitiveMatching.h.

Referenced by configure(), and process_single_zone_station().

int PrimitiveMatching::verbose_
private

Definition at line 37 of file PrimitiveMatching.h.

Referenced by configure(), and process().