8 #include "CLHEP/Random/RandFlat.h"
17 constexpr
int MAXPLANES = 100;
19 constexpr
float sq(
float x) {
return (
x) * (
x); }
35 declareInterface<IMSVertexRecoTool>(
this);
82 return StatusCode::SUCCESS;
88 const EventContext& ctx)
const {
91 CLHEP::HepRandomEngine* rndmEngine = rngWrapper->
getEngine(ctx);
94 ATH_CHECK(xAODVxContainer.
record(std::make_unique<xAOD::VertexContainer>(), std::make_unique<xAOD::VertexAuxContainer>()));
101 if (tracklets.size() < 3) {
return StatusCode::SUCCESS; }
104 ATH_MSG_DEBUG(
"Too many tracklets found globally. Creating dummy MS vertex and exit.");
107 vertices.push_back(dummyVtx);
112 std::vector<Tracklet> BarrelTracklets;
113 std::vector<Tracklet> EndcapTracklets;
114 for (
unsigned int i = 0;
i < tracklets.size(); ++
i) {
115 if (tracklets.at(
i).mdtChamber() <= 11 || tracklets.at(
i).mdtChamber() == 52)
116 BarrelTracklets.push_back(tracklets.at(
i));
118 EndcapTracklets.push_back(tracklets.at(
i));
122 ATH_MSG_DEBUG(
"Too many tracklets found in barrel or endcap for clustering. Creating dummy MS vertex and exit");
125 vertices.push_back(dummyVtx);
129 ATH_MSG_DEBUG(
"Running on event with " << BarrelTracklets.size() <<
" barrel tracklets, " << EndcapTracklets.size()
130 <<
" endcap tracklets.");
133 std::vector<Muon::MSVertexRecoTool::TrkCluster> BarrelClusters =
findTrackClusters(BarrelTracklets);
134 std::vector<Muon::MSVertexRecoTool::TrkCluster> EndcapClusters =
findTrackClusters(EndcapTracklets);
136 for (
unsigned int i = 0;
i < BarrelClusters.size();
i++) {
137 if (BarrelClusters.at(
i).ntrks != (
int)BarrelClusters.at(
i).tracks.size()) {
138 ATH_MSG_INFO(
"ntrks not equal to track container size; this should never happen. Exiting quietly.");
142 for (
unsigned int i = 0;
i < EndcapClusters.size();
i++) {
143 if (EndcapClusters.at(
i).ntrks != (
int)EndcapClusters.at(
i).tracks.size()) {
144 ATH_MSG_INFO(
"ntrks not equal to track container size; this should never happen. Exiting quietly.");
151 std::vector<Tracklet> BarrelSystTracklets, EndcapSystTracklets;
152 for (
unsigned int i = 0;
i < BarrelTracklets.size(); ++
i) {
153 float prob = CLHEP::RandFlat::shoot(rndmEngine, 0, 1);
156 if (BarrelSystTracklets.size() >= 3) {
157 std::vector<Muon::MSVertexRecoTool::TrkCluster> BarrelSystClusters =
findTrackClusters(BarrelSystTracklets);
158 for (
unsigned int i = 0;
i < BarrelSystClusters.size(); ++
i) {
159 BarrelSystClusters.at(
i).isSystematic =
true;
160 BarrelClusters.push_back(BarrelSystClusters.at(
i));
163 for (
unsigned int i = 0;
i < EndcapTracklets.size(); ++
i) {
164 float prob = CLHEP::RandFlat::shoot(rndmEngine, 0, 1);
167 if (EndcapSystTracklets.size() >= 3) {
168 std::vector<Muon::MSVertexRecoTool::TrkCluster> EndcapSystClusters =
findTrackClusters(EndcapSystTracklets);
169 for (
unsigned int i = 0;
i < EndcapSystClusters.size(); ++
i) {
170 EndcapSystClusters.at(
i).isSystematic =
true;
171 EndcapClusters.push_back(EndcapSystClusters.at(
i));
178 for (
unsigned int i = 0;
i < BarrelClusters.size(); ++
i) {
179 if (BarrelClusters[
i].ntrks < 3)
continue;
180 ATH_MSG_DEBUG(
"Attempting to build vertex from " << BarrelClusters[
i].ntrks <<
" tracklets in the barrel");
181 std::unique_ptr<MSVertex> barvertex(
nullptr);
182 MSVxFinder(BarrelClusters[
i].tracks, barvertex, ctx);
183 if (!barvertex)
continue;
187 ATH_MSG_DEBUG(
"Vertex found in the barrel with n_trk = " << barvertex->
getNTracks() <<
" located at (eta,phi) = ("
190 if (BarrelClusters[
i].isSystematic) barvertex->
setAuthor(3);
191 vertices.push_back(barvertex.release());
197 for (
unsigned int i = 0;
i < EndcapClusters.size(); ++
i) {
198 if (EndcapClusters[
i].ntrks < 3)
continue;
199 ATH_MSG_DEBUG(
"Attempting to build vertex from " << EndcapClusters[
i].ntrks <<
" tracklets in the endcap");
201 std::unique_ptr<MSVertex> endvertex(
nullptr);
207 if (!endvertex)
continue;
212 ATH_MSG_DEBUG(
"Vertex found in the endcap with n_trk = " << endvertex->
getNTracks() <<
" located at (eta,phi) = ("
215 if (EndcapClusters[
i].isSystematic) endvertex->
setAuthor(4);
216 vertices.push_back(endvertex.release());
223 return StatusCode::SUCCESS;
230 ATH_MSG_DEBUG(
"Too many tracks found, returning empty cluster");
232 emptycluster.
ntrks = 0;
233 emptycluster.
eta = -99999.;
234 emptycluster.
phi = -99999.;
247 clu.
eta = trkItr->globalPosition().eta();
248 clu.
phi = trkItr->globalPosition().phi();
251 for (
unsigned int i = 0;
i < tracks.size(); ++
i) clu.
trks[
i] = 0;
253 trkClu[ncluster] = clu;
254 trkClu0[ncluster] = clu;
256 if (ncluster >= 99) {
258 emptycluster.
ntrks = 0;
259 emptycluster.
eta = -99999.;
260 emptycluster.
phi = -99999.;
261 for (
unsigned int i = 0;
i < tracks.size(); ++
i) emptycluster.
trks[
i] = 0;
267 for (
int icl = 0; icl < ncluster; ++icl) {
268 bool improvement =
true;
272 for (
int jcl = 0; jcl < ncluster; ++jcl) {
273 float dEta = trkClu[icl].
eta - trkClu0[jcl].
eta;
275 if (std::abs(
dEta) < 0.7 && std::abs(
dPhi) <
M_PI / 3.) {
277 trkClu[icl].
eta = trkClu[icl].
eta -
dEta / ntracks;
278 trkClu[icl].
phi = trkClu[icl].
phi -
dPhi / ntracks;
279 while (std::abs(trkClu[icl].
phi) >
M_PI) {
280 if (trkClu[icl].
phi > 0)
288 double eta_avg_best = trkClu[icl].
eta;
289 double phi_avg_best = trkClu[icl].
phi;
291 while (improvement) {
293 for (
int k = 0;
k < ncluster; ++
k) itracks[
k] = 0;
295 double eta_avg = 0.0;
296 double phi_avg = 0.0;
297 double cosPhi_avg = 0.0;
298 double sinPhi_avg = 0.0;
300 for (
int jcl = 0; jcl < ncluster; ++jcl) {
301 float dEta = std::abs(trkClu[icl].
eta - trkClu0[jcl].
eta);
304 eta_avg += trkClu0[jcl].
eta;
312 eta_avg = eta_avg / ntracks2;
313 phi_avg = std::atan2(sinPhi_avg, cosPhi_avg);
315 if (ntracks2 > trkClu[icl].ntrks) {
316 eta_avg_best = trkClu[icl].
eta;
317 phi_avg_best = trkClu[icl].
phi;
318 trkClu[icl].
ntrks = ntracks2;
319 for (
int k = 0;
k < ncluster; ++
k) { trkClu[icl].
trks[
k] = itracks[
k]; }
321 trkClu[icl].
eta = eta_avg;
322 trkClu[icl].
phi = phi_avg;
327 trkClu[icl].
eta = eta_avg_best;
328 trkClu[icl].
phi = phi_avg_best;
338 for (
int icl = 1; icl < ncluster; ++icl) {
339 if (trkClu[icl].ntrks > BestClusterptr->
ntrks) BestClusterptr = &trkClu[icl];
343 std::vector<Tracklet> unusedTracks;
345 float dEta = std::abs(BestCluster.
eta - trkItr->globalPosition().eta());
348 BestCluster.
tracks.push_back((*trkItr));
350 unusedTracks.push_back((*trkItr));
353 tracks = std::move(unusedTracks);
360 std::vector<Tracklet> trks = tracks;
364 if (trks.size() < 3)
break;
366 if (clust.
ntrks >= 3)
370 if (trks.size() < 3)
break;
384 const EventContext& ctx)
const {
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);
462 float Norm = r0 / R1;
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());
485 TracksForVertexing[
k].push_back(myPerigee);
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;
500 float errpx = xdir * tracklets.at(
i).momentum().perp();
501 float errpy = ydir * tracklets.at(
i).momentum().perp();
502 float errpz = tracklets.at(
i).momentum().z();
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];
524 std::vector<MSVertex*> vertices;
525 vertices.reserve(nplanes);
528 std::vector<float>
sigmaZ[MAXPLANES];
531 std::vector<Amg::Vector3D> pAtVx[MAXPLANES];
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) {
700 std::vector<float> 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());
746 const EventContext& ctx)
const {
748 std::set<std::set<int> > prelim_vx;
752 if (trks.size() > 40) {
759 for (
unsigned int i = 0;
i < trks.size() - 2;
i++) {
760 for (
unsigned int j =
i + 1; j < trks.size() - 1; j++) {
761 for (
unsigned int k = j + 1;
k < trks.size();
k++) {
762 std::set<int> tmpTracks;
769 if (MyVx.perp() < 10000 && std::abs(MyVx.z()) > 7000 && std::abs(MyVx.z()) < 15000 &&
771 prelim_vx.insert(tmpTracks);
777 if (prelim_vx.empty())
return;
781 if (trks.size() <= 20) {
782 std::set<std::set<int> > new_prelim_vx = prelim_vx;
783 std::set<std::set<int> > old_prelim_vx;
785 int foundNewVx =
true;
789 old_prelim_vx = new_prelim_vx;
790 new_prelim_vx.clear();
792 for (
std::set<std::set<int> >::
iterator itr = old_prelim_vx.begin(); itr != old_prelim_vx.end(); ++itr) {
793 for (
unsigned int i_trks = 0; i_trks < trks.size(); i_trks++) {
794 std::set<int> tempCluster = *itr;
795 if (tempCluster.insert(i_trks).second) {
797 if (MyVx.perp() < 10000 && std::abs(MyVx.z()) > 7000 && std::abs(MyVx.z()) < 15000 &&
799 new_prelim_vx.insert(tempCluster);
800 prelim_vx.insert(tempCluster);
817 std::set<std::set<int> >
::iterator prelim_vx_max = prelim_vx.begin();
818 for (
std::set<std::set<int> >::
iterator itr = prelim_vx.begin(); itr != prelim_vx.end(); ++itr) {
819 if ((*itr).size() > (*prelim_vx_max).size()) prelim_vx_max = itr;
822 std::vector<Tracklet> tracklets =
getTracklets(trks, *prelim_vx_max);
827 aveX += ((
Tracklet)*trkItr).globalPosition().x();
828 aveY += ((
Tracklet)*trkItr).globalPosition().y();
830 float tracklet_vxphi = std::atan2(aveY, aveX);
832 float vxtheta = std::atan2(MyVx.x(), MyVx.z());
833 float vxphi =
vxPhiFinder(std::abs(vxtheta), tracklet_vxphi, ctx);
835 std::vector<xAOD::TrackParticle*> vxTrkTracks;
847 std::vector<float> covMatrixVec;
851 vxTrkTracks.push_back(myTrack);
856 vtx = std::make_unique<MSVertex>(2, vxpos, vxTrkTracks, 1, vxTrkTracks.size(), 0, 0, 0);
871 const EventContext& ctx)
const {
873 float aveX(0), aveY(0);
874 for (
auto trkItr = trks.cbegin(); trkItr != trks.cend(); ++trkItr) {
875 aveX += trkItr->globalPosition().x();
876 aveY += trkItr->globalPosition().y();
878 float vxphi = std::atan2(aveY, aveX);
881 std::vector<Tracklet> tracks =
RemoveBadTrk(trks, MyVx);
882 if (tracks.size() < 2)
return;
887 if (tracks.size() ==
Tracks.size())
break;
888 tracks = std::move(
Tracks);
890 if (tracks.size() >= 3 && MyVx.x() > 0) {
891 float vxtheta = std::atan2(MyVx.x(), MyVx.z());
892 vxphi =
vxPhiFinder(std::abs(vxtheta), vxphi, ctx);
895 std::vector<xAOD::TrackParticle*> vxTrackParticles;
899 new Trk::Perigee(0., 0., trklt->momentum().phi(), trklt->momentum().theta(), trklt->charge() / trklt->momentum().mag(),
903 trackparticle->
setFitQuality(1., (
int)trklt->mdtHitsOnTrack().size());
909 std::vector<float> covMatrixVec;
913 vxTrackParticles.push_back(trackparticle);
918 vtx = std::make_unique<MSVertex>(2, vxpos, vxTrackParticles, 1, (
float)vxTrackParticles.size(), 0, 0, 0);
925 float MaxTollDist = 300;
926 std::vector<Tracklet>
Tracks;
927 if (Vx.x() == 0 && Vx.z() == 0)
return tracks;
929 float WorstTrkDist = MaxTollDist;
930 unsigned int iWorstTrk = 0xC0FFEE;
931 for (
unsigned int i = 0;
i < tracks.size(); ++
i) {
932 float TrkSlope =
std::tan(tracks.at(
i).getML1seg().alpha());
933 float TrkInter = tracks.at(
i).getML1seg().globalPosition().perp() - tracks.at(
i).getML1seg().globalPosition().z() * TrkSlope;
934 float dist = std::abs((TrkSlope * Vx.z() - Vx.x() + TrkInter) / std::sqrt(
sq(TrkSlope) + 1));
935 if (dist > MaxTollDist && dist > WorstTrkDist) {
942 for (
unsigned int i = 0;
i < tracks.size(); ++
i) {
943 if (
i != iWorstTrk)
Tracks.push_back(tracks.at(
i));
949 std::vector<Tracklet> returnVal;
950 for (
auto itr = tracklet_subset.cbegin(); itr != tracklet_subset.cend(); ++itr) {
951 if ((
unsigned int)*itr > trks.size())
ATH_MSG_ERROR(
"ERROR - Index out of bounds in getTracklets");
952 returnVal.push_back(trks.at(*itr));
962 if (Vx.x() == 0 && Vx.z() == 0)
return true;
964 float WorstTrkDist = MaxTollDist;
969 float dist = std::abs((TrkSlope * Vx.z() - Vx.x() + TrkInter) / std::sqrt(
sq(TrkSlope) + 1));
970 if (dist > MaxTollDist && dist > WorstTrkDist) {
return true; }
983 for (std::vector<MSVertex*>::const_iterator vxIt = vertices.begin(); vxIt != vertices.end(); ++vxIt) {
988 xAODVx->
setFitQuality((*vxIt)->getChi2(), (*vxIt)->getNTracks() - 1);
994 hMDT(*xAODVx) = (*vxIt)->getNMDT();
995 hRPC(*xAODVx) = (*vxIt)->getNRPC();
996 hTGC(*xAODVx) = (*vxIt)->getNTGC();
1000 for (
auto *
x : vertices)
delete x;
1004 return StatusCode::SUCCESS;
1011 double s(0.),
sx(0.),
sy(0.), sxy(0.), sxx(0.),
d(0.);
1013 for (
unsigned int i = 0;
i < tracks.size(); ++
i) {
1014 double TrkSlope =
std::tan(tracks.at(
i).getML1seg().alpha());
1015 double TrkInter = tracks.at(
i).getML1seg().globalPosition().perp() - tracks.at(
i).getML1seg().globalPosition().z() * TrkSlope;
1020 sxy += (TrkSlope * TrkInter) /
sq(
sigma);
1028 double Rpos = (sxx *
sy -
sx * sxy) /
d;
1029 double Zpos = (
sx *
sy -
s * sxy) /
d;
1048 <<
", (theta>M_PI), return 0");
1052 if (tanThetaHalf <= 0) {
1054 <<
", resulting in tan(0.5*theta)<=0, return 0");
1058 if (std::abs(
eta) < 1.5) {
1066 for (; RpcItr != RpcItrE; ++RpcItr) {
1069 for (; rpcItr != rpcItrE; ++rpcItr) {
1070 if (
m_idHelperSvc->rpcIdHelper().measuresPhi((*rpcItr)->identify())) {
1071 float rpcEta = (*rpcItr)->globalPosition().eta();
1072 float rpcPhi = (*rpcItr)->globalPosition().phi();
1073 float dphi =
phi - rpcPhi;
1076 else if (dphi < -
M_PI)
1078 float deta =
eta - rpcEta;
1079 float DR = std::hypot(deta, dphi);
1089 if (std::abs(
eta) > 0.5) {
1097 for (; TgcItr != TgcItrE; ++TgcItr) {
1100 for (; tgcItr != tgcItrE; ++tgcItr) {
1101 if (
m_idHelperSvc->tgcIdHelper().isStrip((*tgcItr)->identify())) {
1102 float tgcEta = (*tgcItr)->globalPosition().eta();
1103 float tgcPhi = (*tgcItr)->globalPosition().phi();
1104 float dphi =
phi - tgcPhi;
1107 else if (dphi < -
M_PI)
1109 float deta =
eta - tgcEta;
1110 float DR = std::hypot(deta, dphi);
1121 if (nmeas > 0) vxphi = std::atan2(sinphi / nmeas, cosphi / nmeas);
1129 int nHighOccupancy(0);
1133 if (msVtxPos.x() == 0 && msVtxPos.y() == 0 && msVtxPos.z() != 0) {
1134 ATH_MSG_WARNING(
"given MSVertex has position x=y=0 and z!=0, eta() method will cause FPE, returning...");
1143 for (; MDTItr != MDTItrE; ++MDTItr) {
1144 if ((*MDTItr)->empty())
continue;
1147 Amg::Vector3D ChamberCenter = (*mdt)->detectorElement()->center();
1148 float deta = std::abs(msVtxPos.eta() - ChamberCenter.eta());
1149 if (deta > 0.6)
continue;
1150 float dphi = msVtxPos.phi() - ChamberCenter.phi();
1153 else if (dphi < -
M_PI)
1155 if (std::abs(dphi) > 0.6)
continue;
1158 auto [tubeLayerMin, tubeLayerMax] =
m_idHelperSvc->mdtIdHelper().tubeLayerMinMax(
id);
1160 float nTubes = (tubeLayerMax - tubeLayerMin + 1) *
1162 for (; mdt != mdtE; ++mdt) {
1163 if ((*mdt)->adc() < 50)
continue;
1164 if ((*mdt)->status() != 1)
continue;
1165 if ((*mdt)->localPosition()[
Trk::locR] == 0.)
continue;
1169 double ChamberOccupancy = nChHits / nTubes;
1182 for (; RpcItr != RpcItrE; ++RpcItr) {
1185 for (; rpcItr != rpcItrE; ++rpcItr) {
1186 float rpcEta = (*rpcItr)->globalPosition().eta();
1187 float rpcPhi = (*rpcItr)->globalPosition().phi();
1188 float dphi = msVtxPos.phi() - rpcPhi;
1191 else if (dphi < -
M_PI)
1193 float deta = msVtxPos.eta() - rpcEta;
1194 float DR = std::hypot(deta, dphi);
1195 if (DR < 0.6) nrpc++;
1196 if (DR > 1.2)
break;
1205 for (; TgcItr != TgcItrE; ++TgcItr) {
1208 for (; tgcItr != tgcItrE; ++tgcItr) {
1209 float tgcEta = (*tgcItr)->globalPosition().eta();
1210 float tgcPhi = (*tgcItr)->globalPosition().phi();
1211 float dphi = msVtxPos.phi() - tgcPhi;
1214 else if (dphi < -
M_PI)
1216 float deta = msVtxPos.eta() - tgcEta;
1217 float DR = std::hypot(deta, dphi);
1218 if (DR < 0.6) ntgc++;
1219 if (DR > 1.2)
break;