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  if (LUT_layer <0){
284  ATH_MSG_ERROR("FPGATrackSimHoughTransformTool: array index is negative");
285  return image;
286  }
287  int phi_L_bin = m_h_rfix.at(LUT_layer)->FindBin(hit->getGPhi());
288  int MSB = (phi_L_bin >> (m_bitlength -6));
289  if(MSB >= 64) MSB = 63;//for barrel, MSB should be up to 63, but this line force it to not crash
290  for(const auto& LUT_i: m_LUT.at(LUT_layer).at(MSB)){//check LUTs only correspoinding MSB
291  if(LUT_i.input_begin <= phi_L_bin && phi_L_bin <= LUT_i.input_end){//If in the range, then fire it
292  for(const auto& pos: LUT_i.output){
293  image(pos.y -1, pos.x -1).first++;//NOTE : pos is 1 start
294  if (m_traceHits) image(pos.y -1, pos.x -1).second.insert(hit);
295  }
296  }
297  }
298  } else if (m_houghType == "Flexible") {
299  double r = hit->getR();
300  int r_bit = static_cast<int>(r * m_r_max / m_r_max_mm);
301  int input_bins_vector_size = 0;
302 
303  //Bologna Flexible HT uses qA/Pt=.... or Phi0=.... depending from the axis with more bins (qA/Pt axis #bin > Phi0 then Phi0=..... and viceversa)
304  if (r_bit > m_HT_sel) { //formula for qA/Pt HT
305  input_bins_vector_size = m_imageSize_x;
306  } else { //formula for Phi0 HT
307  input_bins_vector_size = m_imageSize_y;
308  }
309 
310  std::vector<std::vector<int>> hitLineQAPtPhi0(input_bins_vector_size);
311  hitLineQAPtPhi0 = lineGenLay(hit);
312 
313  for (const std::vector<int>& it_base : hitLineQAPtPhi0) {
314  if (it_base[0] != -1 && it_base[1] != -1) {
315  image(it_base[0] , it_base[1]).first++;
316  if (m_traceHits) {
317  image(it_base[0] , it_base[1]).second.insert(hit);
318  }
319  }
320  }
321  }else{
322  // This scans over y (pT) because that is more efficient in memory, in C.
323  // Unknown if firmware will want to scan over x instead.
324  unsigned new_size_y = m_imageSize_y / scale;
325  for (unsigned y_ = 0; y_ < new_size_y; y_++) {
326  unsigned y_bin_min = scale * y_;
327  unsigned y_bin_max = scale * (y_ + 1);
328 
329  // Find the min/max x bins
330  auto xBins = yToXBins(y_bin_min, y_bin_max, hit);
331 
332  // Update the image
333  for (unsigned y = y_bin_min; y < y_bin_max; y++){
334  for (unsigned x = xBins.first; x < xBins.second; x++) {
335  image(y, x).first++;
336  if (m_traceHits) image(y, x).second.insert(hit);
337  }
338  }
339  }
340  }
341  }
342 
343  return image;
344 }
345 
346 FPGATrackSimHoughTransformTool::Image FPGATrackSimHoughTransformTool::createImage(const std::vector<std::shared_ptr<const FPGATrackSimHit>> & hits) const
347 {
349 
350  for (unsigned i = 0; i < m_nCombineLayers; i++)
351  {
353  for (unsigned x = 0; x < m_imageSize_x; ++x)
354  for (unsigned y = 0; y < m_imageSize_y; ++y)
355  if (layerImage(y, x).first > 0)
356  {
357  image(y, x).first++;
358  image(y, x).second.insert(layerImage(y, x).second.begin(), layerImage(y, x).second.end());
359  }
360  }
361  return image;
362 }
363 
365 {
367 
368  for (unsigned y0 = 0; y0 < m_imageSize_y; y0++) // Loop over out
369  for (unsigned x0 = 0; x0 < m_imageSize_x; x0++)
370  for (unsigned r = 0; r < m_convSize_y; r++) // Loop over conv
371  for (unsigned c = 0; c < m_convSize_x; c++) {
372  int y = -static_cast<int>(m_convSize_y) / 2 + r + y0; // Indices of input
373  int x = -static_cast<int>(m_convSize_x) / 2 + c + x0; //
374 
375  if (y >= 0 && y < static_cast<int>(m_imageSize_y) && x >= 0 && x < static_cast<int>(m_imageSize_x)) {
376  int val = m_conv[r * m_convSize_x + c] * image(y, x).first;
377  if (val > 0) {
378  out(y0, x0).first += val;
379  out(y0, x0).second.insert(image(y, x).second.begin(), image(y, x).second.end());
380  }
381  }
382  }
383  return out;
384 }
385 
386 bool FPGATrackSimHoughTransformTool::passThreshold(Image const & image, unsigned x, unsigned y) const
387 {
388  // Pass window threshold
389  unsigned width = m_threshold.size() / 2;
390  if (x < width || (image.size(1) - x) < width) return false;
391  for (unsigned i = 0; i < m_threshold.size(); i++) {
392  if (image(y, x - width + i).first < m_threshold[i]) return false;
393  }
394 
395  // Pass local-maximum check
396  if (m_localMaxWindowSize) {
397  for (int j = -m_localMaxWindowSize; j <= m_localMaxWindowSize; j++) {
398  for (int i = -m_localMaxWindowSize; i <= m_localMaxWindowSize; i++) {
399  if (i == 0 && j == 0) continue;
400  if (y + j < image.size(0) && x + i < image.size(1)) {
401  if (image(y+j, x+i).first > image(y, x).first) return false;
402  if (image(y+j, x+i).first == image(y, x).first) {
403  if (image(y+j, x+i).second.size() > image(y, x).second.size()) return false;
404  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)
405  }
406  }
407  }
408  }
409  }
410  return true;
411 }
412 
414 // Helpers
415 
416 
417 // Quantizes val, given a range [min, max) split into nSteps. Returns the bin below.
418 static inline int quant(double min, double max, unsigned nSteps, double val)
419 {
420  return static_cast<int>((val - min) / (max - min) * nSteps);
421 }
422 
423 // Returns the lower bound of the bin specified by step
424 static inline double unquant(double min, double max, unsigned nSteps, int step)
425 {
426  return min + (max - min) * step / nSteps;
427 }
428 
429 template <typename T>
430 static inline std::string to_string(const std::vector<T> &v)
431 {
432  std::ostringstream oss;
433  oss << "[";
434  if (!v.empty())
435  {
436  std::copy(v.begin(), v.end()-1, std::ostream_iterator<T>(oss, ", "));
437  oss << v.back();
438  }
439  oss << "]";
440  return oss.str();
441 }
442 
443 double FPGATrackSimHoughTransformTool::yToX(double y, const std::shared_ptr<const FPGATrackSimHit> &hit) const
444 {
445  double x = 0;
446 
448  {
449  double r = hit->getR(); // mm
450  double phi_hit = hit->getGPhi(); // radians
451  double d0 = std::isnan(m_parMin.d0) ? 0 : m_parMin.d0; // mm, assume min = max
452  x = asin(r * fpgatracksim::A * y - d0 / r) + phi_hit;
453 
454  if (m_fieldCorrection) x += fieldCorrection(m_EvtSel->getRegionID(), y, r);
455  }
456  else
457  {
458  ATH_MSG_ERROR("yToX() not defined for the current m_par selection");
459  }
460 
461  return x;
462 }
463 
464 
465 
466 std::vector<std::vector<int>> FPGATrackSimHoughTransformTool::lineGenLay(const std::shared_ptr<const FPGATrackSimHit> &hit) const
467 {
468  /*
469  Chosen strategy:
470  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.
471  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.
472  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:
473  - make the firmware behave as a HT and adapt the software to the firmware to fully reproduce firmware performance;
474  - 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);
475  Strategies to fill the accumulator:
476  - 1 input bin to 1 output bin;
477  - 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:
478  - 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
479  - the lines drawn in the pipes start each one from a different point, following the monotonouse behavior of the line;
480  - 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;
481  - 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";
482  */
483 
484  std::vector<int64_t> bins_x_new;
485  std::vector<int64_t> bins_y_new;
486 
487  //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)
488  int64_t x_offset = m_phi0_min_bit + m_DBinPhi0_bit_int / 2;
489  int64_t y_offset = m_qApt_min_bit + m_DBinQApt_bit_int / 2;
490  for (unsigned i = 0; i < m_imageSize_x; i++) {
491  bins_x_new.push_back(x_offset + m_DBinPhi0_bit_int * i);
492  }
493  for (unsigned i = 0; i < m_imageSize_y; i++) {
494  bins_y_new.push_back(y_offset + m_DBinQApt_bit_int * i);
495  }
496 
497 
498  std::vector<int64_t> qApt_ht_array;
499  std::vector<int64_t> phi0_ht_array;
500  std::vector<int> zeros = {-1, -1};
501 
502  std::vector<std::vector<int>> hitLineQAPtPhi0;
503 
504  const unsigned bins_along_phi0_sector = m_phi0Bins_bit / m_phi0_sectors;
505  const unsigned bins_along_qApt_sector = m_qAptBins_bit / m_qApt_sectors;
506 
507  for (unsigned i = 0; i < bins_along_phi0_sector; i++) {
508  qApt_ht_array.push_back(0);
509  }
510  for (unsigned i = 0; i < bins_along_qApt_sector; i++) {
511  phi0_ht_array.push_back(0);
512  }
513 
514  int64_t phi_conv_offseted = 0;
515  int64_t Delta_qApt_after_first_sector = 0;
516  int64_t qApt_ht = -1;
517  int64_t phi0_ht = -1;
518  int64_t qApt_ht_pre = -1;
519  int64_t phi0_ht_pre = -1;
520  int64_t qApt_ht_sector = 0;
521  int64_t phi0_ht_sector = 0;
522  int64_t Delta_phi0_after_first_sector = 0;
523 
524  std::vector<double> d_qApt_ht_array;
525  std::vector<double> d_phi0_ht_array;
526 
527  for (unsigned i = 0; i < bins_along_phi0_sector; i++) {
528  d_qApt_ht_array.push_back(0.0);
529  }
530  for (unsigned i = 0; i < bins_along_qApt_sector; i++) {
531  d_phi0_ht_array.push_back(0.0);
532  }
533 
534  double d_phi_conv_offseted = 0.0;
535  double d_qApt_ht_sector = 0.0;
536  double d_phi0_ht_sector = 0.0;
537  double d_one_over_r_by_const = 0.0;
538  double d_phi_conv_over_DBinQApt = 0.0;
539  double d_Delta_phi0_after_first_sector = 0.0;
540 
542  double r = hit->getR();
543  double phi_hit = hit->getGPhi(); // radians
544  int r_bit = static_cast<int>(r * m_r_max / m_r_max_mm);
545  int64_t phi_bit = phi_hit * m_phi_coord_max / m_phi_range;
546  if (r_bit > m_HT_sel) { //Case for qA/Pt HT formula
547  for (unsigned i = 0; i < m_imageSize_x; i++) {
548  hitLineQAPtPhi0.push_back(zeros);
549  }
550  //formula first sector
551 
552  d_one_over_r_by_const = m_one_r_const_twoexp / r_bit;
553  d_phi_conv_over_DBinQApt = phi_bit * m_tot_bitwise_conv / m_DBinQApt_bit_int;
554 
555  for (int pp = 0; pp < m_pipes_phi0; pp++) {//loop over pipes pipes alongside phi0 axis
556  unsigned start_phi0_bins_first_sector = static_cast <unsigned>(pp * m_phi0Bins_bit / m_pipes_phi0);
557  unsigned end_phi0_bins_first_sector = m_phi0_bins_first_sector + static_cast <unsigned>(pp * m_phi0Bins_bit / m_pipes_phi0);
558 
559  for (unsigned j = start_phi0_bins_first_sector; j < end_phi0_bins_first_sector; j++) {
560  double d_c1 = m_bitwise_qApt_conv * bins_x_new[j] / m_DBinQApt_bit_int;
561  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;
562  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);
563 
564  double d_c2 = (d_c1 - d_phi_conv_over_DBinQApt) * d_one_over_r_by_const / m_one_r_const_twoexp_post_conv;
565  double d_c3 = (d_c1 - d_phi_conv_over_DBinQApt) * d_one_over_r_by_const;
567 
568  if (static_cast<int64_t>(d_c1) <= static_cast<int64_t>(d_phi_conv_over_DBinQApt)) {
569  qApt_ht_pre = c2 - m_qApt_min_post_conv;
570  }else{
571  qApt_ht_pre = 1 + c2 - m_qApt_min_post_conv;
572  }
573  qApt_ht_sector = c3;
574  d_qApt_ht_sector = d_c3;
575  qApt_ht_array[j - start_phi0_bins_first_sector] = qApt_ht_sector;
576  d_qApt_ht_array[j - start_phi0_bins_first_sector] = d_qApt_ht_sector;
577 
578  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) {
579  qApt_ht = qApt_ht_pre;
580  }
581  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) {
582  qApt_ht = qApt_ht_pre;
583  }
584 
585  if (qApt_ht >= 0 && qApt_ht <= m_imageSize_y -1) {
586  hitLineQAPtPhi0[j] = {static_cast<int>(qApt_ht), static_cast<int>(j)};
587  }
588  qApt_ht = -1;
589  }
590  if (m_phi0_sectors > 1) { //formula after first sector
591  for (int ps = 0; ps < m_phi0_sectors -1; ps++) {
592  //note: this is integer division, e.g. 3/2 = 1
594 
595  Delta_phi0_after_first_sector = d_c6 * static_cast<int64_t>(d_one_over_r_by_const);
596  //want a double here
597  d_Delta_phi0_after_first_sector = static_cast<double>(d_c6) * d_one_over_r_by_const;
598  for (unsigned psi = start_phi0_bins_first_sector; psi < end_phi0_bins_first_sector; psi++) {
599  int64_t c7 = (qApt_ht_array[psi - start_phi0_bins_first_sector] + Delta_phi0_after_first_sector) / m_one_r_const_twoexp_post_conv;
600 
602 
603  if (-qApt_ht_array[psi - start_phi0_bins_first_sector] < Delta_phi0_after_first_sector) {
604  qApt_ht = 1 + c7 - m_qApt_min_post_conv;
605  }else{
606  qApt_ht = 0 + c7 - m_qApt_min_post_conv;
607  }
608 
609  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;
610 
611  if (qApt_ht >= 0 && qApt_ht <= m_imageSize_y -1 && (1 + d_c7 - d_c9) >= 0 && (0 + d_c7 - d_c9) >= 0 ) {
612 
613  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)};
614  }
615  qApt_ht = -1;
616  }
617  }
618  }
619  }
620  } else { //Case for Phi0 HT formula
621  for (unsigned i = 0; i < m_imageSize_y; i++) {
622  hitLineQAPtPhi0.push_back(zeros);
623  }
624  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;
625  d_phi_conv_offseted = (m_bitwise_phi0_conv * phi_bit - m_phi0_min_bit) * m_bitwise_qApt_conv / m_DBinPhi0_bit_int;
626 
627  for (int pq = 0; pq < m_pipes_qApt; pq++) { //loop over pipes alongside qA/Pt axis
628 
629  unsigned start_qApt_bins_first_sector = static_cast <unsigned>(pq * m_qAptBins_bit / m_pipes_qApt);
630  unsigned end_qApt_bins_first_sector = m_qApt_bins_first_sector + static_cast <unsigned>(pq * m_qAptBins_bit / m_pipes_qApt);
631 
632  for (unsigned n = start_qApt_bins_first_sector; n < end_qApt_bins_first_sector; n++) {
633  //formula for first sector
634  //note: this is integer division e.g. 3/2 = 1
635  int64_t d2 =m_bitwise_phi0_conv * bins_y_new[n] / m_DBinPhi0_bit_int;
636 
637  phi0_ht_sector = phi_conv_offseted + r_bit * d2;
638  phi0_ht_array[n - start_qApt_bins_first_sector] = phi0_ht_sector;
639  //want a double result here
640  d_phi0_ht_sector = d_phi_conv_offseted + r_bit * static_cast<double>(d2);
641  d_phi0_ht_array[n - start_qApt_bins_first_sector] = d_phi0_ht_sector;
642 
643  if (phi0_ht_sector >= 0) {
644  phi0_ht_pre = phi0_ht_sector / m_bitwise_qApt_conv;
645  } else {
646  phi0_ht_pre = -1 + phi0_ht_sector / m_bitwise_qApt_conv;
647  }
648 
649  if (phi0_ht_sector >= 0 && phi0_ht_pre >= 0 && (phi0_ht_sector >= m_bitwise_qApt_conv - m_imageSize_x)) {
650  phi0_ht = phi0_ht_pre;
651  }
657  if (phi0_ht <= m_imageSize_x - 1 && phi0_ht >= 0){
658  hitLineQAPtPhi0[n] = {static_cast<int>(n), static_cast<int>(phi0_ht)};
659  }
660  phi0_ht = -1;
661  }
662  if (m_qApt_sectors > 1) { //formula after first sector
663  for (int ts = 0; ts < m_qApt_sectors - 1; ts++) {
665  Delta_qApt_after_first_sector = r_bit * d3;
666  for (unsigned tsi = start_qApt_bins_first_sector; tsi < end_qApt_bins_first_sector; tsi++) {
667  phi0_ht = (phi0_ht_array[tsi - start_qApt_bins_first_sector] + Delta_qApt_after_first_sector) / m_bitwise_qApt_conv;
668  double d_phi0_ht = (d_phi0_ht_array[tsi - start_qApt_bins_first_sector] + Delta_qApt_after_first_sector) / m_bitwise_qApt_conv;
669 
670  if (phi0_ht <= m_imageSize_x - 1 && phi0_ht >= 0 && d_phi0_ht >= 0 && phi0_ht >= m_bitwise_qApt_conv - m_imageSize_x) {
671  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)};
672  }
673  phi0_ht = -1;
674  }
675  }
676  }
677  }
678  }
679  } else {
680  ATH_MSG_ERROR("lineGenLay() not defined for the current m_par selection");
681  }
682 
683  //return { HitLine, BinInPos };
684  return hitLineQAPtPhi0;
685 }
686 
687 // Find the min/max x bins of the hit's line, in each y bin. Max is exclusive.
688 // Note this assumes yToX is monotonic. Returns {0, 0} if hit lies out of bounds.
689 std::pair<unsigned, unsigned> FPGATrackSimHoughTransformTool::yToXBins(size_t yBin_min, size_t yBin_max, const std::shared_ptr<const FPGATrackSimHit> & hit) const
690 {
691  // Get float values
692  double x_min = yToX(m_bins_y[yBin_min], hit);
693  double x_max = yToX(m_bins_y[yBin_max], hit);
694  if (x_min > x_max) std::swap(x_min, x_max);
695  if (x_max < m_parMin[m_par_x] || x_min > m_parMax[m_par_x])
696  return { 0, 0 }; // out of bounds
697 
698  // Get bins
699  int x_bin_min = quant(m_parMin[m_par_x], m_parMax[m_par_x], m_imageSize_x, x_min);
700  int x_bin_max = quant(m_parMin[m_par_x], m_parMax[m_par_x], m_imageSize_x, x_max) + 1; // exclusive
701 
702  // Extend bins
703  unsigned extend = getExtension(yBin_min, hit->getLayer());
704  x_bin_min -= extend;
705  x_bin_max += extend;
706 
707  // Clamp bins
708  if (x_bin_min < 0) x_bin_min = 0;
709  if (x_bin_max > static_cast<int>(m_imageSize_x)) x_bin_max = m_imageSize_x;
710 
711  return { x_bin_min, x_bin_max };
712 }
713 
714 // We allow variable extension based on the size of m_hitExtend_x. See comments below.
715 unsigned FPGATrackSimHoughTransformTool::getExtension(unsigned y, unsigned layer) const
716 {
717  if (m_hitExtend_x.size() == m_nLayers) return m_hitExtend_x[layer];
718  if (m_hitExtend_x.size() == m_nLayers * 2)
719  {
720  // different extension for low pt vs high pt, split in half but irrespective of sign
721  // first nLayers entries of m_hitExtend_x is for low pt half, rest are for high pt half
722  if (y < m_imageSize_y / 4 || y > 3 * m_imageSize_y / 4) return m_hitExtend_x[layer];
723  return m_hitExtend_x[m_nLayers + layer];
724  }
725  return 0;
726 }
727 
728 // Creates a road from hits that pass through the given bin (x, y), and pushes it onto m_roads
729 void FPGATrackSimHoughTransformTool::addRoad(const std::vector<std::vector<std::shared_ptr<const FPGATrackSimHit>>> & hits, layer_bitmask_t hitLayers, unsigned x, unsigned y)
730 {
731  m_roads.emplace_back();
732  FPGATrackSimRoad & r = m_roads.back();
733 
734  r.setRoadID(m_roads.size() - 1);
735  r.setPID(y * m_imageSize_y + x);
736  r.setHits( std::vector<std::vector<std::shared_ptr<const FPGATrackSimHit>>>(hits)); //copy hits
737 
738  // We use the y coordinate in matchIdealGeoSectors
739  // and so it needs to be available before setting the sector.
740 
741  r.setSubRegion(m_subRegion);
742  r.setX(m_bins_x[x] + m_step_x/2);
743  r.setY(m_bins_y[y] + m_step_y/2);
744  r.setXBin(x);
745  r.setYBin(y);
746  r.setHitLayers(hitLayers);
747  r.setSubRegion(m_subRegion);
748 }
749 
750 
751 // Creates a road from hits that pass through the given bin (x, y), and pushes it onto m_roads
752 void FPGATrackSimHoughTransformTool::addRoad(const std::unordered_set<std::shared_ptr<const FPGATrackSimHit>> & hits, unsigned x, unsigned y)
753 {
754  layer_bitmask_t hitLayers = 0;
755  for (auto const & hit : hits)
756  hitLayers |= 1 << hit->getLayer();
757 
758  auto sorted_hits = ::sortByLayer(hits);
759  sorted_hits.resize(m_nLayers); // If no hits in last layer, return from sortByLayer will be too short
760 
761  addRoad(sorted_hits, hitLayers, x, y);
762 }
763 
764 // Use this version of addRoad when hit tracing is turned off
765 void FPGATrackSimHoughTransformTool::addRoad(const std::vector<std::shared_ptr<const FPGATrackSimHit>> & hits, unsigned x, unsigned y)
766 {
767  // Get the road hits
768  std::vector<std::shared_ptr<const FPGATrackSimHit>> road_hits;
769  layer_bitmask_t hitLayers = 0;
770  for (const auto & hit : hits)
771  {
772  // Find the min/max y bins (after scaling)
773  unsigned int y_bin_min = (y / m_binScale[hit->getLayer()]) * m_binScale[hit->getLayer()];
774  unsigned int y_bin_max = y_bin_min + m_binScale[hit->getLayer()];
775 
776  // Find the min/max x bins
777  auto xBins = yToXBins(y_bin_min, y_bin_max, hit);
778  if (x >= xBins.first && x < xBins.second)
779  {
780  road_hits.push_back(hit);
781  hitLayers |= 1 << hit->getLayer();
782  }
783  }
784 
785  auto sorted_hits = ::sortByLayer(road_hits);
786  sorted_hits.resize(m_nLayers); // If no hits in last layer, return from sortByLayer will be too short
787 
788  addRoad(sorted_hits, hitLayers, x, y);
789 }
790 
791 // 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.
792 void FPGATrackSimHoughTransformTool::makeLUT(std::vector<std::vector<std::vector<LUT>>> &v_LUT, std::vector<TH1D*> &v_h, const std::string& tag){
793  const std::string filepath = m_requirements.value() + "requirement-" + tag + ".root";
794  TFile* fin = TFile::Open(filepath.c_str());
795  ATH_MSG_INFO("open: " << tag);
796  m_bitlength = 14;//FIXME length needed to represent input phi. Should be define from requirement file
797  TTree* requirement = fin->Get<TTree>("requirement");
798  v_LUT.resize(5);
799  for(int i=0; i<5; i++){//FIXME as this target only for barrel so far, hardcoded
800  v_LUT.at(i).resize(64);
801  TH1D* h = (TH1D*)fin->Get(Form("in%d",i));//This is 1D hist to convert float phi to bitwise, depending on layer
802  v_h.push_back(h);
803  }
804  int nrequirement = requirement->GetEntries();
805  int in_min;
806  int in_max;
807  int xi;
808  int yi;
809  int ri;
810  requirement->SetBranchAddress("input_begin", &in_min);
811  requirement->SetBranchAddress("input_end", &in_max);
812  requirement->SetBranchAddress("output_x", &xi);
813  requirement->SetBranchAddress("output_y", &yi);
814  requirement->SetBranchAddress("output_l", &ri);
815  for(int i=0; i<nrequirement; i++){
816  requirement->GetEntry(i);
817  //process for min range
818  int MSB = (in_min >> (m_bitlength -6));
819  bool toBeFilled = true;
820  if(!v_LUT.at(ri).at(MSB).empty()){
821  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.
822  if(LUT_i.input_begin == in_min && LUT_i.input_end == in_max){
823  LUT_i.output.push_back({xi, yi, ri});
824  toBeFilled = false;
825  break;
826  }
827  }
828  }
829  if(toBeFilled){
830  LUT LUT_i;
831  LUT_i.input_begin = in_min;
832  LUT_i.input_end = in_max;
833  LUT_i.layer = ri;
834  LUT_i.output.push_back({xi, yi, ri});
835  v_LUT.at(ri).at(MSB).push_back(std::move(LUT_i));
836  }
837  //process for max range
838  int MSB2 = (in_max >> (m_bitlength -6));
839  if(MSB != MSB2){
840  MSB = MSB2;
841  toBeFilled = true;
842  if(!v_LUT.at(ri).at(MSB).empty()){
843  for(auto& LUT_i : v_LUT.at(ri).at(MSB)){
844  if(LUT_i.input_begin == in_min && LUT_i.input_end == in_max){
845  LUT_i.output.push_back({xi, yi, ri});
846  toBeFilled = false;
847  break;
848  }
849  }
850  }
851  if(toBeFilled){
852  LUT LUT_i;
853  LUT_i.input_begin = in_min;
854  LUT_i.input_end = in_max;
855  LUT_i.layer = ri;
856  LUT_i.output.push_back({xi, yi, ri});
857  v_LUT.at(ri).at(MSB).push_back(LUT_i);
858  }
859  }
860  }
861  int LUTsize = v_LUT.size();
862  for(int layer = 0; layer < LUTsize; layer++){
863  for(int msb = 0; msb < 64; msb++){
864  ATH_MSG_DEBUG("LUT size L(" << layer << ") msb(" << msb << "): " << v_LUT.at(layer).at(msb).size());
865  }
866  }
867 }
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:672
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:466
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:729
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:346
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:792
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:689
lumiFormat.i
int i
Definition: lumiFormat.py:85
python.SystemOfUnits.ps
float ps
Definition: SystemOfUnits.py:150
beamspotman.n
n
Definition: beamspotman.py:727
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:364
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:715
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:40
FPGATrackSimHoughTransformTool::yToX
double yToX(double y, const std::shared_ptr< const FPGATrackSimHit > &hit) const
Definition: FPGATrackSimHoughTransformTool.cxx:443
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:386
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