125 theVertexContainer->setStore(theVertexAuxContainer);
132 std::vector<xAODVertex_pair> myxAODVertices;
134 std::vector<Trk::TrackToVtxLink*> myTrackToVtxLinks;
137 std::vector<Trk::ITrackLink*> origTracks = trackVector;
138 std::vector<Trk::ITrackLink*> seedTracks = trackVector;
141 std::map<Trk::ITrackLink*, Trk::TrackToVtxLink*> TrackLinkOf;
149 TrackLinkOf[trkIter] = newTrkToVtxLink;
150 myTrackToVtxLinks.push_back(newTrkToVtxLink);
154 unsigned int seedtracknumber = seedTracks.size();
157 if (seedtracknumber == 0) {
ATH_MSG_DEBUG(
"New iteration. No tracks available after track selection for seeding."); }
160 ATH_MSG_DEBUG(
"Iteration number " << iteration <<
" and tracks left for seeding " << seedtracknumber);
162 std::vector<const Trk::TrackParameters*> perigeeList;
164 perigeeList.reserve(seedTracks.size());
165for (
const Trk::ITrackLink* seedtrkAtVtxIter : seedTracks) { perigeeList.push_back((seedtrkAtVtxIter)->parameters()); }
169 std::unique_ptr<Trk::IMode3dInfo> info;
173 ATH_MSG_DEBUG(
"Found seed at x: " << seedVertex.x() <<
" at y: " << seedVertex.y() <<
" at z: " << seedVertex.z());
176 theVertexContainer->
push_back(seededxAODVertex);
179 looseConstraintCovariance.setIdentity();
180 looseConstraintCovariance = looseConstraintCovariance * 1e+8;
182 seededxAODVertex->
vxTrackAtVertex() = std::vector<Trk::VxTrackAtVertex>();
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");
192 looseConstraintCovariance.setIdentity();
193 looseConstraintCovariance = looseConstraintCovariance * 1e+8;
205 MvfFitInfo(*actualCandidate) =
207 isInitialized(*actualCandidate) =
false;
208 std::vector<Trk::VxTrackAtVertex*> vectorOfTracks(0);
209 VTAV(*actualCandidate) = vectorOfTracks;
216 std::vector<xAOD::Vertex*>* actualvtxlink = actualLink->
vertices();
218 actualvtxlink->push_back(actualCandidate);
223 ATH_MSG_DEBUG(
" Considering n. " << VTAV(*actualCandidate).size() <<
" tracks for the fit. ");
225 if (VTAV(*actualCandidate).size() < 2) {
226 ATH_MSG_DEBUG(
"No tracks found near seed, while at least two tracks were expected.");
229 for (
auto *tav : VTAV(*actualCandidate)) {
230 if (tav ==
nullptr)
continue;
236 VTAV(*actualCandidate).clear();
238 if (MvfFitInfo.
isAvailable(*actualCandidate) && MvfFitInfo(*actualCandidate) !=
nullptr) {
239 delete MvfFitInfo(*actualCandidate);
240 MvfFitInfo(*actualCandidate) =
nullptr;
242 delete actualCandidate;
243 actualCandidate =
nullptr;
252 ATH_MSG_DEBUG(
"Deleting tracks with really good fit to vertex from seeding tracks.");
255 ATH_MSG_DEBUG(
"Found and deleted " << nFound <<
" tracks from seeding tracks.");
257 ATH_MSG_DEBUG(
"All tracks used for fitting came from fiting tracks, removing closest from seeding.");
265 ATH_MSG_DEBUG(
"You still have not removed any tracks from seeds! Aborting.");
270 bool goodVertex =
checkFit(actualCandidate);
273 ATH_MSG_DEBUG(
"Bad vertex, deleting the vertex and clearing all pointers");
277 if (actualCandidate) {
279 for (
auto *tav : VTAV(*actualCandidate)) {
280 if (tav ==
nullptr)
continue;
286 VTAV(*actualCandidate).clear();
288 if (MvfFitInfo.
isAvailable(*actualCandidate) && MvfFitInfo(*actualCandidate) !=
nullptr) {
289 delete MvfFitInfo(*actualCandidate);
290 MvfFitInfo(*actualCandidate) =
nullptr;
293 delete actualCandidate;
294 actualCandidate =
nullptr;
302 myxAODVertices.emplace_back(0, actualCandidate);
304 seedtracknumber = seedTracks.size();
309 <<
m_maxIterations <<
") reached; to reconstruct more vertices, set maxIterations to a higher value.");
312 ATH_MSG_DEBUG(
"Secondary vertex finding complete with " << iteration <<
" iterations and " << myxAODVertices.size()
313 <<
" vertices found.");
315 for (
const xAODVertex_pair& vtxIter : myxAODVertices) {
325 std::vector<Trk::VxTrackAtVertex>* tracksOfVertex = &(cand->
vxTrackAtVertex());
326 tracksOfVertex->clear();
329 if ((*MVFtrkIter).initialPerigee()) { (*MVFtrkIter).setPerigeeAtVertex(((*MVFtrkIter).initialPerigee())->clone()); }
330 tracksOfVertex->push_back(*MVFtrkIter);
334 for (
const xAODVertex_pair& vtxIter : myxAODVertices) {
340 MVFtrkIter =
nullptr;
343 delete MvfFitInfo(*cand);
349 std::vector<Trk::VxTrackAtVertex>* myVxTracksAtVtx = &((vxIter)->vxTrackAtVertex());
350 if (!myVxTracksAtVtx)
continue;
359 if (linkToXAODTP) { (vxIter)->addTrackAtVertex(*linkToXAODTP, (tracksIter).weight()); }
362 int ntrk = myVxTracksAtVtx->size();
377 if (!theVertexContainer->
empty()) {
382 theVertexContainer->
push_back(dummyxAODVertex);
385 dummyxAODVertex->
vxTrackAtVertex() = std::vector<Trk::VxTrackAtVertex>();
392 else if (theVertexContainer->
empty()) {
394 theVertexContainer->
push_back(dummyxAODVertex);
397 looseConstraintCovariance.setIdentity();
398 looseConstraintCovariance = looseConstraintCovariance * 1e+8;
400 dummyxAODVertex->
vxTrackAtVertex() = std::vector<Trk::VxTrackAtVertex>();
409 for (
unsigned int i = 0; i < theVertexContainer->
size(); i++) {
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());
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);
431 return std::make_pair(theVertexContainer, theVertexAuxContainer);
500 std::vector<Trk::ITrackLink*>& seedTracks)
const {
501 if (not actualCandidate)
return 0;
504 std::vector<Trk::ITrackLink*>::iterator seedBegin = seedTracks.begin();
505 std::vector<Trk::ITrackLink*>::iterator seedEnd = seedTracks.end();
507 bool goodVertex =
checkFit(actualCandidate);
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() &&
521 foundTrack = seedtrkiter;
525 if (foundTrack != seedEnd) {
526 seedTracks.erase(foundTrack);
530 seedBegin = seedTracks.begin();
531 seedEnd = seedTracks.end();
577 double distance = 0.;
579 std::unique_ptr<Trk::PlaneSurface> mySurface =
582 ATH_MSG_DEBUG(
" ImpactPoint3dEstimator failed to find minimum distance between this track and vertex seed: " << err.p);
585 if (distance < 0) {
ATH_MSG_DEBUG(
"Distance was negative!"); }
587 if (distance > 0 && !nearestTrack) {
589 nearestTrack = trkIter;
591 if (distance > 0 && distance < dist) {
593 nearestTrack = trkIter;
598 std::vector<Trk::ITrackLink*>::iterator seedBegin = seedTracks.begin();
599 std::vector<Trk::ITrackLink*>::iterator seedEnd = seedTracks.end();
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();
615 int ntrk = momenta.size();
622 std::vector<double> Pv(ntrk);
623 double vx = 0., vy = 0., vz = 0., eK0 = 0.;
626 for (
int t = 0; t < ntrk; t++) {
632 Pv[t] = trk.x() * trk.x() + trk.y() * trk.y() + trk.z() * trk.z();
633 eK0 += std::sqrt(Pv[t] + pi2);
636 double mnt2 = vx * vx + vy * vy + vz * vz;
637 double mass = eK0 * eK0 - mnt2;
638 mass = 0.001 * (std::sqrt(std::abs(mass)));
643 double modir = vmoment.dot(vdif) / std::sqrt(mnt2);
646 double a0z = (vdif + vmoment * vmoment.dot(vdif) / (mnt2 + 0.00001)).z();
647 double Rxy = vdif.perp();
649 ATH_MSG_DEBUG(
" V0kine : a0z = " << a0z <<
" Rxy = " << Rxy <<
" direction " << modir);
656 if (a0z > 15. || Rxy > 500.) {
return false; }
662 double mGam = eGam * eGam - mnt2;
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;
668 ATH_MSG_DEBUG(
" V0 masses : " << mass <<
" " << std::sqrt(std::abs(mGam)) <<
" " << std::sqrt(std::abs(mLam)));
671 || (mGam > 0 && std::sqrt(mGam) < 40.)
constexpr double KZeroMassInMeV
the mass of the neutral kaon (K0) (in MeV)
constexpr double lambdaMassInMeV
the mass of the lambda baryon (in MeV)