EIC Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
sPHENIXSeedFinder.h
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file sPHENIXSeedFinder.h
1 #ifndef SPHENIX_SPHENIXSEEDFINDER_H
2 #define SPHENIX_SPHENIXSEEDFINDER_H
3 
4 #include "HelixHough.h"
5 #include "HelixKalmanState.h"
6 #include "HelixRange.h" // for HelixRange
7 #include "SimpleHit3D.h"
8 #include "Seamstress.h"
9 
10 
11 #include <algorithm>
12 #include <cmath>
13 #include <map>
14 #include <memory>
15 #include <set>
16 #include <vector>
17 
18 class CylinderKalman;
19 class HelixResolution;
20 class SimpleTrack3D;
21 
22 namespace SeamStress { template <class TClass> class Pincushion; }
23 
24 class AngleIndexPair {
25 public:
26  AngleIndexPair(float ang, unsigned int idx) :
27  angle(ang), index(idx) {
28  float twopi = 2. * M_PI;
29  int a = (int) (angle / twopi);
30  angle -= a * twopi;
31  while (angle < 0.) {
32  angle += twopi;
33  }
34  while (angle >= twopi) {
35  angle -= twopi;
36  }
37  }
39  }
40 
41  bool operator<(const AngleIndexPair& other) const {
42  return angle < other.angle;
43  }
44 
45  static float absDiff(float angle1, float angle2) {
46  float diff = (angle1 - angle2);
47  while (diff > M_PI) {
48  diff -= 2. * M_PI;
49  }
50  while (diff < -M_PI) {
51  diff += 2. * M_PI;
52  }
53  diff = fabs(diff);
54  return diff;
55  }
56 
57  float angle;
58  unsigned int index;
59 };
60 
61 class AngleIndexList {
62 public:
64  sorted(false) {
65  }
67  }
68 
69  void addPair(AngleIndexPair& angind) {
70  sorted = false;
71  vec.push_back(angind);
72  }
73 
74  void getRangeListSimple(float angle, float error,
75  std::vector<AngleIndexPair*>& result) {
76  result.clear();
77 
78  for (unsigned int i = 0; i < vec.size(); i++) {
79  if (AngleIndexPair::absDiff(angle, vec[i].angle) <= error) {
80  result.push_back(&(vec[i]));
81  }
82  }
83  }
84 
85  void getRangeList(float angle, float error,
86  std::vector<AngleIndexPair*>& result) {
87  float twopi = 2. * M_PI;
88  int a = (int) (angle / twopi);
89  angle -= a * twopi;
90  while (angle < 0.) {
91  angle += twopi;
92  }
93  while (angle >= twopi) {
94  angle -= twopi;
95  }
96 
97  if (vec.size() <= 4) {
98  return getRangeListSimple(angle, error, result);
99  }
100 
101  result.clear();
102 
103  unsigned int closest = findClosest(angle);
104  // first, traverse upward
105  unsigned int current = closest;
106  unsigned int lowest = 0;
107  unsigned int highest = vec.size() - 1;
108  while (true) {
109  if (AngleIndexPair::absDiff(angle, vec[current].angle) <= error) {
110  result.push_back(&(vec[current]));
111  current = (current + 1) % (vec.size());
112  if (current == closest) {
113  return;
114  }
115  } else {
116  break;
117  }
118  }
119 
120  // now, traverse downward
121  if (current <= closest) {
122  lowest = current;
123  } else {
124  highest = current;
125  }
126  current = ((closest + vec.size()) - 1) % (vec.size());
127  while (true) {
128  if ((current == lowest) || (current == highest)) {
129  break;
130  }
131  if (AngleIndexPair::absDiff(angle, vec[current].angle) <= error) {
132  result.push_back(&(vec[current]));
133  current = ((current + vec.size()) - 1) % (vec.size());
134  } else {
135  break;
136  }
137  }
138  }
139 
140  unsigned int findClosestSimple(float angle, unsigned int lower,
141  unsigned int upper) {
142  unsigned int closest = lower;
143  float diff = AngleIndexPair::absDiff(vec[closest].angle, angle);
144  for (unsigned int i = (lower + 1); i <= upper; i++) {
145  float tempdiff = AngleIndexPair::absDiff(vec[i].angle, angle);
146  if (tempdiff < diff) {
147  closest = i;
148  diff = tempdiff;
149  }
150  }
151 
152  return closest;
153  }
154 
155  unsigned int findClosest(float angle) {
156  if (vec.size() <= 4) {
157  return findClosestSimple(angle, 0, vec.size() - 1);
158  }
159 
160  if (sorted == false) {
161  std::sort(vec.begin(), vec.end());
162  sorted = true;
163  }
164 
165  unsigned int lower = 0;
166  unsigned int upper = vec.size() - 1;
167  unsigned int middle = vec.size() / 2;
168  while (true) {
169  if ((upper - lower) <= 4) {
170  return findClosestSimple(angle, lower, upper);
171  }
172 
173  if (angle <= vec[middle].angle) {
174  upper = middle;
175  middle = (lower + upper) / 2;
176  } else {
177  lower = middle;
178  middle = (lower + upper) / 2;
179  }
180  }
181  }
182 
183  std::vector<AngleIndexPair> vec;
184  bool sorted;
185 };
186 
188 public:
190  chi2(0.), ux(0.), uy(0.), kappa(0.), dkappa(0.), seed(0), n_hits(0) {
191  }
193  }
194 
195  float chi2;
196  float ux, uy;
197  float kappa;
198  float dkappa;
199  std::vector<unsigned int> hits;
200  unsigned int seed;
201  unsigned int bin;
202  unsigned int n_hits;
203 };
204 
206 public:
207  sPHENIXSeedFinder(unsigned int n_phi, unsigned int n_d, unsigned int n_k,
208  unsigned int n_dzdl, unsigned int n_z0,
209  HelixResolution& min_resolution, HelixResolution& max_resolution,
210  HelixRange& range, std::vector<float>& material,
211  std::vector<float>& radius, float Bfield);
212  sPHENIXSeedFinder(std::vector<std::vector<unsigned int> >& zoom_profile,
213  unsigned int minzoom, HelixRange& range,
214  std::vector<float>& material, std::vector<float>& radius,
215  float Bfield, bool parallel = false, unsigned int num_threads = 1);
216  virtual ~sPHENIXSeedFinder();
217 
218  void finalize(std::vector<SimpleTrack3D>& input,
219  std::vector<SimpleTrack3D>& output);
220 
221  void findTracks(std::vector<SimpleHit3D>& hits,
222  std::vector<SimpleTrack3D>& tracks, const HelixRange& range);
223 
224  void findTracksBySegments(std::vector<SimpleHit3D>& hits,
225  std::vector<SimpleTrack3D>& tracks, const HelixRange& range);
226 
227  void initEvent(std::vector<SimpleHit3D>& hits, unsigned int) {
228  int min_layer = 999999;
229  int max_layer = 0;
230  for (unsigned int i = 0; i < hits.size(); ++i) {
231  if (hits[i].get_layer() < min_layer) {
232  min_layer = hits[i].get_layer();
233  }
234  if (hits[i].get_layer() > max_layer) {
235  max_layer = hits[i].get_layer();
236  }
237  }
238  setSeedLayer(min_layer);
239  setNLayers(max_layer + 1);
240 
241  nfits = 0;
242  combos.clear();
243  fail_combos.clear();
244  pass_combos.clear();
245  seeding = false;
246  // required_layers = min_hits;
248  findtracksiter = 0;
249  CAtime = 0.;
250  KALtime = 0.;
251  findtracks_bin = 0;
252  }
253 
254  void initSeeding(std::vector<SimpleTrack3D>& seeds) {
255  seeding = true;
256  seed_used.clear();
257  seed_used.assign(seeds.size(), false);
258  AngleIndexList templist;
259  angle_list.clear();
260  angle_list.assign(n_layers, templist);
261  }
262 
263  void clear() {
264  track_states.clear();
265  isolation_variable.clear();
266  }
267 
268  void findHelicesParallel(std::vector<SimpleHit3D>& hits,
269  unsigned int min_hits, unsigned int max_hits,
270  std::vector<SimpleTrack3D>& tracks);
271  void findHelicesParallelOneHelicity(std::vector<SimpleHit3D>& hits,
272  unsigned int min_hits, unsigned int max_hits,
273  std::vector<SimpleTrack3D>& tracks);
274 
275  float dcaToVertexXY(SimpleTrack3D& track, float vx, float vy);
276 
277  bool breakRecursion(const std::vector<SimpleHit3D>& hits,
278  const HelixRange& range);
279 
280  float phiError(SimpleHit3D& hit, float min_k, float max_k, float min_d,
281  float max_d, float min_z0, float max_z0, float min_dzdl,
282  float max_dzdl, bool pairvoting = false);
283  float dzdlError(SimpleHit3D& hit, float min_k, float max_k, float min_d,
284  float max_d, float min_z0, float max_z0, float min_dzdl,
285  float max_dzdl, bool pairvoting = false);
286 
287  static float fitTrack(SimpleTrack3D& track);
288  static float fitTrack(SimpleTrack3D& track, std::vector<float>& chi2_hit);
289 
290  void setVerbosity(int v) {
291  verbosity = v;
292  }
293 
294  void setCutOnDca(bool dcut) {
295  cut_on_dca = dcut;
296  }
297  void setDcaCut(float dcut) {
298  dca_cut = dcut;
299  }
300  void setVertex(float vx, float vy, float vz) {
301  vertex_x = vx;
302  vertex_y = vy;
303  vertex_z = vz;
304  }
305 
306  void setRejectGhosts(bool rg) {
307  reject_ghosts = rg;
308  }
309 
310  std::vector<float>& getIsolation() {
311  return isolation_variable;
312  }
313 
314  static void calculateKappaTangents(float* x1_a, float* y1_a, float* z1_a,
315  float* x2_a, float* y2_a, float* z2_a, float* x3_a, float* y3_a,
316  float* z3_a, float* dx1_a, float* dy1_a, float* dz1_a, float* dx2_a,
317  float* dy2_a, float* dz2_a, float* dx3_a, float* dy3_a,
318  float* dz3_a, float* kappa_a, float* dkappa_a, float* ux_mid_a,
319  float* uy_mid_a, float* ux_end_a, float* uy_end_a, float* dzdl_1_a,
320  float* dzdl_2_a, float* ddzdl_1_a, float* ddzdl_2_a);
321  void calculateKappaTangents(float* x1_a, float* y1_a, float* z1_a,
322  float* x2_a, float* y2_a, float* z2_a, float* x3_a, float* y3_a,
323  float* z3_a, float* dx1_a, float* dy1_a, float* dz1_a, float* dx2_a,
324  float* dy2_a, float* dz2_a, float* dx3_a, float* dy3_a,
325  float* dz3_a, float* kappa_a, float* dkappa_a, float* ux_mid_a,
326  float* uy_mid_a, float* ux_end_a, float* uy_end_a, float* dzdl_1_a,
327  float* dzdl_2_a, float* ddzdl_1_a, float* ddzdl_2_a,
328  float sinang_cut, float cosang_diff_inv, float* cur_kappa_a,
329  float* cur_dkappa_a, float* cur_ux_a, float* cur_uy_a,
330  float* cur_chi2_a, float* chi2_a);
331  void projectToLayer(SimpleTrack3D& seed, unsigned int layer, float& x,
332  float& y, float& z);
333 
334  void setRangeFromSeed(HelixRange& range, SimpleTrack3D& seed);
335 
336  void pairRejection(std::vector<SimpleTrack3D>& input,
337  std::vector<SimpleTrack3D>& output, std::vector<bool>& usetrack,
338  std::vector<float>& next_best_chi2);
339  void tripletRejection(std::vector<SimpleTrack3D>& input,
340  std::vector<SimpleTrack3D>& output, std::vector<bool>& usetrack,
341  std::vector<float>& next_best_chi2);
342 
343  bool seedWasUsed(unsigned int seed_index) {
344  return seed_used.at(seed_index);
345  }
346 
347  void setSeparateByHelicity(bool sbh) {
348  separate_by_helicity = sbh;
349  if (is_parallel == true) {
350  for (unsigned int i = 0; i < thread_trackers.size(); ++i) {
351  thread_trackers[i]->setSeparateByHelicity(sbh);
352  }
353  }
354  }
355 
356  void requireLayers(unsigned int nl) {
357  check_layers = true;
358  req_layers = nl;
359  if (is_parallel == true) {
360  for (unsigned int i = 0; i < thread_trackers.size(); ++i) {
361  thread_trackers[i]->requireLayers(nl);
362  }
363  }
364  }
365 
366  virtual void setMaxHitsPairs(unsigned int mhp) {
367  max_hits_pairs = mhp;
368  if (is_parallel == true) {
369  for (unsigned int i = 0; i < thread_trackers.size(); ++i) {
370  thread_trackers[i]->setMaxHitsPairs(mhp);
371  }
372  }
373  }
374 
375  void setBinScale(float b_scl) {
376  bin_scale = b_scl;
377  if (is_parallel == true) {
378  for (unsigned int i = 0; i < thread_trackers.size(); ++i) {
379  thread_trackers[i]->setBinScale(b_scl);
380  }
381  }
382  }
383  void setZBinScale(float b_scl) {
384  z_bin_scale = b_scl;
385  if (is_parallel == true) {
386  for (unsigned int i = 0; i < thread_trackers.size(); ++i) {
387  thread_trackers[i]->setZBinScale(b_scl);
388  }
389  }
390  }
391  void setRemoveHits(bool rh) {
392  remove_hits = rh;
393  if (is_parallel == true) {
394  for (unsigned int i = 0; i < thread_trackers.size(); ++i) {
395  thread_trackers[i]->setRemoveHits(rh);
396  }
397  }
398  }
399 
400  void setSeedLayer(int sl) {
401  seed_layer = sl;
402  if (is_parallel == true) {
403  for (unsigned int i = 0; i < thread_trackers.size(); ++i) {
404  thread_trackers[i]->setSeedLayer(sl);
405  }
406  }
407  }
408 
409  void setNLayers(unsigned int n) {
410  n_layers = n;
411  std::vector<SimpleHit3D> one_layer;
412  layer_sorted.clear();
413  layer_sorted.assign(n_layers, one_layer);
414  temp_comb.assign(n_layers, 0);
415  if (is_parallel == true) {
416  for (unsigned int i = 0; i < thread_trackers.size(); ++i) {
417  thread_trackers[i]->setNLayers(n);
418  }
419  }
420  }
421 
422  void setFastChi2Cut(float par0, float par1, float max) {
423  fast_chi2_cut_par0 = par0;
424  fast_chi2_cut_par1 = par1;
426  if (is_parallel == true) {
427  for (unsigned int i = 0; i < thread_trackers.size(); ++i) {
428  thread_trackers[i]->setFastChi2Cut(par0, par1, max);
429  }
430  }
431  }
432  void setChi2Cut(float c) {
433  chi2_cut = c;
434  if (is_parallel == true) {
435  for (unsigned int i = 0; i < thread_trackers.size(); ++i) {
436  thread_trackers[i]->setChi2Cut(c);
437  }
438  }
439  }
440  void setChi2RemovalCut(float c) {
442  if (is_parallel == true) {
443  for (unsigned int i = 0; i < thread_trackers.size(); ++i) {
444  thread_trackers[i]->setChi2RemovalCut(c);
445  }
446  }
447  }
448 
449  void setNRemovalHits(unsigned int n) {
450  n_removal_hits = n;
451  if (is_parallel == true) {
452  for (unsigned int i = 0; i < thread_trackers.size(); ++i) {
453  thread_trackers[i]->setNRemovalHits(n);
454  }
455  }
456  }
457 
458  void setCosAngleCut(float cut) {
459  cosang_cut = cut;
460  if (is_parallel == true) {
461  for (unsigned int i = 0; i < thread_trackers.size(); ++i) {
462  thread_trackers[i]->setCosAngleCut(cut);
463  }
464  }
465  }
466 
467  void setCellularAutomatonChi2Cut(float cut) {
468  ca_chi2_cut = cut;
469  if (is_parallel == true) {
470  for (unsigned int i = 0; i < thread_trackers.size(); ++i) {
471  thread_trackers[i]->setCellularAutomatonChi2Cut(cut);
472  }
473  }
474  }
475 
476  void setThread() {
477  is_thread = true;
478  }
479 
480  void initSplitting(std::vector<SimpleHit3D>& hits, unsigned int min_hits,
481  unsigned int max_hits);
482 
483  void setHitErrorScale(unsigned int layer, float scale) {
484  if (layer >= hit_error_scale.size()) {
485  hit_error_scale.resize(layer + 1, 1.);
486  }
487  hit_error_scale[layer] = scale;
488  }
489 
490 private:
491  float kappaToPt(float kappa);
492  float ptToKappa(float pt);
493 
494  void findHelicesParallelThread(void* arg);
495  void splitHitsParallelThread(void* arg);
496 
497  void initDummyHits(std::vector<SimpleHit3D>& dummies,
498  const HelixRange& range, HelixKalmanState& init_state);
499 
503  float chi2_cut;
505  unsigned int n_removal_hits;
506  std::set<std::vector<unsigned int> > combos;
507  std::map<std::vector<unsigned int>, HelixKalmanState> pass_combos;
508  std::set<std::vector<unsigned int> > fail_combos;
509  std::vector<float> detector_scatter;
510  std::vector<float> integrated_scatter;
511  std::vector<float> detector_radii;
512  bool seeding;
515  float dca_cut;
517  unsigned int required_layers;
519  unsigned int nfits;
520 
522 
523  std::vector<float> isolation_variable;
524 
525  unsigned int findtracksiter;
526 
527  float prev_max_k;
529  float prev_p_inv;
530 
532 
533  std::vector<TrackSegment> segments1;
534  std::vector<TrackSegment> segments2;
535 
536  std::vector<std::vector<SimpleHit3D> > layer_sorted;
537  std::vector<unsigned int> temp_comb;
538 
540 
541  std::vector<bool> seed_used;
542 
543  unsigned int nthreads;
544  std::vector<SeamStress::Seamstress*> *vssp;
545  std::vector<SeamStress::Seamstress> vss;
547  std::vector<sPHENIXSeedFinder*> thread_trackers;
548  std::vector<std::vector<SimpleTrack3D> > thread_tracks;
549  std::vector<HelixRange> thread_ranges;
550  std::vector<std::vector<SimpleHit3D> > thread_hits;
551  std::vector<std::vector<SimpleHit3D> > split_input_hits;
552  std::vector<std::vector<std::vector<SimpleHit3D> >*> split_output_hits;
553  std::vector<std::vector<HelixRange>*> split_ranges;
555  unsigned int thread_min_hits;
556  unsigned int thread_max_hits;
557  bool is_thread;
558 
559  std::vector<AngleIndexList> angle_list;
560 
561  double CAtime;
562  double KALtime;
563 
564  std::vector<std::vector<SimpleHit3D> > layer_sorted_1[4];
565  unsigned int findtracks_bin;
566 
567  float ca_chi2_cut;
568  float cosang_cut;
569 
570  std::vector<float> hit_error_scale;
571 };
572 
573 #endif