CMS 3D CMS Logo

GhostTrackVertexFinder.cc
Go to the documentation of this file.
1 #include <algorithm>
2 #include <iterator>
3 #include <memory>
4 
5 #include <map>
6 #include <set>
7 #include <vector>
8 
9 #include <Math/SVector.h>
10 #include <Math/SMatrix.h>
11 #include <Math/MatrixFunctions.h>
12 
16 
18 
25 
39 
46 
48 
50 
51 // #define DEBUG
52 
53 #ifdef DEBUG
55 #endif
56 
57 using namespace reco;
58 
59 namespace {
60  using namespace ROOT::Math;
61 
62  typedef SVector<double, 3> Vector3;
63 
64  typedef SMatrix<double, 3, 3, MatRepSym<double, 3> > Matrix3S;
65  typedef SMatrix<double, 2, 2, MatRepSym<double, 2> > Matrix2S;
66  typedef SMatrix<double, 2, 3> Matrix23;
67 
68  typedef ReferenceCountingPointer<VertexTrack<5> > RefCountedVertexTrack;
69  typedef ReferenceCountingPointer<LinearizedTrackState<5> > RefCountedLinearizedTrackState;
70 
71  struct VtxTrackIs {
72  VtxTrackIs(const TransientTrack &track) : track(track) {}
73  bool operator()(const RefCountedVertexTrack &vtxTrack) const {
74  return vtxTrack->linearizedTrack()->track() == track;
75  }
76 
77  const TransientTrack &track;
78  };
79 
80  inline Vector3 conv(const GlobalVector &vec) {
81  Vector3 result;
82  result[0] = vec.x();
83  result[1] = vec.y();
84  result[2] = vec.z();
85  return result;
86  }
87 
88  inline double sqr(double arg) { return arg * arg; }
89 } // namespace
90 
93  const GhostTrack &ghostTrack,
94  const BeamSpot &beamSpot,
95  bool hasBeamSpot,
96  bool hasPrimaries)
98  pred(ghostTrack.prediction()),
104  field(nullptr) {}
105 
109  std::vector<GhostTrackState> states;
115 };
116 
118  return TransientTrackFromFTSFactory().build(pred.fts(field));
119 }
120 
121 static double vtxErrorLong(const GlobalError &error, const GlobalVector &dir) {
122  return ROOT::Math::Similarity(conv(dir), error.matrix());
123 }
124 
125 static GlobalPoint vtxMean(const GlobalPoint &p1, const GlobalError &e1, const GlobalPoint &p2, const GlobalError &e2) {
126  GlobalVector diff = p2 - p1;
127 
128  if UNLIKELY (p1 == p2) {
129  edm::LogWarning("GhostTrackVertexFinder") << "Averaging with self at " << p1;
130  return p1;
131  }
132 
133  double err1 = vtxErrorLong(e1, diff);
134  double err2 = vtxErrorLong(e2, diff);
135 
136  double weight = err1 / (err1 + err2);
137 
138  return p1 + weight * diff;
139 }
140 
141 static VertexState stateMean(const VertexState &v1, const VertexState &v2) {
142  return VertexState(vtxMean(v1.position(), v1.error(), v2.position(), v2.error()), v1.error() + v2.error());
143 }
144 
145 static bool covarianceUpdate(
146  Matrix3S &cov, const Vector3 &residual, const Matrix3S &error, double &chi2, double theta, double phi) {
147  using namespace ROOT::Math;
148 
149  Matrix23 jacobian;
150  jacobian(0, 0) = std::cos(phi) * std::cos(theta);
151  jacobian(0, 1) = std::sin(phi) * std::cos(theta);
152  jacobian(0, 2) = -std::sin(theta);
153  jacobian(1, 0) = -std::sin(phi);
154  jacobian(1, 1) = std::cos(phi);
155 
156  Matrix2S measErr = Similarity(jacobian, error);
157  Matrix2S combErr = Similarity(jacobian, cov) + measErr;
158  if (!measErr.Invert() || !combErr.Invert())
159  return false;
160 
161  cov -= SimilarityT(jacobian * cov, combErr);
162  chi2 += Similarity(jacobian * residual, measErr);
163 
164  return true;
165 }
166 
168  const GhostTrackPrediction &pred,
169  const GhostTrackState &state) {
170  LinearizedTrackStateFactory linTrackFactory;
171  VertexTrackFactory<5> vertexTrackFactory;
172 
173  if (!state.isValid())
174  return CachingVertex<5>();
175 
176  GlobalPoint pca1 = pred.position(state.lambda());
177  GlobalError err1 = pred.positionError(state.lambda());
178 
179  GlobalPoint pca2 = state.globalPosition();
180  GlobalError err2 = state.cartesianError();
181 
182  GlobalPoint point = vtxMean(pca1, err1, pca2, err2);
183 
184  const TransientTrack &recTrack = state.track();
185 
186  RefCountedLinearizedTrackState linState[2] = {linTrackFactory.linearizedTrackState(point, ghostTrack),
187  linTrackFactory.linearizedTrackState(point, recTrack)};
188  if (!linState[0]->isValid() || !linState[1]->isValid())
189  return CachingVertex<5>();
190 
191  Matrix3S cov = SMatrixIdentity();
192  cov *= 10000;
193  double chi2 = 0.;
194  if (!covarianceUpdate(cov,
195  conv(pca1 - point),
196  err1.matrix(),
197  chi2,
198  linState[0]->predictedStateParameters()[1],
199  linState[0]->predictedStateParameters()[2]) ||
200  !covarianceUpdate(cov,
201  conv(pca2 - point),
202  err2.matrix(),
203  chi2,
204  linState[1]->predictedStateParameters()[1],
205  linState[1]->predictedStateParameters()[2]))
206  return CachingVertex<5>();
207 
208  GlobalError error(cov);
209  VertexState vtxState(point, error);
210 
211  std::vector<RefCountedVertexTrack> linTracks(2);
212  linTracks[0] = vertexTrackFactory.vertexTrack(linState[0], vtxState);
213  linTracks[1] = vertexTrackFactory.vertexTrack(linState[1], vtxState);
214 
215  return CachingVertex<5>(point, error, linTracks, chi2);
216 }
217 
218 static RefCountedVertexTrack relinearizeTrack(const RefCountedVertexTrack &track,
219  const VertexState &state,
220  const VertexTrackFactory<5> factory) {
221  RefCountedLinearizedTrackState linTrack = track->linearizedTrack();
222  linTrack = linTrack->stateWithNewLinearizationPoint(state.position());
223  return factory.vertexTrack(linTrack, state);
224 }
225 
226 static std::vector<RefCountedVertexTrack> relinearizeTracks(const std::vector<RefCountedVertexTrack> &tracks,
227  const VertexState &state) {
228  VertexTrackFactory<5> vertexTrackFactory;
229 
230  std::vector<RefCountedVertexTrack> finalTracks;
231  finalTracks.reserve(tracks.size());
232 
233  for (std::vector<RefCountedVertexTrack>::const_iterator iter = tracks.begin(); iter != tracks.end(); ++iter)
234  finalTracks.push_back(relinearizeTrack(*iter, state, vertexTrackFactory));
235 
236  return finalTracks;
237 }
238 
240  const CachingVertex<5> &vtx1, const CachingVertex<5> &vtx2, const FinderInfo &info, double scale1, double scale2) {
241  Vector3 diff = conv(vtx2.position() - vtx1.position());
242  Matrix3S cov = scale1 * vtx1.error().matrix() + scale2 * vtx2.error().matrix();
243 
244  return sqr(ROOT::Math::Dot(diff, diff)) / ROOT::Math::Similarity(cov, diff);
245 }
246 
247 static double trackVertexCompat(const CachingVertex<5> &vtx, const RefCountedVertexTrack &vertexTrack) {
248  using namespace ROOT::Math;
249 
250  TransientTrack track = vertexTrack->linearizedTrack()->track();
251  GlobalPoint point = vtx.position();
253  TrajectoryStateOnSurface tsos = extrap.extrapolate(track.impactPointState(), point);
254 
255  if (!tsos.isValid())
256  return 1.0e6;
257 
258  GlobalPoint point1 = vtx.position();
259  GlobalPoint point2 = tsos.globalPosition();
260  Vector3 dir = conv(point2 - point1);
261  Matrix3S error = vtx.error().matrix() + tsos.cartesianError().matrix().Sub<Matrix3S>(0, 0);
262  if (!error.Invert())
263  return 1.0e6;
264 
265  return ROOT::Math::Similarity(error, dir);
266 }
267 
269  : maxFitChi2_(10.0), mergeThreshold_(3.0), primcut_(2.0), seccut_(5.0), fitType_(kAlwaysWithGhostTrack) {}
270 
272  double maxFitChi2, double mergeThreshold, double primcut, double seccut, FitType fitType)
273  : maxFitChi2_(maxFitChi2), mergeThreshold_(mergeThreshold), primcut_(primcut), seccut_(seccut), fitType_(fitType) {}
274 
276 
278  if (!ghostTrackFitter_.get())
279  ghostTrackFitter_ = std::make_unique<GhostTrackFitter>();
280 
281  return *ghostTrackFitter_;
282 }
283 
285  std::unique_ptr<VertexFitter<5> > *ptr = primary ? &primVertexFitter_ : &secVertexFitter_;
286  if (!ptr->get())
287  *ptr = std::make_unique<AdaptiveVertexFitter>(GeometricAnnealing(primary ? primcut_ : seccut_));
288 
289  return **ptr;
290 }
291 
292 #ifdef DEBUG
293 static void debugTrack(const TransientTrack &track, const TransientVertex *vtx = 0) {
294  const FreeTrajectoryState &fts = track.initialFreeState();
295  GlobalVector mom = fts.momentum();
296  std::cout << "\tpt = " << mom.perp() << ", eta = " << mom.eta() << ", phi = " << mom.phi()
297  << ", charge = " << fts.charge();
298  if (vtx && vtx->hasTrackWeight())
299  std::cout << ", w = " << vtx->trackWeight(track) << std::endl;
300  else
301  std::cout << std::endl;
302 }
303 
304 static void debugTracks(const std::vector<TransientTrack> &tracks, const TransientVertex *vtx = 0) {
305  TrackKinematics kin;
306  for (std::vector<TransientTrack>::const_iterator iter = tracks.begin(); iter != tracks.end(); ++iter) {
307  debugTrack(*iter, vtx);
308  try {
309  TrackBaseRef track = iter->trackBaseRef();
310  kin.add(*track);
311  } catch (exception const &e) {
312  // ignore, yeah this is debugging, so shut up ^^
313  }
314  }
315 
316  std::cout << "mass = " << kin.vectorSum().M() << std::endl;
317 }
318 
319 static void debugTracks(const std::vector<RefCountedVertexTrack> &tracks) {
320  std::vector<TransientTrack> tracks_;
321  for (std::vector<RefCountedVertexTrack>::const_iterator iter = tracks.begin(); iter != tracks.end(); ++iter) {
322  std::cout << "+ " << (*iter)->linearizedTrack()->linearizationPoint() << std::endl;
323  tracks_.push_back((*iter)->linearizedTrack()->track());
324  }
325  debugTracks(tracks_);
326 }
327 
328 static void debugVertex(const TransientVertex &vtx, const GhostTrackPrediction &pred) {
329  double origin = 0.;
330  std::cout << vtx.position() << "-> " << vtx.totalChiSquared() << " with " << vtx.degreesOfFreedom() << std::endl;
331 
332  double err = std::sqrt(vtxErrorLong(vtx.positionError(), pred.direction()) / pred.rho2());
333  std::cout << "* " << (pred.lambda(vtx.position()) * pred.rho() - origin) << " +-" << err << " => "
334  << ((pred.lambda(vtx.position()) * pred.rho() - origin) / err) << std::endl;
335 
336  std::vector<TransientTrack> tracks = vtx.originalTracks();
337  debugTracks(tracks, &vtx);
338 }
339 #endif
340 
341 std::vector<TransientVertex> GhostTrackVertexFinder::vertices(const Vertex &primaryVertex,
342  const GlobalVector &direction,
343  double coneRadius,
344  const std::vector<TransientTrack> &tracks) const {
345  return vertices(RecoVertex::convertPos(primaryVertex.position()),
347  direction,
348  coneRadius,
349  tracks);
350 }
351 
352 std::vector<TransientVertex> GhostTrackVertexFinder::vertices(const Vertex &primaryVertex,
353  const GlobalVector &direction,
354  double coneRadius,
355  const reco::BeamSpot &beamSpot,
356  const std::vector<TransientTrack> &tracks) const {
357  return vertices(RecoVertex::convertPos(primaryVertex.position()),
359  direction,
360  coneRadius,
361  beamSpot,
362  tracks);
363 }
364 
365 std::vector<TransientVertex> GhostTrackVertexFinder::vertices(const Vertex &primaryVertex,
366  const GlobalVector &direction,
367  double coneRadius,
368  const reco::BeamSpot &beamSpot,
369  const std::vector<TransientTrack> &primaries,
370  const std::vector<TransientTrack> &tracks) const {
371  return vertices(RecoVertex::convertPos(primaryVertex.position()),
373  direction,
374  coneRadius,
375  beamSpot,
376  primaries,
377  tracks);
378 }
379 
380 std::vector<TransientVertex> GhostTrackVertexFinder::vertices(const GlobalPoint &primaryPosition,
381  const GlobalError &primaryError,
382  const GlobalVector &direction,
383  double coneRadius,
384  const std::vector<TransientTrack> &tracks) const {
385  GhostTrack ghostTrack = ghostTrackFitter().fit(primaryPosition, primaryError, direction, coneRadius, tracks);
386 
387  CachingVertex<5> primary(primaryPosition, primaryError, std::vector<RefCountedVertexTrack>(), 0.);
388 
389  std::vector<TransientVertex> result = vertices(ghostTrack, primary);
390 
391 #ifdef DEBUG
392  for (std::vector<TransientVertex>::const_iterator iter = result.begin(); iter != result.end(); ++iter)
393  debugVertex(*iter, ghostTrack.prediction());
394 #endif
395 
396  return result;
397 }
398 
399 std::vector<TransientVertex> GhostTrackVertexFinder::vertices(const GlobalPoint &primaryPosition,
400  const GlobalError &primaryError,
401  const GlobalVector &direction,
402  double coneRadius,
403  const BeamSpot &beamSpot,
404  const std::vector<TransientTrack> &tracks) const {
405  GhostTrack ghostTrack = ghostTrackFitter().fit(primaryPosition, primaryError, direction, coneRadius, tracks);
406 
407  CachingVertex<5> primary(primaryPosition, primaryError, std::vector<RefCountedVertexTrack>(), 0.);
408 
409  std::vector<TransientVertex> result = vertices(ghostTrack, primary, beamSpot, true);
410 
411 #ifdef DEBUG
412  for (std::vector<TransientVertex>::const_iterator iter = result.begin(); iter != result.end(); ++iter)
413  debugVertex(*iter, ghostTrack.prediction());
414 #endif
415 
416  return result;
417 }
418 
419 std::vector<TransientVertex> GhostTrackVertexFinder::vertices(const GlobalPoint &primaryPosition,
420  const GlobalError &primaryError,
421  const GlobalVector &direction,
422  double coneRadius,
423  const BeamSpot &beamSpot,
424  const std::vector<TransientTrack> &primaries,
425  const std::vector<TransientTrack> &tracks) const {
426  GhostTrack ghostTrack = ghostTrackFitter().fit(primaryPosition, primaryError, direction, coneRadius, tracks);
427 
428  std::vector<RefCountedVertexTrack> primaryVertexTracks;
429  if (!primaries.empty()) {
430  LinearizedTrackStateFactory linTrackFactory;
431  VertexTrackFactory<5> vertexTrackFactory;
432 
433  VertexState state(primaryPosition, primaryError);
434 
435  for (std::vector<TransientTrack>::const_iterator iter = primaries.begin(); iter != primaries.end(); ++iter) {
436  RefCountedLinearizedTrackState linState = linTrackFactory.linearizedTrackState(primaryPosition, *iter);
437 
438  primaryVertexTracks.push_back(vertexTrackFactory.vertexTrack(linState, state));
439  }
440  }
441 
442  CachingVertex<5> primary(primaryPosition, primaryError, primaryVertexTracks, 0.);
443 
444  std::vector<TransientVertex> result = vertices(ghostTrack, primary, beamSpot, true, true);
445 
446 #ifdef DEBUG
447  for (std::vector<TransientVertex>::const_iterator iter = result.begin(); iter != result.end(); ++iter)
448  debugVertex(*iter, ghostTrack.prediction());
449 #endif
450 
451  return result;
452 }
453 
454 std::vector<TransientVertex> GhostTrackVertexFinder::vertices(const GlobalPoint &primaryPosition,
455  const GlobalError &primaryError,
456  const GhostTrack &ghostTrack) const {
457  CachingVertex<5> primary(primaryPosition, primaryError, std::vector<RefCountedVertexTrack>(), 0.);
458 
459  std::vector<TransientVertex> result = vertices(ghostTrack, primary);
460 
461 #ifdef DEBUG
462  for (std::vector<TransientVertex>::const_iterator iter = result.begin(); iter != result.end(); ++iter)
463  debugVertex(*iter, ghostTrack.prediction());
464 #endif
465 
466  return result;
467 }
468 
469 std::vector<TransientVertex> GhostTrackVertexFinder::vertices(const GlobalPoint &primaryPosition,
470  const GlobalError &primaryError,
471  const BeamSpot &beamSpot,
472  const GhostTrack &ghostTrack) const {
473  CachingVertex<5> primary(primaryPosition, primaryError, std::vector<RefCountedVertexTrack>(), 0.);
474 
475  std::vector<TransientVertex> result = vertices(ghostTrack, primary, beamSpot, true);
476 
477 #ifdef DEBUG
478  for (std::vector<TransientVertex>::const_iterator iter = result.begin(); iter != result.end(); ++iter)
479  debugVertex(*iter, ghostTrack.prediction());
480 #endif
481 
482  return result;
483 }
484 
485 std::vector<TransientVertex> GhostTrackVertexFinder::vertices(const GlobalPoint &primaryPosition,
486  const GlobalError &primaryError,
487  const BeamSpot &beamSpot,
488  const std::vector<TransientTrack> &primaries,
489  const GhostTrack &ghostTrack) const {
490  std::vector<RefCountedVertexTrack> primaryVertexTracks;
491  if (!primaries.empty()) {
492  LinearizedTrackStateFactory linTrackFactory;
493  VertexTrackFactory<5> vertexTrackFactory;
494 
495  VertexState state(primaryPosition, primaryError);
496 
497  for (std::vector<TransientTrack>::const_iterator iter = primaries.begin(); iter != primaries.end(); ++iter) {
498  RefCountedLinearizedTrackState linState = linTrackFactory.linearizedTrackState(primaryPosition, *iter);
499 
500  primaryVertexTracks.push_back(vertexTrackFactory.vertexTrack(linState, state));
501  }
502  }
503 
504  CachingVertex<5> primary(primaryPosition, primaryError, primaryVertexTracks, 0.);
505 
506  std::vector<TransientVertex> result = vertices(ghostTrack, primary, beamSpot, true, true);
507 
508 #ifdef DEBUG
509  for (std::vector<TransientVertex>::const_iterator iter = result.begin(); iter != result.end(); ++iter)
510  debugVertex(*iter, ghostTrack.prediction());
511 #endif
512 
513  return result;
514 }
515 
516 std::vector<TransientVertex> GhostTrackVertexFinder::vertices(const Vertex &primaryVertex,
517  const GhostTrack &ghostTrack) const {
518  return vertices(
520 }
521 
522 std::vector<TransientVertex> GhostTrackVertexFinder::vertices(const Vertex &primaryVertex,
523  const BeamSpot &beamSpot,
524  const GhostTrack &ghostTrack) const {
525  return vertices(RecoVertex::convertPos(primaryVertex.position()),
527  beamSpot,
528  ghostTrack);
529 }
530 
531 std::vector<TransientVertex> GhostTrackVertexFinder::vertices(const Vertex &primaryVertex,
532  const BeamSpot &beamSpot,
533  const std::vector<TransientTrack> &primaries,
534  const GhostTrack &ghostTrack) const {
535  return vertices(RecoVertex::convertPos(primaryVertex.position()),
537  beamSpot,
538  primaries,
539  ghostTrack);
540 }
541 
542 static GhostTrackPrediction dummyPrediction(const Vertex &primaryVertex, const Track &ghostTrack) {
545  GlobalVector(ghostTrack.px(), ghostTrack.py(), ghostTrack.pz()),
546  0.05);
547 }
548 
549 std::vector<TransientVertex> GhostTrackVertexFinder::vertices(const Vertex &primaryVertex,
550  const Track &ghostTrack,
551  const std::vector<TransientTrack> &tracks,
552  const std::vector<float> &weights) const {
553  GhostTrack ghostTrack_(ghostTrack,
554  tracks,
555  weights,
556  dummyPrediction(primaryVertex, ghostTrack),
558  true);
559 
562  std::vector<RefCountedVertexTrack>(),
563  0.);
564 
565  std::vector<TransientVertex> result = vertices(ghostTrack_, primary);
566 
567 #ifdef DEBUG
568  for (std::vector<TransientVertex>::const_iterator iter = result.begin(); iter != result.end(); ++iter)
569  debugVertex(*iter, ghostTrack_.prediction());
570 #endif
571 
572  return result;
573 }
574 
575 std::vector<TransientVertex> GhostTrackVertexFinder::vertices(const Vertex &primaryVertex,
576  const Track &ghostTrack,
577  const BeamSpot &beamSpot,
578  const std::vector<TransientTrack> &tracks,
579  const std::vector<float> &weights) const {
580  GhostTrack ghostTrack_(ghostTrack,
581  tracks,
582  weights,
583  dummyPrediction(primaryVertex, ghostTrack),
585  true);
586 
589  std::vector<RefCountedVertexTrack>(),
590  0.);
591 
592  std::vector<TransientVertex> result = vertices(ghostTrack_, primary, beamSpot, true);
593 
594 #ifdef DEBUG
595  for (std::vector<TransientVertex>::const_iterator iter = result.begin(); iter != result.end(); ++iter)
596  debugVertex(*iter, ghostTrack_.prediction());
597 #endif
598 
599  return result;
600 }
601 
602 std::vector<TransientVertex> GhostTrackVertexFinder::vertices(const Vertex &primaryVertex,
603  const Track &ghostTrack,
604  const BeamSpot &beamSpot,
605  const std::vector<TransientTrack> &primaries,
606  const std::vector<TransientTrack> &tracks,
607  const std::vector<float> &weights) const {
608  GhostTrack ghostTrack_(ghostTrack,
609  tracks,
610  weights,
611  dummyPrediction(primaryVertex, ghostTrack),
613  true);
614 
615  std::vector<RefCountedVertexTrack> primaryVertexTracks;
616  if (!primaries.empty()) {
617  LinearizedTrackStateFactory linTrackFactory;
618  VertexTrackFactory<5> vertexTrackFactory;
619 
622 
623  for (std::vector<TransientTrack>::const_iterator iter = primaries.begin(); iter != primaries.end(); ++iter) {
624  RefCountedLinearizedTrackState linState = linTrackFactory.linearizedTrackState(state.position(), *iter);
625 
626  primaryVertexTracks.push_back(vertexTrackFactory.vertexTrack(linState, state));
627  }
628  }
629 
632  primaryVertexTracks,
633  0.);
634 
635  std::vector<TransientVertex> result = vertices(ghostTrack_, primary, beamSpot, true, true);
636 
637 #ifdef DEBUG
638  for (std::vector<TransientVertex>::const_iterator iter = result.begin(); iter != result.end(); ++iter)
639  debugVertex(*iter, ghostTrack_.prediction());
640 #endif
641 
642  return result;
643 }
644 
645 static double fitChi2(const CachingVertex<5> &vtx) { return vtx.totalChiSquared() / vtx.degreesOfFreedom(); }
646 
647 std::vector<CachingVertex<5> > GhostTrackVertexFinder::initialVertices(const FinderInfo &info) const {
648  std::vector<CachingVertex<5> > vertices;
649  for (std::vector<GhostTrackState>::const_iterator iter = info.states.begin(); iter != info.states.end(); ++iter) {
650  if (!iter->isValid())
651  continue;
652 
653  GhostTrackState state(*iter);
654  state.linearize(info.pred);
655 
656  if (!state.isValid())
657  continue;
658 
659  CachingVertex<5> vtx = vertexAtState(info.ghostTrack, info.pred, state);
660 
661  if (vtx.isValid()) // && fitChi2(vtx) < maxFitChi2_)
662  vertices.push_back(vtx);
663  }
664 
665  return vertices;
666 }
667 
668 static void mergeTrackHelper(const std::vector<RefCountedVertexTrack> &tracks,
669  std::vector<RefCountedVertexTrack> &newTracks,
670  const VertexState &state,
671  const VtxTrackIs &ghostTrackFinder,
672  RefCountedVertexTrack &ghostTrack,
673  const VertexTrackFactory<5> &factory) {
674  for (std::vector<RefCountedVertexTrack>::const_iterator iter = tracks.begin(); iter != tracks.end(); ++iter) {
675  bool gt = ghostTrackFinder(*iter);
676  if (gt && ghostTrack)
677  continue;
678 
679  RefCountedVertexTrack track = relinearizeTrack(*iter, state, factory);
680 
681  if (gt)
682  ghostTrack = *iter;
683  else
684  newTracks.push_back(*iter);
685  }
686 }
687 
689  const CachingVertex<5> &vertex2,
690  const FinderInfo &info,
691  bool isPrimary) const {
692  VertexTrackFactory<5> vertexTrackFactory;
693 
694  VertexState state = stateMean(vertex1.vertexState(), vertex2.vertexState());
695  std::vector<RefCountedVertexTrack> linTracks;
696  VtxTrackIs isGhostTrack(info.ghostTrack);
697  RefCountedVertexTrack vtxGhostTrack;
698 
699  mergeTrackHelper(vertex1.tracks(), linTracks, state, isGhostTrack, vtxGhostTrack, vertexTrackFactory);
700  mergeTrackHelper(vertex2.tracks(), linTracks, state, isGhostTrack, vtxGhostTrack, vertexTrackFactory);
701 
702  if (vtxGhostTrack && (fitType_ == kAlwaysWithGhostTrack || linTracks.size() < 2))
703  linTracks.push_back(vertexTrackFactory.vertexTrack(vtxGhostTrack->linearizedTrack(), vtxGhostTrack->vertexState()));
704 
705  try {
707  if (info.hasBeamSpot && isPrimary)
708  vtx = vertexFitter(true).vertex(linTracks, info.beamSpot.position(), info.beamSpot.error());
709  else
710  vtx = vertexFitter(isPrimary).vertex(linTracks);
711  if (vtx.isValid())
712  return vtx;
713  } catch (const VertexException &e) {
714  // fit failed
715  }
716 
717  return CachingVertex<5>();
718 }
719 
721  typedef std::pair<unsigned int, unsigned int> Indices;
722 
723  std::multimap<float, Indices> compatMap;
724  unsigned int n = vertices.size();
725  for (unsigned int i = 0; i < n; i++) {
726  const CachingVertex<5> &v1 = vertices[i];
727  for (unsigned int j = i + 1; j < n; j++) {
728  const CachingVertex<5> &v2 = vertices[j];
729 
730  float compat = vertexCompat(v1, v2, info, i == 0 ? primcut_ : seccut_, seccut_);
731 
732  if (compat > mergeThreshold_)
733  continue;
734 
735  compatMap.insert(std::make_pair(compat, Indices(i, j)));
736  }
737  }
738 
739  bool changesMade = false;
740  bool repeat = true;
741  while (repeat) {
742  repeat = false;
743  for (std::multimap<float, Indices>::const_iterator iter = compatMap.begin(); iter != compatMap.end(); ++iter) {
744  unsigned int v1 = iter->second.first;
745  unsigned int v2 = iter->second.second;
746 
748  if (!newVtx.isValid() || (v1 != 0 && fitChi2(newVtx) > maxFitChi2_))
749  continue;
750 
751  std::swap(vertices[v1], newVtx);
752  vertices.erase(vertices.begin() + v2);
753  n--;
754 
755  std::multimap<float, Indices> newCompatMap;
756  for (++iter; iter != compatMap.end(); ++iter) {
757  if (iter->second.first == v1 || iter->second.first == v2 || iter->second.second == v1 ||
758  iter->second.second == v2)
759  continue;
760 
761  Indices indices = iter->second;
762  indices.first -= indices.first > v2;
763  indices.second -= indices.second > v2;
764 
765  newCompatMap.insert(std::make_pair(iter->first, indices));
766  }
767  std::swap(compatMap, newCompatMap);
768 
769  for (unsigned int i = 0; i < n; i++) {
770  if (i == v1)
771  continue;
772 
773  const CachingVertex<5> &other = vertices[i];
774  float compat =
775  vertexCompat(vertices[v1], other, info, v1 == 0 ? primcut_ : seccut_, i == 0 ? primcut_ : seccut_);
776 
777  if (compat > mergeThreshold_)
778  continue;
779 
780  compatMap.insert(std::make_pair(compat, Indices(std::min(i, v1), std::max(i, v1))));
781  }
782 
783  changesMade = true;
784  repeat = true;
785  break;
786  }
787  }
788 
789  return changesMade;
790 }
791 
793  std::vector<std::pair<RefCountedVertexTrack, std::vector<RefCountedVertexTrack> > > trackBundles(vertices_.size());
794 
795  VtxTrackIs isGhostTrack(info.ghostTrack);
796 
797  bool assignmentChanged = false;
798  for (std::vector<CachingVertex<5> >::const_iterator iter = vertices_.begin(); iter != vertices_.end(); ++iter) {
799  std::vector<RefCountedVertexTrack> vtxTracks = iter->tracks();
800 
801  if (vtxTracks.empty()) {
802  LinearizedTrackStateFactory linTrackFactory;
803  VertexTrackFactory<5> vertexTrackFactory;
804 
805  RefCountedLinearizedTrackState linState = linTrackFactory.linearizedTrackState(iter->position(), info.ghostTrack);
806 
807  trackBundles[iter - vertices_.begin()].first = vertexTrackFactory.vertexTrack(linState, iter->vertexState());
808  }
809 
810  for (std::vector<RefCountedVertexTrack>::const_iterator track = vtxTracks.begin(); track != vtxTracks.end();
811  ++track) {
812  if (isGhostTrack(*track)) {
813  trackBundles[iter - vertices_.begin()].first = *track;
814  continue;
815  }
816 
817  if ((*track)->weight() < 1e-3) {
818  trackBundles[iter - vertices_.begin()].second.push_back(*track);
819  continue;
820  }
821 
822  unsigned int idx = iter - vertices_.begin();
823  double best = 1.0e9;
824  for (std::vector<CachingVertex<5> >::const_iterator vtx = vertices_.begin(); vtx != vertices_.end(); ++vtx) {
825  if (info.pred.lambda(vtx->position()) < info.pred.lambda(vertices_[0].position()))
826  continue;
827 
828  double compat = sqr(trackVertexCompat(*vtx, *track));
829 
830  compat /= (vtx == vertices_.begin()) ? primcut_ : seccut_;
831 
832  if (compat < best) {
833  best = compat;
834  idx = vtx - vertices_.begin();
835  }
836  }
837 
838  if ((int)idx != iter - vertices_.begin())
839  assignmentChanged = true;
840 
841  trackBundles[idx].second.push_back(*track);
842  }
843  }
844 
845  if (!assignmentChanged)
846  return false;
847 
848  VertexTrackFactory<5> vertexTrackFactory;
849  std::vector<CachingVertex<5> > vertices;
850  vertices.reserve(vertices_.size());
851 
852  for (std::vector<CachingVertex<5> >::const_iterator iter = vertices_.begin(); iter != vertices_.end(); ++iter) {
853  const std::vector<RefCountedVertexTrack> &tracks = trackBundles[iter - vertices_.begin()].second;
854  if (tracks.empty())
855  continue;
856 
858 
859  if (tracks.size() == 1) {
860  const TransientTrack &track = tracks[0]->linearizedTrack()->track();
861 
862  int idx = -1;
863  for (std::vector<GhostTrackState>::const_iterator iter = info.states.begin(); iter != info.states.end(); ++iter) {
864  if (iter->isTrack() && iter->track() == track) {
865  idx = iter - info.states.begin();
866  break;
867  }
868  }
869  if (idx < 0)
870  continue;
871 
872  vtx = vertexAtState(info.ghostTrack, info.pred, info.states[idx]);
873  if (!vtx.isValid())
874  continue;
875  } else {
876  std::vector<RefCountedVertexTrack> linTracks = relinearizeTracks(tracks, iter->vertexState());
877 
879  linTracks.push_back(
880  relinearizeTrack(trackBundles[iter - vertices_.begin()].first, iter->vertexState(), vertexTrackFactory));
881 
882  bool primary = iter == vertices_.begin();
883  try {
884  if (primary && info.hasBeamSpot)
885  vtx = vertexFitter(true).vertex(linTracks, info.beamSpot.position(), info.beamSpot.error());
886  else
887  vtx = vertexFitter(primary).vertex(linTracks);
888  } catch (const VertexException &e) {
889  // fit failed;
890  }
891  if (!vtx.isValid())
892  return false;
893  }
894 
895  vertices.push_back(vtx);
896  };
897 
898  std::swap(vertices_, vertices);
899  return true;
900 }
901 
903  VtxTrackIs isGhostTrack(info.ghostTrack);
904 
905  std::vector<GhostTrackState> states;
906  std::vector<unsigned int> oldStates;
907  oldStates.reserve(info.states.size());
908 
909  for (std::vector<CachingVertex<5> >::const_iterator iter = vertices.begin(); iter != vertices.end(); ++iter) {
910  std::vector<RefCountedVertexTrack> vtxTracks = iter->tracks();
911 
912  oldStates.clear();
913  for (std::vector<RefCountedVertexTrack>::const_iterator track = vtxTracks.begin(); track != vtxTracks.end();
914  ++track) {
915  if (isGhostTrack(*track) || (*track)->weight() < 1e-3)
916  continue;
917 
918  const TransientTrack &tt = (*track)->linearizedTrack()->track();
919 
920  int idx = -1;
921  for (std::vector<GhostTrackState>::const_iterator iter = info.states.begin(); iter != info.states.end(); ++iter) {
922  if (iter->isTrack() && iter->track() == tt) {
923  idx = iter - info.states.begin();
924  break;
925  }
926  }
927 
928  if (idx >= 0)
929  oldStates.push_back(idx);
930  }
931 
932  if (oldStates.size() == 1)
933  states.push_back(info.states[oldStates[0]]);
934  else
935  states.push_back(GhostTrackState(iter->vertexState()));
936  }
937 
938  KalmanGhostTrackUpdater updater;
940  double ndof, chi2;
941  info.pred = fitter.fit(updater, info.prior, states, ndof, chi2);
942  TransientTrack ghostTrack = transientGhostTrack(info.pred, info.field);
943 
944  std::swap(info.states, states);
945  states.clear();
946 
947  std::vector<CachingVertex<5> > newVertices;
948  for (std::vector<CachingVertex<5> >::const_iterator iter = vertices.begin(); iter != vertices.end(); ++iter) {
949  std::vector<RefCountedVertexTrack> vtxTracks = iter->tracks();
950 
951  int idx = -1;
952  bool redo = false;
953  for (std::vector<RefCountedVertexTrack>::iterator track = vtxTracks.begin(); track != vtxTracks.end(); ++track) {
954  if (isGhostTrack(*track)) {
955  LinearizedTrackStateFactory linTrackFactory;
956  VertexTrackFactory<5> vertexTrackFactory;
957 
958  *track = vertexTrackFactory.vertexTrack(linTrackFactory.linearizedTrackState(iter->position(), ghostTrack),
959  iter->vertexState());
960  redo = true;
961  continue;
962  }
963 
964  const TransientTrack &tt = (*track)->linearizedTrack()->track();
965 
966  if (idx >= 0) {
967  idx = -1;
968  break;
969  }
970 
971  for (std::vector<GhostTrackState>::const_iterator it = info.states.begin(); it != info.states.end(); ++it) {
972  if (!it->isTrack())
973  continue;
974 
975  if (it->track() == tt) {
976  idx = it - info.states.begin();
977  break;
978  }
979  }
980  }
981 
982  if (idx >= 0) {
983  CachingVertex<5> vtx = vertexAtState(ghostTrack, info.pred, info.states[idx]);
984  if (vtx.isValid())
985  newVertices.push_back(vtx);
986  } else if (redo) {
987  bool primary = iter == vertices.begin();
989  if (primary && info.hasBeamSpot)
990  vtx = vertexFitter(true).vertex(vtxTracks, info.beamSpot.position(), info.beamSpot.error());
991  else
992  vtx = vertexFitter(primary).vertex(vtxTracks);
993  if (vtx.isValid())
994  newVertices.push_back(vtx);
995  } else
996  newVertices.push_back(*iter);
997  }
998 
999  std::swap(newVertices, vertices);
1000  info.ghostTrack = ghostTrack;
1001 }
1002 
1003 // implementation
1004 
1005 std::vector<TransientVertex> GhostTrackVertexFinder::vertices(const GhostTrack &ghostTrack,
1006  const CachingVertex<5> &primary,
1007  const BeamSpot &beamSpot,
1008  bool hasBeamSpot,
1009  bool hasPrimaries) const {
1010  FinderInfo info(primary, ghostTrack, beamSpot, hasBeamSpot, hasPrimaries);
1011 
1012  std::vector<TransientVertex> result;
1013  if (info.states.empty())
1014  return result;
1015 
1016  info.field = info.states[0].track().field();
1017  info.ghostTrack = transientGhostTrack(info.pred, info.field);
1018 
1019  std::vector<CachingVertex<5> > vertices = initialVertices(info);
1020  if (primary.isValid()) {
1021  vertices.push_back(primary);
1022  if (vertices.size() > 1)
1023  std::swap(vertices.front(), vertices.back());
1024  }
1025 
1026  unsigned int reassigned = 0;
1027  while (reassigned < 3) {
1028  if (vertices.size() < 2)
1029  break;
1030 
1031 #ifdef DEBUG
1032  for (std::vector<CachingVertex<5> >::const_iterator iter = vertices.begin(); iter != vertices.end(); ++iter)
1033 
1034  debugVertex(*iter, ghostTrack.prediction());
1035 
1036  std::cout << "----- recursive merging: ---------" << std::endl;
1037 #endif
1038 
1039  bool changed = recursiveMerge(vertices, info);
1040  if ((!changed && !reassigned) || vertices.size() < 2)
1041  break;
1042  if (changed)
1043  reassigned = 0;
1044 
1047  changed = true;
1048  }
1049 
1050  try {
1051 #ifdef DEBUG
1052  for (std::vector<CachingVertex<5> >::const_iterator iter = vertices.begin(); iter != vertices.end(); ++iter)
1053  debugVertex(*iter, ghostTrack.prediction());
1054  std::cout << "----- reassignment: ---------" << std::endl;
1055 #endif
1056  if (reassignTracks(vertices, info)) {
1057  reassigned++;
1058  changed = true;
1059  } else
1060  reassigned = 0;
1061  } catch (const VertexException &e) {
1062  // just keep vertices as they are
1063  }
1064 
1065  if (!changed)
1066  break;
1067  }
1068 
1069  for (std::vector<CachingVertex<5> >::const_iterator iter = vertices.begin(); iter != vertices.end(); ++iter) {
1070  std::vector<RefCountedVertexTrack> tracks = iter->tracks();
1071  std::vector<RefCountedVertexTrack> newTracks;
1072  newTracks.reserve(tracks.size());
1073 
1074  std::remove_copy_if(tracks.begin(), tracks.end(), std::back_inserter(newTracks), VtxTrackIs(info.ghostTrack));
1075 
1076  if (newTracks.empty())
1077  continue;
1078 
1079  CachingVertex<5> vtx(iter->vertexState(), newTracks, iter->totalChiSquared());
1080  result.push_back(vtx);
1081  }
1082 
1083  return result;
1084 }
GhostTrackFitter & ghostTrackFitter() const
FreeTrajectoryState fts(const MagneticField *fieldProvider) const
reco::Vertex::Point convertPos(const GlobalPoint &p)
RefCountedLinearizedTrackState linearizedTrackState(const GlobalPoint &linP, const reco::TransientTrack &track) const override
static const TGPicture * info(bool iBackgroundIsBlack)
std::unique_ptr< VertexFitter< 5 > > primVertexFitter_
const bool isValid(const Frame &aFrame, const FrameQuality &aQuality, const uint16_t aExpectedPos)
static bool covarianceUpdate(Matrix3S &cov, const Vector3 &residual, const Matrix3S &error, double &chi2, double theta, double phi)
GlobalPoint position(double lambda=0.) const
bool isPrimary(const SimTrack &simTrk, const PSimHit *simHit)
void add(const reco::Track &track, double weight=1.0)
reco::TransientTrack build(const FreeTrajectoryState &fts) const
T z() const
Definition: PV3DBase.h:61
Common base class.
RefCountedVertexTrack vertexTrack(const RefCountedLinearizedTrackState lt, const VertexState vs, float weight=1.0) const
double px() const
x coordinate of momentum vector
Definition: TrackBase.h:640
Sin< T >::type sin(const T &t)
Definition: Sin.h:22
static RefCountedVertexTrack relinearizeTrack(const RefCountedVertexTrack &track, const VertexState &state, const VertexTrackFactory< 5 > factory)
reco::Vertex::Error convertError(const GlobalError &ge)
Definition: ConvertError.h:8
VertexState const & vertexState() const
double py() const
y coordinate of momentum vector
Definition: TrackBase.h:643
Definition: weight.py:1
static double vertexCompat(const CachingVertex< 5 > &vtx1, const CachingVertex< 5 > &vtx2, const FinderInfo &info, double scale1=1.0, double scale2=1.0)
CachingVertex< 5 > mergeVertices(const CachingVertex< 5 > &vertex1, const CachingVertex< 5 > &vertex2, const FinderInfo &info, bool isPrimary) const
static TransientTrack transientGhostTrack(const GhostTrackPrediction &pred, const MagneticField *field)
static double fitChi2(const CachingVertex< 5 > &vtx)
A arg
Definition: Factorize.h:31
static VertexState stateMean(const VertexState &v1, const VertexState &v2)
GhostTrackPrediction fit(const GhostTrackFitter::PredictionUpdater &updater, const GhostTrackPrediction &prior, std::vector< GhostTrackState > &states, double &ndof, double &chi2) override
T x() const
Definition: PV3DBase.h:59
T y() const
Definition: PV3DBase.h:60
const GlobalVector direction() const
Definition: TTTypes.h:54
std::vector< RefCountedVertexTrack > tracks() const
Indices
Definition: EdmEventSize.cc:28
GlobalError positionError(double lambda=0.) const
static std::vector< RefCountedVertexTrack > relinearizeTracks(const std::vector< RefCountedVertexTrack > &tracks, const VertexState &state)
virtual CachingVertex< N > vertex(const std::vector< reco::TransientTrack > &tracks) const =0
bool recursiveMerge(std::vector< CachingVertex< 5 > > &vertices, const FinderInfo &info) const
void swap(edm::DataFrameContainer &lhs, edm::DataFrameContainer &rhs)
T sqrt(T t)
Definition: SSEVec.h:19
TrackCharge charge() const
GlobalError error() const
Definition: VertexState.h:64
Cos< T >::type cos(const T &t)
Definition: Cos.h:22
const math::XYZTLorentzVector & vectorSum() const
VertexFitter< 5 > & vertexFitter(bool primary) const
GlobalVector momentum() const
static GhostTrackPrediction dummyPrediction(const Vertex &primaryVertex, const Track &ghostTrack)
static GlobalPoint vtxMean(const GlobalPoint &p1, const GlobalError &e1, const GlobalPoint &p2, const GlobalError &e2)
const AlgebraicSymMatrix33 matrix() const
ROOT::Math::DisplacementVector3D< ROOT::Math::Cartesian3D< float >, ROOT::Math::GlobalCoordinateSystemTag > GlobalVector
vector in glovbal coordinate system
Definition: Vector3D.h:28
bool reassignTracks(std::vector< CachingVertex< 5 > > &vertices, const FinderInfo &info) const
void refitGhostTrack(std::vector< CachingVertex< 5 > > &vertices, FinderInfo &info) const
bool isValid() const
std::unique_ptr< VertexFitter< 5 > > secVertexFitter_
double pz() const
z coordinate of momentum vector
Definition: TrackBase.h:646
double lambda(const GlobalPoint &point) const
FinderInfo(const CachingVertex< 5 > &primaryVertex, const GhostTrack &ghostTrack, const BeamSpot &beamSpot, bool hasBeamSpot, bool hasPrimaries)
EPOS::IO_EPOS conv
ROOT::Math::PositionVector3D< ROOT::Math::Cartesian3D< float >, ROOT::Math::GlobalCoordinateSystemTag > GlobalPoint
point in global coordinate system
Definition: Point3D.h:18
static double trackVertexCompat(const CachingVertex< 5 > &vtx, const RefCountedVertexTrack &vertexTrack)
fixed size matrix
const GhostTrackPrediction & prediction() const
Definition: GhostTrack.h:41
Square< F >::type sqr(const F &f)
Definition: Square.h:14
std::vector< TransientVertex > vertices(const reco::Vertex &primaryVertex, const GlobalVector &direction, double coneRadius, const std::vector< TransientTrack > &tracks) const
std::vector< CachingVertex< 5 > > initialVertices(const FinderInfo &info) const
GhostTrack fit(const GlobalPoint &priorPosition, const GlobalError &priorError, const GlobalVector &direction, double coneRadius, const std::vector< TransientTrack > &tracks) const
static double vtxErrorLong(const GlobalError &error, const GlobalVector &dir)
static void mergeTrackHelper(const std::vector< RefCountedVertexTrack > &tracks, std::vector< RefCountedVertexTrack > &newTracks, const VertexState &state, const VtxTrackIs &ghostTrackFinder, RefCountedVertexTrack &ghostTrack, const VertexTrackFactory< 5 > &factory)
std::unique_ptr< GhostTrackFitter > ghostTrackFitter_
static CachingVertex< 5 > vertexAtState(const TransientTrack &ghostTrack, const GhostTrackPrediction &pred, const GhostTrackState &state)
#define UNLIKELY(x)
Definition: Likely.h:21
Log< level::Warning, false > LogWarning
GlobalPoint position() const
GlobalError error() const
primaryVertex
hltOfflineBeamSpot for HLTMON
Geom::Theta< T > theta() const
*vegas h *****************************************************used in the default bin number in original ***version of VEGAS is ***a higher bin number might help to derive a more precise ***grade subtle point
Definition: invegas.h:5
Global3DVector GlobalVector
Definition: GlobalVector.h:10
GlobalPoint position() const
Definition: VertexState.h:62