CMS 3D CMS Logo

TrackBuildingLayer.cc
Go to the documentation of this file.
2 
6 
8 
9 using namespace emtf::phase2;
10 using namespace emtf::phase2::algo;
11 
12 // Static
13 seg_theta_t TrackBuildingLayer::calc_theta_median(std::vector<seg_theta_t> thetas) {
14  auto i_last = thetas.size() - 1;
15 
16  // Sort Thetas
17  // This will sort ascending order (lower-value means lower-index)
18  data::mergesort(&thetas[0], thetas.size(), [](seg_theta_t lower_index_value, seg_theta_t larger_index_value) -> int {
19  return lower_index_value > larger_index_value ? 1 : 0;
20  });
21 
22  // Check if any model_thm_site is null
23  // Since the theta array has been sorted, it's enough
24  // to check the last index, because the invalid value will be the max
25  seg_theta_t invalid_theta = -1; // This maps to 255 since it underflows
26 
27  bool any_invalid = thetas[i_last] == invalid_theta;
28 
29  // Calculate median
30  if (any_invalid) {
31  // Use the min value as the median if there are any invalid thetas
32  return thetas[0];
33  } else {
34  // Calculate the median if all thetas are valid
35  return data::getMedianOfSorted(&thetas[0], thetas.size());
36  }
37 }
38 
39 // Members
41 
43  const std::vector<road_t>& roads,
44  const bool& displaced_en,
45  std::vector<track_t>& tracks) const {
46  // Apply
47  for (unsigned int i_road = 0; i_road < roads.size(); ++i_road) {
48  // Get road and track
49  const auto& road = roads[i_road];
50  auto& track = tracks.emplace_back();
51 
52  // Initialize track
53  track.phi = 0;
54  track.theta = 0;
55  track.valid = 0;
56 
57  for (unsigned int site_id = 0; site_id < v3::kNumTrackSites; ++site_id) {
58  track.site_segs[site_id] = 0;
59  track.site_mask[site_id] = 0;
60  track.site_rm_mask[site_id] = 0;
61  }
62 
63  for (unsigned int i_feature = 0; i_feature < v3::kNumTrackFeatures; ++i_feature) {
64  track.features[i_feature] = 0;
65  }
66 
67  // Short-Circuit: If the road has quality-0 skip it
68  if (road.quality == 0) {
69  continue;
70  }
71 
72  // Debug Info
73  if (this->context_.config_.verbosity_ > 1) {
74  if (i_road == 0) {
75  edm::LogInfo("L1TEMTFpp") << std::endl;
76  edm::LogInfo("L1TEMTFpp") << "==========================================================================="
77  << std::endl;
78  edm::LogInfo("L1TEMTFpp") << "BEGIN TRACK BUILDING" << std::endl;
79  edm::LogInfo("L1TEMTFpp") << "---------------------------------------------------------------------------"
80  << std::endl;
81  }
82 
83  edm::LogInfo("L1TEMTFpp") << "***************************************************************************"
84  << std::endl;
85  edm::LogInfo("L1TEMTFpp") << "Begin building track " << i_road << std::endl;
86  }
87 
88  // Attach segments
89  attachSegments(segments, road, displaced_en, track);
90 
91  // Debug Info
92  if (this->context_.config_.verbosity_ > 1) {
93  edm::LogInfo("L1TEMTFpp") << "End building track " << i_road << std::endl;
94 
95  if (i_road == (roads.size() - 1)) {
96  edm::LogInfo("L1TEMTFpp") << "---------------------------------------------------------------------------"
97  << std::endl;
98  edm::LogInfo("L1TEMTFpp") << "END TRACK BUILDING" << std::endl;
99  edm::LogInfo("L1TEMTFpp") << "==========================================================================="
100  << std::endl;
101  }
102  }
103  }
104 }
105 
107  const road_t& road,
108  const bool& displaced_en,
109  track_t& track) const {
110  // ===========================================================================
111  // Constants
112  // ---------------------------------------------------------------------------
113  seg_theta_t invalid_theta = -1; // This will map to 255 since it underflows
114 
115  // ===========================================================================
116  // Unpack road
117  // ---------------------------------------------------------------------------
118  // trk_col: Recall that the hitmap is 288 cols wide, and the full chamber hitmap is 315 cols;
119  // the chamber hitmap doesn't fit in the hitmap, so we skipped the first 27 cols.
120  // In order to calculate the full hitmap col, we need to add back the 27 cols that we skipped.
121  // sector_col: The sector's column is the center col of the phi map adding back the 27 skipped cols.
122  const auto trk_zone = road.zone;
123  const auto trk_pattern = road.pattern;
124  const auto trk_quality = road.quality;
125 
126  int bit_sel_zone = (1u << trk_zone);
127 
128  const trk_col_t trk_col = road.col + v3::kHitmapCropColStart;
129  const trk_col_t sector_col = static_cast<trk_col_t>(v3::kHitmapNCols / 2) + v3::kHitmapCropColStart;
130 
131  // ===========================================================================
132  // Initialize vars
133  // ---------------------------------------------------------------------------
134  std::array<seg_phi_t, v3::kNumTrackSites> trk_seg_phi_diff;
135  std::array<seg_theta_t, v3::kNumTrackSites> trk_seg_theta;
136 
137  for (unsigned int site_id = 0; site_id < v3::kNumTrackSites; ++site_id) {
138  trk_seg_phi_diff[site_id] = 0;
139  trk_seg_theta[site_id] = 0;
140  }
141 
142  // ===========================================================================
143  // Unpack model
144  // ---------------------------------------------------------------------------
145  const auto& model = context_.model_;
146  const auto& model_hm = model.zones_[trk_zone].hitmap;
147  const auto& model_ftc = model.features_;
148 
149  auto* model_pat = &(model.zones_[trk_zone].prompt_patterns[trk_pattern]);
150 
151  if (displaced_en) {
152  model_pat = &(model.zones_[trk_zone].disp_patterns[trk_pattern]);
153  }
154 
155  // ===========================================================================
156  // Convert column center to emtf_phi units
157  // ---------------------------------------------------------------------------
158  // Each column is emtf_phi=1<<n wide, therefore half of this would be 1<<(n-1)
159  // since shifting to right m, is the same as dividing by 2^m.
160  seg_phi_t trk_abs_phi =
161  (static_cast<seg_phi_t>(trk_col) << v3::kHitmapColFactorLog2) + (1 << (v3::kHitmapColFactorLog2 - 1));
162  seg_phi_t sector_abs_phi =
163  (static_cast<seg_phi_t>(sector_col) << v3::kHitmapColFactorLog2) + (1 << (v3::kHitmapColFactorLog2 - 1));
164 
165  // Calculate track phi
166  // Note this is the track phi with respect to the sector center
167  trk_feature_t trk_rel_phi = static_cast<trk_feature_t>(trk_abs_phi) - static_cast<trk_feature_t>(sector_abs_phi);
168 
169  // ===========================================================================
170  // Get pattern info for each row
171  // ---------------------------------------------------------------------------
172  std::array<trk_col_t, v3::kHitmapNRows> trk_pat_begin;
173  std::array<trk_col_t, v3::kHitmapNRows> trk_pat_center;
174  std::array<trk_col_t, v3::kHitmapNRows> trk_pat_end;
175  std::array<seg_phi_t, v3::kHitmapNRows> trk_pat_phi;
176 
177  for (unsigned int i_row = 0; i_row < v3::kHitmapNRows; ++i_row) {
178  // Get the model pattern
179  const auto& model_pat_row = (*model_pat)[i_row];
180 
181  // Offset the pattern's begin, center, and end by the track column
182  trk_pat_begin[i_row] = trk_col + model_pat_row.begin;
183  trk_pat_center[i_row] = trk_col + model_pat_row.center;
184  trk_pat_end[i_row] = trk_col + model_pat_row.end;
185  trk_pat_phi[i_row] = 0;
186 
187  // Short-Circuit: If the pattern's center is less than the padding used
188  // when matching the pattern to the hitmap then the pattern center is 0.
189  // This is because at that point, the center is out-of-bounds.
190  if (trk_pat_center[i_row] <= v3::kPatternMatchingPadding)
191  continue;
192 
193  // When the center is beyond the padding, then the pattern
194  // is in-bound, therefore we subtract the padding offset.
195  // To get the center in terms of the non-padded row BW we need to remove padding
196  // since col-padding + 1 should map to 1 in the non-padded hitmap
197  const auto& temp_trk_pat_center = trk_pat_center[i_row] - v3::kPatternMatchingPadding;
198 
199  // Convert the pattern center to emtf_phi units
200  trk_pat_phi[i_row] = (static_cast<seg_phi_t>(temp_trk_pat_center) << v3::kHitmapColFactorLog2) +
201  (1 << (v3::kHitmapColFactorLog2 - 1));
202  }
203 
204  // ===========================================================================
205  // Select segments using phi only
206  // ---------------------------------------------------------------------------
207 
208  // clang-format off
209  std::vector<std::vector<unsigned int>> site_chambers = {
210  { 0, 1, 2, 9, 10, 11, 45}, // ME1/1
211  { 3, 4, 5, 12, 13, 14, 46}, // ME1/2
212  { 18, 19, 20, 48, 21, 22, 23, 24, 25, 26, 49}, // ME2/1 + ME2/2
213  { 27, 28, 29, 50, 30, 31, 32, 33, 34, 35, 51}, // ME3/1 + ME3/2
214  { 36, 37, 38, 52, 39, 40, 41, 42, 43, 44, 53}, // ME4/1 + ME4/2
215  { 57, 58, 59, 66, 67, 68, 100}, // RE1/2
216  { 75, 76, 77, 78, 79, 80, 103}, // RE2/2
217  { 81, 82, 83, 104, 84, 85, 86, 87, 88, 89, 105}, // RE3/1 + RE3/2
218  { 90, 91, 92, 106, 93, 94, 95, 96, 97, 98, 107}, // RE4/1 + RE4/2
219  { 54, 55, 56, 63, 64, 65, 99}, // GE1/1
220  { 72, 73, 74, 102}, // GE2/1
221  {108, 109, 110, 111, 112, 113, 114} // ME0
222  };
223 
224  std::vector<unsigned int> site_chamber_orders = {
225  0, 0, 2, 2, 2, 0, 0, 2, 2, 0, 1, 0
226  };
227 
228  std::vector<std::vector<int>> chamber_orders = {
229  {-1, -1, 6, -1, 0, 1, -1, 2, 3, -1, 4, 5},
230  { 3, -1, -1, 0, -1, -1, 1, -1, -1, 2, -1, -1},
231  { 3, -1, 10, 0, 4, 5, 1, 6, 7, 2, 8, 9}
232  };
233  // clang-format on
234 
235  auto n_rows = model_hm.size();
236 
237  for (unsigned int i_row = 0; i_row < n_rows; ++i_row) { // Begin loop rows
238 
239  const auto& model_hm_row = model_hm[i_row];
240 
241  const auto& trk_pat_row_begin = trk_pat_begin[i_row];
242  const auto& trk_pat_row_end = trk_pat_end[i_row];
243  const auto& trk_pat_row_phi = trk_pat_phi[i_row];
244 
245  if (this->context_.config_.verbosity_ > 2) {
246  edm::LogInfo("L1TEMTFpp") << "Pattern Row:"
247  << " row " << i_row << " begin " << trk_pat_row_begin << " end " << trk_pat_row_end
248  << " phi " << trk_pat_row_phi << std::endl;
249  }
250 
251  for (const auto& model_hm_site : model_hm_row) { // Begin loop sites in row
252 
253  const int site_id = static_cast<int>(model_hm_site.id);
254 
255  auto& site_seg_id = track.site_segs[site_id];
256  auto& site_bit = track.site_mask[site_id];
257  auto& site_min_phi_diff = trk_seg_phi_diff[site_id];
258 
259  const auto& s_chambers = site_chambers[site_id];
260  const auto& s_chamber_order_id = site_chamber_orders[site_id];
261  const auto& s_chamber_order = chamber_orders[s_chamber_order_id];
262 
263  for (const auto& chamber_idx : s_chamber_order) { // Begin loop chambers in site
264 
265  if (chamber_idx == -1)
266  continue;
267 
268  int chamber_id = s_chambers[chamber_idx];
269 
270  for (unsigned int i_ch_seg = 0; i_ch_seg < v3::kChamberSegments; ++i_ch_seg) { // Begin loop segments
271 
272  const int seg_id = chamber_id * v3::kChamberSegments + i_ch_seg;
273  const auto& seg = segments[seg_id];
274 
275  // Short-Circuit: If the segment is invalid move on
276  if (!seg.valid) {
277  continue;
278  }
279 
280  // Short-Circuit: If the segment is not in the zone move on
281  if ((seg.zones & bit_sel_zone) != bit_sel_zone) {
282  continue;
283  }
284 
285  // Short-Circuit: If the segment is outside of the pattern move on
286  const trk_col_t seg_col = (seg.phi >> 4) + v3::kPatternMatchingPadding;
287 
288  if (!(trk_pat_row_begin <= seg_col && seg_col <= trk_pat_row_end)) {
289  continue;
290  }
291 
292  // Calculate abs diff between the pattern's row phi and the segment's phi
293  seg_phi_t diff;
294 
295  if (trk_pat_row_phi > seg.phi) {
296  diff = trk_pat_row_phi - seg.phi;
297  } else {
298  diff = seg.phi - trk_pat_row_phi;
299  }
300 
301  if (this->context_.config_.verbosity_ > 2) {
302  edm::LogInfo("L1TEMTFpp") << "Site candidate:"
303  << " site_id " << site_id << " seg_id " << seg_id << " seg_phi " << seg.phi
304  << " seg_theta1 " << seg.theta1 << " seg_theta2 " << seg.theta2 << " seg_bend "
305  << seg.bend << std::endl;
306  }
307 
308  // Short-Circuit: If the difference is larger than the min diff move on
309  if (site_bit == 1 && site_min_phi_diff <= diff)
310  continue;
311 
312  // Select better segment
313  site_seg_id = seg_id;
314  site_bit = 1;
315  site_min_phi_diff = diff;
316  } // End loop segments
317 
318  } // End loop chambers in site
319 
320  // Debug Info
321  if (this->context_.config_.verbosity_ > 2 && site_bit == 1) {
322  edm::LogInfo("L1TEMTFpp") << "Segment attached:"
323  << " site_id " << site_id << " seg_id " << site_seg_id << " seg_phi "
324  << segments[site_seg_id].phi << " seg_theta1 " << segments[site_seg_id].theta1
325  << " seg_theta2 " << segments[site_seg_id].theta2 << " seg_bend "
326  << segments[site_seg_id].bend << std::endl;
327  }
328  } // End loop sites in row
329 
330  } // End loop rows
331 
332  // ===========================================================================
333  // Calculate theta medians
334  // ---------------------------------------------------------------------------
335  const auto& model_thmc = model.theta_medians_;
336 
337  std::vector<seg_theta_t> theta_medians;
338 
339  for (const auto& model_thm : model_thmc) { // Begin loop model theta medians
340 
341  std::vector<seg_theta_t> group_medians;
342 
343  for (const auto& model_thm_group : model_thm) { // Begin loop theta median groups
344 
345  std::vector<seg_theta_t> group;
346 
347  for (const auto& model_thm_site : model_thm_group) { // Begin loop group sites
348  int site_id = static_cast<int>(model_thm_site.id);
349 
350  const auto& site_bit = track.site_mask[site_id];
351 
352  // Initialize as invalid theta
353  auto& theta = group.emplace_back(invalid_theta);
354 
355  // Short-Circuit: If no segment was selected, move on.
356  if (site_bit == 0)
357  continue;
358 
359  // Get selected segment's theta value
360  const auto& site_seg_id = track.site_segs[site_id];
361  const auto& site_seg = segments[site_seg_id];
362 
363  if (model_thm_site.theta_id == theta_id_t::kTheta1) {
364  theta = site_seg.theta1;
365  } else if (model_thm_site.theta_id == theta_id_t::kTheta2) {
366  theta = site_seg.theta2;
367  }
368 
369  // If the segment theta is 0 this is invalid theta value
370  if (theta == 0) {
371  theta = invalid_theta;
372  }
373  } // End loop group sites
374 
375  // Calculate theta median
376  if (this->context_.config_.verbosity_ > 2) {
377  for (const auto& theta : group) {
378  edm::LogInfo("L1TEMTFpp") << "theta " << theta << std::endl;
379  }
380  }
381 
382  auto group_median = calc_theta_median(group);
383  group_medians.push_back(group_median);
384 
385  if (this->context_.config_.verbosity_ > 2) {
386  edm::LogInfo("L1TEMTFpp") << "group_median " << group_median << std::endl;
387  }
388  } // End loop theta median groups
389 
390  // Calculate model_thm_group median
391  auto theta_median = calc_theta_median(group_medians);
392  theta_medians.push_back(theta_median);
393 
394  if (this->context_.config_.verbosity_ > 2) {
395  edm::LogInfo("L1TEMTFpp") << "theta_median " << theta_median << std::endl;
396  }
397  } // End loop theta medians
398 
399  // ===========================================================================
400  // Select track theta
401  // ---------------------------------------------------------------------------
402  seg_theta_t trk_abs_theta;
403 
404  if (trk_zone != 2) {
405  trk_abs_theta = theta_medians[0];
406  } else {
407  trk_abs_theta = theta_medians[1];
408  }
409 
410  // If median is invalid, try station 1 median
411  if (trk_abs_theta == invalid_theta) {
412  trk_abs_theta = theta_medians[2];
413  }
414 
415  // If all medians are invalid use 0 (0 is an invalid theta)
416  if (trk_abs_theta == invalid_theta) {
417  trk_abs_theta = 0;
418  }
419 
420  // ===========================================================================
421  // Compare segment theta to track theta
422  // ---------------------------------------------------------------------------
423 
424  // if theta_window < diff, it is invalid
425 
426  // clang-format off
427  std::vector<std::vector<seg_theta_t>> site_theta_window = {
428  {5, 0, 2, 2, 2, 34, 0, 3, 3, 5, 6, 5},
429  {5, 9, 5, 4, 5, 14, 7, 7, 7, 7, 7, 4},
430  {11, 6, 5, 6, 6, 10, 8, 8, 9, 8, 0, 0}
431  };
432  // clang-format on
433 
434  if (displaced_en) {
435  // clang-format off
436  site_theta_window = {
437  {14, 40, 4, 3, 3, 45, 0, 4, 4, 15, 8, 13},
438  {16, 18, 7, 5, 5, 22, 7, 7, 8, 17, 9, 14},
439  {26, 15, 8, 9, 9, 17, 11, 9, 10, 26, 21, 0}
440  };
441  // clang-format on
442  }
443 
444  for (unsigned int site_id = 0; site_id < v3::kNumTrackSites; ++site_id) {
445  auto& site_bit = track.site_mask[site_id];
446  auto& site_rm_bit = track.site_rm_mask[site_id];
447 
448  // Get Theta Window
449  const auto& theta_window = site_theta_window[trk_zone][site_id];
450 
451  // Short-Circuit: If no segment was selected, move on.
452  if (site_bit == 0)
453  continue;
454 
455  const auto& site_seg_id = track.site_segs[site_id];
456  const auto& site_seg = segments[site_seg_id];
457 
458  // Init differences with out-of-bounds values
459  seg_theta_t diff_1 = theta_window + 1;
460  seg_theta_t diff_2 = theta_window + 1;
461 
462  // Calculate abs theta 1 diff
463  if (site_seg.theta1 != 0) {
464  if (site_seg.theta1 < trk_abs_theta) {
465  diff_1 = trk_abs_theta - site_seg.theta1;
466  } else {
467  diff_1 = site_seg.theta1 - trk_abs_theta;
468  }
469  }
470 
471  // Calculate abs theta 2 diff
472  if (site_seg.theta2 != 0) {
473  if (site_seg.theta2 < trk_abs_theta) {
474  diff_2 = trk_abs_theta - site_seg.theta2;
475  } else {
476  diff_2 = site_seg.theta2 - trk_abs_theta;
477  }
478  }
479 
480  // Select the theta with the smallest difference
481  if (diff_1 <= diff_2 && diff_1 < theta_window) {
482  // Select theta 1 as the correct theta value
483  trk_seg_theta[site_id] = site_seg.theta1;
484  } else if (diff_2 < theta_window) {
485  // Select theta 2 as the correct theta value
486  trk_seg_theta[site_id] = site_seg.theta2;
487  } else {
488  // Invalidate site if both differences are outside of the theta window
489  site_bit = 0;
490  site_rm_bit = 1;
491 
492  // Debug Info
493  if (this->context_.config_.verbosity_ > 4) {
494  edm::LogInfo("L1TEMTFpp") << "Segment outside of theta window; detatched:"
495  << " site_id " << site_id << " seg_id " << site_seg_id << " seg_phi " << site_seg.phi
496  << " seg_theta1 " << site_seg.theta1 << " seg_theta2 " << site_seg.theta2
497  << std::endl;
498  }
499  }
500  }
501 
502  // ===========================================================================
503  // Assign Data
504  // ---------------------------------------------------------------------------
505  track.zone = trk_zone;
506  track.col = trk_col;
507  track.pattern = trk_pattern;
508  track.quality = trk_quality;
509  track.phi = trk_abs_phi;
510  track.theta = trk_abs_theta;
511  track.valid = 1;
512 
513  // ===========================================================================
514  // Fill features
515  // ---------------------------------------------------------------------------
516  int i_feature = 0;
517 
518  for (auto& model_ft : model_ftc) {
519  for (auto& model_ft_site : model_ft.sites) {
520  int site_id = static_cast<int>(model_ft_site);
521 
522  const auto& site_seg_id = track.site_segs[site_id];
523  const auto& site_bit = track.site_mask[site_id];
524  const auto& site_seg = segments[site_seg_id];
525 
526  auto& trk_feature = track.features[i_feature++];
527 
528  // Short-Circuit: No segment attached
529  if (site_bit == 0) {
530  continue;
531  }
532 
533  // Fill features
534  if (model_ft.id == feature_id_t::kPhi) {
535  // Note: This is the segment's phi with respect to the track's abs phi
536  trk_feature = static_cast<trk_feature_t>(site_seg.phi) - static_cast<trk_feature_t>(trk_abs_phi);
537  } else if (model_ft.id == feature_id_t::kTheta) {
538  // Note: This is the segment's theta with respect to the track's abs theta
539  trk_feature = static_cast<trk_feature_t>(trk_seg_theta[site_id]) - static_cast<trk_feature_t>(trk_abs_theta);
540  } else if (model_ft.id == feature_id_t::kBend) {
541  trk_feature = site_seg.bend;
542  } else if (model_ft.id == feature_id_t::kQuality) {
543  trk_feature = site_seg.qual1;
544  }
545  }
546  }
547 
548  // Additional features
549  track.features[i_feature++] = trk_quality > 0 ? trk_rel_phi : decltype(trk_rel_phi)(0);
550  track.features[i_feature++] = trk_quality > 0 ? trk_abs_theta : decltype(trk_abs_theta)(0);
551  track.features[i_feature++] = trk_quality;
552  track.features[i_feature++] = 0; // unused
553 
554  // Debug Info
555  if (this->context_.config_.verbosity_ > 1) {
556  edm::LogInfo("L1TEMTFpp") << "Track"
557  << " zone " << track.zone << " col " << track.col << " pat " << track.pattern << " qual "
558  << track.quality << " sector_abs_phi " << sector_abs_phi << " abs_phi " << track.phi
559  << " rel_phi " << trk_rel_phi << " abs_theta " << track.theta << " features "
560  << std::endl;
561 
562  for (unsigned int i = 0; i < v3::kNumTrackFeatures; ++i) {
563  if (i > 0) {
564  edm::LogInfo("L1TEMTFpp") << " ";
565  }
566 
567  edm::LogInfo("L1TEMTFpp") << track.features[i];
568  }
569 
570  edm::LogInfo("L1TEMTFpp") << std::endl;
571  }
572 }
T getMedianOfSorted(T arr[], const unsigned int &arr_size)
Definition: DataUtils.h:140
constexpr int kHitmapNRows
Definition: EMTFConstants.h:47
static seg_theta_t calc_theta_median(std::vector< seg_theta_t >)
ap_uint< 8 > seg_theta_t
Definition: EMTFTypes.h:67
constexpr int kHitmapNCols
Definition: EMTFConstants.h:48
void attachSegments(const segment_collection_t &, const road_t &, const bool &, track_t &) const
trk_patt_t pattern
Definition: EMTFTypes.h:152
trk_qual_t quality
Definition: EMTFTypes.h:153
constexpr int kPatternMatchingPadding
Definition: EMTFConstants.h:56
constexpr int kNumTrackFeatures
Definition: EMTFConstants.h:40
constexpr int kHitmapCropColStart
Definition: EMTFConstants.h:52
Log< level::Info, false > LogInfo
constexpr int kChamberSegments
Definition: EMTFConstants.h:29
void apply(const segment_collection_t &, const std::vector< road_t > &, const bool &, std::vector< track_t > &) const
constexpr int kNumTrackSites
Definition: EMTFConstants.h:42
constexpr int kHitmapColFactorLog2
Definition: EMTFConstants.h:51
void mergesort(T arr[], const unsigned int &arr_size, const unsigned int &first_n, const C &comparator)
Definition: DataUtils.h:66
ap_uint< 9 > trk_col_t
Definition: EMTFTypes.h:98
ap_uint< 13 > seg_phi_t
Definition: EMTFTypes.h:65
Geom::Theta< T > theta() const
ap_int< 13 > trk_feature_t
Definition: EMTFTypes.h:113
EMTFConfiguration config_
Definition: EMTFContext.h:39
std::array< segment_t, v3::kNumSegments > segment_collection_t
Definition: EMTFTypes.h:93