ATLAS Offline Software
InDetAdaptiveMultiSecVtxFinderTool.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2019-2023 CERN for the benefit of the ATLAS collaboration
3 */
4 // Author: Neza Ribaric <neza.ribaric@cern.ch>
5 
6 /***************************************************************************
7  InDetAdaptiveMultiSecVtxFinderTool.cxx -
8  Description
9  -------------------
10  begin : 01-12-2019
11  authors : Neza Ribaric ( Lancaster University )
12  information : Tool for Secondary Vertex Finding using AdaptiveMultivertexFitter and InDetTrackSelection
13  ***************************************************************************/
14 
16 
17 #include <map>
18 #include <utility>
19 #include <vector>
20 
22 #include "CLHEP/Matrix/SymMatrix.h"
23 #include "CLHEP/Matrix/Vector.h"
34 #include "TrkTrack/LinkToTrack.h"
35 #include "TrkTrack/Track.h"
44 #include "VxVertex/RecVertex.h"
45 #include "VxVertex/Vertex.h"
50 #include "xAODTracking/Vertex.h"
53 
54 namespace InDet {
55 
56  InDetAdaptiveMultiSecVtxFinderTool::InDetAdaptiveMultiSecVtxFinderTool(const std::string& t, const std::string& n,
57  const IInterface* p) :
58  base_class(t, n, p) {}
59 
61  /* Get the right vertex fitting tool from ToolSvc */
62  ATH_CHECK(m_VertexFitter.retrieve());
63  ATH_CHECK(m_SeedFinder.retrieve());
64  ATH_CHECK(m_ImpactPoint3dEstimator.retrieve());
65  ATH_CHECK(m_trkFilter.retrieve());
66 
67  ATH_MSG_DEBUG("Initialization successful");
68  return StatusCode::SUCCESS;
69  }
70 
71  namespace {
72  struct xAODVertex_pair {
73  double first;
75  xAODVertex_pair(double p1, xAOD::Vertex* p2) : first(p1), second(p2) {}
76  bool operator<(const xAODVertex_pair& other) const { return first > other.first; }
77  };
78  } // anonymous namespace
79 
80  std::pair<xAOD::VertexContainer*, xAOD::VertexAuxContainer*>
81  InDetAdaptiveMultiSecVtxFinderTool::findVertex(
82  const xAOD::TrackParticleContainer* trackParticles) {
83  ATH_MSG_DEBUG(" Number of input tracks before track selection: " << trackParticles->size());
84 
85  std::vector<Trk::ITrackLink*> selectedTracks;
86  bool selectionPassed;
87  xAOD::TrackParticle::Decorator<bool> trackPass("TrackPassedSelection");
88 
89  for (const xAOD::TrackParticle* itr : *trackParticles) {
90  xAOD::Vertex null;
91  null.makePrivateStore();
92  null.setPosition(Amg::Vector3D(0, 0, 0));
93  AmgSymMatrix(3) vertexError;
94  vertexError.setZero();
95  null.setCovariancePosition(vertexError);
96  selectionPassed = static_cast<bool>(m_trkFilter->accept(*itr, &null));
97  if (selectionPassed) selectionPassed = static_cast<bool>(m_SVtrkFilter->accept(*itr, &null));
98 
99  if (selectionPassed) {
100  trackPass(*itr) = true;
101 
102  Amg::VectorX par = (itr)->definingParameters();
103  par[0] = (itr)->hitPattern();
104 
106  link.setElement(itr);
108 
109  linkTT->setStorableObject(*trackParticles);
110  selectedTracks.push_back(linkTT);
111  }
112  }
113 
114  ATH_MSG_DEBUG("Of " << trackParticles->size() << " tracks " << selectedTracks.size() << " survived the preselection.");
115 
116  std::pair<xAOD::VertexContainer*, xAOD::VertexAuxContainer*> returnContainers = doVertexing(selectedTracks);
117 
118  return returnContainers;
119  }
120 
121  std::pair<xAOD::VertexContainer*, xAOD::VertexAuxContainer*>
122  InDetAdaptiveMultiSecVtxFinderTool::doVertexing( const std::vector<Trk::ITrackLink*>& trackVector) {
123  xAOD::VertexContainer* theVertexContainer = new xAOD::VertexContainer;
124  xAOD::VertexAuxContainer* theVertexAuxContainer = new xAOD::VertexAuxContainer;
125  theVertexContainer->setStore(theVertexAuxContainer);
126 
128  static const xAOD::Vertex::Decorator<Trk::MvfFitInfo*> MvfFitInfo("MvfFitInfo");
129  static const xAOD::Vertex::Decorator<bool> isInitialized("isInitialized");
131 
132  std::vector<xAODVertex_pair> myxAODVertices;
133 
134  std::vector<Trk::TrackToVtxLink*> myTrackToVtxLinks;
135 
137  std::vector<Trk::ITrackLink*> origTracks = trackVector;
138  std::vector<Trk::ITrackLink*> seedTracks = trackVector;
139 
140  // create a map between ITrackLink* and TrackToVtxLink*
141  std::map<Trk::ITrackLink*, Trk::TrackToVtxLink*> TrackLinkOf;
142 
143  // fill vector of track parameters used for fitting
144  // create map
145 
146  for (Trk::ITrackLink* trkIter : origTracks) {
147  Trk::TrackToVtxLink* newTrkToVtxLink(new Trk::TrackToVtxLink(new std::vector<xAOD::Vertex*>));
148 
149  TrackLinkOf[trkIter] = newTrkToVtxLink;
150  myTrackToVtxLinks.push_back(newTrkToVtxLink);
151  }
152 
153  int iteration = 0;
154  unsigned int seedtracknumber = seedTracks.size();
155 
156  do {
157  if (seedtracknumber == 0) { ATH_MSG_DEBUG("New iteration. No tracks available after track selection for seeding."); }
158 
159  iteration += 1;
160  ATH_MSG_DEBUG("Iteration number " << iteration << " and tracks left for seeding " << seedtracknumber);
161 
162  std::vector<const Trk::TrackParameters*> perigeeList;
163 
164  perigeeList.reserve(seedTracks.size());
165 for (const Trk::ITrackLink* seedtrkAtVtxIter : seedTracks) { perigeeList.push_back((seedtrkAtVtxIter)->parameters()); }
166 
167  ATH_MSG_DEBUG("Going to seed finder");
168 
169  std::unique_ptr<Trk::IMode3dInfo> info;
170  Amg::Vector3D seedVertex;
171  seedVertex = m_SeedFinder->findSeed(m_privtx.x(), m_privtx.y(), info, perigeeList);
172 
173  ATH_MSG_DEBUG("Found seed at x: " << seedVertex.x() << " at y: " << seedVertex.y() << " at z: " << seedVertex.z());
174 
175  xAOD::Vertex* seededxAODVertex = new xAOD::Vertex;
176  theVertexContainer->push_back(seededxAODVertex);
177  seededxAODVertex->setPosition(seedVertex);
178  Amg::MatrixX looseConstraintCovariance(3, 3);
179  looseConstraintCovariance.setIdentity();
180  looseConstraintCovariance = looseConstraintCovariance * 1e+8;
181  seededxAODVertex->setCovariancePosition(looseConstraintCovariance);
182  seededxAODVertex->vxTrackAtVertex() = std::vector<Trk::VxTrackAtVertex>();
183  seededxAODVertex->setVertexType(xAOD::VxType::NotSpecified);
184 
185  if (seedVertex.z() == 0) {
186  ATH_MSG_DEBUG("No good seed found: no further vertices in event");
187  ATH_MSG_DEBUG("Number of input tracks: " << perigeeList.size() << ", but no good seed returned");
188  break;
189  }
190 
191  xAOD::Vertex* constraintVertex = nullptr;
192  looseConstraintCovariance.setIdentity();
193  looseConstraintCovariance = looseConstraintCovariance * 1e+8;
194  constraintVertex = new xAOD::Vertex();
195  constraintVertex->makePrivateStore();
196  constraintVertex->setPosition(seedVertex);
197  constraintVertex->setCovariancePosition(looseConstraintCovariance);
198  constraintVertex->setFitQuality(0., -3.);
199  constraintVertex->setVertexType(xAOD::VxType::NotSpecified);
200 
201  xAOD::Vertex* actualCandidate = new xAOD::Vertex;
202  actualCandidate->makePrivateStore();
203  actualCandidate->setVertexType(xAOD::VxType::NotSpecified);
204 
205  MvfFitInfo(*actualCandidate) =
206  new Trk::MvfFitInfo(constraintVertex, new Amg::Vector3D(seedVertex), new Amg::Vector3D(seedVertex));
207  isInitialized(*actualCandidate) = false;
208  std::vector<Trk::VxTrackAtVertex*> vectorOfTracks(0);
209  VTAV(*actualCandidate) = vectorOfTracks;
210 
211  for (Trk::ITrackLink* trkIter : origTracks) {
212  // now fill perigeesToFit list of track parameters from origTracks
213  float doe = findCompatibleTracks(seedVertex, trkIter);
214  if (doe < m_significanceCutSeeding) {
215  Trk::TrackToVtxLink* actualLink = TrackLinkOf[trkIter];
216  std::vector<xAOD::Vertex*>* actualvtxlink = actualLink->vertices();
217  // adding vertex to candidates of track
218  actualvtxlink->push_back(actualCandidate);
219  VTAV(*actualCandidate).push_back(new Trk::MVFVxTrackAtVertex((trkIter)->clone(), actualLink));
220  }
221  }
222 
223  ATH_MSG_DEBUG(" Considering n. " << VTAV(*actualCandidate).size() << " tracks for the fit. ");
224 
225  if (VTAV(*actualCandidate).size() < 2) {
226  ATH_MSG_DEBUG("No tracks found near seed, while at least two tracks were expected.");
227 
228  if (VTAV.isAvailable(*actualCandidate)) {
229  for (auto *tav : VTAV(*actualCandidate)) {
230  if (tav == nullptr) continue;
231 
232  (static_cast<Trk::MVFVxTrackAtVertex*>(tav))->setLinkToVertices(nullptr);
233  delete tav;
234  tav = nullptr;
235  }
236  VTAV(*actualCandidate).clear();
237  }
238  if (MvfFitInfo.isAvailable(*actualCandidate) && MvfFitInfo(*actualCandidate) != nullptr) {
239  delete MvfFitInfo(*actualCandidate);
240  MvfFitInfo(*actualCandidate) = nullptr;
241  }
242  delete actualCandidate;
243  actualCandidate = nullptr;
244 
245  break;
246  }
247 
248  ATH_MSG_DEBUG("Going to fitter.");
249 
250  m_VertexFitter->addVtxTofit(actualCandidate);
251 
252  ATH_MSG_DEBUG("Deleting tracks with really good fit to vertex from seeding tracks.");
253  int nFound = removeTracksFromSeeds(actualCandidate, seedTracks);
254 
255  ATH_MSG_DEBUG("Found and deleted " << nFound << " tracks from seeding tracks.");
256  if (nFound == 0) {
257  ATH_MSG_DEBUG("All tracks used for fitting came from fiting tracks, removing closest from seeding.");
258  // all the tracks used for the fit came from fitting track list
259  //-> so remove the closest track to seed from seeding, otherwise you'll keep finding the same seed position
260 
261  removeClosestTrack(seedVertex, seedTracks, nFound);
262  }
263 
264  if (nFound == 0) {
265  ATH_MSG_DEBUG("You still have not removed any tracks from seeds! Aborting.");
266  break;
267  }
268 
269  ATH_MSG_DEBUG("Checking goodness of fit.");
270  bool goodVertex = checkFit(actualCandidate);
271 
272  if (!goodVertex) {
273  ATH_MSG_DEBUG("Bad vertex, deleting the vertex and clearing all pointers");
274 
275  seededxAODVertex->setVertexType(xAOD::VxType::KinkVtx);
276 
277  if (actualCandidate) {
278  if (VTAV.isAvailable(*actualCandidate)) {
279  for (auto *tav : VTAV(*actualCandidate)) {
280  if (tav == nullptr) continue;
281 
282  (static_cast<Trk::MVFVxTrackAtVertex*>(tav))->setLinkToVertices(nullptr);
283  delete tav;
284  tav = nullptr;
285  }
286  VTAV(*actualCandidate).clear();
287  }
288  if (MvfFitInfo.isAvailable(*actualCandidate) && MvfFitInfo(*actualCandidate) != nullptr) {
289  delete MvfFitInfo(*actualCandidate);
290  MvfFitInfo(*actualCandidate) = nullptr;
291  }
292 
293  delete actualCandidate;
294  actualCandidate = nullptr;
295  }
296 
297  } else {
298  ATH_MSG_DEBUG("I have found a good vertex!");
299 
300  seededxAODVertex->setVertexType(xAOD::VxType::NoVtx);
301  actualCandidate->setVertexType(xAOD::VxType::SecVtx);
302  myxAODVertices.emplace_back(0, actualCandidate);
303  }
304  seedtracknumber = seedTracks.size();
305  } while (seedTracks.size() > 1 && iteration < m_maxIterations);
306 
307  if (iteration >= m_maxIterations) {
308  ATH_MSG_DEBUG("Maximum number of iterations ("
309  << m_maxIterations << ") reached; to reconstruct more vertices, set maxIterations to a higher value.");
310  }
311 
312  ATH_MSG_DEBUG("Secondary vertex finding complete with " << iteration << " iterations and " << myxAODVertices.size()
313  << " vertices found.");
314 
315  for (const xAODVertex_pair& vtxIter : myxAODVertices) {
316  xAOD::Vertex* fittedVert = vtxIter.second;
317 
318  xAOD::Vertex* cand = new xAOD::Vertex;
319  theVertexContainer->push_back(cand);
320  cand->setPosition(fittedVert->position());
321  cand->setCovariancePosition(fittedVert->covariancePosition());
322  cand->setFitQuality(fittedVert->chiSquared(), fittedVert->numberDoF());
324 
325  std::vector<Trk::VxTrackAtVertex>* tracksOfVertex = &(cand->vxTrackAtVertex());
326  tracksOfVertex->clear();
327 
328  for (Trk::VxTrackAtVertex* MVFtrkIter : VTAV(*fittedVert)) {
329  if ((*MVFtrkIter).initialPerigee()) { (*MVFtrkIter).setPerigeeAtVertex(((*MVFtrkIter).initialPerigee())->clone()); }
330  tracksOfVertex->push_back(*MVFtrkIter);
331  }
332  }
333 
334  for (const xAODVertex_pair& vtxIter : myxAODVertices) {
335  xAOD::Vertex* cand = vtxIter.second;
336 
337  for (Trk::VxTrackAtVertex* MVFtrkIter : VTAV(*cand)) {
338  (static_cast<Trk::MVFVxTrackAtVertex*>(MVFtrkIter))->setLinkToVertices(nullptr);
339  delete MVFtrkIter;
340  MVFtrkIter = nullptr;
341  }
342 
343  delete MvfFitInfo(*cand);
344  }
345 
346  ATH_MSG_DEBUG("Looping over vertex container");
347 
348  for (xAOD::Vertex* vxIter : *theVertexContainer) {
349  std::vector<Trk::VxTrackAtVertex>* myVxTracksAtVtx = &((vxIter)->vxTrackAtVertex());
350  if (!myVxTracksAtVtx) continue;
351 
352  for (Trk::VxTrackAtVertex& tracksIter : *myVxTracksAtVtx) {
353  Trk::LinkToXAODTrackParticle* linkToXAODTP = nullptr;
354  Trk::ITrackLink* tmpLink = (tracksIter).trackOrParticleLink();
355  if (tmpLink->type() == Trk::ITrackLink::ToxAODTrackParticle) {
356  linkToXAODTP = static_cast<Trk::LinkToXAODTrackParticle*>(tmpLink);
357  }
358 
359  if (linkToXAODTP) { (vxIter)->addTrackAtVertex(*linkToXAODTP, (tracksIter).weight()); }
360  }
361 
362  int ntrk = myVxTracksAtVtx->size();
363  if (ntrk == 2) {
364  ATH_MSG_DEBUG("Could do a V0 search");
365 
366  bool isV0 = V0check(getVertexMomenta(vxIter), (&(*vxIter))->position());
367  if (isV0) {
368  ATH_MSG_DEBUG("Labeling as V0");
369  (vxIter)->setVertexType(xAOD::VxType::V0Vtx);
370  }
371  }
372  }
373 
374  // delete all TrackToVtxLink objects
375  for (Trk::TrackToVtxLink* iterator : myTrackToVtxLinks) { delete iterator; }
376 
377  if (!theVertexContainer->empty()) {
378  xAOD::Vertex* secVtx = theVertexContainer->front();
379  if (!secVtx->vxTrackAtVertex().empty()) {
381  xAOD::Vertex* dummyxAODVertex = new xAOD::Vertex;
382  theVertexContainer->push_back(dummyxAODVertex); // have to add vertex to container here first so it can use its aux store
383  dummyxAODVertex->setPosition(secVtx->position());
384  dummyxAODVertex->setCovariancePosition(secVtx->covariancePosition());
385  dummyxAODVertex->vxTrackAtVertex() = std::vector<Trk::VxTrackAtVertex>();
386  dummyxAODVertex->setVertexType(xAOD::VxType::NoVtx);
387  } else {
389  }
390  }
391 
392  else if (theVertexContainer->empty()) {
393  xAOD::Vertex* dummyxAODVertex = new xAOD::Vertex;
394  theVertexContainer->push_back(dummyxAODVertex); // have to add vertex to container here first so it can use its aux store
395  dummyxAODVertex->setPosition(Amg::Vector3D(0, 0, 0));
396  Amg::MatrixX looseConstraintCovariance(3, 3);
397  looseConstraintCovariance.setIdentity();
398  looseConstraintCovariance = looseConstraintCovariance * 1e+8;
399  dummyxAODVertex->setCovariancePosition(looseConstraintCovariance);
400  dummyxAODVertex->vxTrackAtVertex() = std::vector<Trk::VxTrackAtVertex>();
401  dummyxAODVertex->setVertexType(xAOD::VxType::NoVtx);
402  }
403 
404  int noVtx = 0;
405  int kinkVtx = 0;
406  int notSpec = 0;
407  int secVtx = 0;
408  int V0vtx = 0;
409  for (unsigned int i = 0; i < theVertexContainer->size(); i++) {
410  xAOD::VxType::VertexType vtxType;
411  vtxType = static_cast<xAOD::VxType::VertexType>((*theVertexContainer)[i]->vertexType());
412  switch (vtxType) {
413  case xAOD::VxType::NoVtx: noVtx++; break;
414  case xAOD::VxType::KinkVtx: kinkVtx++; break;
415  case xAOD::VxType::NotSpecified: notSpec++; break;
416  case xAOD::VxType::V0Vtx: V0vtx++; break;
417  case xAOD::VxType::SecVtx: secVtx++; break;
418  default: ATH_MSG_DEBUG("Unfamiliar vertex type");
419  }
420 
421  ATH_MSG_DEBUG(" Vtx: " << i << " x= " << (*theVertexContainer)[i]->position().x() << " y= "
422  << (*theVertexContainer)[i]->position().y() << " z= " << (*theVertexContainer)[i]->position().z()
423  << " ntracks= " << (*theVertexContainer)[i]->vxTrackAtVertex().size() << " chi2= "
424  << (*theVertexContainer)[i]->chiSquared() << " #dof = " << (*theVertexContainer)[i]->numberDoF());
425  }
426 
427  ATH_MSG_DEBUG("Done finding " << theVertexContainer->size() << " vertices and cleaning the container.");
428  ATH_MSG_DEBUG("Seeds good/bad/all : " << noVtx << "/" << kinkVtx << "/" << notSpec);
429  ATH_MSG_DEBUG("'Good' secondaries : " << secVtx << " and V0: " << V0vtx);
430 
431  return std::make_pair(theVertexContainer, theVertexAuxContainer);
432  }
433 
434  void InDetAdaptiveMultiSecVtxFinderTool::setPrimaryVertexPosition(double vx, double vy, double vz) {
435  m_privtx = Amg::Vector3D(vx, vy, vz);
436  }
437 
438  StatusCode InDetAdaptiveMultiSecVtxFinderTool::finalize() { return StatusCode::SUCCESS; }
439 
440  void InDetAdaptiveMultiSecVtxFinderTool::countTracksAndNdf(xAOD::Vertex* myxAODVertex, float& ndf, int& ntrk) const {
441  ndf = -3.0;
442  ntrk = 0;
443 
444  if (myxAODVertex) {
445  ndf = myxAODVertex->numberDoF();
446 
448 
449  for (Trk::VxTrackAtVertex* trkAtVtxIter : VTAV(*myxAODVertex)) {
450  if ((trkAtVtxIter)->weight() > m_minWghtAtVtx) { ntrk += 1; }
451  }
452  }
453  }
454 
455  const std::vector<Amg::Vector3D> InDetAdaptiveMultiSecVtxFinderTool::getVertexMomenta(xAOD::Vertex* myxAODVertex) const {
456  std::vector<Amg::Vector3D> TrkAtVtxMomenta;
457 
458  std::vector<Trk::VxTrackAtVertex>* tracksAtVertex = &(myxAODVertex->vxTrackAtVertex());
459 
460  ATH_MSG_DEBUG(" getVertexMomenta ... #Tracks associated at vertex : " << tracksAtVertex->size());
461 
462  for (const Trk::VxTrackAtVertex& tracksAtVertexIter : *tracksAtVertex) {
463  if ((tracksAtVertexIter).weight() <= m_minWghtAtVtx) continue;
464  {
465  const Trk::TrackParameters* sv_perigee = (tracksAtVertexIter).perigeeAtVertex();
466  if (!sv_perigee) {
467  ATH_MSG_DEBUG("perigeeAtVertex not available!!");
468  continue;
469  }
470 
471  double qp = 1. / (std::fabs(sv_perigee->parameters()[Trk::qOverP]));
472  double theta = sv_perigee->parameters()[Trk::theta];
473  double phi = sv_perigee->parameters()[Trk::phi];
474 
475  TrkAtVtxMomenta.emplace_back(qp * sin(theta) * cos(phi), qp * sin(theta) * sin(phi), qp * cos(theta));
476  }
477  }
478 
479  return TrkAtVtxMomenta;
480  }
481 
482  bool InDetAdaptiveMultiSecVtxFinderTool::checkFit(xAOD::Vertex* actualCandidate) const {
483  int ntracks = 0;
484  if (not actualCandidate) return false;
485  float ndf = actualCandidate->numberDoF();
486 
488 
489  for (Trk::VxTrackAtVertex* trkAtVtxIter : VTAV(*actualCandidate)) {
490  if ((trkAtVtxIter)->weight() > m_minWghtAtVtx) { ntracks += 1; }
491  }
492 
493  ATH_MSG_DEBUG(" xAOD::Vertex : " << (actualCandidate != nullptr ? 1 : 0) << ", #dof = " << ndf
494  << ", #tracks (weight>0.01) = " << ntracks);
495 
496  return ( ndf > 0 && ntracks >= 2);
497  }
498 
499  int InDetAdaptiveMultiSecVtxFinderTool::removeTracksFromSeeds(xAOD::Vertex* actualCandidate,
500  std::vector<Trk::ITrackLink*>& seedTracks) const {
501  if (not actualCandidate) return 0;
503 
504  std::vector<Trk::ITrackLink*>::iterator seedBegin = seedTracks.begin();
505  std::vector<Trk::ITrackLink*>::iterator seedEnd = seedTracks.end();
506 
507  bool goodVertex = checkFit(actualCandidate);
508 
509  int nFound = 0;
510 
511  for (Trk::VxTrackAtVertex* trkAtVtxIter : VTAV(*actualCandidate)) {
512  // delete the pointer to this vertex if the vertex was bad
513  if (!goodVertex) {
514  (static_cast<Trk::MVFVxTrackAtVertex*>(trkAtVtxIter))->linkToVertices()->vertices()->pop_back();
515  }
516 
517  std::vector<Trk::ITrackLink*>::iterator foundTrack = seedEnd;
518  for (std::vector<Trk::ITrackLink*>::iterator seedtrkiter = seedBegin; seedtrkiter != seedEnd; ++seedtrkiter) {
519  if ((*seedtrkiter)->parameters() == (trkAtVtxIter)->trackOrParticleLink()->parameters() &&
520  (trkAtVtxIter)->weight() > m_minWghtAtVtx) {
521  foundTrack = seedtrkiter;
522  }
523  }
524 
525  if (foundTrack != seedEnd) {
526  seedTracks.erase(foundTrack);
527 
528  nFound += 1;
529 
530  seedBegin = seedTracks.begin();
531  seedEnd = seedTracks.end();
532  }
533  }
534 
535  return nFound;
536  }
537 
538  float InDetAdaptiveMultiSecVtxFinderTool::findCompatibleTracks(Amg::Vector3D& seedVertex, Trk::ITrackLink* trkIter) const {
539  double distance = 0.;
540 
541  try {
542  std::unique_ptr<Trk::PlaneSurface> mySurface =
543  m_ImpactPoint3dEstimator->Estimate3dIP((trkIter)->parameters(), &seedVertex, distance);
544  ATH_MSG_VERBOSE(" ImpactPoint3dEstimator done ");
546  ATH_MSG_DEBUG(" ImpactPoint3dEstimator failed to find minimum distance between track and vertex seed: " << err.p);
547  }
548 
549  if (distance < 0) { ATH_MSG_DEBUG(" Distance between track and seed vtx is negative: " << distance); }
550 
551  const Trk::TrackParameters* myPerigee = ((trkIter)->parameters());
552  double doe = 99999999.9;
553  double error = 0.;
554 
555  if (myPerigee && myPerigee->covariance()) {
556  error = std::sqrt((*myPerigee->covariance())(Trk::d0, Trk::d0) + (*myPerigee->covariance())(Trk::z0, Trk::z0));
557  } // end of the security check
558 
559  if (error == 0.) {
560  ATH_MSG_ERROR(" Error is zero! " << distance);
561  error = 1.;
562  }
563 
564  doe = distance / error;
565 
566  ATH_MSG_VERBOSE("Distance between track and seed vtx: " << distance << " d/s(d) = " << distance / error << " err " << error);
567 
568  return doe;
569  }
570 
571  void InDetAdaptiveMultiSecVtxFinderTool::removeClosestTrack(Amg::Vector3D& seedVertex, std::vector<Trk::ITrackLink*>& seedTracks,
572  int& nFound) const {
573  const Trk::ITrackLink* nearestTrack = nullptr;
574  double dist = 1e8;
575 
576  for (Trk::ITrackLink* trkIter : seedTracks) {
577  double distance = 0.;
578  try {
579  std::unique_ptr<Trk::PlaneSurface> mySurface =
580  m_ImpactPoint3dEstimator->Estimate3dIP((trkIter)->parameters(), &seedVertex, distance);
582  ATH_MSG_DEBUG(" ImpactPoint3dEstimator failed to find minimum distance between this track and vertex seed: " << err.p);
583  }
584  ATH_MSG_DEBUG("Seed to track dist: " << distance);
585  if (distance < 0) { ATH_MSG_DEBUG("Distance was negative!"); }
586 
587  if (distance > 0 && !nearestTrack) {
588  dist = distance;
589  nearestTrack = trkIter;
590  }
591  if (distance > 0 && distance < dist) {
592  dist = distance;
593  nearestTrack = trkIter;
594  }
595  }
596  if (nearestTrack) {
597  ATH_MSG_DEBUG("Found closest track to seed and deleting.");
598  std::vector<Trk::ITrackLink*>::iterator seedBegin = seedTracks.begin();
599  std::vector<Trk::ITrackLink*>::iterator seedEnd = seedTracks.end();
600  nFound += 1;
601  std::vector<Trk::ITrackLink*>::iterator foundTrack = std::find(seedBegin, seedEnd, nearestTrack);
602  if (foundTrack != seedEnd) {
603  seedTracks.erase(foundTrack);
604  seedBegin = seedTracks.begin();
605  seedEnd = seedTracks.end();
606  } else {
607  ATH_MSG_DEBUG("The nearest track was not found!");
608  }
609  } else {
610  ATH_MSG_DEBUG("What else can I try?");
611  }
612  }
613 
614  bool InDetAdaptiveMultiSecVtxFinderTool::V0check(const std::vector<Amg::Vector3D>& momenta, const Amg::Vector3D& posi) const {
615  int ntrk = momenta.size();
616 
617  if (ntrk < 2) {
618  ATH_MSG_DEBUG(" ntrk < 2 , Meaningless to test mass ");
619  return false;
620  }
621 
622  std::vector<double> Pv(ntrk);
623  double vx = 0., vy = 0., vz = 0., eK0 = 0.;
624  double pi2 = 139.57018 * 139.57018; // Pion in MeV
625 
626  for (int t = 0; t < ntrk; t++) {
627  Amg::Vector3D trk = momenta[t];
628 
629  vz += trk.z();
630  vx += trk.x();
631  vy += trk.y();
632  Pv[t] = trk.x() * trk.x() + trk.y() * trk.y() + trk.z() * trk.z();
633  eK0 += std::sqrt(Pv[t] + pi2);
634  }
635 
636  double mnt2 = vx * vx + vy * vy + vz * vz;
637  double mass = eK0 * eK0 - mnt2;
638  mass = 0.001 * (std::sqrt(std::abs(mass)));
639 
640  Amg::Vector3D vdif = posi - m_privtx;
641  Amg::Vector3D vmoment = Amg::Vector3D(vx, vy, vz);
642 
643  double modir = vmoment.dot(vdif) / std::sqrt(mnt2);
644 
645  // borrowed from InnerDetector/InDetRecAlgs/InDetV0Finder/InDetV0FinderTool
646  double a0z = (vdif + vmoment * vmoment.dot(vdif) / (mnt2 + 0.00001)).z();
647  double Rxy = vdif.perp();
648 
649  ATH_MSG_DEBUG(" V0kine : a0z = " << a0z << " Rxy = " << Rxy << " direction " << modir);
650 
651  if (ntrk != 2) {
652  ATH_MSG_DEBUG(" ntrk != 2 , Meaningless to test V0 ");
653  return false;
654  }
655 
656  if (a0z > 15. || Rxy > 500.) { return false; }
657 
658  // 1 eV^(-1) of time = hbar / eV = 6.582173*10^(-16) second, for energy-time in natural unit
659  // double planck = 6.582173 ;
660 
661  double eGam = std::sqrt(Pv[0] + 0.511 * 0.511) + std::sqrt(Pv[1] + 0.511 * 0.511);
662  double mGam = eGam * eGam - mnt2;
663 
664  double prtn2 = 938.27205 * 938.27205;
665  double eLam = Pv[0] > Pv[1] ? std::sqrt(Pv[0] + prtn2) + std::sqrt(Pv[1] + pi2) : std::sqrt(Pv[0] + pi2) + std::sqrt(Pv[1] + prtn2);
666  double mLam = eLam * eLam - mnt2;
667 
668  ATH_MSG_DEBUG(" V0 masses : " << mass << " " << std::sqrt(std::abs(mGam)) << " " << std::sqrt(std::abs(mLam)));
669 
670  return ((fabs(mass - 497.614) < 100.) // K short
671  || (mGam > 0 && std::sqrt(mGam) < 40.) // gamma conversion ;
672  || (mLam > 0 && std::abs(std::sqrt(mLam) - 1115.683) < 200.) // Lambda
673  );
674  }
675 
676 } // end namespace InDet
grepfile.info
info
Definition: grepfile.py:38
xAOD::iterator
JetConstituentVector::iterator iterator
Definition: JetConstituentVector.cxx:68
covarianceTool.ndf
ndf
Definition: covarianceTool.py:678
operator<
bool operator<(const DataVector< T > &a, const DataVector< T > &b)
Vector ordering relation.
RecVertex.h
LinkToTrack.h
AllowedVariables::e
e
Definition: AsgElectronSelectorTool.cxx:37
MvfFitInfo.h
python.SystemOfUnits.second
int second
Definition: SystemOfUnits.py:120
xAOD::Vertex_v1::setPosition
void setPosition(const Amg::Vector3D &position)
Sets the 3-position.
python.tests.PyTestsLib.finalize
def finalize(self)
_info( "content of StoreGate..." ) self.sg.dump()
Definition: PyTestsLib.py:50
Amg::VectorX
Eigen::Matrix< double, Eigen::Dynamic, 1 > VectorX
Dynamic Vector - dynamic allocation.
Definition: EventPrimitives.h:30
xAOD::Vertex_v1::setFitQuality
void setFitQuality(float chiSquared, float numberDoF)
Set the 'Fit Quality' information.
Definition: Vertex_v1.cxx:150
Amg::MatrixX
Eigen::Matrix< double, Eigen::Dynamic, Eigen::Dynamic > MatrixX
Dynamic Matrix - dynamic allocation.
Definition: EventPrimitives.h:27
xAOD::VertexAuxContainer_v1
Temporary container used until we have I/O for AuxStoreInternal.
Definition: VertexAuxContainer_v1.h:32
Trk::MVFVxTrackAtVertex
Definition: MVFVxTrackAtVertex.h:31
TrackParameters.h
Trk::VxTrackAtVertex
The VxTrackAtVertex is a common class for all present TrkVertexFitters The VxTrackAtVertex is designe...
Definition: VxTrackAtVertex.h:77
phi
Scalar phi() const
phi method
Definition: AmgMatrixBasePlugin.h:67
xAOD::Vertex
Vertex_v1 Vertex
Define the latest version of the vertex class.
Definition: Event/xAOD/xAODTracking/xAODTracking/Vertex.h:16
find
std::string find(const std::string &s)
return a remapped string
Definition: hcg.cxx:135
Base_Fragment.mass
mass
Definition: Sherpa_i/share/common/Base_Fragment.py:59
InDet
Primary Vertex Finder.
Definition: VP1ErrorUtils.h:36
xAOD::VxType::V0Vtx
@ V0Vtx
Vertex from V0 decay.
Definition: TrackingPrimitives.h:575
initialize
void initialize()
Definition: run_EoverP.cxx:894
TrackParticleBase.h
EventPrimitivesHelpers.h
theta
Scalar theta() const
theta method
Definition: AmgMatrixBasePlugin.h:75
TRTCalib_cfilter.p1
p1
Definition: TRTCalib_cfilter.py:130
python.PhysicalConstants.pi2
float pi2
Definition: PhysicalConstants.py:52
Trk::z0
@ z0
Definition: ParamDefs.h:64
xAOD::Vertex_v1::position
const Amg::Vector3D & position() const
Returns the 3-pos.
read_hist_ntuple.t
t
Definition: read_hist_ntuple.py:5
drawFromPickle.cos
cos
Definition: drawFromPickle.py:36
ATH_MSG_VERBOSE
#define ATH_MSG_VERBOSE(x)
Definition: AthMsgStreamMacros.h:28
xAOD::VertexContainer
VertexContainer_v1 VertexContainer
Definition of the current "Vertex container version".
Definition: VertexContainer.h:14
x
#define x
ParamDefs.h
xAOD::VxType::NoVtx
@ NoVtx
Dummy vertex. TrackParticle was not used in vertex fit.
Definition: TrackingPrimitives.h:570
AmgSymMatrix
#define AmgSymMatrix(dim)
Definition: EventPrimitives.h:50
dqt_zlumi_pandas.weight
int weight
Definition: dqt_zlumi_pandas.py:189
Track.h
xAOD::VxType::VertexType
VertexType
Vertex types.
Definition: TrackingPrimitives.h:569
xAOD::Vertex_v1::setVertexType
void setVertexType(VxType::VertexType vType)
Set the type of the vertex.
python.setupRTTAlg.size
int size
Definition: setupRTTAlg.py:39
GeoPrimitives.h
TRTCalib_cfilter.p2
p2
Definition: TRTCalib_cfilter.py:131
python.utils.AtlRunQueryDQUtils.p
p
Definition: AtlRunQueryDQUtils.py:210
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
LinkToXAODTrackParticle.h
TrackParticleAuxContainer.h
SG::Decorator
Helper class to provide type-safe access to aux data.
Definition: Decorator.h:59
dqt_zlumi_pandas.err
err
Definition: dqt_zlumi_pandas.py:182
xAOD::VertexAuxContainer
VertexAuxContainer_v1 VertexAuxContainer
Definition of the current jet auxiliary container.
Definition: VertexAuxContainer.h:19
lumiFormat.i
int i
Definition: lumiFormat.py:85
z
#define z
beamspotman.n
n
Definition: beamspotman.py:731
Trk::theta
@ theta
Definition: ParamDefs.h:66
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
xAOD::VxType::SecVtx
@ SecVtx
Secondary vertex.
Definition: TrackingPrimitives.h:572
ATH_MSG_DEBUG
#define ATH_MSG_DEBUG(x)
Definition: AthMsgStreamMacros.h:29
error::ImpactPoint3dEstimatorProblem
Definition: IImpactPoint3dEstimator.h:72
InDet::InDetAdaptiveMultiSecVtxFinderTool::InDetAdaptiveMultiSecVtxFinderTool
InDetAdaptiveMultiSecVtxFinderTool(const std::string &t, const std::string &n, const IInterface *p)
Definition: InDetAdaptiveMultiSecVtxFinderTool.cxx:63
VxTrackAtVertex.h
Trk::LinkToXAODTrackParticle
Element link to XAOD TrackParticle.
Definition: LinkToXAODTrackParticle.h:33
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
xAOD::VxType::KinkVtx
@ KinkVtx
Kink vertex.
Definition: TrackingPrimitives.h:576
TrackSummary.h
Trk::ParametersBase
Definition: ParametersBase.h:55
DataVector
Derived DataVector<T>.
Definition: DataVector.h:794
Vertex.h
InDetAdaptiveMultiSecVtxFinderTool.h
LinkToTrackParticleBase.h
EventPrimitives.h
Trk::d0
@ d0
Definition: ParamDefs.h:63
createCoolChannelIdFile.par
par
Definition: createCoolChannelIdFile.py:29
Vertex.h
DataVector::push_back
value_type push_back(value_type pElem)
Add an element to the end of the collection.
SG::AuxElement::makePrivateStore
void makePrivateStore()
Create a new (empty) private store for this object.
Definition: AuxElement.cxx:192
Amg::Vector3D
Eigen::Matrix< double, 3, 1 > Vector3D
Definition: GeoPrimitives.h:47
IVertexFitter.h
IDTPM::chiSquared
float chiSquared(const U &p)
Definition: TrackParametersHelper.h:128
xAOD::Vertex_v1::numberDoF
float numberDoF() const
Returns the number of degrees of freedom of the vertex fit as float.
TrackParticle.h
DataVector.h
An STL vector of pointers that by default owns its pointed-to elements.
VertexContainer.h
InDetDD::other
@ other
Definition: InDetDD_Defs.h:16
xAOD::Vertex_v1::chiSquared
float chiSquared() const
Returns the of the vertex fit as float.
y
#define y
xAOD::Vertex_v1
Class describing a Vertex.
Definition: Vertex_v1.h:42
PlaneSurface.h
DeMoScan.first
bool first
Definition: DeMoScan.py:536
IMode3dFinder.h
IVertexLinearizedTrackFactory.h
Trk::qOverP
@ qOverP
perigee
Definition: ParamDefs.h:67
physics_parameters.parameters
parameters
Definition: physics_parameters.py:144
Trk::phi
@ phi
Definition: ParamDefs.h:75
xAOD::TrackParticle_v1
Class describing a TrackParticle.
Definition: TrackParticle_v1.h:43
MVFVxTrackAtVertex.h
drawFromPickle.sin
sin
Definition: drawFromPickle.py:36
xAOD::Vertex_v1::vxTrackAtVertex
std::vector< Trk::VxTrackAtVertex > & vxTrackAtVertex()
Non-const access to the VxTrackAtVertex vector.
Definition: Vertex_v1.cxx:181
get_generator_info.error
error
Definition: get_generator_info.py:40
FitQuality.h
error
Definition: IImpactPoint3dEstimator.h:70
Amg::distance
float distance(const Amg::Vector3D &p1, const Amg::Vector3D &p2)
calculates the distance between two point in 3D space
Definition: GeoPrimitivesHelpers.h:54
DataVector::size
size_type size() const noexcept
Returns the number of elements in the collection.
xAOD::VxType::NotSpecified
@ NotSpecified
Default value, no explicit type set.
Definition: TrackingPrimitives.h:577
xAOD::Vertex_v1::setCovariancePosition
void setCovariancePosition(const AmgSymMatrix(3)&covariancePosition)
Sets the vertex covariance matrix.
TrackParticleContainer.h
VertexAuxContainer.h
Trk::MvfFitInfo
Definition: MvfFitInfo.h:40