47 ATH_CHECK(container.record(std::make_unique<xAOD::TrackParticleContainer>(), std::make_unique<xAOD::TrackParticleAuxContainer>()));
50 std::vector<std::vector<const Muon::MdtPrepData*> > SortedMdt;
54 if (nMDT <= 0) {
return StatusCode::SUCCESS; }
68 std::vector<TrackletSegment> segs[6][2][16];
69 std::vector<std::vector<const Muon::MdtPrepData*> >
::const_iterator ChamberItr = SortedMdt.begin();
70 for (; ChamberItr != SortedMdt.end(); ++ChamberItr) {
71 std::vector<TrackletSegment> mlsegments;
72 std::vector<const Muon::MdtPrepData*>::const_iterator mdt1 = ChamberItr->begin();
73 std::vector<const Muon::MdtPrepData*>::const_iterator mdtEnd = ChamberItr->end();
78 bool mdt1_isBarrel =
m_idHelperSvc->mdtIdHelper().isBarrel(mdt1_ID);
79 bool mdt1_isEndcap =
m_idHelperSvc->mdtIdHelper().isEndcap(mdt1_ID);
81 int maxLayer =
m_idHelperSvc->mdtIdHelper().tubeLayerMax(mdt1_ID);
85 for (; mdt1 != mdtEnd; ++mdt1) {
93 if (tl1 == maxLayer)
break;
96 std::vector<const Muon::MdtPrepData*>::const_iterator mdt2 = (mdt1 + 1);
97 if (mdt2 == mdtEnd)
continue;
99 for (; mdt2 != mdtEnd; ++mdt2) {
108 if (mdt1 == mdt2 || (tl2 - tl1) > 1 || (tl2 - tl1) < 0)
continue;
109 if ((tl2 - tl1) == 0 && (
m_idHelperSvc->mdtIdHelper().tube(mdt2_ID) -
112 if (mdt1_isBarrel && std::abs((*mdt1)->globalPosition().z() - (*mdt2)->globalPosition().z()) >
m_d12_max)
continue;
113 if (mdt1_isEndcap && std::abs((*mdt1)->globalPosition().perp() - (*mdt2)->globalPosition().perp()) >
m_d12_max)
continue;
116 std::vector<const Muon::MdtPrepData*>::const_iterator mdt3 = (mdt2 + 1);
117 if (mdt3 == mdtEnd)
continue;
119 for (; mdt3 != mdtEnd; ++mdt3) {
127 if (mdt1 == mdt3 || mdt2 == mdt3)
continue;
129 if ((tl3 - tl2) > 1 || (tl3 - tl2) < 0 || (tl3 - tl1) <= 0)
continue;
130 if ((tl3 - tl2) == 0 && (
m_idHelperSvc->mdtIdHelper().tube(mdt3_ID) -
133 if (mdt1_isBarrel && std::abs((*mdt1)->globalPosition().z() - (*mdt3)->globalPosition().z()) >
m_d13_max)
continue;
134 if (mdt1_isEndcap && std::abs((*mdt1)->globalPosition().perp() - (*mdt3)->globalPosition().perp()) >
m_d13_max)
continue;
137 std::vector<const Muon::MdtPrepData*> mdts;
138 mdts.push_back((*mdt1));
139 mdts.push_back((*mdt2));
140 mdts.push_back((*mdt3));
142 for (
const TrackletSegment &tmpSeg : tmpSegs) mlsegments.push_back(tmpSeg);
149 int stationRegion =
m_idHelperSvc->mdtIdHelper().stationRegion(mdt1_ID);
151 if (stationRegion == 0)
152 for (
const TrackletSegment &mlsegment : mlsegments) segs[0][ML - 1][sector - 1].push_back(mlsegment);
153 else if (stationRegion == 2)
154 for (
const TrackletSegment &mlsegment : mlsegments) segs[1][ML - 1][sector - 1].push_back(mlsegment);
155 else if (stationRegion == 3)
156 for (
const TrackletSegment &mlsegment : mlsegments) segs[2][ML - 1][sector - 1].push_back(mlsegment);
158 else if (mdt1_isEndcap){
159 if (stationRegion == 0)
160 for (
const TrackletSegment &mlsegment : mlsegments) segs[3][ML - 1][sector - 1].push_back(mlsegment);
161 else if (stationRegion == 2)
162 for (
const TrackletSegment &mlsegment : mlsegments) segs[4][ML - 1][sector - 1].push_back(mlsegment);
163 else if (stationRegion == 3)
164 for (
const TrackletSegment &mlsegment : mlsegments) segs[5][ML - 1][sector - 1].push_back(mlsegment);
171 std::vector<TrackletSegment> CleanSegs[6][2][16];
172 for (
int st = 0; st < 6; ++st) {
173 for (
int ml = 0; ml < 2; ++ml) {
174 for (
int sector = 0; sector < 16; ++sector) {
175 if (!segs[st][ml][sector].
empty()) {
176 CleanSegs[st][ml][sector] =
CleanSegments(segs[st][ml][sector]);
183 for (
int st = 0; st < 6; ++st) {
185 for (
int sector = 0; sector < 16; ++sector) {
188 const Identifier trkID = ML1seg.getIdentifier();
191 int stationRegion =
m_idHelperSvc->mdtIdHelper().stationRegion(trkID);
194 if (stationRegion == 0){
196 else DeltaAlphaCut =
c_BIL / 750.0;
198 else if (stationRegion == 2){
200 else DeltaAlphaCut =
c_BML / 750.0;
202 else if (stationRegion == 3){
204 else DeltaAlphaCut =
c_BOL / 750.0;
213 if (ML1seg.mdtChamber() != ML2seg.mdtChamber() || ML1seg.mdtChEta() != ML2seg.mdtChEta())
continue;
215 double deltaAlpha = ML1seg.alpha() - ML2seg.alpha();
218 if (std::abs(deltaAlpha) < DeltaAlphaCut && goodDeltab) {
221 double charge_discriminant = deltaAlpha * ML1seg.globalPosition().z() * std::tan(ML1seg.alpha());
222 double charge = charge_discriminant < 0 ? -1 : 1;
224 double pTot =
TrackMomentum(ML1seg.getIdentifier(), deltaAlpha);
229 std::vector<const Muon::MdtPrepData*> mdts = ML1seg.mdtHitsOnTrack();
230 std::vector<const Muon::MdtPrepData*> mdts2 = ML2seg.mdtHitsOnTrack();
234 if (!CombinedSeg.empty()) {
237 double pT = pTot * std::sin(CombinedSeg[0].alpha());
238 double pz = pTot * std::cos(CombinedSeg[0].alpha());
239 Amg::Vector3D momentum(pT * std::cos(CombinedSeg[0].globalPosition().
phi()),
240 pT * std::sin(CombinedSeg[0].globalPosition().
phi()),
244 matrix.setIdentity();
245 matrix(0, 0) = std::pow(CombinedSeg[0].rError(),2);
246 matrix(1, 1) = std::pow(CombinedSeg[0].zError(),2);
247 matrix(2, 2) = std::pow(0.00000000001,2);
249 matrix(3, 3) = std::pow(CombinedSeg[0].alphaError(),2);
250 matrix(4, 4) = std::pow(Trk1overPErr,2);
252 ATH_MSG_DEBUG(
"Track " << tracklets.size() <<
" found with p = (" << momentum.x() <<
", "
253 << momentum.y() <<
", " << momentum.z()
254 <<
") and |p| = " << tmpTrk.
momentum().mag() <<
" MeV");
255 tracklets.push_back(tmpTrk);
260 double pT = pTot * std::sin(ML1seg.alpha());
261 double pz = pTot * std::cos(ML1seg.alpha());
262 Amg::Vector3D momentum(pT * std::cos(ML1seg.globalPosition().phi()),
263 pT * std::sin(ML1seg.globalPosition().phi()),
267 matrix.setIdentity();
268 matrix(0, 0) = std::pow(ML1seg.rError(),2);
269 matrix(1, 1) = std::pow(ML1seg.zError(),2);
270 matrix(2, 2) = std::pow(0.00000000001,2);
272 matrix(3, 3) = std::pow(ML1seg.alphaError(),2);
273 matrix(4, 4) = std::pow(Trk1overPErr,2);
275 ATH_MSG_DEBUG(
"Track " << tracklets.size() <<
" found with p = (" << momentum.x() <<
", "
276 << momentum.y() <<
", " << momentum.z()
277 <<
") and |p| = " << tmpTrk.
momentum().mag() <<
" MeV");
278 tracklets.push_back(tmpTrk);
284 std::vector<const Muon::MdtPrepData*> mdts = ML1seg.mdtHitsOnTrack();
285 std::vector<const Muon::MdtPrepData*> mdts2 = ML2seg.mdtHitsOnTrack();
289 if (!CombinedSeg.empty()) {
292 double pT = pTot * std::sin(CombinedSeg[0].alpha());
293 double pz = pTot * std::cos(CombinedSeg[0].alpha());
294 Amg::Vector3D momentum(pT * std::cos(CombinedSeg[0].globalPosition().
phi()),
295 pT * std::sin(CombinedSeg[0].globalPosition().
phi()),
299 matrix.setIdentity();
300 matrix(0, 0) = std::pow(CombinedSeg[0].rError(),2);
301 matrix(1, 1) = std::pow(CombinedSeg[0].zError(),2);
302 matrix(2, 2) = std::pow(0.0000001,2);
304 matrix(3, 3) = std::pow(CombinedSeg[0].alphaError(),2);
308 tracklets.push_back(tmpTrk);
325 return StatusCode::SUCCESS;
466 std::vector<std::pair<double, double> > SeedParams;
476 double x1 = mdts.front()->globalPosition().z();
477 double y1 = mdts.front()->globalPosition().perp();
478 double r1 = std::abs(mdts.front()->localPosition()[
Trk::locR]);
480 double x2 = mdts.back()->globalPosition().z();
481 double y2 = mdts.back()->globalPosition().perp();
482 double r2 = std::abs(mdts.back()->localPosition()[
Trk::locR]);
484 double DeltaX = x2 - x1;
485 double DeltaY = y2 - y1;
486 double DistanceOfCenters = std::hypot(DeltaX, DeltaY);
487 if (DistanceOfCenters < 30)
return SeedParams;
488 double Alpha0 = std::acos(DeltaX / DistanceOfCenters);
491 double phi = mdts.front()->globalPosition().phi();
492 double RSum = r1 + r2;
493 if (RSum > DistanceOfCenters)
return SeedParams;
494 double Alpha1 = std::asin(RSum / DistanceOfCenters);
495 double line_theta = Alpha0 + Alpha1;
496 double z_line = x1 + r1 * std::sin(line_theta);
497 double rho_line = y1 - r1 * std::cos(line_theta);
500 Amg::Vector3D gDir(std::cos(
phi) * std::sin(line_theta), std::sin(
phi) * std::sin(line_theta), std::cos(line_theta));
501 Amg::Vector3D globalDir1(std::cos(
phi) * std::sin(line_theta), std::sin(
phi) * std::sin(line_theta), std::cos(line_theta));
502 double gSlope1 = (globalDir1.perp() / globalDir1.z());
503 double gInter1 = gPos1.perp() - gSlope1 * gPos1.z();
505 if (resid <
m_SeedResidual) SeedParams.emplace_back(gSlope1, gInter1);
507 line_theta = Alpha0 - Alpha1;
508 z_line = x1 - r1 * std::sin(line_theta);
509 rho_line = y1 + r1 * std::cos(line_theta);
511 Amg::Vector3D globalDir2(std::cos(
phi) * std::sin(line_theta), std::sin(
phi) * std::sin(line_theta), std::cos(line_theta));
512 double gSlope2 = (globalDir2.perp() / globalDir2.z());
513 double gInter2 = gPos2.perp() - gSlope2 * gPos2.z();
515 if (resid <
m_SeedResidual) SeedParams.emplace_back(gSlope2, gInter2);
517 double Alpha2 = std::asin(std::abs(r2 - r1) / DistanceOfCenters);
520 line_theta = Alpha0 + Alpha2;
521 z_line = x1 - r1 * std::sin(line_theta);
522 rho_line = y1 + r1 * std::cos(line_theta);
525 Amg::Vector3D globalDir3(std::cos(
phi) * std::sin(line_theta), std::sin(
phi) * std::sin(line_theta), std::cos(line_theta));
526 double gSlope3 = (globalDir3.perp() / globalDir3.z());
527 double gInter3 = gPos3.perp() - gSlope3 * gPos3.z();
529 if (resid <
m_SeedResidual) SeedParams.emplace_back(gSlope3, gInter3);
532 line_theta = Alpha0 - Alpha2;
533 z_line = x1 + r1 * std::sin(line_theta);
534 rho_line = y1 - r1 * std::cos(line_theta);
537 Amg::Vector3D globalDir4(std::cos(
phi) * std::sin(line_theta), std::sin(
phi) * std::sin(line_theta), std::cos(line_theta));
538 double gSlope4 = (globalDir4.perp() / globalDir4.z());
539 double gInter4 = gPos4.perp() - gSlope4 * gPos4.z();
541 if (resid <
m_SeedResidual) SeedParams.emplace_back(gSlope4, gInter4);
544 line_theta = Alpha0 + Alpha2;
545 z_line = x1 + r1 * std::sin(line_theta);
546 rho_line = y1 - r1 * std::cos(line_theta);
549 Amg::Vector3D globalDir3(std::cos(
phi) * std::sin(line_theta), std::sin(
phi) * std::sin(line_theta), std::cos(line_theta));
550 double gSlope3 = (globalDir3.perp() / globalDir3.z());
551 double gInter3 = gPos3.perp() - gSlope3 * gPos3.z();
553 if (resid <
m_SeedResidual) SeedParams.emplace_back(gSlope3, gInter3);
556 line_theta = Alpha0 - Alpha2;
557 z_line = x1 - r1 * std::sin(line_theta);
558 rho_line = y1 + r1 * std::cos(line_theta);
561 Amg::Vector3D globalDir4(std::cos(
phi) * std::sin(line_theta), std::sin(
phi) * std::sin(line_theta), std::cos(line_theta));
562 double gSlope4 = (globalDir4.perp() / globalDir4.z());
563 double gInter4 = gPos4.perp() - gSlope4 * gPos4.z();
565 if (resid <
m_SeedResidual) SeedParams.emplace_back(gSlope4, gInter4);
589 const std::vector<std::pair<double, double> >& SeedParams)
const {
590 std::vector<TrackletSegment> segs;
593 for (
const std::pair<double,double> &SeedParam : SeedParams) {
597 double s(0),
sz(0), sy(0);
604 const double mdt_y = std::hypot(prd->globalPosition().x(), prd->globalPosition().y());
605 const double mdt_z = prd->globalPosition().z();
608 sz += mdt_z / sigma2;
609 sy += mdt_y / sigma2;
615 const double yc = sy / s;
616 const double zc =
sz / s;
619 double alpha = std::atan2(SeedParam.first, 1.0);
620 if (alpha < 0) alpha +=
M_PI;
622 double d = (SeedParam.second - yc + zc * SeedParam.first) * std::cos(alpha);
626 if (std::abs(std::cos(alpha)) > 0.97 && (
m_idHelperSvc->mdtIdHelper().isBarrel(mdtID)))
continue;
627 if (std::abs(std::cos(alpha)) < 0.03 && (
m_idHelperSvc->mdtIdHelper().isEndcap(mdtID)))
continue;
630 double sPyy(0), sPyz(0), sPyyzz(0);
632 double mdt_y = std::hypot(prd->globalPosition().x(), prd->globalPosition().y());
633 double mdt_z = prd->globalPosition().z();
635 sPyy += std::pow(mdt_y-yc,2) / sigma2;
636 sPyz += (mdt_y - yc) * (mdt_z - zc) / sigma2;
637 sPyyzz += ((mdt_y - yc) - (mdt_z - zc)) * ((mdt_y - yc) + (mdt_z - zc)) / sigma2;
642 double deltaAlpha = 0;
645 double sumRyi(0), sumRzi(0), sumRi(0);
648 const double cos_a = std::cos(alpha);
649 const double sin_a = std::sin(alpha);
651 double mdt_y = prd->globalPosition().perp();
652 double mdt_z = prd->globalPosition().z();
653 double yPi = -(mdt_z - zc) * sin_a + (mdt_y - yc) * cos_a - d;
654 double signR = yPi >= 0 ? -1. : 1;
656 double ri = signR * prd->localPosition()[
Trk::locR];
657 sumRyi += ri * (mdt_y - yc) / sigma2;
658 sumRzi += ri * (mdt_z - zc) / sigma2;
659 sumRi += ri / sigma2;
660 chi2 += std::pow(yPi+ri,2) / sigma2;
662 double bAlpha = -1 * sPyz + cos_a * (sin_a * sPyyzz + 2 * cos_a * sPyz + sumRzi) + sin_a * sumRyi;
663 double AThTh = sPyy + cos_a * (2 * sin_a * sPyz - cos_a * sPyyzz);
667 if (std::abs(AThTh) < 1.e-7)
break;
669 double alphaNew = alpha + bAlpha / AThTh;
670 double dNew = sumRi / s;
672 dalpha = std::sqrt(1 / std::abs(AThTh));
673 dd = std::sqrt(1 / s);
674 deltaAlpha = std::abs(alphaNew - alpha);
675 deltad = std::abs(d - dNew);
677 if (deltaAlpha < 5.e-7 && deltad < 5.e-6)
break;
681 if (Nitr > 10)
break;
685 double chi2Prob = TMath::Prob(
chi2, mdts.size() - 2);
688 double z0 = zc - d * std::sin(alpha);
689 double dz0 = std::hypot(dd*std::sin(alpha), d*dalpha*std::cos(alpha));
690 double y0 = yc + d * std::cos(alpha);
691 double dy0 = std::hypot(dd*std::cos(alpha), d*dalpha*std::sin(alpha));
702 for (
unsigned int k = 0; k < mdts.size(); ++k) {
703 int base = std::pow(10, k);
704 double mdtR = std::hypot(mdts.at(k)->globalPosition().x(), mdts.at(k)->globalPosition().y());
705 double mdtZ = mdts.at(k)->globalPosition().z();
706 double zTest = (mdtR - y0) / std::tan(alpha) + z0 - mdtZ;
715 double mdtPhi = mdts.at(0)->globalPosition().phi();
716 Amg::Vector3D segpos(y0 * std::cos(mdtPhi), y0 * std::sin(mdtPhi), z0);
719 segs.push_back(MyTrackletSegment);
720 if (pattern == -1)
break;
725 if (segs.size() > 1) {
726 std::vector<TrackletSegment> tmpSegs;
727 for (
unsigned int i1 = 0; i1 < segs.size(); ++i1) {
728 bool isUnique =
true;
729 int pattern1 = segs.at(i1).getHitPattern();
730 for (
unsigned int i2 = (i1 + 1); i2 < segs.size(); ++i2) {
731 if (pattern1 == -1)
break;
732 int pattern2 = segs.at(i2).getHitPattern();
733 if (pattern1 == pattern2) isUnique =
false;
735 if (isUnique) tmpSegs.push_back(segs.at(i1));
737 segs = std::move(tmpSegs);
747 std::vector<TrackletSegment> CleanSegs;
748 std::vector<TrackletSegment> segs = Segs;
749 bool keepCleaning(
true);
752 while (keepCleaning) {
754 keepCleaning =
false;
756 for (std::vector<TrackletSegment>::iterator it = segs.begin(); it != segs.end(); ++it) {
757 if (it->isCombined())
continue;
758 std::vector<TrackletSegment> segsToCombine;
759 double tanTh1 = std::tan(it->alpha());
760 double r1 = it->globalPosition().perp();
761 double zi1 = it->globalPosition().z() - r1 / tanTh1;
763 for (std::vector<TrackletSegment>::iterator sit = (it + 1); sit != segs.end(); ++sit) {
764 if (sit->isCombined())
continue;
765 if (it->mdtChamber() != sit->mdtChamber())
continue;
766 if ((it->mdtChEta()) * (sit->mdtChEta()) < 0)
continue;
767 if (it->mdtChPhi() != sit->mdtChPhi())
continue;
768 if (std::abs(it->alpha() - sit->alpha()) > 0.005)
continue;
769 double tanTh2 = std::tan(sit->alpha());
770 double r2 = sit->globalPosition().perp();
771 double zi2 = sit->globalPosition().z() - r2 / tanTh2;
773 double rmid = (r1 + r2) / 2.;
774 double z1 = rmid / tanTh1 + zi1;
775 double z2 = rmid / tanTh2 + zi2;
776 double zdist = std::abs(z1 - z2);
778 segsToCombine.push_back(*sit);
779 sit->isCombined(
true);
784 if (segsToCombine.empty()) {
785 CleanSegs.push_back(*it);
788 else if (!segsToCombine.empty()) {
790 std::vector<const Muon::MdtPrepData*> mdts = it->mdtHitsOnTrack();
792 std::vector<const Muon::MdtPrepData*> tmpmdts = seg.mdtHitsOnTrack();
796 if (tmpprd->identify() == tmpprd2->identify()) {
806 if (mdts.size() > it->mdtHitsOnTrack().size()) {
809 if (refitsegs.empty()) {
810 if (segsToCombine.size() == 1) {
811 segsToCombine[0].isCombined(
false);
812 CleanSegs.push_back(*it);
813 CleanSegs.push_back(segsToCombine[0]);
816 std::vector<int> nSeg;
817 for (
unsigned int i = 0; i < mdts.size(); ++i) {
820 for (
unsigned int k = 0; k < it->mdtHitsOnTrack().
size(); ++k) {
821 if (it->mdtHitsOnTrack()[k]->identify() == mdts[i]->identify()) {
827 for (
unsigned int k = 0; k < segsToCombine.size(); ++k) {
828 for (
unsigned int m = 0; m < segsToCombine[k].mdtHitsOnTrack().
size(); ++m) {
829 if (segsToCombine[k].mdtHitsOnTrack()[m]->identify() == mdts[i]->identify()) {
838 bool keeprefitting(
true);
840 while (keeprefitting) {
842 int nMinSeg(nSeg[0]);
844 std::vector<int> nrfsegs;
845 std::vector<const Muon::MdtPrepData*> refitmdts;
847 for (
unsigned int i = 1; i < mdts.size(); ++i) {
848 if (nSeg[i] < nMinSeg) {
849 refitmdts.push_back(minmdt);
850 nrfsegs.push_back(nMinSeg);
854 refitmdts.push_back(mdts[i]);
855 nrfsegs.push_back(nSeg[i]);
859 mdts = std::move(refitmdts);
860 nSeg = std::move(nrfsegs);
863 if (!refitsegs.empty()) {
864 for (
const TrackletSegment &refitseg : refitsegs) CleanSegs.push_back(refitseg);
865 keeprefitting =
false;
866 }
else if (mdts.size() <= 3) {
867 CleanSegs.push_back(*it);
868 keeprefitting =
false;
870 if (nItr2 > 10)
break;
875 for (
const TrackletSegment &refitseg : refitsegs) CleanSegs.push_back(refitseg);
880 CleanSegs.push_back(*it);
887 if (nItr > 10)
break;
1022 std::vector<Tracklet> myTracks = tracks;
1024 for (
const Tracklet &track : myTracks) {
1025 Identifier id1 = track.getML1seg().mdtHitsOnTrack().at(0)->identify();
1026 Identifier id2 = track.getML2seg().mdtHitsOnTrack().at(0)->identify();
1027 int nLayerML1 =
m_idHelperSvc->mdtIdHelper().tubeLayerMax(id1);
1028 int nLayerML2 =
m_idHelperSvc->mdtIdHelper().tubeLayerMax(id2);
1029 double ratio = (double)(track.mdtHitsOnTrack().size()) / (nLayerML1 + nLayerML2);
1030 if (ratio > 0.75) tracks.push_back(track);
1034 std::vector<Tracklet> UniqueTracks;
1035 std::vector<unsigned int> AmbigTrks;
1036 for (
unsigned int tk1 = 0; tk1 < tracks.size(); ++tk1) {
1039 bool isResolved =
false;
1040 for (
unsigned int AmbigTrksIdx : AmbigTrks) {
1041 if (tk1 == AmbigTrksIdx) {
1046 if (isResolved)
continue;
1047 std::vector<Tracklet> AmbigTracks;
1048 AmbigTracks.push_back(tracks.at(tk1));
1050 double Trk1ML1R = tracks.at(tk1).getML1seg().globalPosition().perp();
1051 double Trk1ML1Z = tracks.at(tk1).getML1seg().globalPosition().z();
1052 double Trk1ML2R = tracks.at(tk1).getML2seg().globalPosition().perp();
1053 double Trk1ML2Z = tracks.at(tk1).getML2seg().globalPosition().z();
1055 Identifier tk1ID = tracks.at(tk1).muonIdentifier();
1056 bool tk1_isBarrel =
m_idHelperSvc->mdtIdHelper().isBarrel(tk1ID);
1057 bool tk1_isEndcap =
m_idHelperSvc->mdtIdHelper().isEndcap(tk1ID);
1060 for (
unsigned int tk2 = (tk1 + 1); tk2 < tracks.size(); ++tk2) {
1061 if (tracks.at(tk1).mdtChamber() == tracks.at(tk2).mdtChamber() && tracks.at(tk1).mdtChPhi() == tracks.at(tk2).mdtChPhi() &&
1062 (tracks.at(tk1).mdtChEta()) * (tracks.at(tk2).mdtChEta()) > 0) {
1064 for (
unsigned int AmbigTrksIdx : AmbigTrks) {
1065 if (tk2 == AmbigTrksIdx) {
1070 if (isResolved)
continue;
1072 double Trk2ML1R = tracks.at(tk2).getML1seg().globalPosition().perp();
1073 double Trk2ML1Z = tracks.at(tk2).getML1seg().globalPosition().z();
1074 double Trk2ML2R = tracks.at(tk2).getML2seg().globalPosition().perp();
1075 double Trk2ML2Z = tracks.at(tk2).getML2seg().globalPosition().z();
1078 double DistML1(1000), DistML2(1000);
1080 DistML1 = std::abs(Trk1ML1Z - Trk2ML1Z);
1081 DistML2 = std::abs(Trk1ML2Z - Trk2ML2Z);
1082 }
else if (tk1_isEndcap) {
1083 DistML1 = std::abs(Trk1ML1R - Trk2ML1R);
1084 DistML2 = std::abs(Trk1ML2R - Trk2ML2R);
1086 if (DistML1 < 40 || DistML2 < 40) {
1088 std::vector<const Muon::MdtPrepData*> mdts1 = tracks.at(tk1).mdtHitsOnTrack();
1089 std::vector<const Muon::MdtPrepData*> mdts2 = tracks.at(tk2).mdtHitsOnTrack();
1093 if (mdt1->identify() == mdt2->identify()) {
1100 if (nShared <= 1)
continue;
1102 AmbigTracks.push_back(tracks.at(tk2));
1103 AmbigTrks.push_back(tk2);
1108 if (AmbigTracks.size() == 1) {
1109 UniqueTracks.push_back(tracks.at(tk1));
1115 bool hasMomentum = tracks.at(tk1).charge() != 0;
1116 double aveX(0), aveY(0), aveZ(0), aveAlpha(0);
1117 double aveP(0), nAmbigP(0), TrkCharge(tracks.at(tk1).charge());
1118 bool allSameSign(
true);
1120 for (
const Tracklet &AmbigTrack : AmbigTracks) {
1122 aveX += AmbigTrack.globalPosition().x();
1123 aveY += AmbigTrack.globalPosition().y();
1124 aveZ += AmbigTrack.globalPosition().z();
1125 aveAlpha += AmbigTrack.getML1seg().alpha();
1128 if (std::abs(AmbigTrack.charge() - TrkCharge) > 0.1) allSameSign =
false;
1130 aveP += AmbigTrack.momentum().mag();
1132 aveAlpha += AmbigTrack.alpha();
1133 aveX += AmbigTrack.globalPosition().x();
1134 aveY += AmbigTrack.globalPosition().y();
1135 aveZ += AmbigTrack.globalPosition().z();
1139 aveX = aveX / (double)AmbigTracks.size();
1140 aveY = aveY / (double)AmbigTracks.size();
1141 aveZ = aveZ / (double)AmbigTracks.size();
1143 aveAlpha = aveAlpha / (double)AmbigTracks.size();
1144 double alphaErr = tracks.at(tk1).getML1seg().alphaError();
1145 double rErr = tracks.at(tk1).getML1seg().rError();
1146 double zErr = tracks.at(tk1).getML1seg().zError();
1155 matrix.setIdentity();
1156 matrix(0, 0) = std::pow(tracks.at(tk1).getML1seg().rError(),2);
1157 matrix(1, 1) = std::pow(tracks.at(tk1).getML1seg().zError(),2);
1158 matrix(2, 2) = std::pow(0.0000001,2);
1159 matrix(3, 3) = std::pow(tracks.at(tk1).getML1seg().alphaError(),2);
1161 Tracklet aveTrack(aveSegML1, momentum, matrix, 0);
1162 UniqueTracks.push_back(aveTrack);
1163 }
else if (allSameSign) {
1168 aveP = aveP / nAmbigP;
1169 double pT = aveP * std::sin(tracks.at(tk1).getML1seg().alpha());
1170 double pz = aveP * std::cos(tracks.at(tk1).getML1seg().alpha());
1171 Amg::Vector3D momentum(pT * std::cos(tracks.at(tk1).globalPosition().phi()),
1172 pT * std::sin(tracks.at(tk1).globalPosition().phi()),
1176 MyTrack.
charge(tracks.at(tk1).charge());
1177 UniqueTracks.push_back(MyTrack);
1179 aveX = aveX / (double)AmbigTracks.size();
1180 aveY = aveY / (double)AmbigTracks.size();
1181 aveZ = aveZ / (double)AmbigTracks.size();
1183 aveAlpha = aveAlpha / (double)AmbigTracks.size();
1184 double alphaErr = tracks.at(tk1).getML1seg().alphaError();
1185 double rErr = tracks.at(tk1).getML1seg().rError();
1186 double zErr = tracks.at(tk1).getML1seg().zError();
1195 matrix.setIdentity();
1196 matrix(0, 0) = std::pow(tracks.at(tk1).getML1seg().rError(),2);
1197 matrix(1, 1) = std::pow(tracks.at(tk1).getML1seg().zError(),2);
1198 matrix(2, 2) = std::pow(0.0000001,2);
1199 matrix(3, 3) = std::pow(tracks.at(tk1).getML1seg().alphaError(),2);
1201 Tracklet aveTrack(aveSegML1, momentum, matrix, 0);
1202 UniqueTracks.push_back(aveTrack);
1207 else if (tk1_isEndcap) {
1208 std::vector<const Muon::MdtPrepData*> AllMdts;
1209 for (
Tracklet const &AmbigTrack : AmbigTracks) {
1210 std::vector<const Muon::MdtPrepData*> mdts = AmbigTrack.mdtHitsOnTrack();
1211 std::vector<const Muon::MdtPrepData*> tmpAllMdt = AllMdts;
1213 bool isNewHit =
true;
1215 if (mdt->identify() == tmpmdt->identify()) {
1220 if (isNewHit) AllMdts.push_back(mdt);
1225 if (!MyECsegs.empty()) {
1234 matrix.setIdentity();
1235 matrix(0, 0) = std::pow(ECseg.
rError(),2);
1236 matrix(1, 1) = std::pow(ECseg.
zError(),2);
1237 matrix(2, 2) = std::pow(0.0000001,2);
1238 matrix(3, 3) = std::pow(ECseg.
alphaError(),2);
1240 Tracklet MyCombTrack(MyECsegs.at(0), ECseg, momentum, matrix, 0);
1241 UniqueTracks.push_back(MyCombTrack);
1243 UniqueTracks.push_back(tracks.at(tk1));
1248 return UniqueTracks;