Belle II Software  release-08-01-10
FastInterceptFinder2DFPGA.cc
1 /**************************************************************************
2  * basf2 (Belle II Analysis Software Framework) *
3  * Author: The Belle II Collaboration *
4  * *
5  * See git log for contributors and copyright holders. *
6  * This file is licensed under LGPL-3.0, see LICENSE.md. *
7  **************************************************************************/
8 #include <tracking/datcon/findlets/FastInterceptFinder2DFPGA.h>
9 #include <tracking/trackFindingCDC/utilities/StringManipulation.h>
10 #include <vxd/dataobjects/VxdID.h>
11 #include <framework/core/ModuleParamList.h>
12 #include <framework/core/ModuleParamList.templateDetails.h>
13 
14 using namespace Belle2;
15 using namespace TrackFindingCDC;
16 
18 {
19 }
20 
21 void FastInterceptFinder2DFPGA::exposeParameters(ModuleParamList* moduleParamList, const std::string& prefix)
22 {
23  Super::exposeParameters(moduleParamList, prefix);
24 
25  moduleParamList->addParameter(TrackFindingCDC::prefixed(prefix, "isUFinder"), m_param_isUFinder,
26  "Intercept finder for u-side or v-side?", m_param_isUFinder);
27 
28  moduleParamList->addParameter(TrackFindingCDC::prefixed(prefix, "writeGnuplotOutput"), m_param_writeGnuplotOutput,
29  "Write gnuplot debugging output to file?", m_param_writeGnuplotOutput);
30 
31  moduleParamList->addParameter(TrackFindingCDC::prefixed(prefix, "gnuplotHSOutputFileName"), m_param_gnuplotHSOutputFileName,
32  "Name of the gnuplot debug file.", m_param_gnuplotHSOutputFileName);
33 
34  moduleParamList->addParameter(TrackFindingCDC::prefixed(prefix, "gnuplotHSRectOutputFileName"), m_param_gnuplotHSRectOutputFileName,
35  "Name of the gnuplot debug HS sectors file.", m_param_gnuplotHSRectOutputFileName);
36 
37  moduleParamList->addParameter(TrackFindingCDC::prefixed(prefix, "gnuplotHSCoGOutputFileName"), m_param_gnuplotHSCoGOutputFileName,
38  "Name of the gnuplot debug cluster CoG file.", m_param_gnuplotHSCoGOutputFileName);
39 
40  moduleParamList->addParameter(TrackFindingCDC::prefixed(prefix, "maximumRecursionLevel"), m_param_maxRecursionLevel,
41  "Maximum recursion level for the fast Hough trafo algorithm.", m_param_maxRecursionLevel);
42 
43  moduleParamList->addParameter(TrackFindingCDC::prefixed(prefix, "nAngleSectors"), m_param_nAngleSectors,
44  "Number of angle sectors (= x-axis) dividing the Hough space.", m_param_nAngleSectors);
45 
46  moduleParamList->addParameter(TrackFindingCDC::prefixed(prefix, "nVerticalSectors"), m_param_nVerticalSectors,
47  "Number of vertical sectors (= y-axis) dividing the Hough space.", m_param_nVerticalSectors);
48 
49  moduleParamList->addParameter(TrackFindingCDC::prefixed(prefix, "verticalHoughSpaceSize"), m_param_verticalHoughSpaceSize,
50  "Vertical size of the Hough space. Data type: long", m_param_verticalHoughSpaceSize);
51 
52  moduleParamList->addParameter(TrackFindingCDC::prefixed(prefix, "minimumX"), m_param_minimumX,
53  "Minimum x value of the Hough space.", m_param_minimumX);
54 
55  moduleParamList->addParameter(TrackFindingCDC::prefixed(prefix, "maximumX"), m_param_maximumX,
56  "Maximum x value of the Hough space.", m_param_maximumX);
57 
58  moduleParamList->addParameter(TrackFindingCDC::prefixed(prefix, "minimumHSClusterSize"), m_param_MinimumHSClusterSize,
59  "Minimum size of the Hough Space clusters.", m_param_MinimumHSClusterSize);
60 
61  moduleParamList->addParameter(TrackFindingCDC::prefixed(prefix, "maximumHSClusterSize"), m_param_MaximumHSClusterSize,
62  "Maximum size of the Hough Space clusters.", m_param_MaximumHSClusterSize);
63 
64  moduleParamList->addParameter(TrackFindingCDC::prefixed(prefix, "maximumHSClusterSizeX"), m_param_MaximumHSClusterSizeX,
65  "Maximum size of the Hough Space clusters in horizontal direction.", m_param_MaximumHSClusterSizeX);
66 
67  moduleParamList->addParameter(TrackFindingCDC::prefixed(prefix, "maximumHSClusterSizeY"), m_param_MaximumHSClusterSizeY,
68  "Maximum size of the Hough Space clusters in vertical direction.", m_param_MaximumHSClusterSizeY);
69 
70 }
71 
73 {
75 
77  B2ASSERT("The maximum number of currentRecursion in u must not be larger than 14, but it is " << m_param_maxRecursionLevel,
80  // If Hough trafo for theta, divide Hough space not linear in theta, but linear in tan(theta).
81  // This leads to smaller HS sectors in the forward and backward regions, but an even distributions of extrapolated PXD hits.
82  if (not m_param_isUFinder) {
84  }
85  for (uint i = 0; i < m_param_nAngleSectors; i++) {
86  double x = m_param_minimumX + m_unitX * (double)i;
87  double xc = x + 0.5 * m_unitX;
88  if (not m_param_isUFinder) {
89  x = atan(tan(m_param_minimumX) + m_unitX * i);
90  xc = atan(tan(m_param_minimumX) + m_unitX * ((double)i + 0.5));
91  }
92 
93  m_HSXLUT[i] = x;
94  m_HSSinValuesLUT[i] = convertFloatToInt(sin(x), 3);
95  m_HSCosValuesLUT[i] = convertFloatToInt(cos(x), 3);
98  m_HSXCenterLUT[i] = xc;
99  }
103 
105  for (uint i = 0; i <= m_param_nVerticalSectors; i++) {
108  }
109  B2DEBUG(29, "HS size x: " << (m_param_maximumX - m_param_minimumX) << " HS size y: " << m_param_verticalHoughSpaceSize <<
110  " unitX: " << m_unitX << " unitY: " << m_unitY);
111 }
112 
113 void FastInterceptFinder2DFPGA::apply(const std::vector<std::pair<VxdID, std::pair<long, long>>>& hits,
114  std::vector<std::pair<double, double>>& tracks)
115 {
117  m_activeSectorArray.clear();
118  m_activeSectorArray.reserve(4096);
119  m_trackCandidates.clear();
120 
122  m_rectcounter = 1;
123  m_rectoutstream.open(m_param_gnuplotHSRectOutputFileName.c_str(), std::ios::trunc);
124  m_cogoutstream.open(m_param_gnuplotHSCoGOutputFileName.c_str(), std::ios::trunc);
125  gnuplotoutput(hits);
126  }
127 
129 
131 
132  for (auto& trackCand : m_trackCandidates) {
133  tracks.emplace_back(trackCand);
134  }
135 
136  B2DEBUG(29, "m_activeSectorArray.size: " << m_activeSectorArray.size() << " m_trackCandidates.size: " << m_trackCandidates.size());
137 
139  m_rectoutstream.close();
140  m_cogoutstream.close();
141  }
142 
143 }
144 
145 void FastInterceptFinder2DFPGA::fastInterceptFinder2d(const std::vector<std::pair<VxdID, std::pair<long, long>>>& hits,
146  uint xmin, uint xmax, uint ymin, uint ymax, uint currentRecursion)
147 {
148  std::vector<std::pair<VxdID, std::pair<long, long>>> containedHits;
149 
150  if (currentRecursion == m_param_maxRecursionLevel + 1) return;
151 
152  // these int-divisions can cause {min, center} or {center, max} to be the same, which is a desired behaviour
153  const uint centerx = xmin + (uint)((xmax - xmin) / 2);
154  const uint centery = ymin + (uint)((ymax - ymin) / 2);
155  const uint xIndexCache[3] = {xmin, centerx, xmax};
156  const uint yIndexCache[3] = {ymin, centery, ymax};
157 
158  for (int i = 0; i < 2 ; ++i) {
159  const uint left = xIndexCache[i];
160  const uint right = xIndexCache[i + 1];
161  const uint localIndexX = left;
162 
163  if (left == right) continue;
164 
165  const double& localLeft = m_HSXLUT[left];
166  const double& localRight = m_HSXLUT[right];
167  const short& sinLeft = m_HSSinValuesLUT[left];
168  const short& cosLeft = m_HSCosValuesLUT[left];
169  const short& sinRight = m_HSSinValuesLUT[right];
170  const short& cosRight = m_HSCosValuesLUT[right];
171 
172  // the sin and cos of the current center can't be stored in a LUT, as the number of possible centers
173  // is quite large and the logic would become rather complex
174  const short& sinCenter = m_HSCenterSinValuesLUT[(left + right) / 2];
175  const short& cosCenter = m_HSCenterCosValuesLUT[(left + right) / 2];
176 
177  for (int j = 0; j < 2; ++j) {
178 
179  const uint lowerIndex = yIndexCache[j];
180  const uint upperIndex = yIndexCache[j + 1];
181 
182  const uint localIndexY = lowerIndex;
183  const long& localUpperCoordinate = m_HSYLUT[lowerIndex];
184  const long& localLowerCoordinate = m_HSYLUT[upperIndex];
185 
186  if (lowerIndex == upperIndex) continue;
187 
188  std::vector<bool> layerHits(7); /* For layer filter */
189  containedHits.clear();
190  for (auto& hit : hits) {
191  const VxdID& sensor = hit.first;
192 
193  const long& m = hit.second.first;
194  const long& a = hit.second.second;
195 
196  long yLeft = m * cosLeft + a * sinLeft;
197  long yRight = m * cosRight + a * sinRight;
198  long yCenter = m * cosCenter + a * sinCenter;
199  long derivativeyLeft = m * -sinLeft + a * cosLeft;
200  long derivativeyRight = m * -sinRight + a * cosRight;
201  long derivativeyCenter = m * -sinCenter + a * cosCenter;
202 
203  // Only interested in the rising arm of the sinosoidal curves.
204  // Thus if derivative on both sides of the cell is negative, ignore and continue.
205  if (derivativeyLeft < 0 and derivativeyRight < 0 and derivativeyCenter < 0) continue;
206 
207  /* Check if HS-parameter curve is inside (or outside) actual sub-HS */
208  if ((yLeft <= localUpperCoordinate and yRight >= localLowerCoordinate) or
209  (yCenter <= localUpperCoordinate and yLeft >= localLowerCoordinate and yRight >= localLowerCoordinate) or
210  (yCenter >= localLowerCoordinate and yLeft <= localUpperCoordinate and yRight <= localUpperCoordinate)) {
211  layerHits[sensor.getLayerNumber()] = true; /* layer filter */
212  containedHits.emplace_back(hit);
213  }
214  }
215 
216  if (layerFilter(layerHits) > 0) {
217  // recursive call of fastInterceptFinder2d, until currentRecursion == m_maxRecursionLevel
218  if (currentRecursion < m_param_maxRecursionLevel) {
219 
221  m_rectoutstream << "set object " << m_rectcounter << " rect from " << localLeft << ", " << localLowerCoordinate <<
222  " to " << localRight << ", " << localUpperCoordinate << " fc rgb \"" <<
223  m_const_rectColor[currentRecursion % 8] << "\" fs solid 0.5 behind" << std::endl;
224  m_rectcounter++;
225  }
226 
227  fastInterceptFinder2d(containedHits, left, right, lowerIndex, upperIndex, currentRecursion + 1);
228 
229  } else {
230  m_SectorArray[localIndexY * m_param_nAngleSectors + localIndexX] = -layerFilter(layerHits);
231  m_activeSectorArray.push_back(std::make_pair(localIndexX, localIndexY));
232 
234  m_rectoutstream << "set object " << m_rectcounter << " rect from " << localLeft << ", " << localLowerCoordinate <<
235  " to " << localRight << ", " << localUpperCoordinate << " fc rgb \"" <<
236  m_const_rectColor[currentRecursion % 8] << "\" fs solid 0.5 behind" << std::endl;
237  m_rectcounter++;
238  }
239 
240  }
241  }
242  }
243  }
244 }
245 
247 {
248  // cell content meanings:
249  // -3, -4 : active sector, not yet visited
250  // 0 : non-active sector (will never be visited, only checked)
251  // 1,2,3...: index of the clusters
252 
253  m_clusterCount = 1;
254 
255  // this sorting makes sure the clusters can be searched from bottom left of the HS to top right
256  // normally, a C++ array looks like a matrix:
257  // (0 , 0) ... (maxX, 0 )
258  // ... ...
259  // (0, maxY) ... (maxX, maxY)
260  // but for sorting we want it to be like regular coordinates
261  // (0, maxY) ... (maxX, maxY)
262  // ... ...
263  // (0, 0 ) ... (maxX, 0 )
264  // By setting the offset to the maximum allowed number of cells (2^14) and simplifying
265  // (16384 - a.second) * 16384 + a.first < (16384 - b.second) * 16384 + b.first
266  // we get the formula below
267  auto sortSectors = [](const std::pair<uint, uint> a, const std::pair<uint, uint> b) {
268  return ((int)b.second - (int)a.second) * 16384 < (int)b.first - (int)a.first;
269  };
270  std::sort(m_activeSectorArray.begin(), m_activeSectorArray.end(), sortSectors);
271 
272  for (const auto& currentCell : m_activeSectorArray) {
273  const uint currentIndex = currentCell.second * m_param_nAngleSectors + currentCell.first;
274  if (m_SectorArray[currentIndex] > -1) continue;
275 
276  m_clusterInitialPosition = currentCell;
277  m_clusterCoG = currentCell;
278  m_clusterSize = 1;
279  m_SectorArray[currentIndex] = m_clusterCount;
280  // Check for HS sectors connected to each other which could form a cluster
281  DepthFirstSearch(currentCell.first, currentCell.second);
282  // if cluster valid (i.e. not too small and not too big): finalize!
284  double CoGX = (((double)m_clusterCoG.first / (double)m_clusterSize) + 0.5) * m_unitX + m_param_minimumX;
285  if (not m_param_isUFinder) {
286  CoGX = atan(tan(m_param_minimumX) + m_unitX * (((double)m_clusterCoG.first / (double)m_clusterSize) + 0.5));
287  }
288  double CoGY = m_param_verticalHoughSpaceSize - ((double)m_clusterCoG.second / (double)m_clusterSize - 0.5) * m_unitY;
289 
290  if (m_param_isUFinder) {
291  // Angle from Hough space only yields phi-pi/2, so adjust for this and make sure phi still is in -pi...+pi
292  double trackPhi = CoGX + M_PI_2;
293  if (trackPhi < -M_PI) trackPhi += 2 * M_PI;
294  if (trackPhi > M_PI) trackPhi -= 2 * M_PI;
295 
296  // 1./CoGY * 1e10 yields trackRadius in mm. To convert to µm, which all other values are in,
297  // multiplication by another 1e3 is required -> total of 1e13
298  double trackRadius = 1. / CoGY * 1e+13;
299 
300  m_trackCandidates.emplace_back(std::make_pair(trackPhi, trackRadius));
301  } else {
302  m_trackCandidates.emplace_back(std::make_pair(CoGX, CoGY));
303  }
304  B2DEBUG(29, "m_clusterCoG.first: " << m_clusterCoG.first << " " << ((double)m_clusterCoG.first / (double)m_clusterSize) <<
305  " m_clusterCoG.second: " << m_clusterCoG.second << " " << ((double)m_clusterCoG.second / (double)m_clusterSize) <<
306  " CoGX: " << CoGX << " CoGY: " << CoGY);
307 
309  m_cogoutstream << CoGX << " " << CoGY << std::endl;
310  }
311  }
312  m_clusterCount++;
313  }
314 }
315 
316 void FastInterceptFinder2DFPGA::DepthFirstSearch(uint lastIndexX, uint lastIndexY)
317 {
319 
320  for (uint currentIndexY = lastIndexY; currentIndexY >= lastIndexY - 1; currentIndexY--) {
321  if (abs((int)m_clusterInitialPosition.second - (int)currentIndexY) >= m_param_MaximumHSClusterSizeY or
323  for (uint currentIndexX = lastIndexX; currentIndexX <= lastIndexX + 1; currentIndexX++) {
324  if (abs((int)m_clusterInitialPosition.first - (int)currentIndexX) >= m_param_MaximumHSClusterSizeX or
326 
327  // The cell (currentIndexX, currentIndexY) is the current one has already been checked, so continue
328  if (lastIndexX == currentIndexX && lastIndexY == currentIndexY) continue;
329 
330  // first check bounds to avoid out-of-bound array access
331  // as they are uints, they are always >= 0, and in case of an overflow they would be too large
332  if (currentIndexX < m_param_nAngleSectors and currentIndexY < m_param_nVerticalSectors) {
333 
334  if (m_SectorArray[currentIndexY * m_param_nAngleSectors + currentIndexX] < 0 /*and m_clusterSize < m_MaximumHSClusterSize*/) {
335  // Only continue searching if the current cluster is smaller than the maximum cluster size
336  m_SectorArray[currentIndexY * m_param_nAngleSectors + currentIndexX] = m_clusterCount;
337  m_clusterCoG = std::make_pair(m_clusterCoG.first + currentIndexX, m_clusterCoG.second + currentIndexY);
338  m_clusterSize++;
339  // search in the next Hough Space cells...
340  DepthFirstSearch(currentIndexX, currentIndexY);
341  }
342 
343  }
344  }
345  }
346 }
347 
348 void FastInterceptFinder2DFPGA::gnuplotoutput(const std::vector<std::pair<VxdID, std::pair<long, long>>>& hits)
349 {
350  std::ofstream hsoutstream;
351  hsoutstream.open(m_param_gnuplotHSOutputFileName.c_str(), std::ios::trunc);
352 
353  hsoutstream << "set pointsize 1.5\nset style line 42 lc rgb '#0060ad' pt 7 # circle" << std::endl;
354 
355  hsoutstream << "set style line 80 lt rgb \"#808080\"" << std::endl;
356  hsoutstream << "set style line 81 lt 0" << std::endl;
357  hsoutstream << "set style line 81 lt rgb \"#808080\"" << std::endl << std::endl;
358 
359  hsoutstream << "set style line 1 lt rgb \"#A00000\" lw 1 pt 1" << std::endl;
360  hsoutstream << "set style line 2 lt rgb \"#00A000\" lw 1 pt 6" << std::endl;
361  hsoutstream << "set style line 3 lt rgb \"#000000\" lw 1 pt 6" << std::endl;
362 
363  hsoutstream << "set style line 3 lt rgb 'black' lw 1 pt 6" << std::endl;
364  hsoutstream << "set style line 4 lt rgb 'blue' lw 1 pt 6" << std::endl;
365  hsoutstream << "set style line 5 lt rgb 'green' lw 1 pt 6" << std::endl;
366  hsoutstream << "set style line 6 lt rgb 'red' lw 1 pt 6" << std::endl;
367 
368  hsoutstream << "# Description position\nset key top right" << std::endl << std::endl;
369  hsoutstream << "# Grid and border style\nset grid back linestyle 81\nset border 3 back linestyle 80" << std::endl << std::endl;
370 
371  hsoutstream << "# No mirrors\nset xtics nomirror\nset ytics nomirror" << std::endl << std::endl;
372  hsoutstream << "# Encoding\nset encoding utf8" << std::endl << std::endl;
373  hsoutstream << "set xlabel \"x\"\nset ylabel \"y\"" << std::endl << std::endl;
374 
375  hsoutstream << "set xrange [-pi-0.5:pi+0.5]" << std::endl << std::endl;
376 
377  hsoutstream << "load '" << m_param_gnuplotHSRectOutputFileName << "'" << std::endl << std::endl;
378 
379  uint count = 0;
380  for (auto& hit : hits) {
381  const VxdID& id = hit.first;
382  int layer = id.getLayerNumber();
383  // Multiplication with 1000 is necessary, as in the actual intercept finding step, cos and sin are multiplied by 1000, too.
384  // To directly compare the information in the gnuplot HoughSpace, just multiply by 1000 here instead of adding another
385  // '1000 * ' when writing to the gnuplot debug file.
386  const long xc = 1000 * hit.second.first;
387  const long yc = 1000 * hit.second.second;
388 
389  // only plot when derivative is positive
390  hsoutstream << "plot " << xc << " * -sin(x) + " << yc << " * cos(x) > 0 ? " << xc << " * cos(x) + " << yc <<
391  " * sin(x) : 1/0 notitle linestyle " << layer << " # " << id << std::endl;
392  if (count < hits.size() - 1) hsoutstream << "re";
393  count++;
394  }
395 
396  hsoutstream << std::endl;
397  hsoutstream << "replot '" << m_param_gnuplotHSCoGOutputFileName << "' u 1:2 w p ls 42 notitle" << std::endl << std::endl;
398  hsoutstream << "pause -1" << std::endl;
399  hsoutstream.close();
400 }
void gnuplotoutput(const std::vector< std::pair< VxdID, std::pair< long, long >>> &hits)
gnuplot output for debugging
std::vector< int > m_SectorArray
vector containing only the 1D representation of active cells to speed up processing
uint m_param_MinimumHSClusterSize
minimum cluster size of sectors belonging to intercepts in the Hough Space
const std::string m_const_rectColor[8]
color definition for the sector debug output
void FindHoughSpaceCluster()
Find Hough Space clusters.
double m_param_maximumX
maximum x value of the Hough Space, defaults to the value for u-side
uint m_clusterSize
size of the current cluster
void initialize() override
Create the store arrays.
std::array< long, 16385 > m_HSYLUT
y values of the Hough Space sector boarders
std::array< double, 16385 > m_HSXLUT
x values of the Hough Space sector boarders
std::vector< std::pair< double, double > > m_trackCandidates
vector containing track candidates, consisting of the found intersection values in the Hough Space
std::string m_param_gnuplotHSRectOutputFileName
gnuplot HS sector output filename
uint m_param_nVerticalSectors
number of sectors of the Hough Space on the vertical axis
bool m_param_isUFinder
Is this the intercept finder for the u-side hits (r-phi) or v-side (r-z)?
long m_param_verticalHoughSpaceSize
vertical size of the Hough Space, defaults to the value for u-side
std::array< long, 16385 > m_HSCosValuesLUT
cosine values of the Hough Space sector boarder coordinates
void DepthFirstSearch(uint lastIndexX, uint lastIndexY)
Perform depth first search recursive algorithm to find clusters in the Hough Space.
std::array< long, 16385 > m_HSSinValuesLUT
Look-Up-Tables for values as cache to speed up calculation sine values of the Hough Space sector boar...
std::array< long, 16384 > m_HSCenterCosValuesLUT
cosine values of the Hough Space sector center coordinates
uint m_param_maxRecursionLevel
maximum number of recursive calls of fastInterceptFinder2d
std::ofstream m_rectoutstream
HS sector debug file.
std::ofstream m_cogoutstream
HS CoG debug file.
std::pair< int, int > m_clusterCoG
center of gravity containing describing the current best track parameters in the Hough Space
double m_param_minimumX
minimum x value of the Hough Space, defaults to the value for u-side
uint m_param_nAngleSectors
number of sectors of the Hough Space on the horizontal axis
std::string m_param_gnuplotHSOutputFileName
gnuplot HS output filename
std::vector< std::pair< uint, uint > > m_activeSectorArray
vector containing information for each cell whether it contained enough hits after m_maxRecursionLeve...
void apply(const std::vector< std::pair< VxdID, std::pair< long, long >>> &hits, std::vector< std::pair< double, double >> &tracks) override
Load in the prepared hits and create tracks for extrapolation to PXD.
std::array< long, 16384 > m_HSYCenterLUT
y values of the Hough Space sector centers
uint m_param_MaximumHSClusterSizeX
maximum cluster size in x of sectors belonging to intercepts in the Hough Space
std::string m_param_gnuplotHSCoGOutputFileName
gnuplot HS sector output filename
void fastInterceptFinder2d(const std::vector< std::pair< VxdID, std::pair< long, long >>> &hits, uint xmin, uint xmax, uint ymin, uint ymax, uint currentRecursion)
find intercepts in the 2D Hough Space by recursively calling itself until no hits are assinged to a g...
uint m_param_MaximumHSClusterSize
maximum cluster size of sectors belonging to intercepts in the Hough Space
bool m_param_writeGnuplotOutput
use gnuplot output?
unsigned short layerFilter(std::vector< bool > layer)
Layer filter, checks if at least hits from 3 layers are in a set of hits.
FastInterceptFinder2DFPGA()
Find intercepts in the 2D Hough space.
uint m_rectcounter
count HS debug rectangles
void exposeParameters(ModuleParamList *moduleParamList, const std::string &prefix) override
Expose the parameters of the sub findlets.
std::array< double, 16384 > m_HSXCenterLUT
x values of the Hough Space sector centers
std::pair< int, int > m_clusterInitialPosition
start cell of the recursive cluster finding in the Hough Space
uint m_param_MaximumHSClusterSizeY
maximum cluster size in y of sectors belonging to intercepts in the Hough Space
std::array< long, 16384 > m_HSCenterSinValuesLUT
sine values of the Hough Space sector center coordinates
The Module parameter list class.
void initialize() override
Receive and dispatch signal before the start of the event processing.
virtual void exposeParameters(ModuleParamList *moduleParamList, const std::string &prefix)
Forward prefixed parameters of this findlet to the module parameter list.
Definition: Findlet.h:69
Class to uniquely identify a any structure of the PXD and SVD.
Definition: VxdID.h:33
void addParameter(const std::string &name, T &paramVariable, const std::string &description, const T &defaultValue)
Adds a new parameter to the module list.
double atan(double a)
atan for double
Definition: beamHelpers.h:34
double tan(double a)
tan for double
Definition: beamHelpers.h:31
long convertFloatToInt(double value, int power)
Convert float or double to long int for more similarity to the FPGA implementation.
Definition: DATCONHelpers.h:21
Abstract base class for different kinds of events.