ATLAS Offline Software
Loading...
Searching...
No Matches
InDetIterativePriVxFinderTool.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3 */
4
5/***************************************************************************
6 InDetIterativePriVxFinderTool.cxx - Description
7 -------------------
8 begin : 23-02-2010
9 authors : Giacinto Piacquadio (CERN PH-ADE-ID)
10 changes :
11 2016-04-26 David Shope <david.richard.shope@cern.ch>
12 EDM Migration to xAOD - from Trk::VxCandidate to xAOD::Vertex
13 findVertex will now always return an xAOD::VertexContainer,
14 even when using a TrackCollection.
15 as input.
16***************************************************************************/
25#include "TrkTrack/Track.h"
27
29#include "VxVertex/RecVertex.h"
31
35
39#include "xAODTracking/Vertex.h"
42
43#include <utility>
44#include <vector>
45
46namespace InDet {
48 const std::string& t,
49 const std::string& n,
50 const IInterface* p)
51 : AthAlgTool(t, n, p)
52{
53 declareInterface<IVertexFinder>(this);
54}
55
57
58StatusCode
60{
62 ATH_MSG_FATAL(" Split vertices cannot be obtained if beam spot constraint "
63 "is true! Change settings...");
64 return StatusCode::FAILURE;
65 }
66
67 /* Get the right vertex fitting tool from ToolSvc */
68 if (m_iVertexFitter.retrieve().isFailure()) {
69 ATH_MSG_FATAL("Failed to retrieve tool " << m_iVertexFitter);
70 return StatusCode::FAILURE;
71 }
72
73 if (m_SeedFinder.retrieve().isFailure()) {
74 ATH_MSG_FATAL("Failed to retrieve tool " << m_SeedFinder);
75 return StatusCode::FAILURE;
76 }
77
78 if (m_LinearizedTrackFactory.retrieve().isFailure()) {
79 ATH_MSG_FATAL("Failed to retrieve tool " << m_LinearizedTrackFactory);
80 return StatusCode::FAILURE;
81 }
82
83 if (m_ImpactPoint3dEstimator.retrieve().isFailure()) {
84 ATH_MSG_FATAL("Failed to retrieve tool " << m_ImpactPoint3dEstimator);
85 return StatusCode::FAILURE;
86 }
87
88 ATH_CHECK(m_beamSpotKey.initialize());
89
90 if (m_trkFilter.retrieve().isFailure()) {
91 ATH_MSG_ERROR(" Unable to retrieve " << m_trkFilter);
92 return StatusCode::FAILURE;
93 }
94
95 // since some parameters special to an inherited class this method
96 // will be overloaded by the inherited class
98
99 return StatusCode::SUCCESS;
100}
101
102namespace {
103struct xAODVertex_pair
104{
105 double first;
106 xAOD::Vertex* second;
107 xAODVertex_pair(double p1, xAOD::Vertex* p2)
108 : first(p1)
109 , second(p2)
110 {}
111 bool operator<(const xAODVertex_pair& other) const
112 {
113 return first > other.first;
114 }
115};
116} // anonymous namespace
117
118std::pair<xAOD::VertexContainer*, xAOD::VertexAuxContainer*>
120 const TrackCollection* trackTES) const
121{
122
124 " Number of input tracks before track selection: " << trackTES->size());
125
127 const InDet::BeamSpotData* beamSpot = *beamSpotHandle;
128
129 std::vector<Trk::ITrackLink*> selectedTracks;
130
131 using TrackDataVecIter = DataVector<Trk::Track>::const_iterator;
132
133 bool selectionPassed;
134 for (TrackDataVecIter itr = (*trackTES).begin(); itr != (*trackTES).end();
135 ++itr) {
136
137 if (m_useBeamConstraint && beamSpot != nullptr) {
138 Trk::RecVertex beamPosition{ beamSpot->beamVtx() };
139 selectionPassed =
140 static_cast<bool>(m_trkFilter->accept(**itr, &beamPosition));
141 } else {
142 Trk::Vertex null(Amg::Vector3D(0, 0, 0));
143 selectionPassed = static_cast<bool>(m_trkFilter->accept(**itr, &null));
144 }
145 if (selectionPassed) {
147 link.setElement(*itr);
148 Trk::LinkToTrack* linkTT = new Trk::LinkToTrack(link);
149 linkTT->setStorableObject(*trackTES);
150 selectedTracks.push_back(linkTT);
151 }
152 }
153
154 ATH_MSG_DEBUG("Of " << trackTES->size() << " tracks " << selectedTracks.size()
155 << " survived the preselection.");
156
157 std::pair<xAOD::VertexContainer*, xAOD::VertexAuxContainer*>
158 returnContainers = findVertex(ctx, selectedTracks);
159
160 return returnContainers;
161}
162
163std::pair<xAOD::VertexContainer*, xAOD::VertexAuxContainer*>
165 const EventContext& ctx,
166 const xAOD::TrackParticleContainer* trackParticles) const
167{
168 ATH_MSG_DEBUG(" Number of input tracks before track selection: "
169 << trackParticles->size());
170
172 const InDet::BeamSpotData* beamSpot = *beamSpotHandle;
173
174 std::vector<Trk::ITrackLink*> selectedTracks;
175
176 using TrackParticleDataVecIter =
178
179 bool selectionPassed;
180 for (TrackParticleDataVecIter itr = trackParticles->begin();
181 itr != trackParticles->end();
182 ++itr) {
183
184 if (m_useBeamConstraint && beamSpot != nullptr) {
185 xAOD::Vertex beamPosition;
186 beamPosition.makePrivateStore();
187 beamPosition.setPosition(beamSpot->beamVtx().position());
188 beamPosition.setCovariancePosition(
189 beamSpot->beamVtx().covariancePosition());
190 selectionPassed =
191 static_cast<bool>(m_trkFilter->accept(**itr, &beamPosition));
192 } else {
193
194 xAOD::Vertex null;
195 null.makePrivateStore();
196 null.setPosition(Amg::Vector3D(0, 0, 0));
197 AmgSymMatrix(3) vertexError;
198 vertexError.setZero();
199 null.setCovariancePosition(vertexError);
200 selectionPassed = static_cast<bool>(m_trkFilter->accept(**itr, &null));
201 }
202
203 if (selectionPassed) {
205 link.setElement(*itr);
208 linkTT->setStorableObject(*trackParticles);
209 selectedTracks.push_back(linkTT);
210 }
211 }
212
213 ATH_MSG_DEBUG("Of " << trackParticles->size() << " tracks "
214 << selectedTracks.size()
215 << " survived the preselection.");
216
217 std::pair<xAOD::VertexContainer*, xAOD::VertexAuxContainer*>
218 returnContainers = findVertex(ctx, selectedTracks);
219
220 return returnContainers;
221}
222
223std::pair<xAOD::VertexContainer*, xAOD::VertexAuxContainer*>
225 const EventContext& ctx,
226 const std::vector<Trk::ITrackLink*>& trackVector) const
227{
229 const InDet::BeamSpotData* beamSpot = *beamSpotHandle;
230 // two things need to be added
231 // 1) the seeding mechanism
232 // 2) the iterative removal of tracks
233
234 std::vector<Trk::ITrackLink*> origTracks = trackVector;
235 std::vector<Trk::ITrackLink*> seedTracks = trackVector;
236
237 // TODO: xAODVertex_pair never seems to be used?
238 std::vector<xAODVertex_pair> myxAODVertices;
239
240 xAOD::VertexContainer* theVertexContainer = new xAOD::VertexContainer;
241 xAOD::VertexAuxContainer* theVertexAuxContainer =
243 theVertexContainer->setStore(theVertexAuxContainer);
244
245 // bail out early with only Dummy vertex if multiplicity cut is applied and
246 // exceeded
247
248 if (m_doMaxTracksCut && (trackVector.size() > m_maxTracks)) {
249 ATH_MSG_WARNING(trackVector.size()
250 << " tracks - exceeds maximum (" << m_maxTracks
251 << "), skipping vertexing and returning only dummy...");
252 xAOD::Vertex* dummyxAODVertex = new xAOD::Vertex;
253 theVertexContainer->push_back(
254 dummyxAODVertex); // have to add vertex to container here first so it can
255 // use its aux store
256 dummyxAODVertex->setPosition(beamSpot->beamVtx().position());
257 dummyxAODVertex->setCovariancePosition(
258 beamSpot->beamVtx().covariancePosition());
259 dummyxAODVertex->vxTrackAtVertex() = std::vector<Trk::VxTrackAtVertex>();
260 dummyxAODVertex->setVertexType(xAOD::VxType::NoVtx);
261 return std::make_pair(theVertexContainer, theVertexAuxContainer);
262 }
263
264 int iterations = 0;
265 unsigned int seedtracknumber = seedTracks.size();
266
267 // used to store seed info
268 Amg::Vector3D actualVertex;
269
270 // prepare iterators for tracks only necessary for seeding
271 std::vector<Trk::ITrackLink*>::iterator seedBegin;
272 std::vector<Trk::ITrackLink*>::iterator seedEnd;
273
274 do {
275
276 seedBegin = seedTracks.begin();
277 seedEnd = seedTracks.end();
278
279 if (seedtracknumber == 0) {
280 ATH_MSG_DEBUG(" New iteration. No tracks available after track selection "
281 "for seeding. No finding done.");
282 break;
283 }
284
285 ATH_MSG_DEBUG("ITERATION NUMBER " << iterations);
286
287 // now find a new SEED
288
289 std::vector<const Trk::TrackParameters*> perigeeList;
290 for (std::vector<Trk::ITrackLink*>::iterator seedtrkAtVtxIter = seedBegin;
291 seedtrkAtVtxIter != seedEnd;
292 ++seedtrkAtVtxIter) {
293 perigeeList.push_back((*seedtrkAtVtxIter)->parameters());
294 }
295
296 xAOD::Vertex theconstraint;
297 if (m_useBeamConstraint && beamSpot != nullptr) {
298 theconstraint =
299 xAOD::Vertex(); // Default constructor creates a private store
300 theconstraint.setPosition(beamSpot->beamVtx().position());
301 theconstraint.setCovariancePosition(
302 beamSpot->beamVtx().covariancePosition());
303 theconstraint.setFitQuality(
304 beamSpot->beamVtx().fitQuality().chiSquared(),
305 beamSpot->beamVtx().fitQuality().doubleNumberDoF());
306 actualVertex = m_SeedFinder->findSeed(perigeeList, &theconstraint);
307 } else {
308 actualVertex = m_SeedFinder->findSeed(perigeeList);
309 Amg::MatrixX looseConstraintCovariance(3, 3);
310 looseConstraintCovariance.setIdentity();
311 looseConstraintCovariance = looseConstraintCovariance * 1e+8;
312 theconstraint = xAOD::Vertex();
313 theconstraint.setPosition(actualVertex);
314 theconstraint.setCovariancePosition(looseConstraintCovariance);
315 theconstraint.setFitQuality(0., -3.);
316 }
317
318 if (msgLvl(MSG::DEBUG)) {
319 msg(MSG::DEBUG) << " seed at x: " << actualVertex.x()
320 << " at y: " << actualVertex.y()
321 << " at z: " << actualVertex.z() << endmsg;
322 }
323
324 if (actualVertex.z() == 0.) {
325 break;
326 }
327
328 // now question (remove tracks which are too far away??? I think so...)
329 std::vector<const Trk::TrackParameters*> perigeesToFit;
330 std::vector<const Trk::TrackParameters*> perigeesToFitSplitVertex;
331
332 int numberOfTracks(perigeeList.size());
333
334 std::vector<const Trk::TrackParameters*>::const_iterator perigeeListBegin =
335 perigeeList.begin();
336 std::vector<const Trk::TrackParameters*>::const_iterator perigeeListEnd =
337 perigeeList.end();
338
339 int counter = 0;
340
341 for (std::vector<const Trk::TrackParameters*>::const_iterator
342 perigeeListIter = perigeeListBegin;
343 perigeeListIter != perigeeListEnd;
344 ++perigeeListIter) {
345 if (numberOfTracks <= 2) {
346 perigeesToFit.push_back(*perigeeListIter);
347 counter += 1;
348 } else if (numberOfTracks <= 4 && !m_createSplitVertices) {
349 perigeesToFit.push_back(*perigeeListIter);
350 counter += 1;
351 } else if (numberOfTracks <= 4 * m_splitVerticesTrkInvFraction &&
353 // few tracks are left, put them into the fit regardless their position!
354 if (counter % m_splitVerticesTrkInvFraction == 0) {
355 perigeesToFit.push_back(*perigeeListIter);
356 counter += 1;
357 } else {
358 perigeesToFitSplitVertex.push_back(*perigeeListIter);
359 counter += 1;
360 }
361 } else { // check first whether it is not too far away!
362 double distance = 0.;
363 try {
364 std::unique_ptr<Trk::PlaneSurface> mySurface =
365 m_ImpactPoint3dEstimator->Estimate3dIP(
366 *perigeeListIter, &actualVertex, distance);
368 msg(MSG::WARNING) << " ImpactPoint3dEstimator failed to find minimum "
369 "distance between track and vertex seed: "
370 << err.p << endmsg;
371 }
372
373 if (distance < 0) {
374 msg(MSG::WARNING)
375 << " Distance between track and seed vtx is negative: " << distance
376 << endmsg;
377 }
378
379 const Trk::TrackParameters* myPerigee = (*perigeeListIter);
380
381 // very approximate error
382 double error = 0.;
383
384 if (myPerigee && myPerigee->covariance()) {
385 error = std::sqrt((*myPerigee->covariance())(Trk::d0, Trk::d0) +
386 (*myPerigee->covariance())(Trk::z0, Trk::z0));
387 } // end of the security check
388
389 if (error == 0.) {
390 msg(MSG::ERROR) << " Error is zero! " << distance << endmsg;
391 error = 1.;
392 }
393
394 if (distance / error < m_significanceCutSeeding) {
395 if (counter % m_splitVerticesTrkInvFraction == 0 ||
397 perigeesToFit.push_back(*perigeeListIter);
398 counter += 1;
399 } else {
400 perigeesToFitSplitVertex.push_back(*perigeeListIter);
401 counter += 1;
402 }
403 }
404 }
405 }
406
407 if (perigeesToFit.empty()) {
408 ATH_MSG_DEBUG(" No good seed found. Exiting search for vertices...");
409 break;
410 }
411
412 // now you have perigeeToFit and perigeeToFitSplitVertices
413 // AND HERE YOU DO THE FIT
414 // to reassign vertices you look ino what is already in myVxCandidate
415 // you do it only ONCE!
416
417 xAOD::Vertex* myxAODVertex = nullptr;
418 xAOD::Vertex* myxAODSplitVertex = nullptr;
419
420 if (m_useBeamConstraint && !perigeesToFit.empty()) {
421 myxAODVertex = m_iVertexFitter->fit(perigeesToFit, theconstraint);
422 } else if (!m_useBeamConstraint && perigeesToFit.size() > 1) {
423 myxAODVertex = m_iVertexFitter->fit(perigeesToFit);
424 }
425 if (m_createSplitVertices && perigeesToFitSplitVertex.size() > 1) {
426 myxAODSplitVertex = m_iVertexFitter->fit(perigeesToFitSplitVertex);
427 }
428
429 double ndf = 0.;
430 int ntracks = 0;
431 countTracksAndNdf(myxAODVertex, ndf, ntracks);
432
433 double ndfSplitVertex = 0.;
434 int ntracksSplitVertex = 0;
435 countTracksAndNdf(myxAODSplitVertex, ndfSplitVertex, ntracksSplitVertex);
436
437 bool goodVertex = myxAODVertex != nullptr &&
438 ((!m_useBeamConstraint && ndf > 0 && ntracks >= 2) ||
439 (m_useBeamConstraint && ndf > 3 && ntracks >= 2));
440
441 if (msgLvl(MSG::DEBUG)) {
442 msg(MSG::DEBUG) << " xAOD::Vertex is pointer: " << myxAODVertex
443 << " ndf = " << ndf << " ntracks (with weight>0.01) "
444 << ntracks << " beam constraint "
445 << (m_useBeamConstraint ? "yes" : "no") << endmsg;
446 }
447
448 if (!goodVertex) {
449 removeAllFrom(perigeesToFit, seedTracks);
450 } else {
452 // now you HAVE a good vertex
453 // but you want to add the tracks which you missed...
454
455 int numberOfAddedTracks = 0;
456
457 // iterate on remaining vertices and cross-check if tracks need to be
458 // attached to new vertex
459 xAOD::VertexContainer::iterator vxBegin = theVertexContainer->begin();
460 xAOD::VertexContainer::iterator vxEnd = theVertexContainer->end();
461
462 for (xAOD::VertexContainer::iterator vxIter = vxBegin; vxIter != vxEnd;
463 ++vxIter) {
464 // now iterate on tracks at vertex
465
466 std::vector<Trk::VxTrackAtVertex>* myVxTracksAtVtx =
467 (&(*vxIter)->vxTrackAtVertex());
468
469 if (!myVxTracksAtVtx)
470 continue;
471
472 std::vector<Trk::VxTrackAtVertex>::iterator tracksBegin =
473 myVxTracksAtVtx->begin();
474 std::vector<Trk::VxTrackAtVertex>::iterator tracksEnd =
475 myVxTracksAtVtx->end();
476
477 for (std::vector<Trk::VxTrackAtVertex>::iterator tracksIter =
478 tracksBegin;
479 tracksIter != tracksEnd;) {
480 // only try with tracks which are not too tightly assigned to
481 // another vertex
482 if ((*tracksIter).weight() > 0.01) {
483 ++tracksIter;
484 continue;
485 }
486
487 const Trk::TrackParameters* trackPerigee =
488 (*tracksIter).initialPerigee();
489
490 if (trackPerigee == nullptr) {
491 ATH_MSG_ERROR("Cast to perigee gives null pointer");
492 return std::make_pair(theVertexContainer, theVertexAuxContainer);
493 }
494
495 double chi2_newvtx = compatibility(*trackPerigee, *myxAODVertex);
496 double chi2_oldvtx = compatibility(*trackPerigee, *(*vxIter));
497
498 bool remove = false;
499
500 if (chi2_newvtx < chi2_oldvtx) {
501 ATH_MSG_DEBUG(" Found track of old vertex (chi2= "
502 << chi2_oldvtx
503 << ") more compatible to new one (chi2= "
504 << chi2_newvtx << ")");
505
506 perigeesToFit.push_back(trackPerigee);
507 // but you need to re-add it to the seedTracks too...
508
509 bool isFound = false;
510
511 std::vector<Trk::ITrackLink*>::iterator origBegin =
512 origTracks.begin();
513 std::vector<Trk::ITrackLink*>::iterator origEnd =
514 origTracks.end();
515
516 for (std::vector<Trk::ITrackLink*>::iterator origIter = origBegin;
517 origIter != origEnd;
518 ++origIter) {
519 if ((*origIter)->parameters() == trackPerigee) {
520 isFound = true;
521 seedTracks.push_back(*origIter);
522 break;
523 }
524 }
525 if (!isFound) {
526 ATH_MSG_WARNING(" Cannot find old perigee to re-add back to "
527 "seed tracks... ");
528 }
529
530 numberOfAddedTracks += 1;
531
532 remove = true;
533 }
534
535 if (remove) {
536 // now you have to delete the track from the old vertex...
537 // easy???
538 tracksIter = myVxTracksAtVtx->erase(tracksIter);
539 tracksBegin = myVxTracksAtVtx->begin();
540 tracksEnd = myVxTracksAtVtx->end();
541 } else {
542 ++tracksIter;
543 }
544 } // end of iterating on tracks
545 } // end of iterating on already found vertices in event
546
547 // now you have to delete the previous xAOD::Vertex, do a new fit, then
548 // check if you still have a good vertex
549
550 if (numberOfAddedTracks > 0) {
551 delete myxAODVertex;
552 myxAODVertex = nullptr;
553
554 if (m_useBeamConstraint && !perigeesToFit.empty()) {
555 myxAODVertex = m_iVertexFitter->fit(perigeesToFit, theconstraint);
556 } else if (!m_useBeamConstraint && perigeesToFit.size() > 1) {
557 myxAODVertex = m_iVertexFitter->fit(perigeesToFit);
558 }
559
560 ndf = 0.;
561 ntracks = 0;
562 countTracksAndNdf(myxAODVertex, ndf, ntracks);
563
564 goodVertex = myxAODVertex != nullptr &&
565 ((!m_useBeamConstraint && ndf > 0 && ntracks >= 2) ||
566 (m_useBeamConstraint && ndf > 3 && ntracks >= 2));
567
568 ATH_MSG_DEBUG(" Refitted xAODVertex is pointer: "
569 << myxAODVertex << " ndf = " << ndf
570 << " ntracks (with weight>0.01) " << ntracks
571 << " beam constraint "
572 << (m_useBeamConstraint ? "yes" : "no"));
573
574 if (!goodVertex) {
575 removeAllFrom(perigeesToFit, seedTracks);
576 ATH_MSG_DEBUG(" Adding tracks resulted in an invalid vertex. "
577 "Should be rare. ");
578 }
579 } // end if tracks were added...
580 } // end reassign tracks from previous vertices and refitting if needed
581
582 // need to re-ask goodVertex since it can be changed in the mean time
583 if (goodVertex) {
584 removeCompatibleTracks(myxAODVertex, perigeesToFit, seedTracks);
585 }
586 } // end else case on if not good Vertex
587
588 bool goodSplitVertex = false;
589
591 goodSplitVertex = myxAODSplitVertex != nullptr && ndfSplitVertex > 0 &&
592 ntracksSplitVertex >= 2;
593
594 ATH_MSG_DEBUG(" xAODSplitVertex is pointer: "
595 << myxAODSplitVertex << " ndf = " << ndfSplitVertex
596 << " ntracks (with weight>0.01) " << ntracksSplitVertex);
597
598 if (!goodSplitVertex) {
599 removeAllFrom(perigeesToFitSplitVertex, seedTracks);
600 } else {
602 myxAODSplitVertex, perigeesToFitSplitVertex, seedTracks);
603
604 } // end else if not good Vertex
605 } // end if create split vertices
606
608 if (goodVertex) {
609 theVertexContainer->push_back(myxAODVertex);
610 } else {
611 if (myxAODVertex) {
612 delete myxAODVertex;
613 myxAODVertex = nullptr;
614 }
615 }
616 } else {
617 if (goodVertex) {
618 // type does not seem to be set earlier
619 myxAODVertex->setVertexType(xAOD::VxType::PriVtx);
620 theVertexContainer->push_back(myxAODVertex);
621 } else {
622 if (myxAODVertex) {
623 delete myxAODVertex;
624 myxAODVertex = nullptr;
625 }
626
627 xAOD::Vertex* dummyxAODVertex = new xAOD::Vertex;
628 theVertexContainer->push_back(
629 dummyxAODVertex); // have to add vertex to container here first so it
630 // can use its aux store
631 dummyxAODVertex->setPosition(beamSpot->beamVtx().position());
632 dummyxAODVertex->setCovariancePosition(
633 beamSpot->beamVtx().covariancePosition());
634 dummyxAODVertex->vxTrackAtVertex() =
635 std::vector<Trk::VxTrackAtVertex>();
636 dummyxAODVertex->setVertexType(xAOD::VxType::NoVtx);
637 }
638 if (goodSplitVertex) {
639 // type does not seem to be set earlier
640 myxAODSplitVertex->setVertexType(xAOD::VxType::PriVtx);
641 theVertexContainer->push_back(myxAODSplitVertex);
642 } else {
643 if (myxAODSplitVertex) {
644 delete myxAODSplitVertex;
645 myxAODSplitVertex = nullptr;
646 }
647
648 xAOD::Vertex* dummyxAODVertex = new xAOD::Vertex;
649 theVertexContainer->push_back(
650 dummyxAODVertex); // have to add vertex to container here first so it
651 // can use its aux store
652 dummyxAODVertex->setPosition(beamSpot->beamVtx().position());
653 dummyxAODVertex->setCovariancePosition(
654 beamSpot->beamVtx().covariancePosition());
655 dummyxAODVertex->vxTrackAtVertex() =
656 std::vector<Trk::VxTrackAtVertex>();
657 dummyxAODVertex->setVertexType(xAOD::VxType::NoVtx);
658 }
659 }
660
661 ++iterations;
662 } while (seedTracks.size() > 1 && iterations < m_maxVertices);
663
664 if (iterations == m_maxVertices) {
665 ATH_MSG_DEBUG("Reached maximum iterations, have "<<iterations<<" vertices");
666 }
667 else if (iterations > m_maxVertices) {
668 ATH_MSG_WARNING("Exceeded maximum iterations, have "<<iterations<<" vertices, m_maxVertices = "<<m_maxVertices);
669 }
670
671 //---- add dummy vertex at the end
672 //------------------------------------------------------//
673 //---- if one or more vertices are already there: let dummy have same position
674 // as primary vertex
676 if (!theVertexContainer->empty()) {
677 xAOD::Vertex* primaryVtx = theVertexContainer->front();
678 if (!primaryVtx->vxTrackAtVertex().empty()) {
680 xAOD::Vertex* dummyxAODVertex = new xAOD::Vertex;
681 theVertexContainer->push_back(
682 dummyxAODVertex); // have to add vertex to container here first so it
683 // can use its aux store
684 dummyxAODVertex->setPosition(primaryVtx->position());
685 dummyxAODVertex->setCovariancePosition(
686 primaryVtx->covariancePosition());
687 dummyxAODVertex->vxTrackAtVertex() =
688 std::vector<Trk::VxTrackAtVertex>();
689 dummyxAODVertex->setVertexType(xAOD::VxType::NoVtx);
690 } else {
692 }
693 }
694 //---- if no vertex is there let dummy be at beam spot
695
696 else if (theVertexContainer->empty()) {
697 xAOD::Vertex* dummyxAODVertex = new xAOD::Vertex;
698 theVertexContainer->push_back(
699 dummyxAODVertex); // have to add vertex to container here first so it
700 // can use its aux store
701 dummyxAODVertex->setPosition(beamSpot->beamVtx().position());
702 dummyxAODVertex->setCovariancePosition(
703 beamSpot->beamVtx().covariancePosition());
704 dummyxAODVertex->vxTrackAtVertex() = std::vector<Trk::VxTrackAtVertex>();
705 dummyxAODVertex->setVertexType(xAOD::VxType::NoVtx);
706 }
707 // loop over the pile up to set it as pile up (EXCLUDE first and last
708 // vertex, do not do that in split mode)
709 for (unsigned int i = 0; i < theVertexContainer->size() - 1; i++) {
710
712 " Vtx: " << i << " x= " << (*theVertexContainer)[i]->position().x()
713 << " y= " << (*theVertexContainer)[i]->position().y() << " z= "
714 << (*theVertexContainer)[i]->position().z() << " ntracks= "
715 << (*theVertexContainer)[i]->vxTrackAtVertex().size()
716 << " chi2= " << (*theVertexContainer)[i]->chiSquared()
717 << " ndf = " << (*theVertexContainer)[i]->numberDoF());
718 if (i > 0) {
719 (*theVertexContainer)[i]->setVertexType(xAOD::VxType::PileUp);
720 }
721 }
722 }
723
724 xAOD::VertexContainer::iterator vxBegin = theVertexContainer->begin();
725 xAOD::VertexContainer::iterator vxEnd = theVertexContainer->end();
726
727 // prepare iterators for tracks only necessary for seeding
728 std::vector<Trk::ITrackLink*>::iterator origtrkbegin = origTracks.begin();
729 std::vector<Trk::ITrackLink*>::iterator origtrkend = origTracks.end();
730
731 for (xAOD::VertexContainer::iterator vxIter = vxBegin; vxIter != vxEnd;
732 ++vxIter) {
733 std::vector<Trk::VxTrackAtVertex>* myVxTracksAtVtx =
734 &((*vxIter)->vxTrackAtVertex());
735
736 if (!myVxTracksAtVtx)
737 continue;
738
739 std::vector<Trk::VxTrackAtVertex>::iterator tracksBegin =
740 myVxTracksAtVtx->begin();
741 std::vector<Trk::VxTrackAtVertex>::iterator tracksEnd =
742 myVxTracksAtVtx->end();
743
744 bool found = false;
745
746 for (std::vector<Trk::VxTrackAtVertex>::iterator tracksIter = tracksBegin;
747 tracksIter != tracksEnd;
748 ++tracksIter) {
749
750 // now look for corresponding ITrackLink
751 for (std::vector<Trk::ITrackLink*>::iterator origtrkiter = origtrkbegin;
752 origtrkiter != origtrkend;
753 ++origtrkiter) {
754 if ((*origtrkiter)->parameters() == (*tracksIter).initialPerigee()) {
755 found = true;
756
757 // assigning the input track to the fitted vertex through
758 // VxTrackAtVertices vector
759 (*tracksIter).setOrigTrack(*origtrkiter);
760
761 // See if the trklink is to an xAOD::TrackParticle
762 Trk::LinkToXAODTrackParticle* linkToXAODTP = nullptr;
763 Trk::ITrackLink* tmpLink = (*tracksIter).trackOrParticleLink();
764 if (tmpLink->type() == Trk::ITrackLink::ToxAODTrackParticle) {
765 linkToXAODTP = static_cast<Trk::LinkToXAODTrackParticle*>(tmpLink);
766 }
767
768 // If track is an xAOD::TrackParticle, set directly in xAOD::Vertex
769 if (linkToXAODTP) {
770 (*vxIter)->addTrackAtVertex(*linkToXAODTP, (*tracksIter).weight());
771 }
772
773 origTracks.erase(origtrkiter);
774 origtrkbegin = origTracks.begin();
775 origtrkend = origTracks.end();
776 break;
777 }
778 }
779 if (!found) {
780 ATH_MSG_ERROR(" Cannot find vector element to fix links (step 4)! ");
781 }
782 } // end iterate on tracks at vtx
783 } // end iterate on vertices
784
785 for (std::vector<Trk::ITrackLink*>::iterator origtrkiter = origtrkbegin;
786 origtrkiter != origtrkend;
787 ++origtrkiter) {
788 if ((*origtrkiter) != 0) {
789 delete *origtrkiter;
790 *origtrkiter = 0;
791 }
792 }
793
794 return std::make_pair(theVertexContainer, theVertexAuxContainer);
795}
796
797StatusCode
799{
800 return StatusCode::SUCCESS;
801}
802
803void
805{
806 ATH_MSG_DEBUG("VxPrimary initialize(): Parametersettings "
807 << '\n'
808 << "VertexFitter " << m_iVertexFitter << '\n');
809}
810
811
812double
814 const Trk::TrackParameters& measPerigee,
815 const xAOD::Vertex& vertex) const
816{
817 Trk::LinearizedTrack* myLinearizedTrack =
818 m_LinearizedTrackFactory->linearizedTrack(&measPerigee, vertex.position());
819
820 AmgMatrix(2, 2) weightReduced =
821 myLinearizedTrack->expectedCovarianceAtPCA().block<2, 2>(0, 0);
822
823 AmgMatrix(2, 2) errorVertexReduced =
824 (myLinearizedTrack->positionJacobian() *
825 (vertex.covariancePosition() *
826 myLinearizedTrack->positionJacobian().transpose()))
827 .block<2, 2>(0, 0);
828
829 weightReduced += errorVertexReduced;
830
831 weightReduced = weightReduced.inverse().eval();
832 Amg::Vector2D trackParameters2D =
833 myLinearizedTrack->expectedParametersAtPCA().block<2, 1>(0, 0);
834 double returnValue = trackParameters2D.dot(weightReduced * trackParameters2D);
835
836 delete myLinearizedTrack;
837 myLinearizedTrack = nullptr;
838
839 return returnValue;
840}
841
842void
844 std::vector<const Trk::TrackParameters*>& perigeesToFit,
845 std::vector<Trk::ITrackLink*>& seedTracks) const
846{
847 // remove all perigeesToFit and go on...
848
849 std::vector<Trk::ITrackLink*>::iterator seedBegin = seedTracks.begin();
850 std::vector<Trk::ITrackLink*>::iterator seedEnd = seedTracks.end();
851
852 std::vector<const Trk::TrackParameters*>::iterator perigeesToFitBegin =
853 perigeesToFit.begin();
854 std::vector<const Trk::TrackParameters*>::iterator perigeesToFitEnd =
855 perigeesToFit.end();
856
857 for (std::vector<const Trk::TrackParameters*>::iterator perigeesToFitIter =
858 perigeesToFitBegin;
859 perigeesToFitIter != perigeesToFitEnd;
860 ++perigeesToFitIter) {
861
862 bool found = false;
863
864 for (std::vector<Trk::ITrackLink*>::iterator seedIter = seedTracks.begin();
865 seedIter != seedEnd;
866 ++seedIter) {
867 if ((*seedIter)->parameters() == *perigeesToFitIter) {
868 found = true;
869 seedTracks.erase(seedIter);
870 seedBegin = seedTracks.begin();
871 seedEnd = seedTracks.end();
872 break;
873 }
874 }
875 if (!found) {
877 " Cannot find vector element to delete when removing BAD vertex! ");
878 }
879 } // for cycle
880}
881
882void
884 double& ndf,
885 int& ntracks)
886{
887 if (myxAODVertex) {
888 ndf = myxAODVertex->numberDoF();
889
890 std::vector<Trk::VxTrackAtVertex> myVxTracksAtVtx =
891 myxAODVertex->vxTrackAtVertex();
892
893 std::vector<Trk::VxTrackAtVertex>::iterator tracksBegin =
894 myVxTracksAtVtx.begin();
895 std::vector<Trk::VxTrackAtVertex>::iterator tracksEnd =
896 myVxTracksAtVtx.end();
897
898 for (std::vector<Trk::VxTrackAtVertex>::iterator tracksIter = tracksBegin;
899 tracksIter != tracksEnd;
900 ++tracksIter) {
901 if ((*tracksIter).weight() > 0.01) {
902 ntracks += 1;
903 }
904 }
905 }
906}
907
908void
910 xAOD::Vertex* myxAODVertex,
911 std::vector<const Trk::TrackParameters*>& perigeesToFit,
912 std::vector<Trk::ITrackLink*>& seedTracks) const
913{
914 // now you have your new vertex with its new tracks
915 // now you have to get the compatibility also of all tracks which DIDN'T
916 // BELONG to the vertex!
917 std::vector<Trk::VxTrackAtVertex>* tracksAtVertex =
918 &(myxAODVertex->vxTrackAtVertex());
919
920 std::vector<Trk::VxTrackAtVertex>::const_iterator tracksAtVertexBegin =
921 tracksAtVertex->begin();
922 std::vector<Trk::VxTrackAtVertex>::const_iterator tracksAtVertexEnd =
923 tracksAtVertex->end();
924
925 std::vector<Trk::ITrackLink*>::iterator seedBegin = seedTracks.begin();
926 std::vector<Trk::ITrackLink*>::iterator seedEnd = seedTracks.end();
927
928 std::vector<const Trk::TrackParameters*>::iterator perigeesToFitBegin =
929 perigeesToFit.begin();
930 std::vector<const Trk::TrackParameters*>::iterator perigeesToFitEnd =
931 perigeesToFit.end();
932
933 for (std::vector<Trk::VxTrackAtVertex>::const_iterator tracksAtVertexIter =
934 tracksAtVertexBegin;
935 tracksAtVertexIter != tracksAtVertexEnd;
936 ++tracksAtVertexIter) {
937
938 bool found = false;
939
940 for (std::vector<Trk::ITrackLink*>::iterator seedIter = seedBegin;
941 seedIter != seedEnd;
942 ++seedIter) {
943 if ((*seedIter)->parameters() == (*tracksAtVertexIter).initialPerigee()) {
944 found = true;
945 if ((*tracksAtVertexIter).weight() > 0.01) {
946 seedTracks.erase(seedIter);
947 seedBegin = seedTracks.begin();
948 seedEnd = seedTracks.end();
949 }
950 break;
951 }
952 }
953
954 if (!found) {
955 ATH_MSG_ERROR(" Cannot find vector element to delete (step 1)! ");
956 }
957
958 found = false;
959 for (std::vector<const Trk::TrackParameters*>::iterator perigeesToFitIter =
960 perigeesToFitBegin;
961 perigeesToFitIter != perigeesToFitEnd;
962 ++perigeesToFitIter) {
963 if (*perigeesToFitIter == (*tracksAtVertexIter).initialPerigee()) {
964 found = true;
965 if ((*tracksAtVertexIter).weight() > 0.01) {
966 perigeesToFit.erase(perigeesToFitIter);
967 perigeesToFitBegin = perigeesToFit.begin();
968 perigeesToFitEnd = perigeesToFit.end();
969 }
970 break;
971 }
972 }
973
974 if (!found) {
975 ATH_MSG_ERROR(" Cannot find vector element to delete (step 2)! ");
976 }
977 } // finishing iterating on tracks at vertex
978
979 std::vector<Trk::VxTrackAtVertex>* myVxTracksAtVertex =
980 &(myxAODVertex->vxTrackAtVertex());
981
982 std::vector<Trk::VxTrackAtVertex>::iterator tracksBegin =
983 myVxTracksAtVertex->begin();
984 std::vector<Trk::VxTrackAtVertex>::iterator tracksEnd =
985 myVxTracksAtVertex->end();
986
987 for (std::vector<const Trk::TrackParameters*>::iterator perigeesToFitIter =
988 perigeesToFitBegin;
989 perigeesToFitIter != perigeesToFitEnd;
990 ++perigeesToFitIter) {
991 bool found = false;
992
993 // compute the chi2 with respect to the last fitted vertex!
994 //(easy since track was NOT used in the last vertex fit...)
995
996 const Trk::TrackParameters* myPerigee = (*perigeesToFitIter);
997
998 if (myPerigee == nullptr) {
999 ATH_MSG_ERROR(" nullptr to perigee ");
1000 return;
1001 }
1002
1003 double chi2 = compatibility(*myPerigee, *myxAODVertex);
1004
1005 // check if still sufficiently compatible to previous vertex
1006 //(CAN BE VERY LOOSE TO BE CONSERVATIVE AGAINST FAR OUTLIERS)
1008 for (std::vector<Trk::ITrackLink*>::iterator seedIter =
1009 seedTracks.begin();
1010 seedIter != seedEnd;
1011 ++seedIter) {
1012 if ((*seedIter)->parameters() == *perigeesToFitIter) {
1013 found = true;
1014 seedTracks.erase(seedIter);
1015 seedBegin = seedTracks.begin();
1016 seedEnd = seedTracks.end();
1017 break;
1018 }
1019 }
1020
1021 if (!found) {
1022 ATH_MSG_ERROR(" Cannot find vector element to delete (step 3)! ");
1023 }
1024 } else {
1025 // look if the track is attached to the vertex. If this is the case you
1026 // should delete the track from the vertex!
1027 for (std::vector<Trk::VxTrackAtVertex>::iterator tracksIter = tracksBegin;
1028 tracksIter != tracksEnd;
1029 ++tracksIter) {
1030 if ((*tracksIter).initialPerigee() == *perigeesToFitIter) {
1031 // delete *tracksIter;
1032 // delete has to happen BEFORE the erase (because the iterator will
1033 // point to the next object in the vector AFTER the erase!)
1034 myVxTracksAtVertex->erase(tracksIter);
1035 tracksBegin = myVxTracksAtVertex->begin();
1036 tracksEnd = myVxTracksAtVertex->end();
1037 found = true;
1038 break;
1039 }
1040 }
1041 }
1042 } // iterate on all perigeesToFit
1043}
1044
1045} // end namespace InDet
#define endmsg
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_ERROR(x)
#define ATH_MSG_FATAL(x)
#define ATH_MSG_WARNING(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 AmgMatrix(rows, cols)
DataVector< Trk::Track > TrackCollection
This typedef represents a collection of Trk::Track objects.
#define y
#define x
#define z
AthAlgTool(const std::string &type, const std::string &name, const IInterface *parent)
Constructor with parameters:
bool msgLvl(const MSG::Level lvl) const
MsgStream & msg() const
DataModel_detail::const_iterator< DataVector > const_iterator
Standard const_iterator.
Definition DataVector.h:838
value_type push_back(value_type pElem)
Add an element to the end of the collection.
DataModel_detail::iterator< DataVector > iterator
Definition DataVector.h:842
const_iterator end() const noexcept
Return a const_iterator pointing past the end of the collection.
const_iterator begin() const noexcept
Return a const_iterator pointing at the beginning 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
void printParameterSettings()
Internal method to print the parameters setting.
void removeCompatibleTracks(xAOD::Vertex *myxAODVertex, std::vector< const Trk::TrackParameters * > &perigeesToFit, std::vector< Trk::ITrackLink * > &seedTracks) const
InDetIterativePriVxFinderTool(const std::string &t, const std::string &n, const IInterface *p)
Constructor.
ToolHandle< Trk::IVertexFitter > m_iVertexFitter
virtual ~InDetIterativePriVxFinderTool()
Destructor.
double compatibility(const Trk::TrackParameters &measPerigee, const xAOD::Vertex &vertex) const
void removeAllFrom(std::vector< const Trk::TrackParameters * > &perigeesToFit, std::vector< Trk::ITrackLink * > &seedTracks) const
virtual std::pair< xAOD::VertexContainer *, xAOD::VertexAuxContainer * > findVertex(const EventContext &ctx, const TrackCollection *trackTES) const override
Finding method for Trk::Track collection.
ToolHandle< Trk::IVertexSeedFinder > m_SeedFinder
static void countTracksAndNdf(xAOD::Vertex *myxAODVertex, double &ndf, int &ntracks)
SG::ReadCondHandleKey< InDet::BeamSpotData > m_beamSpotKey
ToolHandle< Trk::IImpactPoint3dEstimator > m_ImpactPoint3dEstimator
ToolHandle< Trk::IVertexLinearizedTrackFactory > m_LinearizedTrackFactory
void makePrivateStore()
Create a new (empty) private store for this object.
AUTO - An Undocumented Tracking Object.
Definition LinkToTrack.h:20
Element link to XAOD TrackParticle.
Trk::RecVertex inherits from Trk::Vertex.
Definition RecVertex.h:44
This class is a simplest representation of a vertex candidate.
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.
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.
double chi2(TH1 *h0, TH1 *h1)
Eigen::Matrix< double, Eigen::Dynamic, Eigen::Dynamic > MatrixX
Dynamic Matrix - dynamic allocation.
Eigen::Matrix< double, 2, 1 > Vector2D
Eigen::Matrix< double, 3, 1 > Vector3D
Primary Vertex Finder.
@ PriVtx
Primary Vertex.
Definition VertexType.h:27
@ d0
Definition ParamDefs.h:63
@ z0
Definition ParamDefs.h:64
ParametersBase< TrackParametersDim, Charged > TrackParameters
VertexType
Vertex types.
@ PileUp
Pile-up vertex.
@ PriVtx
Primary vertex.
@ NoVtx
Dummy vertex. TrackParticle was not used in vertex fit.
VertexAuxContainer_v1 VertexAuxContainer
Definition of the current jet auxiliary container.
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".