ATLAS Offline Software
FPGATrackSimHoughTransformTool.cxx
Go to the documentation of this file.
1 // Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
2 
21 
22 #include <sstream>
23 #include <cmath>
24 #include <algorithm>
25 
26 static inline int quant(double min, double max, unsigned nSteps, double val);
27 static inline double unquant(double min, double max, unsigned nSteps, int step);
28 template <typename T>
29 static inline std::string to_string(const std::vector<T> &v);
30 
31 
33 {
34 
35  // Move temp variables over from properties to struct
42 
43 
44  // Debug
45  ATH_MSG_INFO("Image size: " << m_imageSize_x << " x " << m_imageSize_y);
46  ATH_MSG_INFO("Convolution size: " << m_convSize_x << " x " << m_convSize_y);
47  ATH_MSG_INFO("Convolution: " << to_string(const_cast<std::vector<int>&>(m_conv.value())));
48  ATH_MSG_INFO("Hit Extend: " << to_string(const_cast<std::vector<unsigned>&>(m_hitExtend_x.value())));
49 
50  // Retrieve info
52  ATH_CHECK(m_FPGATrackSimMapping.retrieve());
53  m_nLayers = m_FPGATrackSimMapping->PlaneMap_1st(0)->getNLogiLayers();
54 
55  // Error checking
56  // TODO check bounds are set correctly
57  bool ok = false;
59  ATH_MSG_FATAL("initialize() Image size must be greater than 0");
60  else if (m_conv.size() != m_convSize_x * m_convSize_y)
61  ATH_MSG_FATAL("initialize() Convolution sizes don't match");
62  else if (!m_conv.empty() && (m_convSize_x % 2 == 0 || m_convSize_y % 2 == 0))
63  ATH_MSG_FATAL("initialize() Convolution sizes must be odd");
64  else if (m_hitExtend_x.size() % m_nLayers)
65  ATH_MSG_FATAL("initialize() Hit extentsion list must have size % nLayers");
66  else if (!m_combineLayers.empty() && m_combineLayers.size() != m_nLayers)
67  ATH_MSG_FATAL("initialize() Combine layers list must have size = nLayers");
68  else if (m_threshold.size() % 2 != 1)
69  ATH_MSG_FATAL("initialize() Threshold size must be odd");
70  else if (!m_binScale.empty() && m_binScale.size() != m_nLayers)
71  ATH_MSG_FATAL("initialize() Bin scale list must have size = nLayers");
72  else if (std::any_of(m_binScale.begin(), m_binScale.end(), [&](unsigned i){ return m_imageSize_y % i != 0; }))
73  ATH_MSG_FATAL("initialize() The imagesize is not divisible by scale");
74  else
75  ok = true;
76  if (!ok) return StatusCode::FAILURE;
77 
78  // Warnings / corrections
80  {
81  ATH_MSG_WARNING("initialize() localMaxWindowSize requires tracing hits, turning on automatically");
82  m_traceHits = true;
83  }
84  if (m_idealGeoRoads)
85  {
86  if (m_useSectors)
87  {
88  ATH_MSG_WARNING("initialize() idealGeoRoads conflicts with useSectors, switching off FPGATrackSim sector matching");
89  m_useSectors = false;
90  }
91  if (!m_traceHits)
92  {
93  ATH_MSG_WARNING("initialize() idealGeoRoads requires tracing hits, turning on automatically");
94  m_traceHits = true;
95  }
96  }
97  if (m_binScale.empty()) m_binScale.value().resize(m_nLayers, 1);
98 
99  // Fill convenience variables
102  for (unsigned i = 0; i <= m_imageSize_x; i++)
103  m_bins_x.push_back(unquant(m_parMin[m_par_x], m_parMax[m_par_x], m_imageSize_x, i));
104  for (unsigned i = 0; i <= m_imageSize_y; i++)
105  m_bins_y.push_back(unquant(m_parMin[m_par_y], m_parMax[m_par_y], m_imageSize_y, i));
106 
107  // Initialize combine layers
108  if (!m_combineLayers.empty())
109  {
110  m_nCombineLayers = *std::max_element(m_combineLayers.begin(), m_combineLayers.end()) + 1;
112  for (unsigned i = 0; i < m_combineLayers.size(); i++)
113  m_combineLayer2D[m_combineLayers[i]].push_back(i);
114  }
115  else
116  {
118  for (unsigned i = 0; i < m_nLayers; i++)
119  m_combineLayer2D.push_back({ i });
120  }
121 
122  if (m_houghType == "LowResource"){
123  makeLUT(m_LUT, m_h_rfix, Form("%d-%d", m_imageSize_y.value(), m_imageSize_x.value()));
124  } else if (m_houghType == "Flexible") {
125  double phi0_max_bit_th = (m_parMax.phi * m_phi_coord_max * m_bitwise_phi0_conv) / (m_phi_range);
126  double qApt_max_bit_th = (m_parMax.qOverPt * fpgatracksim::A * m_phi_coord_max * m_r_max_mm * m_bitwise_qApt_conv) / (m_r_max * m_phi_range);
127 
128  m_one_r_const_twoexp = std::pow(2, static_cast<int>(2 * std::log2(m_r_max + 1)));
131  m_DBinQApt_bit_int = (qApt_max_bit_th - m_qApt_min_bit) / m_imageSize_y;
132  m_DBinPhi0_bit_int = (phi0_max_bit_th - m_phi0_min_bit) / m_imageSize_x;
133  double phi0_max_bit = m_phi0_min_bit + (m_imageSize_x * m_DBinPhi0_bit_int);
134  double qApt_max_bit = m_qApt_min_bit + (m_imageSize_y * m_DBinQApt_bit_int);
135  m_qAptBins_bit = (qApt_max_bit - m_qApt_min_bit) / m_DBinQApt_bit_int;
136  m_phi0Bins_bit = (phi0_max_bit - m_phi0_min_bit) / m_DBinPhi0_bit_int;
142 
143  double DBinQApt_clean = ((qApt_max_bit_th - m_qApt_min_bit) / m_imageSize_y) / m_bitwise_qApt_conv;
144  double DBinPhi0_clean = ((phi0_max_bit_th - m_phi0_min_bit) / m_imageSize_x) / m_bitwise_phi0_conv;
145  m_HT_sel = static_cast<int>(DBinPhi0_clean / DBinQApt_clean);
146  }
147  return StatusCode::SUCCESS;
148 }
149 
150 
151 
153 // Main Algorithm
154 
155 StatusCode FPGATrackSimHoughTransformTool::getRoads(const std::vector<std::shared_ptr<const FPGATrackSimHit>> & hits, std::vector<std::shared_ptr<const FPGATrackSimRoad>> & roads)
156 {
157  roads.clear();
158  m_roads.clear();
159 
161 
162  //objects for road merge, all roads go through them, except m_traceHits is disabled
163  std::vector<std::pair<unsigned, unsigned>> roadListXY;
164  std::unordered_set<std::shared_ptr<const FPGATrackSimHit>> merged_image;
166 
167  if (!m_conv.empty()) m_image = convolute(m_image);
168 
169  for (unsigned y = 0; y < m_imageSize_y; y++){
170  for (unsigned x = 0; x < m_imageSize_x; x++){
171  if (passThreshold(m_image, x, y)){
172  if (m_traceHits){
173  //first road is pushed to the roadList
174  roadListXY.push_back({x, y});
175  }else{
176  addRoad(hits, x, y);
177  }
178  }
179  }
180  }
181 
182  for (const auto & roadXY : roadListXY){
183  ATH_MSG_DEBUG("roadList x : " << roadXY.first << ", y : " << roadXY.second);
184  }
185 
186  if(!m_traceHits){
187  if(m_roadMerge)
188  ATH_MSG_DEBUG("Trace hits is disabled. Road merge doesn't work with this state at the moment.");
189  }
190 
191  if(!m_roadMerge){//in case road marge is disabled, add road as usual
192  for (const auto & roadXY : roadListXY){
193  unsigned x = roadXY.first;
194  unsigned y = roadXY.second;
195  addRoad(m_image(y, x).second, x, y);
196  }
197  }else{
198  if(!roadListXY.empty()){
199  std::vector<std::pair<unsigned, unsigned>> mergedRoadListXY;//merged road liste
200  size_t roadCounter = 0; // the number of roads after road merge
202  //Road marge works as follows
203  //1. Take a road from the input list, add it to the merged road list, and remove it from the input list
204  //2. If any road in the input list is neighbouring to the road in the merged road list, then add it to the merged road list and remove it from the input list
205  //3. Once it reaches the end of the input list, select the second road in the merged road list, and repeat the check with the input list
206  //4. Until it reaches the end of the merged road list, repeat 2.-3.
207  //5. Once it reaches the end of the merged road list, all the hits associated with the road in the merged road list are re-associated with the first road in the merged road list
208  //6. As a representative, only the first road is added as a road
209  //7. Select the next road in the input list, then repeat 2.-6.
210  //8. Repeat until all the roda in the input list are considered
212  while(!roadListXY.empty()){
213  mergedRoadListXY.push_back(roadListXY[0]);
214  roadListXY.erase(roadListXY.begin());
215  for(size_t i = 0; i < mergedRoadListXY.size(); i++){
216  for(int j = 0; j < std::ssize(roadListXY); j++){
217  if(std::abs(static_cast<int>(roadListXY[j].first) - static_cast<int>(mergedRoadListXY[i].first)) < 2 &&
218  std::abs(static_cast<int>(roadListXY[j].second) - static_cast<int>(mergedRoadListXY[i].second)) < 2){
219  mergedRoadListXY.push_back(roadListXY[j]);
220  roadListXY.erase(roadListXY.begin() + j);
221  //note: on first iteration, j=0 so j-- will produce negative number
222  j--;
223  }
224  }
225  }
226  if (!mergedRoadListXY.empty()){
227  ATH_MSG_DEBUG( mergedRoadListXY.size() -1 <<" roads are merged to road(" << mergedRoadListXY[0].first << "," << mergedRoadListXY[0].second << ")");
228  }
229  for (const auto & roadXY : mergedRoadListXY){
230  unsigned x = roadXY.first;
231  unsigned y = roadXY.second;
232  merged_image.insert(m_image(y, x).second.begin(), m_image(y, x).second.end());
233  }
234  addRoad(merged_image, mergedRoadListXY[0].first, mergedRoadListXY[0].second);
235  mergedRoadListXY.clear();
236  merged_image.clear();
237  roadCounter++;
238  }
239  ATH_MSG_DEBUG("There is/are " << roadCounter << " roads after road merge");
240  }
241  }
242 
243  roads.reserve(m_roads.size());
244  for (FPGATrackSimRoad & r : m_roads) roads.emplace_back(std::make_shared<const FPGATrackSimRoad>(r));
245 
246  return StatusCode::SUCCESS;
247 }
248 
249 FPGATrackSimHoughTransformTool::Image FPGATrackSimHoughTransformTool::createLayerImage(std::vector<unsigned> const & layers, const std::vector<std::shared_ptr<const FPGATrackSimHit>> & hits, unsigned const scale) const
250 {
252 
253  for (const auto& hit : hits) {
254  if (std::find(layers.begin(), layers.end(), hit->getLayer()) == layers.end()) continue;
255 
256  if (m_houghType == "LowResource"){
257  //FIXME at the moment, only the barrel is considered. And as the r is mostly the same for two strip layers, those two layers share the LUTs of acceptable input phi values. Here, LUT_layer is used to switch the list of LUTs
258  int LUT_layer = -1;
259  switch (hit->getLayer()){
260  case 0 :
261  LUT_layer = 0;
262  break;
263  case 1 :
264  case 2 :
265  LUT_layer = 1;
266  break;
267  case 3 :
268  case 4 :
269  LUT_layer = 2;
270  break;
271  case 5 :
272  case 6 :
273  LUT_layer = 3;
274  break;
275  case 7 :
276  case 8 :
277  LUT_layer = 4;
278  break;
279  default :
280  ATH_MSG_FATAL("Debug: something wrong! layer: " << hit->getLayer());
281  break;
282  }
283  int phi_L_bin = m_h_rfix.at(LUT_layer)->FindBin(hit->getGPhi());
284  int MSB = (phi_L_bin >> (m_bitlength -6));
285  if(MSB >= 64) MSB = 63;//for barrel, MSB should be up to 63, but this line force it to not crash
286  for(const auto& LUT_i: m_LUT.at(LUT_layer).at(MSB)){//check LUTs only correspoinding MSB
287  if(LUT_i.input_begin <= phi_L_bin && phi_L_bin <= LUT_i.input_end){//If in the range, then fire it
288  for(const auto& pos: LUT_i.output){
289  image(pos.y -1, pos.x -1).first++;//NOTE : pos is 1 start
290  if (m_traceHits) image(pos.y -1, pos.x -1).second.insert(hit);
291  }
292  }
293  }
294  } else if (m_houghType == "Flexible") {
295  double r = hit->getR();
296  int r_bit = static_cast<int>(r * m_r_max / m_r_max_mm);
297  int input_bins_vector_size = 0;
298 
299  //Bologna Flexible HT uses qA/Pt=.... or Phi0=.... depending from the axis with more bins (qA/Pt axis #bin > Phi0 then Phi0=..... and viceversa)
300  if (r_bit > m_HT_sel) { //formula for qA/Pt HT
301  input_bins_vector_size = m_imageSize_x;
302  } else { //formula for Phi0 HT
303  input_bins_vector_size = m_imageSize_y;
304  }
305 
306  std::vector<std::vector<int>> hitLineQAPtPhi0(input_bins_vector_size);
307  hitLineQAPtPhi0 = lineGenLay(hit);
308 
309  for (const std::vector<int>& it_base : hitLineQAPtPhi0) {
310  if (it_base[0] != -1 && it_base[1] != -1) {
311  image(it_base[0] , it_base[1]).first++;
312  if (m_traceHits) {
313  image(it_base[0] , it_base[1]).second.insert(hit);
314  }
315  }
316  }
317  }else{
318  // This scans over y (pT) because that is more efficient in memory, in C.
319  // Unknown if firmware will want to scan over x instead.
320  unsigned new_size_y = m_imageSize_y / scale;
321  for (unsigned y_ = 0; y_ < new_size_y; y_++) {
322  unsigned y_bin_min = scale * y_;
323  unsigned y_bin_max = scale * (y_ + 1);
324 
325  // Find the min/max x bins
326  auto xBins = yToXBins(y_bin_min, y_bin_max, hit);
327 
328  // Update the image
329  for (unsigned y = y_bin_min; y < y_bin_max; y++){
330  for (unsigned x = xBins.first; x < xBins.second; x++) {
331  image(y, x).first++;
332  if (m_traceHits) image(y, x).second.insert(hit);
333  }
334  }
335  }
336  }
337  }
338 
339  return image;
340 }
341 
342 FPGATrackSimHoughTransformTool::Image FPGATrackSimHoughTransformTool::createImage(const std::vector<std::shared_ptr<const FPGATrackSimHit>> & hits) const
343 {
345 
346  for (unsigned i = 0; i < m_nCombineLayers; i++)
347  {
349  for (unsigned x = 0; x < m_imageSize_x; ++x)
350  for (unsigned y = 0; y < m_imageSize_y; ++y)
351  if (layerImage(y, x).first > 0)
352  {
353  image(y, x).first++;
354  image(y, x).second.insert(layerImage(y, x).second.begin(), layerImage(y, x).second.end());
355  }
356  }
357  return image;
358 }
359 
361 {
363 
364  for (unsigned y0 = 0; y0 < m_imageSize_y; y0++) // Loop over out
365  for (unsigned x0 = 0; x0 < m_imageSize_x; x0++)
366  for (unsigned r = 0; r < m_convSize_y; r++) // Loop over conv
367  for (unsigned c = 0; c < m_convSize_x; c++) {
368  int y = -static_cast<int>(m_convSize_y) / 2 + r + y0; // Indices of input
369  int x = -static_cast<int>(m_convSize_x) / 2 + c + x0; //
370 
371  if (y >= 0 && y < static_cast<int>(m_imageSize_y) && x >= 0 && x < static_cast<int>(m_imageSize_x)) {
372  int val = m_conv[r * m_convSize_x + c] * image(y, x).first;
373  if (val > 0) {
374  out(y0, x0).first += val;
375  out(y0, x0).second.insert(image(y, x).second.begin(), image(y, x).second.end());
376  }
377  }
378  }
379  return out;
380 }
381 
382 bool FPGATrackSimHoughTransformTool::passThreshold(Image const & image, unsigned x, unsigned y) const
383 {
384  // Pass window threshold
385  unsigned width = m_threshold.size() / 2;
386  if (x < width || (image.size(1) - x) < width) return false;
387  for (unsigned i = 0; i < m_threshold.size(); i++) {
388  if (image(y, x - width + i).first < m_threshold[i]) return false;
389  }
390 
391  // Pass local-maximum check
392  if (m_localMaxWindowSize) {
393  for (int j = -m_localMaxWindowSize; j <= m_localMaxWindowSize; j++) {
394  for (int i = -m_localMaxWindowSize; i <= m_localMaxWindowSize; i++) {
395  if (i == 0 && j == 0) continue;
396  if (y + j < image.size(0) && x + i < image.size(1)) {
397  if (image(y+j, x+i).first > image(y, x).first) return false;
398  if (image(y+j, x+i).first == image(y, x).first) {
399  if (image(y+j, x+i).second.size() > image(y, x).second.size()) return false;
400  if (image(y+j, x+i).second.size() == image(y, x).second.size() && j <= 0 && i <= 0) return false; // favor bottom-left (low phi, low neg q/pt)
401  }
402  }
403  }
404  }
405  }
406  return true;
407 }
408 
410 // Helpers
411 
412 
413 // Quantizes val, given a range [min, max) split into nSteps. Returns the bin below.
414 static inline int quant(double min, double max, unsigned nSteps, double val)
415 {
416  return static_cast<int>((val - min) / (max - min) * nSteps);
417 }
418 
419 // Returns the lower bound of the bin specified by step
420 static inline double unquant(double min, double max, unsigned nSteps, int step)
421 {
422  return min + (max - min) * step / nSteps;
423 }
424 
425 template <typename T>
426 static inline std::string to_string(const std::vector<T> &v)
427 {
428  std::ostringstream oss;
429  oss << "[";
430  if (!v.empty())
431  {
432  std::copy(v.begin(), v.end()-1, std::ostream_iterator<T>(oss, ", "));
433  oss << v.back();
434  }
435  oss << "]";
436  return oss.str();
437 }
438 
439 double FPGATrackSimHoughTransformTool::yToX(double y, const std::shared_ptr<const FPGATrackSimHit> &hit) const
440 {
441  double x = 0;
442 
444  {
445  double r = hit->getR(); // mm
446  double phi_hit = hit->getGPhi(); // radians
447  double d0 = std::isnan(m_parMin.d0) ? 0 : m_parMin.d0; // mm, assume min = max
448  x = asin(r * fpgatracksim::A * y - d0 / r) + phi_hit;
449 
450  if (m_fieldCorrection) x += fieldCorrection(m_EvtSel->getRegionID(), y, r);
451  }
452  else
453  {
454  ATH_MSG_ERROR("yToX() not defined for the current m_par selection");
455  }
456 
457  return x;
458 }
459 
460 
461 
462 std::vector<std::vector<int>> FPGATrackSimHoughTransformTool::lineGenLay(const std::shared_ptr<const FPGATrackSimHit> &hit) const
463 {
464  /*
465  Chosen strategy:
466  The Bologna Flexible HT firmware does mathematical operations to implement the HT and utilizes only integer with variable bits range at the necessary minimum to do so.
467  In the firmware some variables and flags are used to select 1)the scale factors the lead the float values to integer values and 2)the bits range of the internal variables.
468  Because to lead the firmware to behave exactly as a "regular" software would have required to many work and resources on the FPGA, it has been chosen to:
469  - make the firmware behave as a HT and adapt the software to the firmware to fully reproduce firmware performance;
470  - change the HT software to properly behave as the firmware in some operations (as the fact that the bits range is not infinite and so on);
471  Strategies to fill the accumulator:
472  - 1 input bin to 1 output bin;
473  - Assuming [Nx, Ny] binning accumulator is used, here the accumulator is separated into M "pipes," which each of them are[Nx/M, Ny] or [Nx, Ny/M]accumulator. In each pipe the line is drawn as described below:
474  - only part of the "line" coming from a hit is drawn using the HT formula, the rest is done "shifting and replacing" the drawn line to the rest of the pipe
475  - the lines drawn in the pipes start each one from a different point, following the monotonouse behavior of the line;
476  - this reduce the amount of multiplication in the firmware but is not "exactly" as it would be in software, that is why it ahs been decided to keep it;
477  - the accumulator in separated in "sectors" (not overlapped) alongside 1 axis. The first sector is filled with the line drawn with the HT formula, the others with the "shift and replace";
478  */
479 
480  std::vector<int64_t> bins_x_new;
481  std::vector<int64_t> bins_y_new;
482 
483  //Input values of the bins for the HT formula. The value is the center of the bin (in dev code the latter can be changed)
484  int64_t x_offset = m_phi0_min_bit + m_DBinPhi0_bit_int / 2;
485  int64_t y_offset = m_qApt_min_bit + m_DBinQApt_bit_int / 2;
486  for (unsigned i = 0; i < m_imageSize_x; i++) {
487  bins_x_new.push_back(x_offset + m_DBinPhi0_bit_int * i);
488  }
489  for (unsigned i = 0; i < m_imageSize_y; i++) {
490  bins_y_new.push_back(y_offset + m_DBinQApt_bit_int * i);
491  }
492 
493 
494  std::vector<int64_t> qApt_ht_array;
495  std::vector<int64_t> phi0_ht_array;
496  std::vector<int> zeros = {-1, -1};
497 
498  std::vector<std::vector<int>> hitLineQAPtPhi0;
499 
500  const unsigned bins_along_phi0_sector = m_phi0Bins_bit / m_phi0_sectors;
501  const unsigned bins_along_qApt_sector = m_qAptBins_bit / m_qApt_sectors;
502 
503  for (unsigned i = 0; i < bins_along_phi0_sector; i++) {
504  qApt_ht_array.push_back(0);
505  }
506  for (unsigned i = 0; i < bins_along_qApt_sector; i++) {
507  phi0_ht_array.push_back(0);
508  }
509 
510  int64_t phi_conv_offseted = 0;
511  int64_t Delta_qApt_after_first_sector = 0;
512  int64_t qApt_ht = -1;
513  int64_t phi0_ht = -1;
514  int64_t qApt_ht_pre = -1;
515  int64_t phi0_ht_pre = -1;
516  int64_t qApt_ht_sector = 0;
517  int64_t phi0_ht_sector = 0;
518  int64_t Delta_phi0_after_first_sector = 0;
519 
520  std::vector<double> d_qApt_ht_array;
521  std::vector<double> d_phi0_ht_array;
522 
523  for (unsigned i = 0; i < bins_along_phi0_sector; i++) {
524  d_qApt_ht_array.push_back(0.0);
525  }
526  for (unsigned i = 0; i < bins_along_qApt_sector; i++) {
527  d_phi0_ht_array.push_back(0.0);
528  }
529 
530  double d_phi_conv_offseted = 0.0;
531  double d_qApt_ht_sector = 0.0;
532  double d_phi0_ht_sector = 0.0;
533  double d_one_over_r_by_const = 0.0;
534  double d_phi_conv_over_DBinQApt = 0.0;
535  double d_Delta_phi0_after_first_sector = 0.0;
536 
538  double r = hit->getR();
539  double phi_hit = hit->getGPhi(); // radians
540  int r_bit = static_cast<int>(r * m_r_max / m_r_max_mm);
541  int64_t phi_bit = phi_hit * m_phi_coord_max / m_phi_range;
542  if (r_bit > m_HT_sel) { //Case for qA/Pt HT formula
543  for (unsigned i = 0; i < m_imageSize_x; i++) {
544  hitLineQAPtPhi0.push_back(zeros);
545  }
546  //formula first sector
547 
548  d_one_over_r_by_const = m_one_r_const_twoexp / r_bit;
549  d_phi_conv_over_DBinQApt = phi_bit * m_tot_bitwise_conv / m_DBinQApt_bit_int;
550 
551  for (int pp = 0; pp < m_pipes_phi0; pp++) {//loop over pipes pipes alongside phi0 axis
552  unsigned start_phi0_bins_first_sector = static_cast <unsigned>(pp * m_phi0Bins_bit / m_pipes_phi0);
553  unsigned end_phi0_bins_first_sector = m_phi0_bins_first_sector + static_cast <unsigned>(pp * m_phi0Bins_bit / m_pipes_phi0);
554 
555  for (unsigned j = start_phi0_bins_first_sector; j < end_phi0_bins_first_sector; j++) {
556  double d_c1 = m_bitwise_qApt_conv * bins_x_new[j] / m_DBinQApt_bit_int;
557  int64_t c2 = (static_cast<int64_t>(d_c1) - static_cast<int64_t>(d_phi_conv_over_DBinQApt)) * static_cast<int64_t>(d_one_over_r_by_const) / m_one_r_const_twoexp_post_conv;
558  int64_t c3 = (static_cast<int64_t>(d_c1) - static_cast<int64_t>(d_phi_conv_over_DBinQApt)) * static_cast<int64_t>(d_one_over_r_by_const);
559 
560  double d_c2 = (d_c1 - d_phi_conv_over_DBinQApt) * d_one_over_r_by_const / m_one_r_const_twoexp_post_conv;
561  double d_c3 = (d_c1 - d_phi_conv_over_DBinQApt) * d_one_over_r_by_const;
563 
564  if (static_cast<int64_t>(d_c1) <= static_cast<int64_t>(d_phi_conv_over_DBinQApt)) {
565  qApt_ht_pre = c2 - m_qApt_min_post_conv;
566  }else{
567  qApt_ht_pre = 1 + c2 - m_qApt_min_post_conv;
568  }
569  qApt_ht_sector = c3;
570  d_qApt_ht_sector = d_c3;
571  qApt_ht_array[j - start_phi0_bins_first_sector] = qApt_ht_sector;
572  d_qApt_ht_array[j - start_phi0_bins_first_sector] = d_qApt_ht_sector;
573 
574  if (static_cast<int64_t>(d_c1) <= static_cast<int64_t>(d_phi_conv_over_DBinQApt) && (d_c2 - m_qApt_min_post_conv - d_c4) >= 0) {
575  qApt_ht = qApt_ht_pre;
576  }
577  if (static_cast<int64_t>(d_c1) > static_cast<int64_t>(d_phi_conv_over_DBinQApt) && 1 + (d_c2 - m_qApt_min_post_conv - d_c4) >= 0) {
578  qApt_ht = qApt_ht_pre;
579  }
580 
581  if (qApt_ht >= 0 && qApt_ht <= m_imageSize_y -1) {
582  hitLineQAPtPhi0[j] = {static_cast<int>(qApt_ht), static_cast<int>(j)};
583  }
584  qApt_ht = -1;
585  }
586  if (m_phi0_sectors > 1) { //formula after first sector
587  for (int ps = 0; ps < m_phi0_sectors -1; ps++) {
588  //note: this is integer division, e.g. 3/2 = 1
590 
591  Delta_phi0_after_first_sector = d_c6 * static_cast<int64_t>(d_one_over_r_by_const);
592  //want a double here
593  d_Delta_phi0_after_first_sector = static_cast<double>(d_c6) * d_one_over_r_by_const;
594  for (unsigned psi = start_phi0_bins_first_sector; psi < end_phi0_bins_first_sector; psi++) {
595  int64_t c7 = (qApt_ht_array[psi - start_phi0_bins_first_sector] + Delta_phi0_after_first_sector) / m_one_r_const_twoexp_post_conv;
596 
598 
599  if (-qApt_ht_array[psi - start_phi0_bins_first_sector] < Delta_phi0_after_first_sector) {
600  qApt_ht = 1 + c7 - m_qApt_min_post_conv;
601  }else{
602  qApt_ht = 0 + c7 - m_qApt_min_post_conv;
603  }
604 
605  double d_c7 = (d_qApt_ht_array[psi - start_phi0_bins_first_sector] + d_Delta_phi0_after_first_sector) / m_one_r_const_twoexp_post_conv;
606 
607  if (qApt_ht >= 0 && qApt_ht <= m_imageSize_y -1 && (1 + d_c7 - d_c9) >= 0 && (0 + d_c7 - d_c9) >= 0 ) {
608 
609  hitLineQAPtPhi0[((ps + 1) * m_phi0_bins_first_sector) + psi] = {static_cast<int>(qApt_ht), static_cast<int>(((ps + 1) * m_phi0_bins_first_sector) + psi)};
610  }
611  qApt_ht = -1;
612  }
613  }
614  }
615  }
616  } else { //Case for Phi0 HT formula
617  for (unsigned i = 0; i < m_imageSize_y; i++) {
618  hitLineQAPtPhi0.push_back(zeros);
619  }
620  phi_conv_offseted = (m_bitwise_phi0_conv * phi_bit - static_cast<int64_t>(m_phi0_min_bit)) * m_bitwise_qApt_conv / m_DBinPhi0_bit_int;
621  d_phi_conv_offseted = (m_bitwise_phi0_conv * phi_bit - m_phi0_min_bit) * m_bitwise_qApt_conv / m_DBinPhi0_bit_int;
622 
623  for (int pq = 0; pq < m_pipes_qApt; pq++) { //loop over pipes alongside qA/Pt axis
624 
625  unsigned start_qApt_bins_first_sector = static_cast <unsigned>(pq * m_qAptBins_bit / m_pipes_qApt);
626  unsigned end_qApt_bins_first_sector = m_qApt_bins_first_sector + static_cast <unsigned>(pq * m_qAptBins_bit / m_pipes_qApt);
627 
628  for (unsigned n = start_qApt_bins_first_sector; n < end_qApt_bins_first_sector; n++) {
629  //formula for first sector
630  //note: this is integer division e.g. 3/2 = 1
631  int64_t d2 =m_bitwise_phi0_conv * bins_y_new[n] / m_DBinPhi0_bit_int;
632 
633  phi0_ht_sector = phi_conv_offseted + r_bit * d2;
634  phi0_ht_array[n - start_qApt_bins_first_sector] = phi0_ht_sector;
635  //want a double result here
636  d_phi0_ht_sector = d_phi_conv_offseted + r_bit * static_cast<double>(d2);
637  d_phi0_ht_array[n - start_qApt_bins_first_sector] = d_phi0_ht_sector;
638 
639  if (phi0_ht_sector >= 0) {
640  phi0_ht_pre = phi0_ht_sector / m_bitwise_qApt_conv;
641  } else {
642  phi0_ht_pre = -1 + phi0_ht_sector / m_bitwise_qApt_conv;
643  }
644 
645  if (phi0_ht_sector >= 0 && phi0_ht_pre >= 0 && (phi0_ht_sector >= m_bitwise_qApt_conv - m_imageSize_x)) {
646  phi0_ht = phi0_ht_pre;
647  }
648  if (phi0_ht_sector < 0 && phi0_ht_pre >= 0 && (-1 + phi0_ht_sector >= m_bitwise_qApt_conv - m_imageSize_x)) {
649  phi0_ht = phi0_ht_pre;
650  }
651 
652  if (phi0_ht <= m_imageSize_x - 1 && phi0_ht >= 0){
653  hitLineQAPtPhi0[n] = {static_cast<int>(n), static_cast<int>(phi0_ht)};
654  }
655  phi0_ht = -1;
656  }
657  if (m_qApt_sectors > 1) { //formula after first sector
658  for (int ts = 0; ts < m_qApt_sectors - 1; ts++) {
660  Delta_qApt_after_first_sector = r_bit * d3;
661  for (unsigned tsi = start_qApt_bins_first_sector; tsi < end_qApt_bins_first_sector; tsi++) {
662  phi0_ht = (phi0_ht_array[tsi - start_qApt_bins_first_sector] + Delta_qApt_after_first_sector) / m_bitwise_qApt_conv;
663  double d_phi0_ht = (d_phi0_ht_array[tsi - start_qApt_bins_first_sector] + Delta_qApt_after_first_sector) / m_bitwise_qApt_conv;
664 
665  if (phi0_ht <= m_imageSize_x - 1 && phi0_ht >= 0 && d_phi0_ht >= 0 && phi0_ht >= m_bitwise_qApt_conv - m_imageSize_x) {
666  hitLineQAPtPhi0[((ts + 1) * m_qApt_bins_first_sector) + tsi] = {static_cast<int>((ts + 1) * m_qApt_bins_first_sector + tsi), static_cast<int>(phi0_ht)};
667  }
668  phi0_ht = -1;
669  }
670  }
671  }
672  }
673  }
674  } else {
675  ATH_MSG_ERROR("lineGenLay() not defined for the current m_par selection");
676  }
677 
678  //return { HitLine, BinInPos };
679  return hitLineQAPtPhi0;
680 }
681 
682 // Find the min/max x bins of the hit's line, in each y bin. Max is exclusive.
683 // Note this assumes yToX is monotonic. Returns {0, 0} if hit lies out of bounds.
684 std::pair<unsigned, unsigned> FPGATrackSimHoughTransformTool::yToXBins(size_t yBin_min, size_t yBin_max, const std::shared_ptr<const FPGATrackSimHit> & hit) const
685 {
686  // Get float values
687  double x_min = yToX(m_bins_y[yBin_min], hit);
688  double x_max = yToX(m_bins_y[yBin_max], hit);
689  if (x_min > x_max) std::swap(x_min, x_max);
690  if (x_max < m_parMin[m_par_x] || x_min > m_parMax[m_par_x])
691  return { 0, 0 }; // out of bounds
692 
693  // Get bins
694  int x_bin_min = quant(m_parMin[m_par_x], m_parMax[m_par_x], m_imageSize_x, x_min);
695  int x_bin_max = quant(m_parMin[m_par_x], m_parMax[m_par_x], m_imageSize_x, x_max) + 1; // exclusive
696 
697  // Extend bins
698  unsigned extend = getExtension(yBin_min, hit->getLayer());
699  x_bin_min -= extend;
700  x_bin_max += extend;
701 
702  // Clamp bins
703  if (x_bin_min < 0) x_bin_min = 0;
704  if (x_bin_max > static_cast<int>(m_imageSize_x)) x_bin_max = m_imageSize_x;
705 
706  return { x_bin_min, x_bin_max };
707 }
708 
709 // We allow variable extension based on the size of m_hitExtend_x. See comments below.
710 unsigned FPGATrackSimHoughTransformTool::getExtension(unsigned y, unsigned layer) const
711 {
712  if (m_hitExtend_x.size() == m_nLayers) return m_hitExtend_x[layer];
713  if (m_hitExtend_x.size() == m_nLayers * 2)
714  {
715  // different extension for low pt vs high pt, split in half but irrespective of sign
716  // first nLayers entries of m_hitExtend_x is for low pt half, rest are for high pt half
717  if (y < m_imageSize_y / 4 || y > 3 * m_imageSize_y / 4) return m_hitExtend_x[layer];
718  return m_hitExtend_x[m_nLayers + layer];
719  }
720  return 0;
721 }
722 
723 // Creates a road from hits that pass through the given bin (x, y), and pushes it onto m_roads
724 void FPGATrackSimHoughTransformTool::addRoad(const std::vector<std::vector<std::shared_ptr<const FPGATrackSimHit>>> & hits, layer_bitmask_t hitLayers, unsigned x, unsigned y)
725 {
726  m_roads.emplace_back();
727  FPGATrackSimRoad & r = m_roads.back();
728 
729  r.setRoadID(m_roads.size() - 1);
730  r.setPID(y * m_imageSize_y + x);
731  r.setHits( std::vector<std::vector<std::shared_ptr<const FPGATrackSimHit>>>(hits)); //copy hits
732 
733  // We use the y coordinate in matchIdealGeoSectors
734  // and so it needs to be available before setting the sector.
735 
736  r.setSubRegion(m_subRegion);
737  r.setX(m_bins_x[x] + m_step_x/2);
738  r.setY(m_bins_y[y] + m_step_y/2);
739  r.setXBin(x);
740  r.setYBin(y);
741  r.setHitLayers(hitLayers);
742  r.setSubRegion(m_subRegion);
743 }
744 
745 
746 // Creates a road from hits that pass through the given bin (x, y), and pushes it onto m_roads
747 void FPGATrackSimHoughTransformTool::addRoad(const std::unordered_set<std::shared_ptr<const FPGATrackSimHit>> & hits, unsigned x, unsigned y)
748 {
749  layer_bitmask_t hitLayers = 0;
750  for (auto const & hit : hits)
751  hitLayers |= 1 << hit->getLayer();
752 
753  auto sorted_hits = ::sortByLayer(hits);
754  sorted_hits.resize(m_nLayers); // If no hits in last layer, return from sortByLayer will be too short
755 
756  addRoad(sorted_hits, hitLayers, x, y);
757 }
758 
759 // Use this version of addRoad when hit tracing is turned off
760 void FPGATrackSimHoughTransformTool::addRoad(const std::vector<std::shared_ptr<const FPGATrackSimHit>> & hits, unsigned x, unsigned y)
761 {
762  // Get the road hits
763  std::vector<std::shared_ptr<const FPGATrackSimHit>> road_hits;
764  layer_bitmask_t hitLayers = 0;
765  for (const auto & hit : hits)
766  {
767  // Find the min/max y bins (after scaling)
768  unsigned int y_bin_min = (y / m_binScale[hit->getLayer()]) * m_binScale[hit->getLayer()];
769  unsigned int y_bin_max = y_bin_min + m_binScale[hit->getLayer()];
770 
771  // Find the min/max x bins
772  auto xBins = yToXBins(y_bin_min, y_bin_max, hit);
773  if (x >= xBins.first && x < xBins.second)
774  {
775  road_hits.push_back(hit);
776  hitLayers |= 1 << hit->getLayer();
777  }
778  }
779 
780  auto sorted_hits = ::sortByLayer(road_hits);
781  sorted_hits.resize(m_nLayers); // If no hits in last layer, return from sortByLayer will be too short
782 
783  addRoad(sorted_hits, hitLayers, x, y);
784 }
785 
786 // A pre-calculated list of LUTs is installed. Each LUT represents the range of input phi value to fire one bin (x,y) on a given layer l.
787 void FPGATrackSimHoughTransformTool::makeLUT(std::vector<std::vector<std::vector<LUT>>> &v_LUT, std::vector<TH1D*> &v_h, const std::string& tag){
788  const std::string filepath = m_requirements.value() + "requirement-" + tag + ".root";
789  TFile* fin = TFile::Open(filepath.c_str());
790  ATH_MSG_INFO("open: " << tag);
791  m_bitlength = 14;//FIXME length needed to represent input phi. Should be define from requirement file
792  TTree* requirement = fin->Get<TTree>("requirement");
793  v_LUT.resize(5);
794  for(int i=0; i<5; i++){//FIXME as this target only for barrel so far, hardcoded
795  v_LUT.at(i).resize(64);
796  TH1D* h = (TH1D*)fin->Get(Form("in%d",i));//This is 1D hist to convert float phi to bitwise, depending on layer
797  v_h.push_back(h);
798  }
799  int nrequirement = requirement->GetEntries();
800  int in_min;
801  int in_max;
802  int xi;
803  int yi;
804  int ri;
805  requirement->SetBranchAddress("input_begin", &in_min);
806  requirement->SetBranchAddress("input_end", &in_max);
807  requirement->SetBranchAddress("output_x", &xi);
808  requirement->SetBranchAddress("output_y", &yi);
809  requirement->SetBranchAddress("output_l", &ri);
810  for(int i=0; i<nrequirement; i++){
811  requirement->GetEntry(i);
812  //process for min range
813  int MSB = (in_min >> (m_bitlength -6));
814  bool toBeFilled = true;
815  if(!v_LUT.at(ri).at(MSB).empty()){
816  for(auto& LUT_i : v_LUT.at(ri).at(MSB)){// For the sake of process speed and reproducibility of FPGA performance, LUTs are pushed to different vectors depending on their input MSB value.
817  if(LUT_i.input_begin == in_min && LUT_i.input_end == in_max){
818  LUT_i.output.push_back({xi, yi, ri});
819  toBeFilled = false;
820  break;
821  }
822  }
823  }
824  if(toBeFilled){
825  LUT LUT_i;
826  LUT_i.input_begin = in_min;
827  LUT_i.input_end = in_max;
828  LUT_i.layer = ri;
829  LUT_i.output.push_back({xi, yi, ri});
830  v_LUT.at(ri).at(MSB).push_back(LUT_i);
831  }
832  //process for max range
833  int MSB2 = (in_max >> (m_bitlength -6));
834  if(MSB != MSB2){
835  MSB = MSB2;
836  toBeFilled = true;
837  if(!v_LUT.at(ri).at(MSB).empty()){
838  for(auto& LUT_i : v_LUT.at(ri).at(MSB)){
839  if(LUT_i.input_begin == in_min && LUT_i.input_end == in_max){
840  LUT_i.output.push_back({xi, yi, ri});
841  toBeFilled = false;
842  break;
843  }
844  }
845  }
846  if(toBeFilled){
847  LUT LUT_i;
848  LUT_i.input_begin = in_min;
849  LUT_i.input_end = in_max;
850  LUT_i.layer = ri;
851  LUT_i.output.push_back({xi, yi, ri});
852  v_LUT.at(ri).at(MSB).push_back(LUT_i);
853  }
854  }
855  }
856  int LUTsize = v_LUT.size();
857  for(int layer = 0; layer < LUTsize; layer++){
858  for(int msb = 0; msb < 64; msb++){
859  ATH_MSG_DEBUG("LUT size L(" << layer << ") msb(" << msb << "): " << v_LUT.at(layer).at(msb).size());
860  }
861  }
862 }
FPGATrackSimHoughTransformTool::m_one_r_const_twoexp_post_conv
long int m_one_r_const_twoexp_post_conv
Definition: FPGATrackSimHoughTransformTool.h:227
WritePulseShapeToCool.zeros
zeros
Definition: WritePulseShapeToCool.py:66
FPGATrackSimHoughTransformTool::m_bins_y
std::vector< double > m_bins_y
Definition: FPGATrackSimHoughTransformTool.h:210
FPGATrackSimHoughTransformTool::m_tempMax_qOverPt
Gaudi::Property< float > m_tempMax_qOverPt
Definition: FPGATrackSimHoughTransformTool.h:163
FPGATrackSimHoughTransformTool::pos::x
int x
Definition: FPGATrackSimHoughTransformTool.h:126
FPGATrackSimHoughTransformTool::m_FPGATrackSimBankSvc
ServiceHandle< IFPGATrackSimBankSvc > m_FPGATrackSimBankSvc
Definition: FPGATrackSimHoughTransformTool.h:146
FPGATrackSimTrackPars::IHIP
@ IHIP
Definition: FPGATrackSimTrackPars.h:49
beamspotman.r
def r
Definition: beamspotman.py:674
FPGATrackSimHoughTransformTool::m_phi_range
Gaudi::Property< double > m_phi_range
Definition: FPGATrackSimHoughTransformTool.h:190
FPGATrackSimHoughTransformTool::LUT::output
std::vector< pos > output
Definition: FPGATrackSimHoughTransformTool.h:136
FPGATrackSimHoughTransformTool::m_phi0_min_bit
double m_phi0_min_bit
Definition: FPGATrackSimHoughTransformTool.h:218
FPGATrackSimHoughTransformTool::lineGenLay
std::vector< std::vector< int > > lineGenLay(const std::shared_ptr< const FPGATrackSimHit > &hit) const
Definition: FPGATrackSimHoughTransformTool.cxx:462
FPGATrackSimHoughTransformTool::m_qApt_sectors
Gaudi::Property< int > m_qApt_sectors
Definition: FPGATrackSimHoughTransformTool.h:195
ATH_MSG_FATAL
#define ATH_MSG_FATAL(x)
Definition: AthMsgStreamMacros.h:34
FPGATrackSimTrackPars::phi
double phi
Definition: FPGATrackSimTrackPars.h:24
FPGATrackSimHoughTransformTool::m_LUT
std::vector< std::vector< std::vector< LUT > > > m_LUT
Definition: FPGATrackSimHoughTransformTool.h:259
TRTCalib_Extractor.hits
hits
Definition: TRTCalib_Extractor.py:35
FPGATrackSimHoughTransformTool::LUT::input_begin
int input_begin
Definition: FPGATrackSimHoughTransformTool.h:133
FPGATrackSimHoughTransformTool::m_nLayers
unsigned m_nLayers
Definition: FPGATrackSimHoughTransformTool.h:204
FPGATrackSimHoughTransformTool::m_useSectors
Gaudi::Property< bool > m_useSectors
Definition: FPGATrackSimHoughTransformTool.h:178
FPGATrackSimHoughTransformTool::m_nCombineLayers
unsigned m_nCombineLayers
Definition: FPGATrackSimHoughTransformTool.h:205
ATH_MSG_INFO
#define ATH_MSG_INFO(x)
Definition: AthMsgStreamMacros.h:31
FPGATrackSimHoughTransformTool::m_fieldCorrection
Gaudi::Property< bool > m_fieldCorrection
Definition: FPGATrackSimHoughTransformTool.h:177
find
std::string find(const std::string &s)
return a remapped string
Definition: hcg.cxx:135
FPGATrackSimHoughTransformTool::addRoad
void addRoad(const std::vector< std::vector< std::shared_ptr< const FPGATrackSimHit >>> &hits, layer_bitmask_t hitLayers, unsigned x, unsigned y)
Definition: FPGATrackSimHoughTransformTool.cxx:724
FPGATrackSimHoughTransformTool::pos::y
int y
Definition: FPGATrackSimHoughTransformTool.h:127
FPGATrackSimHoughTransformTool::m_traceHits
Gaudi::Property< bool > m_traceHits
Definition: FPGATrackSimHoughTransformTool.h:175
FPGATrackSimPlaneMap.h
Maps physical layers to logical layers.
FPGATrackSimHoughTransformTool::m_pipes_qApt
Gaudi::Property< int > m_pipes_qApt
Definition: FPGATrackSimHoughTransformTool.h:196
FPGATrackSimTrackPars::qOverPt
double qOverPt
Definition: FPGATrackSimTrackPars.h:25
max
constexpr double max()
Definition: ap_fixedTest.cxx:33
FPGATrackSimHoughTransformTool::LUT::layer
int layer
Definition: FPGATrackSimHoughTransformTool.h:135
FPGATrackSimHoughTransformTool::m_qAptBins_bit
long int m_qAptBins_bit
Definition: FPGATrackSimHoughTransformTool.h:222
min
constexpr double min()
Definition: ap_fixedTest.cxx:26
FPGATrackSimHoughTransformTool::m_r_max
Gaudi::Property< int > m_r_max
Definition: FPGATrackSimHoughTransformTool.h:188
IFPGATrackSimMappingSvc.h
FPGATrackSimHoughTransformTool::m_binScale
Gaudi::Property< std::vector< unsigned > > m_binScale
Definition: FPGATrackSimHoughTransformTool.h:171
FPGATrackSimHoughTransformTool::m_parMin
FPGATrackSimTrackPars m_parMin
Definition: FPGATrackSimHoughTransformTool.h:153
FPGATrackSimHoughTransformTool::m_combineLayers
Gaudi::Property< std::vector< unsigned > > m_combineLayers
Definition: FPGATrackSimHoughTransformTool.h:170
FPGATrackSimHoughTransformTool.h
Implements road finding using a Hough transform.
FPGATrackSimHoughTransformTool::m_phi_coord_max
Gaudi::Property< int > m_phi_coord_max
Definition: FPGATrackSimHoughTransformTool.h:189
FPGATrackSimHoughTransformTool::m_idealGeoRoads
Gaudi::Property< bool > m_idealGeoRoads
Definition: FPGATrackSimHoughTransformTool.h:179
FPGATrackSimTrackPars::d0
double d0
Definition: FPGATrackSimTrackPars.h:26
FPGATrackSimHoughTransformTool::LUT
Definition: FPGATrackSimHoughTransformTool.h:132
module_driven_slicing.layers
layers
Definition: module_driven_slicing.py:113
python.SystemOfUnits.second
float second
Definition: SystemOfUnits.py:135
python.AthDsoLogger.out
out
Definition: AthDsoLogger.py:70
FPGATrackSimHoughTransformTool::m_tempMin_phi
Gaudi::Property< float > m_tempMin_phi
Definition: FPGATrackSimHoughTransformTool.h:160
FPGATrackSimHoughTransformTool::createImage
Image createImage(const std::vector< std::shared_ptr< const FPGATrackSimHit >> &hits) const
Definition: FPGATrackSimHoughTransformTool.cxx:342
FPGATrackSimHoughTransformTool::m_convSize_x
Gaudi::Property< unsigned > m_convSize_x
Definition: FPGATrackSimHoughTransformTool.h:172
FPGATrackSimHoughTransformTool::m_conv
Gaudi::Property< std::vector< int > > m_conv
Definition: FPGATrackSimHoughTransformTool.h:169
FPGATrackSimHoughTransformTool::m_imageSize_y
Gaudi::Property< unsigned > m_imageSize_y
Definition: FPGATrackSimHoughTransformTool.h:168
FPGATrackSimHoughTransformTool::m_qApt_bins_first_sector
long int m_qApt_bins_first_sector
Definition: FPGATrackSimHoughTransformTool.h:225
FPGATrackSimHit::getLayer
int getLayer() const
Definition: FPGATrackSimHit.cxx:87
yodamerge_tmp.scale
scale
Definition: yodamerge_tmp.py:138
x
#define x
FPGATrackSimHoughTransformTool::makeLUT
void makeLUT(std::vector< std::vector< std::vector< LUT >>> &v_LUT, std::vector< TH1D * > &v_h, const std::string &tag="")
Definition: FPGATrackSimHoughTransformTool.cxx:787
FPGATrackSimHoughTransformTool::m_par_y
FPGATrackSimTrackPars::pars_index m_par_y
Definition: FPGATrackSimHoughTransformTool.h:157
FPGATrackSimHoughTransformTool::m_bins_x
std::vector< double > m_bins_x
Definition: FPGATrackSimHoughTransformTool.h:209
FPGATrackSimConstants.h
FPGATrackSimHoughTransformTool::m_tempMax_phi
Gaudi::Property< float > m_tempMax_phi
Definition: FPGATrackSimHoughTransformTool.h:161
FPGATrackSimHit::getGPhi
float getGPhi() const
Definition: FPGATrackSimHit.h:153
FPGATrackSimHoughTransformTool::m_tempMax_d0
Gaudi::Property< float > m_tempMax_d0
Definition: FPGATrackSimHoughTransformTool.h:165
FPGATrackSimHoughTransformTool::m_qApt_min_bit
double m_qApt_min_bit
Definition: FPGATrackSimHoughTransformTool.h:219
FPGATrackSimHoughTransformTool::m_tempMin_qOverPt
Gaudi::Property< float > m_tempMin_qOverPt
Definition: FPGATrackSimHoughTransformTool.h:162
FPGATrackSimHoughTransformTool::m_par_x
FPGATrackSimTrackPars::pars_index m_par_x
Definition: FPGATrackSimHoughTransformTool.h:156
FPGATrackSimRegionMap.h
Maps ITK module indices to FPGATrackSim regions.
FPGATrackSimHoughTransformTool::m_localMaxWindowSize
Gaudi::Property< bool > m_localMaxWindowSize
Definition: FPGATrackSimHoughTransformTool.h:176
python.DataFormatRates.c3
c3
Definition: DataFormatRates.py:127
FPGATrackSimHoughTransformTool::m_phi0Bins_bit
long int m_phi0Bins_bit
Definition: FPGATrackSimHoughTransformTool.h:223
FPGATrackSimHoughTransformTool::m_step_y
double m_step_y
Definition: FPGATrackSimHoughTransformTool.h:208
vector2D< std::pair< int, std::unordered_set< std::shared_ptr< const FPGATrackSimHit > > > >
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
FPGATrackSimHoughTransformTool::m_bitwise_phi0_conv
Gaudi::Property< int > m_bitwise_phi0_conv
Definition: FPGATrackSimHoughTransformTool.h:193
FPGATrackSimHoughTransformTool::yToXBins
std::pair< unsigned, unsigned > yToXBins(size_t yBin_min, size_t yBin_max, const std::shared_ptr< const FPGATrackSimHit > &hit) const
Definition: FPGATrackSimHoughTransformTool.cxx:684
lumiFormat.i
int i
Definition: lumiFormat.py:85
python.SystemOfUnits.ps
float ps
Definition: SystemOfUnits.py:150
beamspotman.n
n
Definition: beamspotman.py:729
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
ATH_MSG_DEBUG
#define ATH_MSG_DEBUG(x)
Definition: AthMsgStreamMacros.h:29
TRT::Hit::layer
@ layer
Definition: HitInfo.h:79
FPGATrackSimHoughTransformTool::convolute
Image convolute(Image const &image) const
Definition: FPGATrackSimHoughTransformTool.cxx:360
TRT::Track::d0
@ d0
Definition: InnerDetector/InDetCalibEvent/TRT_CalibData/TRT_CalibData/TrackInfo.h:62
FPGATrackSimHoughTransformTool::LUT::input_end
int input_end
Definition: FPGATrackSimHoughTransformTool.h:134
FPGATrackSimHoughTransformTool::getExtension
unsigned getExtension(unsigned y, unsigned layer) const
Definition: FPGATrackSimHoughTransformTool.cxx:710
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
FPGATrackSimHoughTransformTool::m_convSize_y
Gaudi::Property< unsigned > m_convSize_y
Definition: FPGATrackSimHoughTransformTool.h:173
checkCorrelInHIST.nSteps
int nSteps
Definition: checkCorrelInHIST.py:458
FPGATrackSimHoughTransformTool::m_step_x
double m_step_x
Definition: FPGATrackSimHoughTransformTool.h:207
FPGATrackSimHoughTransformTool::pos
Definition: FPGATrackSimHoughTransformTool.h:125
WriteCalibToCool.swap
swap
Definition: WriteCalibToCool.py:94
FPGATrackSimHoughTransformTool::m_roads
std::vector< FPGATrackSimRoad > m_roads
Definition: FPGATrackSimHoughTransformTool.h:234
FPGATrackSimHoughTransformTool::m_tot_bitwise_conv
long int m_tot_bitwise_conv
Definition: FPGATrackSimHoughTransformTool.h:226
FPGATrackSimHoughTransformTool::m_subRegion
Gaudi::Property< int > m_subRegion
Definition: FPGATrackSimHoughTransformTool.h:159
FPGATrackSimHoughTransformTool::m_phi0_sectors
Gaudi::Property< int > m_phi0_sectors
Definition: FPGATrackSimHoughTransformTool.h:194
FPGATrackSimHoughTransformTool::initialize
virtual StatusCode initialize() override
Definition: FPGATrackSimHoughTransformTool.cxx:32
FPGATrackSimHoughTransformTool::m_DBinQApt_bit_int
long int m_DBinQApt_bit_int
Definition: FPGATrackSimHoughTransformTool.h:220
FPGATrackSimHoughTransformTool::m_h_rfix
std::vector< TH1D * > m_h_rfix
Definition: FPGATrackSimHoughTransformTool.h:260
ActsTrk::to_string
std::string to_string(const DetectorType &type)
Definition: GeometryDefs.h:34
FPGATrackSimHoughTransformTool::m_DBinPhi0_bit_int
long int m_DBinPhi0_bit_int
Definition: FPGATrackSimHoughTransformTool.h:221
FPGATrackSimHit.h
: FPGATrackSim-specific class to represent an hit in the detector.
FPGATrackSimHoughTransformTool::m_r_max_mm
Gaudi::Property< double > m_r_max_mm
Definition: FPGATrackSimHoughTransformTool.h:191
FPGATrackSimHoughTransformTool::m_imageSize_x
Gaudi::Property< unsigned > m_imageSize_x
Definition: FPGATrackSimHoughTransformTool.h:167
FPGATrackSimHoughTransformTool::m_qApt_min_post_conv
long int m_qApt_min_post_conv
Definition: FPGATrackSimHoughTransformTool.h:228
MyPlots.image
string image
Definition: MyPlots.py:42
FPGATrackSimHoughTransformTool::yToX
double yToX(double y, const std::shared_ptr< const FPGATrackSimHit > &hit) const
Definition: FPGATrackSimHoughTransformTool.cxx:439
FPGATrackSimTrackPars::IPHI
@ IPHI
Definition: FPGATrackSimTrackPars.h:49
python.PyAthena.v
v
Definition: PyAthena.py:154
FPGATrackSimHoughTransformTool::createLayerImage
Image createLayerImage(std::vector< unsigned > const &combine_layers, const std::vector< std::shared_ptr< const FPGATrackSimHit >> &hits, unsigned const scale) const
Definition: FPGATrackSimHoughTransformTool.cxx:249
FPGATrackSimHoughTransformTool::m_one_r_const_twoexp
long int m_one_r_const_twoexp
Definition: FPGATrackSimHoughTransformTool.h:217
python.DataFormatRates.c2
c2
Definition: DataFormatRates.py:123
FPGATrackSimHoughTransformTool::getRoads
virtual StatusCode getRoads(const std::vector< std::shared_ptr< const FPGATrackSimHit >> &hits, std::vector< std::shared_ptr< const FPGATrackSimRoad >> &roads) override
Definition: FPGATrackSimHoughTransformTool.cxx:155
FPGATrackSimHit::getR
float getR() const
Definition: FPGATrackSimHit.h:152
python.CaloAddPedShiftConfig.default
default
Definition: CaloAddPedShiftConfig.py:43
ActsTrk::detail::MakeDerivedVariant::extend
constexpr std::variant< Args..., T > extend(const std::variant< Args... > &, const T &)
Definition: MakeDerivedVariant.h:17
y
#define y
h
Base_Fragment.width
width
Definition: Sherpa_i/share/common/Base_Fragment.py:59
FPGATrackSimHoughTransformTool::passThreshold
bool passThreshold(Image const &image, unsigned x, unsigned y) const
Definition: FPGATrackSimHoughTransformTool.cxx:382
IFPGATrackSimEventSelectionSvc.h
ATH_MSG_WARNING
#define ATH_MSG_WARNING(x)
Definition: AthMsgStreamMacros.h:32
Pythia8_RapidityOrderMPI.val
val
Definition: Pythia8_RapidityOrderMPI.py:14
layer_bitmask_t
uint32_t layer_bitmask_t
Definition: FPGATrackSimTypes.h:22
FPGATrackSimHoughTransformTool::m_HT_sel
int m_HT_sel
Definition: FPGATrackSimHoughTransformTool.h:216
dq_defect_virtual_defect_validation.d2
d2
Definition: dq_defect_virtual_defect_validation.py:81
DeMoScan.first
bool first
Definition: DeMoScan.py:534
IFPGATrackSimBankSvc.h
FPGATrackSimHoughTransformTool::m_pipes_phi0
Gaudi::Property< int > m_pipes_phi0
Definition: FPGATrackSimHoughTransformTool.h:197
FPGATrackSimHoughTransformTool::m_requirements
Gaudi::Property< std::string > m_requirements
Definition: FPGATrackSimHoughTransformTool.h:185
FPGATrackSimHoughTransformTool::m_roadMerge
Gaudi::Property< bool > m_roadMerge
Definition: FPGATrackSimHoughTransformTool.h:184
FPGATrackSimHoughTransformTool::m_bitlength
int m_bitlength
Definition: FPGATrackSimHoughTransformTool.h:138
LArCellBinning.step
step
Definition: LArCellBinning.py:158
compute_lumi.fin
fin
Definition: compute_lumi.py:19
FPGATrackSimHoughTransformTool::m_hitExtend_x
Gaudi::Property< std::vector< unsigned > > m_hitExtend_x
Definition: FPGATrackSimHoughTransformTool.h:174
FPGATrackSimHoughTransformTool::m_bitwise_qApt_conv
Gaudi::Property< int > m_bitwise_qApt_conv
Definition: FPGATrackSimHoughTransformTool.h:192
fieldCorrection
double fieldCorrection(unsigned region, double qoverpt, double r)
Definition: FPGATrackSimFunctions.cxx:163
FPGATrackSimHoughTransformTool::m_FPGATrackSimMapping
ServiceHandle< IFPGATrackSimMappingSvc > m_FPGATrackSimMapping
Definition: FPGATrackSimHoughTransformTool.h:147
calibdata.copy
bool copy
Definition: calibdata.py:26
CaloCondBlobAlgs_fillNoiseFromASCII.tag
string tag
Definition: CaloCondBlobAlgs_fillNoiseFromASCII.py:23
FPGATrackSimHoughTransformTool::m_phi0_bins_first_sector
long int m_phi0_bins_first_sector
Definition: FPGATrackSimHoughTransformTool.h:224
python.CaloScaleNoiseConfig.ts
ts
Definition: CaloScaleNoiseConfig.py:87
FPGATrackSimHoughTransformTool::m_tempMin_d0
Gaudi::Property< float > m_tempMin_d0
Definition: FPGATrackSimHoughTransformTool.h:164
pow
constexpr int pow(int base, int exp) noexcept
Definition: ap_fixedTest.cxx:15
FPGATrackSimHoughTransformTool::m_parMax
FPGATrackSimTrackPars m_parMax
Definition: FPGATrackSimHoughTransformTool.h:154
FPGATrackSimHoughTransformTool::m_combineLayer2D
std::vector< std::vector< unsigned > > m_combineLayer2D
Definition: FPGATrackSimHoughTransformTool.h:199
FPGATrackSimTypes.h
python.compressB64.c
def c
Definition: compressB64.py:93
FPGATrackSimHoughTransformTool::m_EvtSel
ServiceHandle< IFPGATrackSimEventSelectionSvc > m_EvtSel
Definition: FPGATrackSimHoughTransformTool.h:145
FPGATrackSimSectorBank.h
This file declares a class that stores the module IDs of the sectors.
MakeTH3DFromTH2Ds.xBins
list xBins
Definition: MakeTH3DFromTH2Ds.py:76
FPGATrackSimHoughTransformTool::m_houghType
Gaudi::Property< std::string > m_houghType
Definition: FPGATrackSimHoughTransformTool.h:183
FPGATrackSimRoad
Definition: FPGATrackSimRoad.h:31
FPGATrackSimHoughTransformTool::m_threshold
Gaudi::Property< std::vector< int > > m_threshold
Definition: FPGATrackSimHoughTransformTool.h:166
sortByLayer
std::vector< std::vector< std::shared_ptr< const FPGATrackSimHit > > > sortByLayer(Container const &hits)
Definition: FPGATrackSimHit.h:315
FPGATrackSimHoughTransformTool::m_image
Image m_image
Definition: FPGATrackSimHoughTransformTool.h:233