CMS 3D CMS Logo

ConformalUtilsMPlex.cc
Go to the documentation of this file.
1 #include "ConformalUtilsMPlex.h"
5 
6 //#define DEBUG
8 
9 /* From MkFitter.h/.cc
10 // ----------------
11  void ConformalFitTracks(bool fitting, int beg, int end);
12 // ----------------
13  void MkFitter::ConformalFitTracks(bool fitting, int beg, int end) {
14  // bool fitting to determine to use fitting CF error widths
15  // in reality, this is depedent on hits used to make pulls
16  // could consider writing an array for widths for a given hit combo
17  // to give precise widths --> then would drop boolean
18  // also used to determine which hits to use
19 
20  int front, middle, back;
21 
22  // FIXME FITTING HITS --> assume one hit per layer and all layers found! BAD! Need vector of indices to do this right instead...
23  // can always assume 0,1,2 for seeding --> triplets in forward direction
24 #ifdef INWARDFIT
25  front = (fitting ? Config::nLayers - 1
26  : 0); // i.e. would rather have true option not hardcoded... but set by ACTUAL last hit found
27  middle =
28  (fitting ? (Config::nLayers - 1) / 2 : 1); // same with this one... would rather middle hit be in the middle!
29  back = (fitting ? 0 : 2);
30 #else
31  front = (fitting ? 0 : 0);
32  middle = (fitting ? (Config::nLayers - 1) / 2 : 1); // ditto above
33  back = (fitting ? Config::nLayers - 1 : 2); // yup...
34 #endif
35 
36  // write to iC --> next step will be a propagation no matter what
37  conformalFitMPlex(fitting, Label, Err[iC], Par[iC], msPar[front], msPar[middle], msPar[back]);
38 
39  // need to set most off-diagonal elements in unc. to zero, inflate all other elements;
40  if (fitting) {
41  using idx_t = Matriplex::idx_t;
42  const idx_t N = NN;
43 #pragma omp simd
44  for (int n = 0; n < N; ++n) {
45  Err[iC].At(n, 0, 0) = Err[iC].constAt(n, 0, 0) * Config::blowupfit;
46  Err[iC].At(n, 0, 1) = Err[iC].constAt(n, 0, 1) * Config::blowupfit;
47  Err[iC].At(n, 1, 0) = Err[iC].constAt(n, 1, 0) * Config::blowupfit;
48  Err[iC].At(n, 1, 1) = Err[iC].constAt(n, 1, 1) * Config::blowupfit;
49  Err[iC].At(n, 2, 2) = Err[iC].constAt(n, 2, 2) * Config::blowupfit;
50  Err[iC].At(n, 3, 3) = Err[iC].constAt(n, 3, 3) * Config::blowupfit;
51  Err[iC].At(n, 4, 4) = Err[iC].constAt(n, 4, 4) * Config::blowupfit;
52  Err[iC].At(n, 5, 5) = Err[iC].constAt(n, 5, 5) * Config::blowupfit;
53 
54  Err[iC].At(n, 0, 2) = 0.0f;
55  Err[iC].At(n, 0, 3) = 0.0f;
56  Err[iC].At(n, 0, 4) = 0.0f;
57  Err[iC].At(n, 0, 5) = 0.0f;
58  Err[iC].At(n, 1, 2) = 0.0f;
59  Err[iC].At(n, 1, 3) = 0.0f;
60  Err[iC].At(n, 1, 4) = 0.0f;
61  Err[iC].At(n, 1, 5) = 0.0f;
62  Err[iC].At(n, 2, 0) = 0.0f;
63  Err[iC].At(n, 2, 1) = 0.0f;
64  Err[iC].At(n, 2, 3) = 0.0f;
65  Err[iC].At(n, 2, 4) = 0.0f;
66  Err[iC].At(n, 2, 5) = 0.0f;
67  Err[iC].At(n, 3, 0) = 0.0f;
68  Err[iC].At(n, 3, 1) = 0.0f;
69  Err[iC].At(n, 3, 2) = 0.0f;
70  Err[iC].At(n, 3, 4) = 0.0f;
71  Err[iC].At(n, 3, 5) = 0.0f;
72  Err[iC].At(n, 4, 0) = 0.0f;
73  Err[iC].At(n, 4, 1) = 0.0f;
74  Err[iC].At(n, 4, 2) = 0.0f;
75  Err[iC].At(n, 4, 3) = 0.0f;
76  Err[iC].At(n, 4, 5) = 0.0f;
77  Err[iC].At(n, 5, 0) = 0.0f;
78  Err[iC].At(n, 5, 1) = 0.0f;
79  Err[iC].At(n, 5, 2) = 0.0f;
80  Err[iC].At(n, 5, 3) = 0.0f;
81  Err[iC].At(n, 5, 4) = 0.0f;
82  }
83  }
84  }
85 */
86 
87 namespace mkfit {
88 
89  inline void CFMap(const MPlexHH& A, const MPlexHV& B, MPlexHV& C) {
90  using idx_t = Matriplex::idx_t;
91 
92  // C = A * B, C is 3x1, A is 3x3 , B is 3x1
93 
94  typedef float T;
95  typedef float Tv;
96  const idx_t N = NN;
97 
98  const T* a = A.fArray;
99  ASSUME_ALIGNED(a, 64);
100  const Tv* b = B.fArray;
101  ASSUME_ALIGNED(b, 64);
102  Tv* c = C.fArray;
103  ASSUME_ALIGNED(c, 64);
104 
105 #include "RecoTracker/MkFitCore/standalone/CFMatrix33Vector3.ah"
106  }
107 
108  //M. Hansroul, H. Jeremie and D. Savard, NIM A 270 (1988) 498
109  //http://www.sciencedirect.com/science/article/pii/016890028890722X
110 
111  void conformalFitMPlex(bool fitting,
112  MPlexQI seedID,
113  MPlexLS& outErr,
114  MPlexLV& outPar,
115  const MPlexHV& msPar0,
116  const MPlexHV& msPar1,
117  const MPlexHV& msPar2) {
118  bool debug(false);
119 
120  using idx_t = Matriplex::idx_t;
121  const idx_t N = NN;
122 
123  // Store positions in mplex vectors... could consider storing in a 3x3 matrix, too
124  MPlexHV x, y, z, r2;
125 #pragma omp simd
126  for (int n = 0; n < N; ++n) {
127  x.At(n, 0, 0) = msPar0.constAt(n, 0, 0);
128  x.At(n, 1, 0) = msPar1.constAt(n, 0, 0);
129  x.At(n, 2, 0) = msPar2.constAt(n, 0, 0);
130 
131  y.At(n, 0, 0) = msPar0.constAt(n, 1, 0);
132  y.At(n, 1, 0) = msPar1.constAt(n, 1, 0);
133  y.At(n, 2, 0) = msPar2.constAt(n, 1, 0);
134 
135  z.At(n, 0, 0) = msPar0.constAt(n, 2, 0);
136  z.At(n, 1, 0) = msPar1.constAt(n, 2, 0);
137  z.At(n, 2, 0) = msPar2.constAt(n, 2, 0);
138 
139  for (int i = 0; i < 3; ++i) {
140  r2.At(n, i, 0) = getRad2(x.constAt(n, i, 0), y.constAt(n, i, 0));
141  }
142  }
143 
144  // Start setting the output parameters
145 #pragma omp simd
146  for (int n = 0; n < N; ++n) {
147  outPar.At(n, 0, 0) = x.constAt(n, 0, 0);
148  outPar.At(n, 1, 0) = y.constAt(n, 0, 0);
149  outPar.At(n, 2, 0) = z.constAt(n, 0, 0);
150  }
151 
152  // Use r-phi smearing to set initial error estimation for positions
153  // trackStates already initialized to identity for seeding ... don't store off-diag 0's, zero's for fitting set outside CF
154 #pragma omp simd
155  for (int n = 0; n < N; ++n) {
156  const float varPhi = Config::varXY / r2.constAt(n, 0, 0);
157  const float invvarR2 = Config::varR / r2.constAt(n, 0, 0);
158 
159  outErr.At(n, 0, 0) =
160  x.constAt(n, 0, 0) * x.constAt(n, 0, 0) * invvarR2 + y.constAt(n, 0, 0) * y.constAt(n, 0, 0) * varPhi;
161  outErr.At(n, 0, 1) = x.constAt(n, 0, 0) * y.constAt(n, 0, 0) * (invvarR2 - varPhi);
162 
163  outErr.At(n, 1, 0) = outErr.constAt(n, 0, 1);
164  outErr.At(n, 1, 1) =
165  y.constAt(n, 0, 0) * y.constAt(n, 0, 0) * invvarR2 + x.constAt(n, 0, 0) * x.constAt(n, 0, 0) * varPhi;
166 
167  outErr.At(n, 2, 2) = Config::varZ;
168  }
169 
170  MPlexQF initPhi;
171  MPlexQI xtou; // bool to determine "split space", i.e. map x to u or v
172 #pragma omp simd
173  for (int n = 0; n < N; ++n) {
174  initPhi.At(n, 0, 0) = std::abs(getPhi(x.constAt(n, 0, 0), y.constAt(n, 0, 0)));
175  xtou.At(n, 0, 0) =
176  ((initPhi.constAt(n, 0, 0) < Const::PIOver4 || initPhi.constAt(n, 0, 0) > Const::PI3Over4) ? 1 : 0);
177  }
178 
179  MPlexHV u, v;
180 #pragma omp simd
181  for (int n = 0; n < N; ++n) {
182  if (xtou.At(n, 0, 0)) // x mapped to u
183  {
184  for (int i = 0; i < 3; ++i) {
185  u.At(n, i, 0) = x.constAt(n, i, 0) / r2.constAt(n, i, 0);
186  v.At(n, i, 0) = y.constAt(n, i, 0) / r2.constAt(n, i, 0);
187  }
188  } else // x mapped to v
189  {
190  for (int i = 0; i < 3; ++i) {
191  u.At(n, i, 0) = y.constAt(n, i, 0) / r2.constAt(n, i, 0);
192  v.At(n, i, 0) = x.constAt(n, i, 0) / r2.constAt(n, i, 0);
193  }
194  }
195  }
196 
197  MPlexHH A;
198  //#pragma omp simd // triggers an internal compiler error with icc 18.0.2!
199  for (int n = 0; n < N; ++n) {
200  for (int i = 0; i < 3; ++i) {
201  A.At(n, i, 0) = 1.0f;
202  A.At(n, i, 1) = -u.constAt(n, i, 0);
203  A.At(n, i, 2) = -u.constAt(n, i, 0) * u.constAt(n, i, 0);
204  }
205  }
207  MPlexHV C;
208  CFMap(A, v, C);
209 
210  MPlexQF a, b;
211 #pragma omp simd
212  for (int n = 0; n < N; ++n) {
213  b.At(n, 0, 0) = 1.0f / (2.0f * C.constAt(n, 0, 0));
214  a.At(n, 0, 0) = b.constAt(n, 0, 0) * C.constAt(n, 1, 0);
215  }
216 
217  // constant used throughtout
218  const float k = (Const::sol * Config::Bfield) / 100.0f;
219 
220  MPlexQF vrx, vry, pT, px, py, pz;
221 #pragma omp simd
222  for (int n = 0; n < N; ++n) {
223  vrx.At(n, 0, 0) =
224  (xtou.constAt(n, 0, 0) ? x.constAt(n, 0, 0) - a.constAt(n, 0, 0) : x.constAt(n, 0, 0) - b.constAt(n, 0, 0));
225  vry.At(n, 0, 0) =
226  (xtou.constAt(n, 0, 0) ? y.constAt(n, 0, 0) - b.constAt(n, 0, 0) : y.constAt(n, 0, 0) - a.constAt(n, 0, 0));
227  pT.At(n, 0, 0) = k * hipo(vrx.constAt(n, 0, 0), vry.constAt(n, 0, 0));
228  px.At(n, 0, 0) = std::copysign(k * vry.constAt(n, 0, 0), x.constAt(n, 2, 0) - x.constAt(n, 0, 0));
229  py.At(n, 0, 0) = std::copysign(k * vrx.constAt(n, 0, 0), y.constAt(n, 2, 0) - y.constAt(n, 0, 0));
230  pz.At(n, 0, 0) = (pT.constAt(n, 0, 0) * (z.constAt(n, 2, 0) - z.constAt(n, 0, 0))) /
231  hipo((x.constAt(n, 2, 0) - x.constAt(n, 0, 0)), (y.constAt(n, 2, 0) - y.constAt(n, 0, 0)));
232  }
233 
234 #pragma omp simd
235  for (int n = 0; n < N; ++n) {
236  outPar.At(n, 3, 0) = 1.0f / pT.constAt(n, 0, 0);
237  outPar.At(n, 4, 0) = getPhi(px.constAt(n, 0, 0), py.constAt(n, 0, 0));
238  outPar.At(n, 5, 0) = getTheta(pT.constAt(n, 0, 0), pz.constAt(n, 0, 0));
239 #ifdef INWARDFIT // arctan is odd, so pz -> -pz means theta -> -theta
240  if (fitting)
241  outPar.At(n, 5, 0) *= -1.0f;
242 #endif
243  }
244 
245 #pragma omp simd
246  for (int n = 0; n < N; ++n) {
247  outErr.At(n, 3, 3) =
249  outErr.At(n, 4, 4) = (fitting ? Config::phierr049 * Config::phierr049 : Config::phierr012 * Config::phierr012);
250  outErr.At(n, 5, 5) =
252  }
253 
254  if (debug && g_debug) {
255  for (int n = 0; n < N; ++n) {
256  dprintf("afterCF seedID: %1u \n", seedID.constAt(n, 0, 0));
257  // do a dumb copy out
258  TrackState updatedState;
259  for (int i = 0; i < 6; i++) {
260  updatedState.parameters[i] = outPar.constAt(n, i, 0);
261  for (int j = 0; j < 6; j++) {
262  updatedState.errors[i][j] = outErr.constAt(n, i, j);
263  }
264  }
265 
266  dcall(print("CCS", updatedState));
267  updatedState.convertFromCCSToCartesian();
268  dcall(print("Pol", updatedState));
269  dprint("--------------------------------");
270  }
271  }
272  }
273 
274 } // end namespace mkfit
Matriplex::Matriplex< float, HH, HH, NN > MPlexHH
Definition: Matrix.h:52
Definition: APVGainStruct.h:7
void conformalFitMPlex(bool fitting, MPlexQI seedID, MPlexLS &outErr, MPlexLV &outPar, const MPlexHV &msPar0, const MPlexHV &msPar1, const MPlexHV &msPar2)
Matriplex::Matriplex< float, HH, 1, NN > MPlexHV
Definition: Matrix.h:53
float getTheta(float r, float z)
Definition: Hit.h:36
Matriplex::Matriplex< float, LL, 1, NN > MPlexLV
Definition: Matrix.h:49
constexpr float phierr012
constexpr float thetaerr049
#define dcall(x)
Definition: Debug.h:97
bool g_debug
Definition: Debug.cc:2
constexpr float varZ
constexpr float varR
constexpr Matriplex::idx_t NN
Definition: Matrix.h:43
constexpr float Bfield
Definition: Config.h:55
float getRad2(float x, float y)
Definition: Hit.h:30
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
constexpr float ptinverr049
double f[11][100]
Matriplex::Matriplex< int, 1, 1, NN > MPlexQI
Definition: Matrix.h:72
constexpr float thetaerr012
#define debug
Definition: HDRShower.cc:19
constexpr float sol
Definition: Config.h:13
Matriplex::Matriplex< float, 1, 1, NN > MPlexQF
Definition: Matrix.h:71
#define N
Definition: blowfish.cc:9
void invertCramer(MPlex< T, D, D, N > &A, double *determ=nullptr)
Definition: Matriplex.h:730
float hipo(float x, float y)
Definition: Matrix.h:9
SVector6 parameters
Definition: Track.h:48
void print(std::string_view label, const MeasurementState &s)
Definition: Hit.cc:8
double b
Definition: hdecay.h:120
float getPhi(float x, float y)
Definition: Hit.h:34
#define dprint(x)
Definition: Debug.h:95
constexpr float varXY
double a
Definition: hdecay.h:121
constexpr float phierr049
void CFMap(const MPlexHH &A, const MPlexHV &B, MPlexHV &C)
Matriplex::MatriplexSym< float, LL, NN > MPlexLS
Definition: Matrix.h:50
float x
Definition: APVGainStruct.h:7
constexpr float PI3Over4
Definition: Config.h:11
constexpr float ptinverr012
long double T
#define ASSUME_ALIGNED(a, b)
#define dprintf(...)
Definition: Debug.h:98
constexpr float PIOver4
Definition: Config.h:10