52 , m_useBeamConstraint(false)
53 , m_significanceCutSeeding(10)
54 , m_maximumChi2cutForSeeding(6. * 6.)
56 , m_createSplitVertices(false)
57 , m_splitVerticesTrkInvFraction(2)
58 , m_reassignTracksAfterFirstFit(false)
59 , m_doMaxTracksCut(false)
62 declareInterface<IVertexFinder>(
this);
65 declareProperty(
"maximumChi2cutForSeeding", m_maximumChi2cutForSeeding);
69 m_splitVerticesTrkInvFraction,
70 "inverse fraction to split tracks (1:N)");
71 declareProperty(
"reassignTracksAfterFirstFit", m_reassignTracksAfterFirstFit);
82 ATH_MSG_FATAL(
" Split vertices cannot be obtained if beam spot constraint "
83 "is true! Change settings...");
84 return StatusCode::FAILURE;
90 return StatusCode::FAILURE;
95 return StatusCode::FAILURE;
100 return StatusCode::FAILURE;
105 return StatusCode::FAILURE;
112 return StatusCode::FAILURE;
119 return StatusCode::SUCCESS;
123 struct xAODVertex_pair
138 std::pair<xAOD::VertexContainer*, xAOD::VertexAuxContainer*>
144 " Number of input tracks before track selection: " << trackTES->
size());
149 std::vector<Trk::ITrackLink*> selectedTracks;
153 bool selectionPassed;
154 for (TrackDataVecIter itr = (*trackTES).begin(); itr != (*trackTES).end();
160 static_cast<bool>(
m_trkFilter->accept(**itr, &beamPosition));
163 selectionPassed =
static_cast<bool>(
m_trkFilter->accept(**itr, &
null));
165 if (selectionPassed) {
170 selectedTracks.push_back(linkTT);
175 <<
" survived the preselection.");
177 std::pair<xAOD::VertexContainer*, xAOD::VertexAuxContainer*>
178 returnContainers =
findVertex(ctx, selectedTracks);
180 return returnContainers;
183 std::pair<xAOD::VertexContainer*, xAOD::VertexAuxContainer*>
185 const EventContext& ctx,
188 ATH_MSG_DEBUG(
" Number of input tracks before track selection: "
189 << trackParticles->
size());
194 std::vector<Trk::ITrackLink*> selectedTracks;
196 using TrackParticleDataVecIter =
199 bool selectionPassed;
200 for (TrackParticleDataVecIter itr = trackParticles->
begin();
201 itr != trackParticles->
end();
209 beamSpot->beamVtx().covariancePosition());
211 static_cast<bool>(
m_trkFilter->accept(**itr, &beamPosition));
218 vertexError.setZero();
219 null.setCovariancePosition(vertexError);
220 selectionPassed =
static_cast<bool>(
m_trkFilter->accept(**itr, &
null));
223 if (selectionPassed) {
229 selectedTracks.push_back(linkTT);
234 << selectedTracks.size()
235 <<
" survived the preselection.");
237 std::pair<xAOD::VertexContainer*, xAOD::VertexAuxContainer*>
238 returnContainers =
findVertex(ctx, selectedTracks);
240 return returnContainers;
243 std::pair<xAOD::VertexContainer*, xAOD::VertexAuxContainer*>
245 const EventContext& ctx,
246 const std::vector<Trk::ITrackLink*>& trackVector)
const
254 std::vector<Trk::ITrackLink*> origTracks = trackVector;
255 std::vector<Trk::ITrackLink*> seedTracks = trackVector;
258 std::vector<xAODVertex_pair> myxAODVertices;
263 theVertexContainer->setStore(theVertexAuxContainer);
271 <<
"), skipping vertexing and returning only dummy...");
278 beamSpot->beamVtx().covariancePosition());
279 dummyxAODVertex->
vxTrackAtVertex() = std::vector<Trk::VxTrackAtVertex>();
281 return std::make_pair(theVertexContainer, theVertexAuxContainer);
285 unsigned int seedtracknumber = seedTracks.size();
296 seedBegin = seedTracks.begin();
297 seedEnd = seedTracks.end();
299 if (seedtracknumber == 0) {
300 ATH_MSG_DEBUG(
" New iteration. No tracks available after track selection "
301 "for seeding. No finding done.");
309 std::vector<const Trk::TrackParameters*> perigeeList;
311 seedtrkAtVtxIter != seedEnd;
312 ++seedtrkAtVtxIter) {
313 perigeeList.push_back((*seedtrkAtVtxIter)->parameters());
322 beamSpot->beamVtx().covariancePosition());
324 beamSpot->beamVtx().fitQuality().chiSquared(),
325 beamSpot->beamVtx().fitQuality().doubleNumberDoF());
326 actualVertex =
m_SeedFinder->findSeed(perigeeList, &theconstraint);
330 looseConstraintCovariance.setIdentity();
331 looseConstraintCovariance = looseConstraintCovariance * 1
e+8;
340 <<
" at y: " << actualVertex.y()
341 <<
" at z: " << actualVertex.z() <<
endmsg;
344 if (actualVertex.z() == 0.) {
349 std::vector<const Trk::TrackParameters*> perigeesToFit;
350 std::vector<const Trk::TrackParameters*> perigeesToFitSplitVertex;
352 int numberOfTracks(perigeeList.size());
354 std::vector<const Trk::TrackParameters*>::const_iterator perigeeListBegin =
356 std::vector<const Trk::TrackParameters*>::const_iterator perigeeListEnd =
361 for (std::vector<const Trk::TrackParameters*>::const_iterator
362 perigeeListIter = perigeeListBegin;
363 perigeeListIter != perigeeListEnd;
365 if (numberOfTracks <= 2) {
366 perigeesToFit.push_back(*perigeeListIter);
369 perigeesToFit.push_back(*perigeeListIter);
375 perigeesToFit.push_back(*perigeeListIter);
378 perigeesToFitSplitVertex.push_back(*perigeeListIter);
384 std::unique_ptr<Trk::PlaneSurface> mySurface =
386 *perigeeListIter, &actualVertex,
distance);
388 msg(MSG::WARNING) <<
" ImpactPoint3dEstimator failed to find minimum "
389 "distance between track and vertex seed: "
395 <<
" Distance between track and seed vtx is negative: " <<
distance
404 if (myPerigee && myPerigee->covariance()) {
417 perigeesToFit.push_back(*perigeeListIter);
420 perigeesToFitSplitVertex.push_back(*perigeeListIter);
427 if (perigeesToFit.empty()) {
428 ATH_MSG_DEBUG(
" No good seed found. Exiting search for vertices...");
453 double ndfSplitVertex = 0.;
454 int ntracksSplitVertex = 0;
457 bool goodVertex = myxAODVertex !=
nullptr &&
462 msg(
MSG::DEBUG) <<
" xAOD::Vertex is pointer: " << myxAODVertex
463 <<
" ndf = " <<
ndf <<
" ntracks (with weight>0.01) "
464 << ntracks <<
" beam constraint "
475 int numberOfAddedTracks = 0;
486 std::vector<Trk::VxTrackAtVertex>* myVxTracksAtVtx =
487 (&(*vxIter)->vxTrackAtVertex());
489 if (!myVxTracksAtVtx)
493 myVxTracksAtVtx->begin();
495 myVxTracksAtVtx->end();
499 tracksIter != tracksEnd;) {
502 if ((*tracksIter).weight() > 0.01) {
508 (*tracksIter).initialPerigee();
510 if (trackPerigee ==
nullptr) {
511 msg(MSG::ERROR) <<
" Cast to perigee gives 0 pointer " <<
endmsg;
514 double chi2_newvtx =
compatibility(*trackPerigee, *myxAODVertex);
515 double chi2_oldvtx =
compatibility(*trackPerigee, *(*vxIter));
519 if (chi2_newvtx < chi2_oldvtx) {
522 <<
") more compatible to new one (chi2= "
523 << chi2_newvtx <<
")");
525 perigeesToFit.push_back(trackPerigee);
528 bool isFound =
false;
538 if ((*origIter)->parameters() == trackPerigee) {
540 seedTracks.push_back(*origIter);
549 numberOfAddedTracks += 1;
557 tracksIter = myVxTracksAtVtx->erase(tracksIter);
558 tracksBegin = myVxTracksAtVtx->begin();
559 tracksEnd = myVxTracksAtVtx->end();
569 if (numberOfAddedTracks > 0) {
571 myxAODVertex =
nullptr;
583 goodVertex = myxAODVertex !=
nullptr &&
588 << myxAODVertex <<
" ndf = " <<
ndf
589 <<
" ntracks (with weight>0.01) " << ntracks
590 <<
" beam constraint "
595 ATH_MSG_DEBUG(
" Adding tracks resulted in an invalid vertex. "
607 bool goodSplitVertex =
false;
610 goodSplitVertex = myxAODSplitVertex !=
nullptr && ndfSplitVertex > 0 &&
611 ntracksSplitVertex >= 2;
614 << myxAODSplitVertex <<
" ndf = " << ndfSplitVertex
615 <<
" ntracks (with weight>0.01) " << ntracksSplitVertex);
617 if (!goodSplitVertex) {
621 myxAODSplitVertex, perigeesToFitSplitVertex, seedTracks);
628 theVertexContainer->
push_back(myxAODVertex);
632 myxAODVertex =
nullptr;
639 theVertexContainer->
push_back(myxAODVertex);
643 myxAODVertex =
nullptr;
652 beamSpot->beamVtx().covariancePosition());
654 std::vector<Trk::VxTrackAtVertex>();
657 if (goodSplitVertex) {
660 theVertexContainer->
push_back(myxAODSplitVertex);
662 if (myxAODSplitVertex) {
663 delete myxAODSplitVertex;
664 myxAODSplitVertex =
nullptr;
673 beamSpot->beamVtx().covariancePosition());
675 std::vector<Trk::VxTrackAtVertex>();
681 }
while (seedTracks.size() > 1 && iterations <
m_maxVertices);
684 ATH_MSG_DEBUG(
"Reached maximum iterations, have "<<iterations<<
" vertices");
697 if (!theVertexContainer->
empty()) {
707 primaryVtx->covariancePosition());
709 std::vector<Trk::VxTrackAtVertex>();
717 else if (theVertexContainer->
empty()) {
724 beamSpot->beamVtx().covariancePosition());
725 dummyxAODVertex->
vxTrackAtVertex() = std::vector<Trk::VxTrackAtVertex>();
730 for (
unsigned int i = 0;
i < theVertexContainer->
size() - 1;
i++) {
733 " Vtx: " <<
i <<
" x= " << (*theVertexContainer)[
i]->position().
x()
734 <<
" y= " << (*theVertexContainer)[
i]->position().
y() <<
" z= "
735 << (*theVertexContainer)[
i]->position().
z() <<
" ntracks= "
736 << (*theVertexContainer)[
i]->vxTrackAtVertex().
size()
737 <<
" chi2= " << (*theVertexContainer)[
i]->
chiSquared()
738 <<
" ndf = " << (*theVertexContainer)[
i]->numberDoF());
754 std::vector<Trk::VxTrackAtVertex>* myVxTracksAtVtx =
755 &((*vxIter)->vxTrackAtVertex());
757 if (!myVxTracksAtVtx)
761 myVxTracksAtVtx->begin();
763 myVxTracksAtVtx->end();
768 tracksIter != tracksEnd;
773 origtrkiter != origtrkend;
775 if ((*origtrkiter)->parameters() == (*tracksIter).initialPerigee()) {
780 (*tracksIter).setOrigTrack(*origtrkiter);
791 (*vxIter)->addTrackAtVertex(*linkToXAODTP, (*tracksIter).weight());
794 origTracks.erase(origtrkiter);
795 origtrkbegin = origTracks.begin();
796 origtrkend = origTracks.end();
801 ATH_MSG_ERROR(
" Cannot find vector element to fix links (step 4)! ");
807 origtrkiter != origtrkend;
809 if ((*origtrkiter) != 0) {
815 return std::make_pair(theVertexContainer, theVertexAuxContainer);
821 return StatusCode::SUCCESS;
847 myLinearizedTrack->expectedCovarianceAtPCA().block<2, 2>(0, 0);
850 (myLinearizedTrack->positionJacobian() *
851 (
vertex.covariancePosition() *
852 myLinearizedTrack->positionJacobian().transpose()))
855 weightReduced += errorVertexReduced;
857 weightReduced = weightReduced.inverse().eval();
859 myLinearizedTrack->expectedParametersAtPCA().block<2, 1>(0, 0);
860 double returnValue = trackParameters2D.
dot(weightReduced * trackParameters2D);
863 myLinearizedTrack =
nullptr;
871 std::
vector<
Trk::ITrackLink*>& seedTracks)
const
879 perigeesToFit.begin();
885 perigeesToFitIter != perigeesToFitEnd;
886 ++perigeesToFitIter) {
893 if ((*seedIter)->parameters() == *perigeesToFitIter) {
895 seedTracks.erase(seedIter);
896 seedBegin = seedTracks.begin();
897 seedEnd = seedTracks.end();
903 " Cannot find vector element to delete when removing BAD vertex! ");
916 std::vector<Trk::VxTrackAtVertex> myVxTracksAtVtx =
920 myVxTracksAtVtx.begin();
922 myVxTracksAtVtx.end();
925 tracksIter != tracksEnd;
927 if ((*tracksIter).weight() > 0.01) {
937 std::vector<const Trk::TrackParameters*>& perigeesToFit,
938 std::vector<Trk::ITrackLink*>& seedTracks)
const
943 std::vector<Trk::VxTrackAtVertex>* tracksAtVertex =
946 std::vector<Trk::VxTrackAtVertex>::const_iterator tracksAtVertexBegin =
947 tracksAtVertex->begin();
948 std::vector<Trk::VxTrackAtVertex>::const_iterator tracksAtVertexEnd =
949 tracksAtVertex->end();
955 perigeesToFit.begin();
959 for (std::vector<Trk::VxTrackAtVertex>::const_iterator tracksAtVertexIter =
961 tracksAtVertexIter != tracksAtVertexEnd;
962 ++tracksAtVertexIter) {
969 if ((*seedIter)->parameters() == (*tracksAtVertexIter).initialPerigee()) {
971 if ((*tracksAtVertexIter).weight() > 0.01) {
972 seedTracks.erase(seedIter);
973 seedBegin = seedTracks.begin();
974 seedEnd = seedTracks.end();
981 ATH_MSG_ERROR(
" Cannot find vector element to delete (step 1)! ");
987 perigeesToFitIter != perigeesToFitEnd;
988 ++perigeesToFitIter) {
989 if (*perigeesToFitIter == (*tracksAtVertexIter).initialPerigee()) {
991 if ((*tracksAtVertexIter).weight() > 0.01) {
992 perigeesToFit.erase(perigeesToFitIter);
993 perigeesToFitBegin = perigeesToFit.begin();
994 perigeesToFitEnd = perigeesToFit.end();
1001 ATH_MSG_ERROR(
" Cannot find vector element to delete (step 2)! ");
1005 std::vector<Trk::VxTrackAtVertex>* myVxTracksAtVertex =
1009 myVxTracksAtVertex->begin();
1011 myVxTracksAtVertex->end();
1015 perigeesToFitIter != perigeesToFitEnd;
1016 ++perigeesToFitIter) {
1024 if (myPerigee ==
nullptr) {
1036 seedIter != seedEnd;
1038 if ((*seedIter)->parameters() == *perigeesToFitIter) {
1040 seedTracks.erase(seedIter);
1041 seedBegin = seedTracks.begin();
1042 seedEnd = seedTracks.end();
1048 ATH_MSG_ERROR(
" Cannot find vector element to delete (step 3)! ");
1054 tracksIter != tracksEnd;
1056 if ((*tracksIter).initialPerigee() == *perigeesToFitIter) {
1060 myVxTracksAtVertex->erase(tracksIter);
1061 tracksBegin = myVxTracksAtVertex->begin();
1062 tracksEnd = myVxTracksAtVertex->end();