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