387 float aveX(0), aveY(0), aveR(0), aveZ(0);
391 for (
auto trkItr = tracklets.cbegin(); trkItr != tracklets.cend(); ++trkItr) {
392 aveR += trkItr->globalPosition().perp();
393 aveX += trkItr->globalPosition().x();
394 aveY += trkItr->globalPosition().y();
395 aveZ += trkItr->globalPosition().z();
398 aveX = aveX / (
float)tracklets.size();
399 aveY = aveY / (
float)tracklets.size();
400 aveZ = aveZ / (
float)tracklets.size();
401 aveR = aveR / (
float)tracklets.size();
403 float avePhi = std::atan2(aveY, aveX);
404 while (std::abs(avePhi) >
M_PI) {
412 float LoF = std::atan2(aveR, aveZ);
416 float Rpos[MAXPLANES];
418 float LoFdist = std::abs(RadialDist /
std::sin(LoF));
420 float PlaneSpacing = std::abs(200. /
std::cos(LoF));
424 std::vector<const Trk::TrackParameters*> TracksForVertexing[MAXPLANES];
425 std::vector<const Trk::TrackParameters*>
426 TracksForErrors[MAXPLANES];
427 std::vector<bool> isNeutralTrack[MAXPLANES];
429 for (
unsigned int i = 0;
i < tracklets.size(); ++
i) {
431 if (tracklets.at(
i).mdtChamber() <= 11 || tracklets.at(
i).mdtChamber() == 52) {
435 tracklets.at(
i).globalPosition().perp() *
std::sin(avePhi), tracklets.at(
i).globalPosition().z());
436 float x0 = trkgpos.x();
437 float y0 = trkgpos.y();
438 float r0 = trkgpos.perp();
443 float anglesign = 1.0;
444 if ((tracklets.at(
i).globalPosition().phi() - avePhi) < 0) anglesign = -1.0;
445 float NominalTrkAng = anglesign * NominalAngle;
446 float MaxTrkAng = anglesign * MaxOpenAngle;
449 for (
int k = 0;
k < nplanes; ++
k) {
451 if (Rpos[
k] > tracklets.at(
i).globalPosition().perp())
break;
458 float DelR = std::hypot(x0 - Xp, y0 - Yp) /
std::cos(NominalAngle);
459 float X1 = DelR *
std::cos(NominalTrkAng + avePhi) + Xp;
460 float Y1 = DelR *
std::sin(NominalTrkAng + avePhi) + Yp;
461 float R1 = std::hypot(X1, Y1);
465 float Dirmag = std::hypot(X1 - Xp, Y1 - Yp);
466 float Xdir = (X1 - Xp) / Dirmag;
467 float Ydir = (Y1 - Yp) / Dirmag;
468 float trkpx = Xdir * tracklets.at(
i).momentum().perp();
469 float trkpy = Ydir * tracklets.at(
i).momentum().perp();
470 float trkpz = tracklets.at(
i).momentum().z();
472 float charge = tracklets.at(
i).charge();
473 if (std::abs(
charge) < 0.1) {
475 isNeutralTrack[
k].push_back(
true);
477 isNeutralTrack[
k].push_back(
false);
481 Amg::Vector3D trkgpos(X1, Y1, tracklets.at(
i).globalPosition().z());
483 Trk::Perigee* myPerigee =
new Trk::Perigee(0., 0., trkmomentum.phi(), trkmomentum.theta(),
charge / trkmomentum.
mag(),
484 Trk::PerigeeSurface(trkgpos), covariance);
485 TracksForVertexing[
k].push_back(myPerigee);
488 float xp = Rpos[
k] * std::
cos(avePhi);
489 float yp = Rpos[
k] * std::
sin(avePhi);
490 float delR = std::hypot(x0 - xp, y0 - yp) / std::
cos(MaxOpenAngle);
491 float x1 = delR * std::
cos(MaxTrkAng + avePhi) + xp;
492 float y1 = delR * std::
sin(MaxTrkAng + avePhi) + yp;
493 float r1 = std::hypot(
x1,
y1);
494 float norm = r0 / r1;
497 float dirmag = std::hypot(
x1 - xp,
y1 - yp);
498 float xdir = (
x1 - xp) / dirmag;
499 float ydir = (
y1 - yp) / dirmag;
508 Trk::Perigee* errPerigee =
new Trk::Perigee(0., 0., trkerrmom.phi(), trkerrmom.theta(),
charge / trkerrmom.
mag(),
509 Trk::PerigeeSurface(trkerrpos), covariance2);
511 TracksForErrors[
k].push_back(errPerigee);
517 if (nTrkToVertex < 3) return;
520 bool boundaryCheck = true;
521 std::
vector<
float> ExtrapZ[MAXPLANES], dlength[MAXPLANES];
522 std::
vector<std::pair<
unsigned int,
unsigned int> > UsedTracks[MAXPLANES];
523 std::
vector<
bool> ExtrapSuc[MAXPLANES];
525 vertices.reserve(nplanes);
533 for (
int k = 0;
k < nplanes; ++
k) {
534 float rpos = Rpos[
k];
536 for (
unsigned int i = 0;
i < TracksForVertexing[
k].size(); ++
i) {
538 if (TracksForVertexing[
k].
size() < 3)
break;
541 surfaceTransformMatrix.setIdentity();
544 std::unique_ptr<const Trk::TrackParameters> extrap_par(
552 if (isNeutralTrack[
k].at(
i)) {
556 float extrapRdist = TracksForVertexing[
k].at(
i)->position().perp() - Rpos[
k];
557 float sz = std::abs(20 * dirErr * extrapRdist *
sq(pTot) /
sq(TracksForVertexing[
k].at(
i)->
momentum().
perp()));
558 float ExtrapErr =
sz;
559 if (ExtrapErr > maxError)
560 ExtrapSuc[
k].push_back(
false);
562 ExtrapSuc[
k].push_back(
true);
563 std::pair<unsigned int, unsigned int> trkmap(ExtrapZ[
k].
size(),
i);
564 UsedTracks[
k].push_back(trkmap);
565 ExtrapZ[
k].push_back(extrap->localPosition().y());
567 pAtVx[
k].push_back(extrap->momentum());
568 dlength[
k].push_back(0);
575 srfTransMat2.setIdentity();
577 std::unique_ptr<const Trk::TrackParameters> extrap_par2(
584 float zdiff = extrap->localPosition().y() - extrap2->localPosition().y();
585 float ExtrapErr = std::hypot(
sz, zdiff);
586 if (ExtrapErr > maxError)
587 ExtrapSuc[
k].push_back(
false);
590 ExtrapSuc[
k].push_back(
true);
591 std::pair<unsigned int, unsigned int> trkmap(ExtrapZ[
k].
size(),
i);
592 UsedTracks[
k].push_back(trkmap);
593 ExtrapZ[
k].push_back(extrap->localPosition().y());
595 pAtVx[
k].push_back(extrap->momentum());
596 dlength[
k].push_back(zdiff);
599 ExtrapSuc[
k].push_back(
false);
603 ExtrapSuc[
k].push_back(
false);
608 std::vector<Amg::Vector3D> trkp[MAXPLANES];
610 for (
int k = 0;
k < nplanes; ++
k) {
611 if (ExtrapZ[
k].
size() < 3)
continue;
615 float aveZpos(0), posWeight(0);
616 for (
unsigned int i = 0;
i < ExtrapZ[
k].size(); ++
i) {
617 float ExtrapErr = std::hypot(
sigmaZ[
k][
i], dlength[
k][
i], dzLoF);
618 if (isNeutralTrack[
k][
i]) ExtrapErr = std::hypot(
sigmaZ[
k][
i], dzLoF);
619 aveZpos += ExtrapZ[
k][
i] /
sq(ExtrapErr);
620 posWeight += 1. /
sq(ExtrapErr);
623 zLoF = aveZpos / posWeight;
624 float zpossigma(dzLoF), Chi2(0), Chi2Prob(-1);
626 std::vector<unsigned int> vxtracks;
627 std::vector<bool> blacklist;
628 for (
unsigned int i = 0;
i < ExtrapZ[
k].size(); ++
i) blacklist.push_back(
false);
635 float tmpzpossigma(0);
639 unsigned int iworst(0xC0FFEE);
641 for (
unsigned int i = 0;
i < ExtrapZ[
k].size(); ++
i) {
642 if (blacklist[
i])
continue;
643 trkp[
k].push_back(pAtVx[
k][
i]);
644 float delz = zLoF - ExtrapZ[
k][
i];
645 float ExtrapErr = std::hypot(
sigmaZ[
k][
i], dlength[
k][
i], dzLoF);
646 float trkchi2 =
sq(delz) /
sq(ExtrapErr);
647 if (trkchi2 > worstdelz) {
651 tmpzLoF += ExtrapZ[
k][
i] /
sq(ExtrapErr);
652 posWeight += 1. /
sq(ExtrapErr);
653 tmpzpossigma +=
sq(delz);
657 if (tmpnTrks < 3)
break;
658 tmpzpossigma = std::sqrt(tmpzpossigma / (
float)tmpnTrks);
659 zLoF = tmpzLoF / posWeight;
660 zpossigma = tmpzpossigma;
661 float testChi2 = TMath::Prob(tmpchi2, tmpnTrks - 1);
663 blacklist[iworst] =
true;
668 for (
unsigned int i = 0;
i < ExtrapZ[
k].size(); ++
i) {
669 float delz = zLoF - ExtrapZ[
k][
i];
670 float ExtrapErr = std::hypot(
sigmaZ[
k][
i], dlength[
k][
i], dzLoF);
671 float trkErr = std::hypot(ExtrapErr, zpossigma) + 0.001;
672 float trkNsigma = std::abs(delz / trkErr);
673 if (trkNsigma < 3) vxtracks.push_back(
i);
677 if (Nitr >= ((
int)ExtrapZ[
k].
size() - 3))
break;
680 if (vxtracks.size() < 3)
continue;
681 std::vector<xAOD::TrackParticle*> vxTrackParticles;
683 vxTrackParticles.reserve(vxtracks.size());
685 for (
unsigned int i = 0;
i < UsedTracks[
k].size(); ++
i) {
686 if ((*vxtrk) == UsedTracks[
k].at(
i).
first) {
691 Trk::PerigeeSurface(trklt.globalPosition()), covariance);
693 trackparticle->makePrivateStore();
694 trackparticle->setFitQuality(1., (
int)trklt.mdtHitsOnTrack().
size());
700 std::
vector<
float> covMatrixVec;
702 trackparticle->setDefiningParametersCovMatrixVec(covMatrixVec);
704 vxTrackParticles.push_back(trackparticle);
712 vertices.push_back(
new MSVertex(1, position, vxTrackParticles, Chi2Prob, Chi2, 0, 0, 0));
716 for (
int k = 0;
k < nplanes; ++
k) {
717 for (
unsigned int i = 0;
i < TracksForVertexing[
k].size(); ++
i)
delete TracksForVertexing[
k].at(
i);
718 for (
unsigned int i = 0;
i < TracksForErrors[
k].size(); ++
i)
delete TracksForErrors[
k].at(
i);
722 if (vertices.empty()) {
return; }
725 unsigned int bestVx(0);
726 for (
unsigned int k = 1;
k < vertices.size(); ++
k) {
727 if (vertices[
k]->getChi2Probability() <
m_VxChi2ProbCUT || vertices[
k]->getNTracks() < 3)
continue;
728 if (vertices[
k]->getNTracks() < vertices[bestVx]->getNTracks())
continue;
729 if (vertices[
k]->getNTracks() == vertices[bestVx]->getNTracks() &&
730 vertices[
k]->getChi2Probability() < vertices[bestVx]->getChi2Probability())
734 vtx.reset(vertices[bestVx]->
clone());