CMS 3D CMS Logo

MkFitter.cc
Go to the documentation of this file.
1 #include "MkFitter.h"
2 
3 #include "KalmanUtilsMPlex.h"
4 #include "MatriplexPackers.h"
5 
6 //#define DEBUG
7 #include "Debug.h"
8 
9 #include <sstream>
10 
11 namespace mkfit {
12 
14  printf("MkFitter alignment check:\n");
15  Matriplex::align_check(" m_Err[0] =", &m_Err[0].fArray[0]);
16  Matriplex::align_check(" m_Err[1] =", &m_Err[1].fArray[0]);
17  Matriplex::align_check(" m_Par[0] =", &m_Par[0].fArray[0]);
18  Matriplex::align_check(" m_Par[1] =", &m_Par[1].fArray[0]);
19  Matriplex::align_check(" m_msErr[0] =", &m_msErr[0].fArray[0]);
20  Matriplex::align_check(" m_msPar[0] =", &m_msPar[0].fArray[0]);
21  }
22 
23  void MkFitter::printPt(int idx) {
24  for (int i = 0; i < NN; ++i) {
25  printf("%5.2f ", std::hypot(m_Par[idx].At(i, 3, 0), m_Par[idx].At(i, 4, 0)));
26  }
27  }
28 
29  int MkFitter::countValidHits(int itrack, int end_hit) const {
30  int result = 0;
31  for (int hi = 0; hi < end_hit; ++hi) {
32  if (m_HoTArr[hi](itrack, 0, 0).index >= 0)
33  result++;
34  }
35  return result;
36  }
37 
38  int MkFitter::countInvalidHits(int itrack, int end_hit) const {
39  int result = 0;
40  for (int hi = 0; hi < end_hit; ++hi) {
41  // XXXX MT: Should also count -2 hits as invalid?
42  if (m_HoTArr[hi](itrack, 0, 0).index == -1)
43  result++;
44  }
45  return result;
46  }
47 
48  //==============================================================================
49 
50  void MkFitter::inputTracksAndHits(const std::vector<Track>& tracks,
51  const std::vector<HitVec>& layerHits,
52  int beg,
53  int end) {
54  // Assign track parameters to initial state and copy hit values in.
55 
56  // This might not be true for the last chunk!
57  // assert(end - beg == NN);
58 
59  int itrack = 0;
60 
61  for (int i = beg; i < end; ++i, ++itrack) {
62  const Track& trk = tracks[i];
63 
64  m_Err[iC].copyIn(itrack, trk.errors().Array());
65  m_Par[iC].copyIn(itrack, trk.parameters().Array());
66 
67  m_Chg(itrack, 0, 0) = trk.charge();
68  m_Chi2(itrack, 0, 0) = trk.chi2();
69  m_Label(itrack, 0, 0) = trk.label();
70 
71  // CopyIn seems fast enough, but indirections are quite slow.
72  for (int hi = 0; hi < m_Nhits; ++hi) {
73  m_HoTArr[hi](itrack, 0, 0) = trk.getHitOnTrack(hi);
74 
75  const int hidx = trk.getHitIdx(hi);
76  if (hidx < 0)
77  continue;
78 
79  const Hit& hit = layerHits[hi][hidx];
80  m_msErr[hi].copyIn(itrack, hit.errArray());
81  m_msPar[hi].copyIn(itrack, hit.posArray());
82  }
83  }
84  }
85 
86  void MkFitter::inputTracksAndHits(const std::vector<Track>& tracks,
87  const std::vector<LayerOfHits>& layerHits,
88  int beg,
89  int end) {
90  // Assign track parameters to initial state and copy hit values in.
91 
92  // This might not be true for the last chunk!
93  // assert(end - beg == NN);
94 
95  int itrack;
96 
97  for (int i = beg; i < end; ++i) {
98  itrack = i - beg;
99  const Track& trk = tracks[i];
100 
101  m_Label(itrack, 0, 0) = trk.label();
102 
103  m_Err[iC].copyIn(itrack, trk.errors().Array());
104  m_Par[iC].copyIn(itrack, trk.parameters().Array());
105 
106  m_Chg(itrack, 0, 0) = trk.charge();
107  m_Chi2(itrack, 0, 0) = trk.chi2();
108 
109  // CopyIn seems fast enough, but indirections are quite slow.
110  for (int hi = 0; hi < m_Nhits; ++hi) {
111  const int hidx = trk.getHitIdx(hi);
112  const int hlyr = trk.getHitLyr(hi);
113  const Hit& hit = layerHits[hlyr].refHit(hidx);
114 
115  m_msErr[hi].copyIn(itrack, hit.errArray());
116  m_msPar[hi].copyIn(itrack, hit.posArray());
117 
118  m_HoTArr[hi](itrack, 0, 0) = trk.getHitOnTrack(hi);
119  }
120  }
121  }
122 
123  void MkFitter::slurpInTracksAndHits(const std::vector<Track>& tracks,
124  const std::vector<HitVec>& layerHits,
125  int beg,
126  int end) {
127  // Assign track parameters to initial state and copy hit values in.
128 
129  // This might not be true for the last chunk!
130  // assert(end - beg == NN);
131 
132  MatriplexTrackPacker mtp(&tracks[beg]);
133 
134  for (int i = beg; i < end; ++i) {
135  int itrack = i - beg;
136  const Track& trk = tracks[i];
137 
138  m_Label(itrack, 0, 0) = trk.label();
139 
140  mtp.addInput(trk);
141 
142  m_Chg(itrack, 0, 0) = trk.charge();
143  m_Chi2(itrack, 0, 0) = trk.chi2();
144  }
145 
146  mtp.pack(m_Err[iC], m_Par[iC]);
147 
148  // CopyIn seems fast enough, but indirections are quite slow.
149  for (int hi = 0; hi < m_Nhits; ++hi) {
150  MatriplexHitPacker mhp(layerHits[hi].data());
151 
152  for (int i = beg; i < end; ++i) {
153  const int hidx = tracks[i].getHitIdx(hi);
154  const Hit& hit = layerHits[hi][hidx];
155 
156  m_HoTArr[hi](i - beg, 0, 0) = tracks[i].getHitOnTrack(hi);
157 
158  mhp.addInput(hit);
159  }
160 
161  mhp.pack(m_msErr[hi], m_msPar[hi]);
162  }
163  }
164 
165  void MkFitter::inputTracksAndHitIdx(const std::vector<Track>& tracks, int beg, int end, bool inputProp) {
166  // Assign track parameters to initial state and copy hit values in.
167 
168  // This might not be true for the last chunk!
169  // assert(end - beg == NN);
170 
171  const int iI = inputProp ? iP : iC;
172 
173  int itrack = 0;
174  for (int i = beg; i < end; ++i, ++itrack) {
175  const Track& trk = tracks[i];
176 
177  m_Err[iI].copyIn(itrack, trk.errors().Array());
178  m_Par[iI].copyIn(itrack, trk.parameters().Array());
179 
180  m_Chg(itrack, 0, 0) = trk.charge();
181  m_Chi2(itrack, 0, 0) = trk.chi2();
182  m_Label(itrack, 0, 0) = trk.label();
183 
184  for (int hi = 0; hi < m_Nhits; ++hi) {
185  m_HoTArr[hi](itrack, 0, 0) = trk.getHitOnTrack(hi);
186  }
187  }
188  }
189 
190  void MkFitter::inputTracksAndHitIdx(const std::vector<std::vector<Track> >& tracks,
191  const std::vector<std::pair<int, int> >& idxs,
192  int beg,
193  int end,
194  bool inputProp) {
195  // Assign track parameters to initial state and copy hit values in.
196 
197  // This might not be true for the last chunk!
198  // assert(end - beg == NN);
199 
200  const int iI = inputProp ? iP : iC;
201 
202  int itrack = 0;
203  for (int i = beg; i < end; ++i, ++itrack) {
204  const Track& trk = tracks[idxs[i].first][idxs[i].second];
205 
206  m_Label(itrack, 0, 0) = trk.label();
207  m_SeedIdx(itrack, 0, 0) = idxs[i].first;
208  m_CandIdx(itrack, 0, 0) = idxs[i].second;
209 
210  m_Err[iI].copyIn(itrack, trk.errors().Array());
211  m_Par[iI].copyIn(itrack, trk.parameters().Array());
212 
213  m_Chg(itrack, 0, 0) = trk.charge();
214  m_Chi2(itrack, 0, 0) = trk.chi2();
215 
216  for (int hi = 0; hi < m_Nhits; ++hi) {
217  m_HoTArr[hi](itrack, 0, 0) = trk.getHitOnTrack(hi);
218  }
219  }
220  }
221 
222  void MkFitter::inputSeedsTracksAndHits(const std::vector<Track>& seeds,
223  const std::vector<Track>& tracks,
224  const std::vector<HitVec>& layerHits,
225  int beg,
226  int end) {
227  // Assign track parameters to initial state and copy hit values in.
228 
229  // This might not be true for the last chunk!
230  // assert(end - beg == NN);
231 
232  int itrack;
233  for (int i = beg; i < end; ++i) {
234  itrack = i - beg;
235 
236  const Track& see = seeds[i];
237 
238  m_Label(itrack, 0, 0) = see.label();
239  if (see.label() < 0)
240  continue;
241 
242  m_Err[iC].copyIn(itrack, see.errors().Array());
243  m_Par[iC].copyIn(itrack, see.parameters().Array());
244 
245  m_Chg(itrack, 0, 0) = see.charge();
246  m_Chi2(itrack, 0, 0) = see.chi2();
247 
248  const Track& trk = tracks[see.label()];
249 
250  // CopyIn seems fast enough, but indirections are quite slow.
251  for (int hi = 0; hi < m_Nhits; ++hi) {
252  m_HoTArr[hi](itrack, 0, 0) = trk.getHitOnTrack(hi);
253 
254  const int hidx = trk.getHitIdx(hi);
255  if (hidx < 0)
256  continue; //fixme, check if this is harmless
257 
258  const Hit& hit = layerHits[hi][hidx];
259  m_msErr[hi].copyIn(itrack, hit.errArray());
260  m_msPar[hi].copyIn(itrack, hit.posArray());
261  }
262  }
263  }
264 
265  //------------------------------------------------------------------------------
266  // Fitting with interleaved hit loading
267  //------------------------------------------------------------------------------
268 
269  void MkFitter::inputTracksForFit(const std::vector<Track>& tracks, int beg, int end) {
270  // Loads track parameters and hit indices.
271 
272  // XXXXMT4K has Config::nLayers: How many hits do we read in?
273  // Check for max? Expect an argument?
274  // What to do with invalid hits? Skip?
275 
276  // XXXX MT Here the same idx array WAS used for slurping in of tracks and
277  // hots. With this, two index arrays are built, one within each packer.
278 
279  MatriplexTrackPacker mtp(&tracks[beg]);
280  MatriplexHoTPacker mhotp(tracks[beg].getHitsOnTrackArray());
281 
282  int itrack = 0;
283 
284  for (int i = beg; i < end; ++i, ++itrack) {
285  const Track& trk = tracks[i];
286 
287  m_Chg(itrack, 0, 0) = trk.charge();
288  m_Chi2(itrack, 0, 0) = trk.chi2();
289  m_Label(itrack, 0, 0) = trk.label();
290 
291  mtp.addInput(trk);
292 
293  mhotp.addInput(*trk.getHitsOnTrackArray());
294  }
295 
296  mtp.pack(m_Err[iC], m_Par[iC]);
297  for (int ll = 0; ll < Config::nLayers; ++ll) {
298  mhotp.pack(m_HoTArr[ll], ll);
299  }
300  }
301 
302  void MkFitter::fitTracksWithInterSlurp(const std::vector<HitVec>& layersohits,
303  const PropagationFlags& pflags,
304  const int N_proc) {
305  // XXXX This has potential issues hits coming from different layers!
306  // Expected to only work reliably with barrel (consecutive layers from 0 -> m_Nhits)
307  // and with hits present on every layer for every track.
308 
309  // Loops over layers and:
310  // a) slurps in hit parameters;
311  // b) propagates and updates tracks
312 
313  for (int ii = 0; ii < m_Nhits; ++ii) {
314  // XXXX Assuming hit index corresponds to layer!
315  MatriplexHitPacker mhp(layersohits[ii].data());
316 
317  for (int i = 0; i < N_proc; ++i) {
318  const int hidx = m_HoTArr[ii](i, 0, 0).index;
319  const int hlyr = m_HoTArr[ii](i, 0, 0).layer;
320 
321  // XXXXMT4K What to do with hidx < 0 ????
322  // This could solve the unbalanced fit.
323  // Or, if the hidx is the "universal" missing hit, it could just work.
324  // Say, hidx = 0 ... grr ... but then we don't know it is missing.
325 
326  if (hidx < 0 || hlyr < 0) {
327  mhp.addNullInput();
328  } else {
329  mhp.addInput(layersohits[hlyr][hidx]);
330  }
331  }
332 
333  mhp.pack(m_msErr[0], m_msPar[0]);
334 
335  propagateTracksToHitR(m_msPar[0], N_proc, pflags);
336 
337  kalmanUpdate(m_Err[iP], m_Par[iP], m_msErr[0], m_msPar[0], m_Err[iC], m_Par[iC], N_proc);
338  }
339  }
340 
341  //==============================================================================
342  // Fitting functions
343  //==============================================================================
344 
345  void MkFitter::outputTracks(std::vector<Track>& tracks, int beg, int end, int iCP) const {
346  // Copies last track parameters (updated) into Track objects.
347  // The tracks vector should be resized to allow direct copying.
348 
349  int itrack = 0;
350  for (int i = beg; i < end; ++i, ++itrack) {
351  m_Err[iCP].copyOut(itrack, tracks[i].errors_nc().Array());
352  m_Par[iCP].copyOut(itrack, tracks[i].parameters_nc().Array());
353 
354  tracks[i].setCharge(m_Chg(itrack, 0, 0));
355 
356  // XXXXX chi2 is not set (also not in SMatrix fit, it seems)
357  tracks[i].setChi2(m_Chi2(itrack, 0, 0));
358  tracks[i].setLabel(m_Label(itrack, 0, 0));
359  }
360  }
361 
362  void MkFitter::outputFittedTracksAndHitIdx(std::vector<Track>& tracks, int beg, int end, bool outputProp) const {
363  // Copies last track parameters (updated) into Track objects and up to m_Nhits.
364  // The tracks vector should be resized to allow direct copying.
365 
366  const int iO = outputProp ? iP : iC;
367 
368  int itrack = 0;
369  for (int i = beg; i < end; ++i, ++itrack) {
370  m_Err[iO].copyOut(itrack, tracks[i].errors_nc().Array());
371  m_Par[iO].copyOut(itrack, tracks[i].parameters_nc().Array());
372 
373  tracks[i].setCharge(m_Chg(itrack, 0, 0));
374  tracks[i].setChi2(m_Chi2(itrack, 0, 0));
375  tracks[i].setLabel(m_Label(itrack, 0, 0));
376 
377  // QQQQ Could do resize and std::copy, as in MkFinder::copy_out(), but
378  // we do not know the correct N_found_hits.
379  tracks[i].resetHits();
380  tracks[i].reserveHits(m_Nhits);
381  for (int hi = 0; hi < m_Nhits; ++hi) {
382  tracks[i].addHitIdx(m_HoTArr[hi](itrack, 0, 0), 0.);
383  }
384  }
385  }
386 
387 } // end namespace mkfit
int getHitIdx(int posHitIdx) const
Definition: Track.h:450
MPlexQI m_Chg
Definition: MkBase.h:103
static constexpr int iC
Definition: MkBase.h:18
int getHitLyr(int posHitIdx) const
Definition: Track.h:451
const SVector6 & parameters() const
Definition: Track.h:132
MPlex< T, D1, D2, N > hypot(const MPlex< T, D1, D2, N > &a, const MPlex< T, D1, D2, N > &b)
Definition: Matriplex.h:436
int charge() const
Definition: Track.h:171
void addInput(const D &item)
void checkAlignment()
Definition: MkFitter.cc:13
static constexpr int iP
Definition: MkBase.h:19
void outputTracks(std::vector< Track > &tracks, int beg, int end, int iCP) const
Definition: MkFitter.cc:345
MPlexHV m_msPar[Config::nMaxTrkHits]
Definition: MkFitter.h:76
void kalmanUpdate(const MPlexLS &psErr, const MPlexLV &psPar, const MPlexHS &msErr, const MPlexHV &msPar, MPlexLS &outErr, MPlexLV &outPar, const int N_proc)
float chi2() const
Definition: Track.h:172
MPlexLV m_Par[2]
Definition: MkBase.h:102
int label() const
Definition: Track.h:174
int countInvalidHits(int itrack, int end_hit) const
Definition: MkFitter.cc:38
void inputSeedsTracksAndHits(const std::vector< Track > &seeds, const std::vector< Track > &tracks, const std::vector< HitVec > &layerHits, int beg, int end)
Definition: MkFitter.cc:222
void fitTracksWithInterSlurp(const std::vector< HitVec > &layersohits, const PropagationFlags &pflags, int N_proc)
Definition: MkFitter.cc:302
void inputTracksAndHitIdx(const std::vector< Track > &tracks, int beg, int end, bool inputProp)
Definition: MkFitter.cc:165
const SMatrixSym66 & errors() const
Definition: Track.h:133
void inputTracksForFit(const std::vector< Track > &tracks, int beg, int end)
Definition: MkFitter.cc:269
MPlexLS m_Err[2]
Definition: MkBase.h:101
constexpr int nLayers
Definition: Config.h:38
void slurpInTracksAndHits(const std::vector< Track > &tracks, const std::vector< HitVec > &layerHits, int beg, int end)
Definition: MkFitter.cc:123
void align_check(const char *pref, void *adr)
void outputFittedTracksAndHitIdx(std::vector< Track > &tracks, int beg, int end, bool outputProp) const
Definition: MkFitter.cc:362
Definition: EPCuts.h:4
MPlexQI m_SeedIdx
Definition: MkFitter.h:79
void pack(TM &mplex, int base_offset)
constexpr Matriplex::idx_t NN
Definition: Matrix.h:43
void propagateTracksToHitR(const MPlexHV &par, const int N_proc, const PropagationFlags &pf, const MPlexQI *noMatEffPtr=nullptr)
Definition: MkBase.h:42
const HitOnTrack * getHitsOnTrackArray() const
Definition: Track.h:493
ii
Definition: cuy.py:589
int countValidHits(int itrack, int end_hit) const
Definition: MkFitter.cc:29
portabletest::Array Array
MPlexQI m_Label
Definition: MkFitter.h:78
void pack(TMerr &err, TMpar &par)
MPlexQHoT m_HoTArr[Config::nMaxTrkHits]
Definition: MkFitter.h:82
char data[epos_bytes_allocation]
Definition: EPOS_Wrapper.h:80
MPlexQF m_Chi2
Definition: MkFitter.h:73
MPlexQI m_CandIdx
Definition: MkFitter.h:80
void printPt(int idx)
Definition: MkFitter.cc:23
MPlexHS m_msErr[Config::nMaxTrkHits]
Definition: MkFitter.h:75
void inputTracksAndHits(const std::vector< Track > &tracks, const std::vector< HitVec > &layerHits, int beg, int end)
Definition: MkFitter.cc:50
HitOnTrack getHitOnTrack(int posHitIdx) const
Definition: Track.h:448