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