CMS 3D CMS Logo

CACell.h
Go to the documentation of this file.
1 #ifndef RecoTracker_PixelSeeding_src_CACell_h
2 #define RecoTracker_PixelSeeding_src_CACell_h
3 
4 #include <array>
5 #include <cmath>
6 
12 
13 class CACellStatus {
14 public:
15  unsigned char getCAState() const { return theCAState; }
16 
17  // if there is at least one left neighbor with the same state (friend), the state has to be increased by 1.
19 
20  bool isRootCell(const unsigned int minimumCAState) const { return (theCAState >= minimumCAState); }
21 
22 public:
23  unsigned char theCAState = 0;
24  unsigned char hasSameStateNeighbors = 0;
25 };
26 
27 class CACell {
28 public:
30  using CAntuple = std::vector<unsigned int>;
31  using CAntuplet = std::vector<unsigned int>;
32  using CAColl = std::vector<CACell>;
33  using CAStatusColl = std::vector<CACellStatus>;
34 
35  CACell(const HitDoublets* doublets, int doubletId, const int innerHitId, const int outerHitId)
37  theDoubletId(doubletId),
38  theInnerR(doublets->rv(doubletId, HitDoublets::inner)),
39  theInnerZ(doublets->z(doubletId, HitDoublets::inner)) {}
40 
42 
44 
46 
48 
49  float getInnerX() const { return theDoublets->x(theDoubletId, HitDoublets::inner); }
50 
51  float getOuterX() const { return theDoublets->x(theDoubletId, HitDoublets::outer); }
52 
53  float getInnerY() const { return theDoublets->y(theDoubletId, HitDoublets::inner); }
54 
55  float getOuterY() const { return theDoublets->y(theDoubletId, HitDoublets::outer); }
56 
57  float getInnerZ() const { return theInnerZ; }
58 
59  float getOuterZ() const { return theDoublets->z(theDoubletId, HitDoublets::outer); }
60 
61  float getInnerR() const { return theInnerR; }
62 
64 
66 
68 
69  void evolve(unsigned int me, CAStatusColl& allStatus) {
70  allStatus[me].hasSameStateNeighbors = 0;
71  auto mystate = allStatus[me].theCAState;
72 
73  for (auto oc : theOuterNeighbors) {
74  if (allStatus[oc].getCAState() == mystate) {
75  allStatus[me].hasSameStateNeighbors = 1;
76 
77  break;
78  }
79  }
80  }
81 
82  void checkAlignmentAndAct(CAColl& allCells,
83  CAntuple& innerCells,
84  const float ptmin,
85  const float region_origin_x,
86  const float region_origin_y,
87  const float region_origin_radius,
88  const CACut::CAValuesByInnerLayerIds& thetaCutByInnerLayer,
89  const CACut::CAValuesByInnerLayerIds& phiCutByInnerLayer,
90  const float hardPtCut,
91  std::vector<CACell::CAntuplet>* foundTriplets) {
92  int ncells = innerCells.size();
93  int constexpr VSIZE = 16;
94  int ok[VSIZE];
95  float r1[VSIZE];
96  float z1[VSIZE];
97  float thetaCut[VSIZE];
98  float phiCut[VSIZE];
99  auto ro = getOuterR();
100  auto zo = getOuterZ();
101  unsigned int cellId = this - &allCells.front();
102  auto loop = [&](int i, int vs) {
103  for (int j = 0; j < vs; ++j) {
104  auto koc = innerCells[i + j];
105  auto& oc = allCells[koc];
106  r1[j] = oc.getInnerR();
107  z1[j] = oc.getInnerZ();
108  thetaCut[j] = thetaCutByInnerLayer.at(oc.getInnerLayer());
109  phiCut[j] = phiCutByInnerLayer.at(oc.getInnerLayer());
110  }
111  // this vectorize!
112  for (int j = 0; j < vs; ++j)
113  ok[j] = areAlignedRZ(r1[j], z1[j], ro, zo, ptmin, thetaCut[j]);
114  for (int j = 0; j < vs; ++j) {
115  auto koc = innerCells[i + j];
116  auto& oc = allCells[koc];
117  if (ok[j] && haveSimilarCurvature(
118  oc, ptmin, region_origin_x, region_origin_y, region_origin_radius, phiCut[j], hardPtCut)) {
119  if (foundTriplets)
120  foundTriplets->emplace_back(CACell::CAntuplet{koc, cellId});
121  else {
122  oc.tagAsOuterNeighbor(cellId);
123  }
124  }
125  }
126  };
127  auto lim = VSIZE * (ncells / VSIZE);
128  for (int i = 0; i < lim; i += VSIZE)
129  loop(i, VSIZE);
130  loop(lim, ncells - lim);
131  }
132 
133  void checkAlignmentAndTag(CAColl& allCells,
134  CAntuple& innerCells,
135  const float ptmin,
136  const float region_origin_x,
137  const float region_origin_y,
138  const float region_origin_radius,
139  const CACut::CAValuesByInnerLayerIds& thetaCutByInnerLayer,
140  const CACut::CAValuesByInnerLayerIds& phiCutByInnerLayer,
141  const float hardPtCut) {
142  checkAlignmentAndAct(allCells,
143  innerCells,
144  ptmin,
145  region_origin_x,
146  region_origin_y,
147  region_origin_radius,
148  thetaCutByInnerLayer,
149  phiCutByInnerLayer,
150  hardPtCut,
151  nullptr);
152  }
154  CAntuple& innerCells,
155  std::vector<CACell::CAntuplet>& foundTriplets,
156  const float ptmin,
157  const float region_origin_x,
158  const float region_origin_y,
159  const float region_origin_radius,
160  const CACut::CAValuesByInnerLayerIds& thetaCutByInnerLayer,
161  const CACut::CAValuesByInnerLayerIds& phiCutByInnerLayer,
162  const float hardPtCut) {
163  checkAlignmentAndAct(allCells,
164  innerCells,
165  ptmin,
166  region_origin_x,
167  region_origin_y,
168  region_origin_radius,
169  thetaCutByInnerLayer,
170  phiCutByInnerLayer,
171  hardPtCut,
172  &foundTriplets);
173  }
174 
175  int areAlignedRZ(float r1, float z1, float ro, float zo, const float ptmin, const float thetaCut) const {
176  float radius_diff = std::abs(r1 - ro);
177  float distance_13_squared = radius_diff * radius_diff + (z1 - zo) * (z1 - zo);
178 
179  float pMin = ptmin * std::sqrt(distance_13_squared); //this needs to be divided by radius_diff later
180 
181  float tan_12_13_half_mul_distance_13_squared =
182  fabs(z1 * (getInnerR() - ro) + getInnerZ() * (ro - r1) + zo * (r1 - getInnerR()));
183  return tan_12_13_half_mul_distance_13_squared * pMin <= thetaCut * distance_13_squared * radius_diff;
184  }
185 
186  void tagAsOuterNeighbor(unsigned int otherCell) { theOuterNeighbors.push_back(otherCell); }
187 
188  bool haveSimilarCurvature(const CACell& otherCell,
189  const float ptmin,
190  const float region_origin_x,
191  const float region_origin_y,
192  const float region_origin_radius,
193  const float phiCut,
194  const float hardPtCut) const {
195  auto x1 = otherCell.getInnerX();
196  auto y1 = otherCell.getInnerY();
197 
198  auto x2 = getInnerX();
199  auto y2 = getInnerY();
200 
201  auto x3 = getOuterX();
202  auto y3 = getOuterY();
203 
204  float distance_13_squared = (x1 - x3) * (x1 - x3) + (y1 - y3) * (y1 - y3);
205  float tan_12_13_half_mul_distance_13_squared = std::abs(y1 * (x2 - x3) + y2 * (x3 - x1) + y3 * (x1 - x2));
206  // high pt : just straight
207  if (tan_12_13_half_mul_distance_13_squared * ptmin <= 1.0e-4f * distance_13_squared) {
208  float distance_3_beamspot_squared =
209  (x3 - region_origin_x) * (x3 - region_origin_x) + (y3 - region_origin_y) * (y3 - region_origin_y);
210 
211  float dot_bs3_13 = ((x1 - x3) * (region_origin_x - x3) + (y1 - y3) * (region_origin_y - y3));
212  float proj_bs3_on_13_squared = dot_bs3_13 * dot_bs3_13 / distance_13_squared;
213 
214  float distance_13_beamspot_squared = distance_3_beamspot_squared - proj_bs3_on_13_squared;
215 
216  return distance_13_beamspot_squared < (region_origin_radius + phiCut) * (region_origin_radius + phiCut);
217  }
218 
219  //87 cm/GeV = 1/(3.8T * 0.3)
220 
221  //take less than radius given by the hardPtCut and reject everything below
222  float minRadius = hardPtCut * 87.f; // FIXME move out and use real MagField
223 
224  auto det = (x1 - x2) * (y2 - y3) - (x2 - x3) * (y1 - y2);
225 
226  auto offset = x2 * x2 + y2 * y2;
227 
228  auto bc = (x1 * x1 + y1 * y1 - offset) * 0.5f;
229 
230  auto cd = (offset - x3 * x3 - y3 * y3) * 0.5f;
231 
232  auto idet = 1.f / det;
233 
234  auto x_center = (bc * (y2 - y3) - cd * (y1 - y2)) * idet;
235  auto y_center = (cd * (x1 - x2) - bc * (x2 - x3)) * idet;
236 
237  auto radius = std::sqrt((x2 - x_center) * (x2 - x_center) + (y2 - y_center) * (y2 - y_center));
238 
239  if (radius < minRadius)
240  return false; // hard cut on pt
241 
242  auto centers_distance_squared = (x_center - region_origin_x) * (x_center - region_origin_x) +
243  (y_center - region_origin_y) * (y_center - region_origin_y);
244  auto region_origin_radius_plus_tolerance = region_origin_radius + phiCut;
245  auto minimumOfIntersectionRange =
246  (radius - region_origin_radius_plus_tolerance) * (radius - region_origin_radius_plus_tolerance);
247 
248  if (centers_distance_squared >= minimumOfIntersectionRange) {
249  auto maximumOfIntersectionRange =
250  (radius + region_origin_radius_plus_tolerance) * (radius + region_origin_radius_plus_tolerance);
251  return centers_distance_squared <= maximumOfIntersectionRange;
252  }
253 
254  return false;
255  }
256 
257  // trying to free the track building process from hardcoded layers, leaving the visit of the graph
258  // based on the neighborhood connections between cells.
259 
260  void findNtuplets(CAColl& allCells,
261  std::vector<CAntuplet>& foundNtuplets,
262  CAntuplet& tmpNtuplet,
263  const unsigned int minHitsPerNtuplet) const {
264  // the building process for a track ends if:
265  // it has no outer neighbor
266  // it has no compatible neighbor
267  // the ntuplets is then saved if the number of hits it contains is greater than a threshold
268 
269  if (tmpNtuplet.size() == minHitsPerNtuplet - 1) {
270  foundNtuplets.push_back(tmpNtuplet);
271  } else {
272  unsigned int numberOfOuterNeighbors = theOuterNeighbors.size();
273  for (unsigned int i = 0; i < numberOfOuterNeighbors; ++i) {
274  tmpNtuplet.push_back((theOuterNeighbors[i]));
275  allCells[theOuterNeighbors[i]].findNtuplets(allCells, foundNtuplets, tmpNtuplet, minHitsPerNtuplet);
276  tmpNtuplet.pop_back();
277  }
278  }
279  }
280 
281 private:
283 
285  const int theDoubletId;
286 
287  const float theInnerR;
288  const float theInnerZ;
289 };
290 
291 #endif // RecoTracker_PixelSeeding_src_CACell_h
const float theInnerZ
Definition: CACell.h:288
const HitDoublets * theDoublets
Definition: CACell.h:284
float getInnerPhi() const
Definition: CACell.h:65
void updateState()
Definition: CACell.h:18
void findNtuplets(CAColl &allCells, std::vector< CAntuplet > &foundNtuplets, CAntuplet &tmpNtuplet, const unsigned int minHitsPerNtuplet) const
Definition: CACell.h:260
int areAlignedRZ(float r1, float z1, float ro, float zo, const float ptmin, const float thetaCut) const
Definition: CACell.h:175
Hit const & hit(int i, layer l) const
float getInnerR() const
Definition: CACell.h:61
int getInnerLayer() const
Definition: CACell.h:45
float x(int i, layer l) const
const int theDoubletId
Definition: CACell.h:285
float getInnerZ() const
Definition: CACell.h:57
std::vector< CACellStatus > CAStatusColl
Definition: CACell.h:33
float getOuterPhi() const
Definition: CACell.h:67
void checkAlignmentAndPushTriplet(CAColl &allCells, CAntuple &innerCells, std::vector< CACell::CAntuplet > &foundTriplets, const float ptmin, const float region_origin_x, const float region_origin_y, const float region_origin_radius, const CACut::CAValuesByInnerLayerIds &thetaCutByInnerLayer, const CACut::CAValuesByInnerLayerIds &phiCutByInnerLayer, const float hardPtCut)
Definition: CACell.h:153
unsigned char getCAState() const
Definition: CACell.h:15
float getInnerY() const
Definition: CACell.h:53
std::vector< unsigned int > CAntuple
Definition: CACell.h:30
float getOuterR() const
Definition: CACell.h:63
void checkAlignmentAndTag(CAColl &allCells, CAntuple &innerCells, const float ptmin, const float region_origin_x, const float region_origin_y, const float region_origin_radius, const CACut::CAValuesByInnerLayerIds &thetaCutByInnerLayer, const CACut::CAValuesByInnerLayerIds &phiCutByInnerLayer, const float hardPtCut)
Definition: CACell.h:133
float getOuterX() const
Definition: CACell.h:51
T sqrt(T t)
Definition: SSEVec.h:19
const float theInnerR
Definition: CACell.h:287
void tagAsOuterNeighbor(unsigned int otherCell)
Definition: CACell.h:186
void evolve(unsigned int me, CAStatusColl &allStatus)
Definition: CACell.h:69
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
std::vector< CACell > CAColl
Definition: CACell.h:32
double f[11][100]
float rv(int i, layer l) const
int seqNum() const
Definition: DetLayer.h:35
BaseTrackerRecHit const * Hit
float z(int i, layer l) const
float getInnerX() const
Definition: CACell.h:49
Definition: CACell.h:27
float phi(int i, layer l) const
std::vector< unsigned int > CAntuplet
Definition: CACell.h:31
Hit const & getOuterHit() const
Definition: CACell.h:43
double ptmin
Definition: HydjetWrapper.h:86
unsigned char theCAState
Definition: CACell.h:23
CACell(const HitDoublets *doublets, int doubletId, const int innerHitId, const int outerHitId)
Definition: CACell.h:35
CAntuple theOuterNeighbors
Definition: CACell.h:282
float getOuterY() const
Definition: CACell.h:55
bool isRootCell(const unsigned int minimumCAState) const
Definition: CACell.h:20
Hit const & getInnerHit() const
Definition: CACell.h:41
float getOuterZ() const
Definition: CACell.h:59
bool haveSimilarCurvature(const CACell &otherCell, const float ptmin, const float region_origin_x, const float region_origin_y, const float region_origin_radius, const float phiCut, const float hardPtCut) const
Definition: CACell.h:188
DetLayer const * detLayer(layer l) const
unsigned char hasSameStateNeighbors
Definition: CACell.h:24
void checkAlignmentAndAct(CAColl &allCells, CAntuple &innerCells, const float ptmin, const float region_origin_x, const float region_origin_y, const float region_origin_radius, const CACut::CAValuesByInnerLayerIds &thetaCutByInnerLayer, const CACut::CAValuesByInnerLayerIds &phiCutByInnerLayer, const float hardPtCut, std::vector< CACell::CAntuplet > *foundTriplets)
Definition: CACell.h:82
float at(int layerId) const
Definition: CACut.h:122
float y(int i, layer l) const
int getOuterLayer() const
Definition: CACell.h:47