ATLAS Offline Software
Loading...
Searching...
No Matches
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"
35#include "TrkTrack/Track.h"
44#include "VxVertex/RecVertex.h"
45#include "VxVertex/Vertex.h"
50#include "xAODTracking/Vertex.h"
53
54namespace InDet {
55
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());
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;
74 xAOD::Vertex* second;
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*>
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());
165for (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();
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++) {
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
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
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
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
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.;
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
662 double mGam = eGam * eGam - mnt2;
663
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 - ParticleConstants::KZeroMassInMeV) < 100.) // K short
671 || (mGam > 0 && std::sqrt(mGam) < 40.) // gamma conversion ;
672 || (mLam > 0 && std::abs(std::sqrt(mLam) - ParticleConstants::lambdaMassInMeV) < 200.) // Lambda
673 );
674 }
675
676} // 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)
#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)
float findCompatibleTracks(Amg::Vector3D &seedVertex, Trk::ITrackLink *trkIter) const
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
void removeClosestTrack(Amg::Vector3D &seedVertex, std::vector< Trk::ITrackLink * > &seedTracks, int &nFound) const
std::pair< xAOD::VertexContainer *, xAOD::VertexAuxContainer * > findVertex(const xAOD::TrackParticleContainer *trackParticles) override
void makePrivateStore()
Create a new (empty) private store for this object.
SG::Decorator< T, ALLOC > Decorator
class to provide type-safe access to aux data.
Definition AuxElement.h:135
bool isAvailable(const ELT &e) const
Test to see if this variable exists in the store.
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".