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 440 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().

443  {
444  EMTFHitCollection::const_iterator conv_hits_it = conv_hits.begin();
445  EMTFHitCollection::const_iterator conv_hits_end = conv_hits.end();
446 
447  const bool is_csc_me11 = (conv_hit_ptr->Subsystem() == TriggerPrimitive::kCSC) &&
448  (conv_hit_ptr->Station() == 1) && (conv_hit_ptr->Ring() == 1 || conv_hit_ptr->Ring() == 4);
449 
450  // Find all possible duplicated hits, insert them
451  for (; conv_hits_it != conv_hits_end; ++conv_hits_it) {
452  const EMTFHit& conv_hit_i = *conv_hits_it;
453  const EMTFHit& conv_hit_j = *conv_hit_ptr;
454 
455  // All these must match: [bx_history][station][chamber][segment]
456  if (
457  (conv_hit_i.Subsystem() == conv_hit_j.Subsystem()) &&
458  (conv_hit_i.PC_station() == conv_hit_j.PC_station()) &&
459  (conv_hit_i.PC_chamber() == conv_hit_j.PC_chamber()) &&
460  (conv_hit_i.Ring() == conv_hit_j.Ring()) && // because of ME1/1
461  (conv_hit_i.Strip() == conv_hit_j.Strip()) &&
462  //(conv_hit_i.Wire() == conv_hit_j.Wire()) &&
463  (conv_hit_i.Pattern() == conv_hit_j.Pattern()) &&
464  (conv_hit_i.BX() == conv_hit_j.BX()) &&
465  ( (conv_hit_i.Is_RPC() == false) ||
466  ( (conv_hit_i.Strip_low() == conv_hit_j.Strip_low()) &&
467  (conv_hit_i.Strip_hi() == conv_hit_j.Strip_hi()) &&
468  (conv_hit_i.Roll() == conv_hit_j.Roll()) &&
469  (conv_hit_i.Phi_fp() == conv_hit_j.Phi_fp()) &&
470  (conv_hit_i.Theta_fp() == conv_hit_j.Theta_fp()) ) ) &&
471  true
472  ) {
473  // All duplicates with the same strip but different wire must have same phi_fp
474  if (not(conv_hit_i.Phi_fp() == conv_hit_j.Phi_fp()))
475  { edm::LogError("L1T") << "conv_hit_i.Phi_fp() = " << conv_hit_i.Phi_fp()
476  << ", conv_hit_j.Phi_fp() = " << conv_hit_j.Phi_fp(); return; }
477 
478  track.push_Hit( conv_hit_i );
479 
480  } else if (
481  (bugME11Dupes_ && is_csc_me11) && // if reproduce ME1/1 theta duplication bug, do not check 'ring', 'strip' and 'pattern'
482  (conv_hit_i.Subsystem() == conv_hit_j.Subsystem()) &&
483  (conv_hit_i.PC_station() == conv_hit_j.PC_station()) &&
484  (conv_hit_i.PC_chamber() == conv_hit_j.PC_chamber()) &&
485  //(conv_hit_i.Ring() == conv_hit_j.Ring()) && // because of ME1/1
486  //(conv_hit_i.Strip() == conv_hit_j.Strip()) &&
487  //(conv_hit_i.Wire() == conv_hit_j.Wire()) &&
488  //(conv_hit_i.Pattern() == conv_hit_j.Pattern()) &&
489  (conv_hit_i.BX() == conv_hit_j.BX()) &&
490  //(conv_hit_i.Strip_low() == conv_hit_j.Strip_low()) && // For RPC clusters
491  //(conv_hit_i.Strip_hi() == conv_hit_j.Strip_hi()) && // For RPC clusters
492  //(conv_hit_i.Roll() == conv_hit_j.Roll()) && // For RPC clusters
493  true
494  ) {
495  // Dirty hack
496  EMTFHit tmp_hit = conv_hit_j;
497  tmp_hit.set_theta_fp( conv_hit_i.Theta_fp() );
498  track.push_Hit( tmp_hit );
499  }
500  }
501 
502  // Sort by station
503  struct {
504  typedef EMTFHit value_type;
505  bool operator()(const value_type& lhs, const value_type& rhs) const {
506  return lhs.Station() < rhs.Station();
507  }
508  } less_station_cmp;
509 
510  EMTFHitCollection tmp_hits = track.Hits();
511  std::stable_sort(tmp_hits.begin(), tmp_hits.end(), less_station_cmp);
512  track.set_Hits( tmp_hits );
513 }
int Strip_hi() const
Definition: EMTFHit.h:164
int Subsystem() const
Definition: EMTFHit.h:200
int Strip() const
Definition: EMTFHit.h:163
int Phi_fp() const
Definition: EMTFHit.h:175
int Roll() const
Definition: EMTFHit.h:155
void set_theta_fp(int bits)
Definition: EMTFHit.h:118
int PC_station() const
Definition: EMTFHit.h:159
int Strip_low() const
Definition: EMTFHit.h:165
int BX() const
Definition: EMTFHit.h:173
l1t::EMTFHitCollection EMTFHitCollection
Definition: Common.h:25
int Ring() const
Definition: EMTFHit.h:146
int PC_chamber() const
Definition: EMTFHit.h:160
EMTFHitCollection Hits() const
Definition: EMTFTrack.h:81
void push_Hit(const EMTFHit &hit)
Definition: EMTFTrack.h:62
void set_Hits(const EMTFHitCollection &hits)
Definition: EMTFTrack.h:70
int Pattern() const
Definition: EMTFHit.h:168
int Theta_fp() const
Definition: EMTFHit.h:176
int Is_RPC() const
Definition: EMTFHit.h:198
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  int istation = conv_hits_it->Station()-1;
86  int zone_code = conv_hits_it->Zone_code(); // decide based on original zone code
87  if (use_fs_zone_code)
88  zone_code = conv_hits_it->FS_zone_code(); // decide based on new zone code
89 
90  // A hit can go into multiple zones
91  for (int izone = 0; izone < emtf::NUM_ZONES; ++izone) {
92  if (!zone_roads.at(izone).empty()) {
93 
94  if (zone_code & (1<<izone)) {
95  const int zs = (izone*emtf::NUM_STATIONS) + istation;
96  zs_conv_hits.at(zs).push_back(*conv_hits_it);
97 
98  // Update fs_history and bt_history depending on the processor BX
99  // This update only goes into the hits associated to a track, it does not affect the original hit collection
100  EMTFHit& conv_hit = zs_conv_hits.at(zs).back(); // pass by reference
101  int old_fs_segment = conv_hit.FS_segment();
102  int new_fs_segment = update_fs_history(old_fs_segment, bx_, conv_hit.BX());
103  conv_hit.set_fs_segment( new_fs_segment );
104 
105  int old_bt_segment = conv_hit.BT_segment();
106  int new_bt_segment = update_bt_history(old_bt_segment, bx_, conv_hit.BX());
107  conv_hit.set_bt_segment( new_bt_segment );
108  }
109  }
110  }
111 
112  } // end loop over conv_hits
113  } // end loop over extended_conv_hits
114 
115  if (verbose_ > 1) { // debug
116  for (int izone = 0; izone < emtf::NUM_ZONES; ++izone) {
117  for (int istation = 0; istation < emtf::NUM_STATIONS; ++istation) {
118  const int zs = (izone*emtf::NUM_STATIONS) + istation;
119  for (const auto& conv_hit : zs_conv_hits.at(zs)) {
120  std::cout << "z: " << izone << " st: " << istation+1 << " cscid: " << conv_hit.CSC_ID()
121  << " ph_zone_phi: " << conv_hit.Zone_hit() << " ph_low_prec: " << (conv_hit.Zone_hit()<<5)
122  << " ph_high_prec: " << conv_hit.Phi_fp() << " ph_high_low_diff: " << (conv_hit.Phi_fp() - (conv_hit.Zone_hit()<<5))
123  << std::endl;
124  }
125  }
126  }
127  }
128 
129  // Keep the best phi difference for every road by (zone, station)
130  std::array<std::vector<hit_sort_pair_t>, emtf::NUM_ZONES*emtf::NUM_STATIONS> zs_phi_differences;
131 
132  // Get the best-matching hits by comparing phi difference between
133  // pattern and segment
134  for (int izone = 0; izone < emtf::NUM_ZONES; ++izone) {
135  for (int istation = 0; istation < emtf::NUM_STATIONS; ++istation) {
136  const int zs = (izone*emtf::NUM_STATIONS) + istation;
137 
138  // This leaves zone_roads.at(izone) and zs_conv_hits.at(zs) unchanged
139  // zs_phi_differences.at(zs) gets filled with a pair of <phi_diff, conv_hit> for the
140  // conv_hit with the lowest phi_diff from the pattern in this station and zone
142  izone+1, istation+1,
143  zone_roads.at(izone),
144  zs_conv_hits.at(zs),
145  zs_phi_differences.at(zs)
146  );
147 
148  if (not(zone_roads.at(izone).size() == zs_phi_differences.at(zs).size()))
149  { edm::LogError("L1T") << "zone_roads.at(izone).size() = " << zone_roads.at(izone).size()
150  << ", zs_phi_differences.at(zs).size() = " << zs_phi_differences.at(zs).size(); return; }
151  } // end loop over stations
152  } // end loop over zones
153 
154  if (verbose_ > 1) { // debug
155  for (int izone = 0; izone < emtf::NUM_ZONES; ++izone) {
156  const auto& roads = zone_roads.at(izone);
157  for (unsigned iroad = 0; iroad < roads.size(); ++iroad) {
158  const auto& road = roads.at(iroad);
159  for (int istation = 0; istation < emtf::NUM_STATIONS; ++istation) {
160  const int zs = (izone*emtf::NUM_STATIONS) + istation;
161  int ph_diff = zs_phi_differences.at(zs).at(iroad).first;
162  std::cout << "find seg: z: " << road.Zone()-1 << " r: " << road.Winner()
163  << " st: " << istation << " ph_diff: " << ph_diff
164  << std::endl;
165  }
166  }
167  }
168  }
169 
170 
171  // Build all tracks in each zone
172  for (int izone = 0; izone < emtf::NUM_ZONES; ++izone) {
173  const EMTFRoadCollection& roads = zone_roads.at(izone);
174 
175  for (unsigned iroad = 0; iroad < roads.size(); ++iroad) {
176  const EMTFRoad& road = roads.at(iroad);
177 
178  // Create a track
180  track.set_endcap ( road.Endcap() );
181  track.set_sector ( road.Sector() );
182  track.set_sector_idx ( road.Sector_idx() );
183  track.set_bx ( road.BX() );
184  track.set_zone ( road.Zone() );
185  track.set_ph_num ( road.Key_zhit() );
186  track.set_ph_q ( road.Quality_code() );
187  track.set_rank ( road.Quality_code() );
188  track.set_winner ( road.Winner() );
189 
190  track.clear_Hits();
191 
192  // Insert hits
193  for (int istation = 0; istation < emtf::NUM_STATIONS; ++istation) {
194  const int zs = (izone*emtf::NUM_STATIONS) + istation;
195 
196  const EMTFHitCollection& conv_hits = zs_conv_hits.at(zs);
197  int ph_diff = zs_phi_differences.at(zs).at(iroad).first;
198  hit_ptr_t conv_hit_ptr = zs_phi_differences.at(zs).at(iroad).second;
199 
200  if (ph_diff != invalid_ph_diff) {
201  // Inserts the conv_hit with the lowest phi_diff, as well as its duplicate
202  // (same strip and phi, different wire and theta), if a duplicate exists
203  insert_hits(conv_hit_ptr, conv_hits, track);
204  }
205  }
206 
207  if (fixZonePhi_) {
208  if (not(!track.Hits().empty()))
209  { edm::LogError("L1T") << "track.Hits().empty() = " << track.Hits().empty(); return; }
210  }
211 
212  // Output track
213  zone_tracks.at(izone).push_back(track);
214 
215  } // end loop over roads
216  } // end loop over zones
217 
218  if (verbose_ > 0) { // debug
219  for (const auto& tracks : zone_tracks) {
220  for (const auto& track : tracks) {
221  for (const auto& hit : track.Hits()) {
222  std::cout << "match seg: z: " << track.Zone()-1 << " pat: " << track.Winner() << " st: " << hit.Station()
223  << " vi: " << to_binary(0b1, 2) << " hi: " << ((hit.FS_segment()>>4) & 0x3)
224  << " ci: " << ((hit.FS_segment()>>1) & 0x7) << " si: " << (hit.FS_segment() & 0x1)
225  << " ph: " << hit.Phi_fp() << " th: " << hit.Theta_fp()
226  << std::endl;
227  }
228  }
229  }
230  }
231 
232 }
void clear_Hits()
Definition: EMTFTrack.h:54
int Zone() const
Definition: EMTFRoad.h:36
void set_bx(int bits)
Definition: EMTFTrack.h:100
static char to_hex(unsigned int i)
Definition: types.cc:29
int Zone() const
Definition: EMTFTrack.h:139
int BT_segment() const
Definition: EMTFHit.h:184
void set_sector(int bits)
Definition: EMTFTrack.h:93
l1t::EMTFRoadCollection EMTFRoadCollection
Definition: Common.h:27
int Phi_fp() const
Definition: EMTFHit.h:175
int NUM_ZONES
Definition: Common.h:67
int Zone_hit() const
Definition: EMTFHit.h:179
int Winner() const
Definition: EMTFTrack.h:132
void set_ph_num(int bits)
Definition: EMTFTrack.h:106
void set_sector_idx(int bits)
Definition: EMTFTrack.h:94
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:126
int BX() const
Definition: EMTFHit.h:173
void set_zone(int bits)
Definition: EMTFTrack.h:105
int FS_segment() const
Definition: EMTFHit.h:181
int NUM_STATIONS
Definition: Common.h:71
l1t::EMTFHitCollection EMTFHitCollection
Definition: Common.h:25
EMTFHitCollection::const_iterator hit_ptr_t
void set_rank(int bits)
Definition: EMTFTrack.h:97
void set_fs_segment(int bits)
Definition: EMTFHit.h:123
void set_winner(int bits)
Definition: EMTFTrack.h:98
EMTFHitCollection Hits() const
Definition: EMTFTrack.h:81
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:92
void set_ph_q(int bits)
Definition: EMTFTrack.h:107
int Sector_idx() const
Definition: EMTFRoad.h:34
int CSC_ID() const
Definition: EMTFHit.h:153
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 234 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().

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