39 constexpr
float c_BIL = 28.4366;
40 constexpr
float c_BML = 62.8267;
41 constexpr
float c_BMS = 53.1259;
42 constexpr
float c_BOL = 29.7554;
43 constexpr
float sq(
float x) {
return (
x) * (
x); }
48 declareInterface<IMSVertexTrackletTool>(
this);
71 return StatusCode::SUCCESS;
80 ATH_CHECK(container.
record(std::make_unique<xAOD::TrackParticleContainer>(), std::make_unique<xAOD::TrackParticleAuxContainer>()));
83 std::vector<std::vector<const Muon::MdtPrepData*> > SortedMdt;
87 if (nMDT <= 0) {
return StatusCode::SUCCESS; }
100 double d12_max = 50.;
101 double d13_max = 80.;
103 constexpr
double errorCutOff = 0.001;
104 std::vector<TrackletSegment> segs[6][2][16];
105 std::vector<std::vector<const Muon::MdtPrepData*> >::const_iterator ChamberItr = SortedMdt.begin();
106 for (; ChamberItr != SortedMdt.end(); ++ChamberItr) {
107 std::vector<TrackletSegment> mlsegments;
109 std::vector<const Muon::MdtPrepData*>::const_iterator mdt1 = ChamberItr->begin();
110 std::vector<const Muon::MdtPrepData*>::const_iterator mdtEnd = ChamberItr->end();
111 int stName =
m_idHelperSvc->mdtIdHelper().stationName((*mdt1)->identify());
112 int stEta =
m_idHelperSvc->mdtIdHelper().stationEta((*mdt1)->identify());
113 if (stName == 6 || stName == 14 || stName == 15)
continue;
114 if (stName == 1 && std::abs(stEta) >= 7)
continue;
115 if (stName == 53 || stName == 54)
continue;
118 int sector = 2 * (
m_idHelperSvc->mdtIdHelper().stationPhi((*mdt1)->identify()));
119 if (stName == 0 || stName == 2 || stName == 4 || stName == 13 || stName == 17 || stName == 20) sector -= 1;
121 int maxLayer =
m_idHelperSvc->mdtIdHelper().tubeLayerMax((*mdt1)->identify());
122 int ML =
m_idHelperSvc->mdtIdHelper().multilayer((*mdt1)->identify());
123 for (; mdt1 != mdtEnd; ++mdt1) {
129 int tl1 =
m_idHelperSvc->mdtIdHelper().tubeLayer((*mdt1)->identify());
130 if (tl1 == maxLayer)
break;
131 std::vector<const Muon::MdtPrepData*>::const_iterator mdt2 = (mdt1 + 1);
132 for (; mdt2 != mdtEnd; ++mdt2) {
140 int tl2 =
m_idHelperSvc->mdtIdHelper().tubeLayer((*mdt2)->identify());
141 if (mdt1 == mdt2 || (tl2 - tl1) > 1 || (tl2 - tl1) < 0)
continue;
142 if (std::abs((*mdt2)->globalPosition().z() - (*mdt1)->globalPosition().z()) > d12_max && (stName <= 11 || stName == 52))
145 if ((stName > 11 && stName <= 21) || stName == 49) {
146 float mdt1R = (*mdt1)->globalPosition().perp();
147 float mdt2R = (*mdt2)->globalPosition().perp();
148 if (std::abs(mdt1R - mdt2R) > d12_max)
continue;
150 if ((tl2 - tl1) == 0 && (
m_idHelperSvc->mdtIdHelper().tube((*mdt2)->identify()) -
154 std::vector<const Muon::MdtPrepData*>::const_iterator mdt3 = (mdt2 + 1);
155 for (; mdt3 != mdtEnd; ++mdt3) {
163 int tl3 =
m_idHelperSvc->mdtIdHelper().tubeLayer((*mdt3)->identify());
164 if (mdt1 == mdt3 || mdt2 == mdt3)
continue;
165 if ((tl3 - tl2) > 1 || (tl3 - tl2) < 0 || (tl3 - tl1) <= 0)
continue;
166 if ((tl3 - tl2) == 0 && (
m_idHelperSvc->mdtIdHelper().tube((*mdt3)->identify()) -
169 if (std::abs((*mdt3)->globalPosition().z() - (*mdt1)->globalPosition().z()) > d13_max &&
170 (stName <= 11 || stName == 52))
173 if ((stName > 11 && stName <= 21) || stName == 49) {
174 float mdt1R = (*mdt1)->globalPosition().perp();
175 float mdt3R = (*mdt3)->globalPosition().perp();
176 if (std::abs(mdt1R - mdt3R) > d13_max)
continue;
179 std::vector<const Muon::MdtPrepData*> mdts;
180 mdts.push_back((*mdt1));
181 mdts.push_back((*mdt2));
182 mdts.push_back((*mdt3));
184 for (
unsigned int i = 0;
i < tmpSegs.size(); ++
i) mlsegments.push_back(tmpSegs.at(
i));
193 if (stName == 0 || stName == 1 || stName == 7 || stName == 52)
194 for (
unsigned int k = 0;
k < mlsegments.size(); ++
k) segs[0][ML - 1][sector - 1].push_back(mlsegments.at(
k));
195 else if (stName == 2 || stName == 3 || stName == 8)
196 for (
unsigned int k = 0;
k < mlsegments.size(); ++
k) segs[1][ML - 1][sector - 1].push_back(mlsegments.at(
k));
197 else if (stName == 4 || stName == 5 || stName == 9 || stName == 10)
198 for (
unsigned int k = 0;
k < mlsegments.size(); ++
k) segs[2][ML - 1][sector - 1].push_back(mlsegments.at(
k));
199 else if (stName == 13 || stName == 49)
200 for (
unsigned int k = 0;
k < mlsegments.size(); ++
k) segs[3][ML - 1][sector - 1].push_back(mlsegments.at(
k));
201 else if (stName == 17 || stName == 18)
202 for (
unsigned int k = 0;
k < mlsegments.size(); ++
k) segs[4][ML - 1][sector - 1].push_back(mlsegments.at(
k));
203 else if (stName == 20 || stName == 21)
204 for (
unsigned int k = 0;
k < mlsegments.size(); ++
k) segs[5][ML - 1][sector - 1].push_back(mlsegments.at(
k));
206 ATH_MSG_WARNING(
"Found segments belonging to chamber " << stName <<
" that have not been stored");
210 std::vector<TrackletSegment> CleanSegs[6][2][16];
211 for (
int st = 0; st < 6; ++st) {
212 for (
int ml = 0; ml < 2; ++ml) {
213 for (
int sector = 0; sector < 16; ++sector) {
214 if (!segs[st][ml][sector].
empty()) {
215 CleanSegs[st][ml][sector] =
CleanSegments(segs[st][ml][sector]);
221 for (
int st = 0; st < 6; ++st) {
224 for (
int sector = 0; sector < 16; ++sector) {
225 for (
unsigned int i1 = 0; i1 < CleanSegs[st][0][sector].size(); ++i1) {
227 int stName = CleanSegs[st][0][sector].at(i1).mdtChamber();
229 DeltaAlphaCut =
c_BIL / 750.0;
230 else if (stName == 2)
231 DeltaAlphaCut =
c_BML / 750.0;
232 else if (stName == 3)
233 DeltaAlphaCut =
c_BMS / 750.0;
234 else if (stName == 4)
235 DeltaAlphaCut =
c_BOL / 750.0;
236 else if (stName == 7)
237 DeltaAlphaCut =
c_BIL / 750.0;
238 else if (stName == 8)
239 DeltaAlphaCut =
c_BML / 750.0;
240 else if (stName == 9)
241 DeltaAlphaCut =
c_BOL / 750.0;
242 else if (stName == 10)
243 DeltaAlphaCut =
c_BOL / 750.0;
244 else if (stName == 52)
245 DeltaAlphaCut =
c_BIL / 750.0;
246 else if (stName <= 11)
247 DeltaAlphaCut = 0.02;
251 for (
unsigned int i2 = 0; i2 < CleanSegs[st][1][sector].size(); ++i2) {
252 if (CleanSegs[st][0][sector].at(i1).mdtChamber() != CleanSegs[st][1][sector].at(i2).mdtChamber() ||
253 CleanSegs[st][0][sector].at(i1).mdtChEta() != CleanSegs[st][1][sector].at(i2).mdtChEta())
255 float deltaAlpha = CleanSegs[st][0][sector].at(i1).alpha() - CleanSegs[st][1][sector].at(i2).alpha();
256 bool goodDeltab =
DeltabCalc(CleanSegs[st][0][sector].at(i1), CleanSegs[st][1][sector].at(i2));
258 if (std::abs(deltaAlpha) < DeltaAlphaCut && goodDeltab) {
261 if (deltaAlpha * CleanSegs[st][0][sector].at(i1).globalPosition().
z() *
262 std::tan(CleanSegs[st][0][sector].at(i1).alpha()) <
265 float pTot =
TrackMomentum(CleanSegs[st][0][sector].at(i1).mdtChamber(), deltaAlpha);
266 if (pTot < 800.)
continue;
270 std::vector<const Muon::MdtPrepData*> mdts = CleanSegs[st][0][sector].at(i1).mdtHitsOnTrack();
271 std::vector<const Muon::MdtPrepData*> mdts2 = CleanSegs[st][1][sector].at(i2).mdtHitsOnTrack();
272 for (
unsigned int k = 0;
k < mdts2.size(); ++
k) mdts.push_back(mdts2.at(
k));
274 if (!CombinedSeg.empty()) {
277 float pT = pTot *
std::sin(CombinedSeg[0].alpha());
278 float pz = pTot *
std::cos(CombinedSeg[0].alpha());
280 pT *
std::sin(CombinedSeg[0].globalPosition().phi()),
pz);
284 matrix(0, 0) =
sq(CombinedSeg[0].rError());
285 matrix(1, 1) =
sq(CombinedSeg[0].zError());
288 matrix(3, 3) =
sq(CombinedSeg[0].alphaError());
293 <<
") and |p| = " << tmpTrk.
momentum().mag() <<
" MeV");
294 tracklets.push_back(tmpTrk);
300 float pT = pTot *
std::sin(CleanSegs[st][0][sector].at(i1).alpha());
301 float pz = pTot *
std::cos(CleanSegs[st][0][sector].at(i1).alpha());
303 pT *
std::sin(CleanSegs[st][0][sector].at(i1).globalPosition().phi()),
pz);
307 matrix(0, 0) =
sq(CleanSegs[st][0][sector].at(i1).rError());
308 matrix(1, 1) =
sq(CleanSegs[st][0][sector].at(i1).zError());
311 matrix(3, 3) =
sq(CleanSegs[st][0][sector].at(i1).alphaError());
317 <<
") and |p| = " << tmpTrk.
momentum().mag() <<
" MeV");
318 tracklets.push_back(tmpTrk);
323 std::vector<const Muon::MdtPrepData*> mdts = CleanSegs[st][0][sector].at(i1).mdtHitsOnTrack();
324 std::vector<const Muon::MdtPrepData*> mdts2 = CleanSegs[st][1][sector].at(i2).mdtHitsOnTrack();
325 for (
unsigned int k = 0;
k < mdts2.size(); ++
k) mdts.push_back(mdts2.at(
k));
327 if (!CombinedSeg.empty()) {
329 float pT = 100000.0 *
std::sin(CombinedSeg[0].alpha());
330 float pz = 100000.0 *
std::cos(CombinedSeg[0].alpha());
334 matrix(0, 0) =
sq(CombinedSeg[0].rError());
335 matrix(1, 1) =
sq(CombinedSeg[0].zError());
338 matrix(3, 3) =
sq(CombinedSeg[0].alphaError());
342 pT *
std::sin(CombinedSeg[0].globalPosition().phi()),
pz);
344 tracklets.push_back(tmpTrk);
361 return StatusCode::SUCCESS;
373 new Trk::Perigee(0., 0., trkItr->momentum().phi(), trkItr->momentum().theta(), trkItr->charge() / trkItr->momentum().mag(),
387 std::vector<float> covMatrixVec;
413 for (; MDTItr != MDTItrE; ++MDTItr) {
418 if ((*MDTItr)->empty())
continue;
420 int stName =
m_idHelperSvc->mdtIdHelper().stationName((*mpdc)->identify());
423 if (stName == 6 || stName == 14 || stName == 15)
continue;
426 if (stName == 1 && std::abs(
m_idHelperSvc->mdtIdHelper().stationEta((*mpdc)->identify())) >= 7)
continue;
429 if (stName == 53 || stName == 54)
continue;
432 std::vector<const Muon::MdtPrepData*> hitsML1;
433 std::vector<const Muon::MdtPrepData*> hitsML2;
435 for (; mpdc != mpdcE; ++mpdc) {
437 if ((*mpdc)->adc() < 50)
continue;
443 if ((*mpdc)->localPosition()[
Trk::locR] == 0.)
continue;
454 if (
m_idHelperSvc->mdtIdHelper().multilayer((*mpdc)->identify()) == 1)
455 hitsML1.push_back(*mpdc);
457 hitsML2.push_back(*mpdc);
470 std::vector<std::vector<const Muon::MdtPrepData*> >& SortedMdt)
const {
471 if (
hits.empty())
return;
474 int ntubes =
hits.front()->detectorElement()->getNLayers() *
hits.front()->detectorElement()->getNtubesperlayer();
475 if (
hits.size() > 0.75 * ntubes)
return;
477 if (m_idHelperSvc->mdtIdHelper().tubeLayer(mprd1->identify()) > m_idHelperSvc->mdtIdHelper().tubeLayer(mprd2->identify()))
479 if (m_idHelperSvc->mdtIdHelper().tubeLayer(mprd1->identify()) < m_idHelperSvc->mdtIdHelper().tubeLayer(mprd2->identify()))
481 if (m_idHelperSvc->mdtIdHelper().tube(mprd1->identify()) < m_idHelperSvc->mdtIdHelper().tube(mprd2->identify())) return true;
485 SortedMdt.push_back(
hits);
502 std::vector<std::pair<float, float> > SeedParams =
SegSeeds(mdts);
512 std::vector<std::pair<float, float> > SeedParams;
518 float x1 = mdts.front()->globalPosition().z();
519 float y1 = mdts.front()->globalPosition().perp();
520 float r1 = std::abs(mdts.front()->localPosition()[
Trk::locR]);
522 float x2 = mdts.back()->globalPosition().z();
523 float y2 = mdts.back()->globalPosition().perp();
524 float r2 = std::abs(mdts.back()->localPosition()[
Trk::locR]);
526 float DeltaX =
x2 -
x1;
527 float DeltaY =
y2 -
y1;
528 float DistanceOfCenters = std::sqrt(DeltaX * DeltaX + DeltaY * DeltaY);
529 if (DistanceOfCenters < 30)
return SeedParams;
530 float Alpha0 = std::acos(DeltaX / DistanceOfCenters);
533 float phi = mdts.front()->globalPosition().phi();
534 float RSum = r1 + r2;
535 if (RSum > DistanceOfCenters)
return SeedParams;
536 float Alpha1 = std::asin(RSum / DistanceOfCenters);
537 float line_theta = Alpha0 + Alpha1;
538 float z_line =
x1 + r1 *
std::sin(line_theta);
539 float rho_line =
y1 - r1 *
std::cos(line_theta);
544 float gSlope1 = (globalDir1.perp() / globalDir1.z());
545 float gInter1 = gPos1.perp() - gSlope1 * gPos1.z();
547 if (resid <
m_SeedResidual) SeedParams.emplace_back(gSlope1, gInter1);
549 line_theta = Alpha0 - Alpha1;
554 float gSlope2 = (globalDir2.perp() / globalDir2.z());
555 float gInter2 = gPos2.perp() - gSlope2 * gPos2.z();
557 if (resid <
m_SeedResidual) SeedParams.emplace_back(gSlope2, gInter2);
559 float Alpha2 = std::asin(std::abs(r2 - r1) / DistanceOfCenters);
562 line_theta = Alpha0 + Alpha2;
568 float gSlope3 = (globalDir3.perp() / globalDir3.z());
569 float gInter3 = gPos3.perp() - gSlope3 * gPos3.z();
571 if (resid <
m_SeedResidual) SeedParams.emplace_back(gSlope3, gInter3);
574 line_theta = Alpha0 - Alpha2;
580 float gSlope4 = (globalDir4.perp() / globalDir4.z());
581 float gInter4 = gPos4.perp() - gSlope4 * gPos4.z();
583 if (resid <
m_SeedResidual) SeedParams.emplace_back(gSlope4, gInter4);
586 line_theta = Alpha0 + Alpha2;
592 float gSlope3 = (globalDir3.perp() / globalDir3.z());
593 float gInter3 = gPos3.perp() - gSlope3 * gPos3.z();
595 if (resid <
m_SeedResidual) SeedParams.emplace_back(gSlope3, gInter3);
598 line_theta = Alpha0 - Alpha2;
604 float gSlope4 = (globalDir4.perp() / globalDir4.z());
605 float gInter4 = gPos4.perp() - gSlope4 * gPos4.z();
607 if (resid <
m_SeedResidual) SeedParams.emplace_back(gSlope4, gInter4);
618 for (
unsigned int i = 1;
i < (mdts.size() - 1); ++
i) {
619 float mdtR = mdts.at(
i)->globalPosition().perp();
620 float mdtZ = mdts.at(
i)->globalPosition().z();
622 std::abs((mdts.at(
i)->localPosition()[
Trk::locR] - std::abs((mdtR - inter - slope * mdtZ) / std::sqrt(
sq(slope) + 1))) /
624 if (
res > resid) resid =
res;
632 std::vector<std::pair<float, float> >& SeedParams)
const {
633 std::vector<TrackletSegment> segs;
634 int stName =
m_idHelperSvc->mdtIdHelper().stationName(mdts.at(0)->identify());
636 if (stName <= 11 || stName == 52)
637 mlmidpt = std::sqrt(
sq(mdts.at(0)->detectorElement()->center().x()) +
sq(mdts.at(0)->detectorElement()->center().y()));
638 else if (stName <= 21 || stName == 49)
639 mlmidpt = mdts.at(0)->detectorElement()->center().z();
642 for (
unsigned int i_p = 0; i_p < SeedParams.size(); ++i_p) {
646 float s(0),
sz(0),
sy(0);
648 for (
unsigned int i = 0;
i < mdts.size(); ++
i) {
658 sz += mdt_z / sigma2;
659 sy += mdt_y / sigma2;
661 const float yc =
sy /
s;
662 const float zc =
sz /
s;
665 float alpha = std::atan2(SeedParams.at(i_p).first, 1.0);
666 if (alpha < 0) alpha +=
M_PI;
668 float d = (SeedParams.at(i_p).second - yc + zc * SeedParams.at(i_p).first) *
std::cos(alpha);
672 if (std::abs(
std::cos(alpha)) > 0.97 && (stName <= 11 || stName == 52))
continue;
673 if (std::abs(
std::cos(alpha)) < 0.03 && ((stName > 11 && stName < 22) || stName == 49))
continue;
676 float sPyy(0), sPyz(0), sPyyzz(0);
677 for (
unsigned int i = 0;
i < mdts.size(); ++
i) {
682 sPyy +=
sq(mdt_y - yc) / sigma2;
683 sPyz += (mdt_y - yc) * (mdt_z - zc) / sigma2;
684 sPyyzz += ((mdt_y - yc) - (mdt_z - zc)) * ((mdt_y - yc) + (mdt_z - zc)) / sigma2;
689 float deltaAlpha = 0;
692 float sumRyi(0), sumRzi(0), sumRi(0);
695 const float cos_a =
std::cos(alpha);
696 const float sin_a =
std::sin(alpha);
697 for (
unsigned int i = 0;
i < mdts.size(); ++
i) {
701 float yPi = -(mdt_z - zc) * sin_a + (mdt_y - yc) * cos_a -
d;
702 float signR = yPi >= 0 ? -1. : 1;
706 sumRyi += ri * (mdt_y - yc) / sigma2;
707 sumRzi += ri * (mdt_z - zc) / sigma2;
708 sumRi += ri / sigma2;
710 chi2 +=
sq(yPi + ri) / sigma2;
712 float bAlpha = -1 * sPyz + cos_a * (sin_a * sPyyzz + 2 * cos_a * sPyz + sumRzi) + sin_a * sumRyi;
713 float AThTh = sPyy + cos_a * (2 * sin_a * sPyz - cos_a * sPyyzz);
717 if (std::abs(AThTh) < 1.e-7)
break;
719 float alphaNew = alpha + bAlpha / AThTh;
720 float dNew = sumRi /
s;
722 dalpha = std::sqrt(1 / std::abs(AThTh));
723 dd = std::sqrt(1 /
s);
724 deltaAlpha = std::abs(alphaNew - alpha);
725 deltad = std::abs(
d - dNew);
727 if (deltaAlpha < 0.0000005 && deltad < 0.000005)
break;
731 if (Nitr > 10)
break;
735 float chi2Prob = TMath::Prob(
chi2, mdts.size() - 2);
752 for (
unsigned int k = 0;
k < mdts.size(); ++
k) {
754 float mdtR = std::sqrt(
sq(mdts.at(
k)->globalPosition().x()) +
sq(mdts.at(
k)->globalPosition().y()));
755 float mdtZ = mdts.at(
k)->globalPosition().z();
756 float zTest = (mdtR - y0) /
std::tan(alpha) +
z0 - mdtZ;
765 int chEta =
m_idHelperSvc->mdtIdHelper().stationEta(mdts.at(0)->identify());
766 int chPhi =
m_idHelperSvc->mdtIdHelper().stationPhi(mdts.at(0)->identify());
769 float mdtPhi = mdts.at(0)->globalPosition().phi();
772 TrackletSegment MyTrackletSegment(stName, chEta, chPhi, mlmidpt, alpha, dalpha, segpos, dy0, dz0, mdts,
pattern);
773 segs.push_back(MyTrackletSegment);
779 if (segs.size() > 1) {
780 std::vector<TrackletSegment> tmpSegs;
781 for (
unsigned int i1 = 0; i1 < segs.size(); ++i1) {
782 bool isUnique =
true;
783 int pattern1 = segs.at(i1).getHitPattern();
784 for (
unsigned int i2 = (i1 + 1); i2 < segs.size(); ++i2) {
785 if (pattern1 == -1)
break;
786 int pattern2 = segs.at(i2).getHitPattern();
787 if (pattern1 == pattern2) isUnique =
false;
789 if (isUnique) tmpSegs.push_back(segs.at(i1));
801 std::vector<TrackletSegment> CleanSegs;
802 std::vector<TrackletSegment> segs = Segs;
803 bool keepCleaning(
true);
805 while (keepCleaning) {
807 keepCleaning =
false;
809 if (
it->isCombined())
continue;
810 std::vector<TrackletSegment> segsToCombine;
812 float r1 =
it->globalPosition().perp();
813 float zi1 =
it->globalPosition().z() - r1 / tanTh1;
816 if (sit->isCombined())
continue;
817 if (
it->mdtChamber() != sit->mdtChamber())
continue;
818 if ((
it->mdtChEta()) * (sit->mdtChEta()) < 0)
continue;
819 if (
it->mdtChPhi() != sit->mdtChPhi())
continue;
820 if (std::abs(
it->alpha() - sit->alpha()) > 0.005)
continue;
821 float tanTh2 =
std::tan(sit->alpha());
822 float r2 = sit->globalPosition().perp();
823 float zi2 = sit->globalPosition().z() - r2 / tanTh2;
825 float rmid = (r1 + r2) / 2.;
826 float z1 = rmid / tanTh1 + zi1;
827 float z2 = rmid / tanTh2 + zi2;
828 float zdist = std::abs(z1 - z2);
830 segsToCombine.push_back(*sit);
831 sit->isCombined(
true);
836 if (segsToCombine.empty()) {
837 CleanSegs.push_back(*
it);
840 else if (!segsToCombine.empty()) {
842 std::vector<const Muon::MdtPrepData*> mdts =
it->mdtHitsOnTrack();
843 for (
unsigned int i = 0;
i < segsToCombine.size(); ++
i) {
844 std::vector<const Muon::MdtPrepData*> tmpmdts = segsToCombine[
i].mdtHitsOnTrack();
848 if ((*mit)->identify() == (*msit)->identify()) {
853 if (isNewHit &&
Amg::error((*mit)->localCovariance(),
Trk::locR) > 0.001) mdts.push_back(*mit);
858 if (mdts.size() >
it->mdtHitsOnTrack().size()) {
861 if (refitsegs.empty()) {
862 if (segsToCombine.size() == 1) {
863 segsToCombine[0].isCombined(
false);
864 CleanSegs.push_back(*
it);
865 CleanSegs.push_back(segsToCombine[0]);
868 std::vector<int> nSeg;
869 for (
unsigned int i = 0;
i < mdts.size(); ++
i) {
872 for (
unsigned int k = 0;
k <
it->mdtHitsOnTrack().
size(); ++
k) {
873 if (
it->mdtHitsOnTrack()[
k]->identify() == mdts[
i]->identify()) {
879 for (
unsigned int k = 0;
k < segsToCombine.size(); ++
k) {
880 for (
unsigned int m = 0;
m < segsToCombine[
k].mdtHitsOnTrack().
size(); ++
m) {
890 bool keeprefitting(
true);
892 while (keeprefitting) {
894 int nMinSeg(nSeg[0]);
896 std::vector<int> nrfsegs;
897 std::vector<const Muon::MdtPrepData*> refitmdts;
899 for (
unsigned int i = 1;
i < mdts.size(); ++
i) {
900 if (nSeg[
i] < nMinSeg) {
901 refitmdts.push_back(minmdt);
902 nrfsegs.push_back(nMinSeg);
906 refitmdts.push_back(mdts[
i]);
907 nrfsegs.push_back(nSeg[
i]);
915 if (!refitsegs.empty()) {
918 CleanSegs.push_back(*rfit);
920 keeprefitting =
false;
921 }
else if (mdts.size() <= 3) {
922 CleanSegs.push_back(*
it);
923 keeprefitting =
false;
925 if (nItr2 > 10)
break;
931 CleanSegs.push_back(*rfit);
937 CleanSegs.push_back(*
it);
944 if (nItr > 10)
break;
955 float mid1(100), mid2(1000);
965 if (std::abs(deltab2) < std::abs(deltab)) deltab = deltab2;
974 if (std::abs(deltab2) < std::abs(deltab)) deltab = deltab2;
980 return std::abs(deltab) < dbmax;
986 float pTot = 100000.;
989 pTot =
c_BIL / std::abs(deltaAlpha);
991 pTot =
c_BML / std::abs(deltaAlpha);
993 pTot =
c_BMS / std::abs(deltaAlpha);
995 pTot =
c_BMS / std::abs(deltaAlpha);
997 pTot =
c_BOL / std::abs(deltaAlpha);
999 pTot =
c_BIL / std::abs(deltaAlpha);
1001 pTot =
c_BML / std::abs(deltaAlpha);
1003 pTot =
c_BOL / std::abs(deltaAlpha);
1005 pTot =
c_BOL / std::abs(deltaAlpha);
1007 pTot =
c_BIL / std::abs(deltaAlpha);
1008 if (pTot > 10000.) pTot = 100000.;
1019 float pErr = dalpha /
c_BML;
1021 pErr = dalpha /
c_BIL;
1022 else if (ChType == 2)
1023 pErr = dalpha /
c_BML;
1024 else if (ChType == 3)
1025 pErr = dalpha /
c_BMS;
1026 else if (ChType == 54)
1027 pErr = dalpha /
c_BMS;
1028 else if (ChType == 4)
1029 pErr = dalpha /
c_BOL;
1030 else if (ChType == 7)
1031 pErr = dalpha /
c_BIL;
1032 else if (ChType == 8)
1033 pErr = dalpha /
c_BML;
1034 else if (ChType == 9)
1035 pErr = dalpha /
c_BOL;
1036 else if (ChType == 10)
1037 pErr = dalpha /
c_BOL;
1038 else if (ChType == 52)
1039 pErr = dalpha /
c_BIL;
1050 float pErr = dalpha /
c_BML;
1052 pErr = dalpha /
c_BIL;
1053 else if (ChType == 2)
1054 pErr = dalpha /
c_BML;
1055 else if (ChType == 3)
1056 pErr = dalpha /
c_BMS;
1057 else if (ChType == 54)
1058 pErr = dalpha /
c_BMS;
1059 else if (ChType == 4)
1060 pErr = dalpha /
c_BOL;
1061 else if (ChType == 7)
1062 pErr = dalpha /
c_BIL;
1063 else if (ChType == 8)
1064 pErr = dalpha /
c_BML;
1065 else if (ChType == 9)
1066 pErr = dalpha /
c_BOL;
1067 else if (ChType == 10)
1068 pErr = dalpha /
c_BOL;
1069 else if (ChType == 52)
1070 pErr = dalpha /
c_BIL;
1085 std::vector<Tracklet> myTracks = tracks;
1088 for (
unsigned int tk1 = 0; tk1 < myTracks.size(); ++tk1) {
1089 Identifier id1 = myTracks.at(tk1).getML1seg().mdtHitsOnTrack().at(0)->identify();
1090 Identifier id2 = myTracks.at(tk1).getML2seg().mdtHitsOnTrack().at(0)->identify();
1091 int nLayerML1 =
m_idHelperSvc->mdtIdHelper().tubeLayerMax(id1);
1093 float ratio = (
float)(myTracks.at(tk1).mdtHitsOnTrack().size()) / (nLayerML1 + nLayerML2);
1094 if (
ratio > 0.75) tracks.push_back(myTracks.at(tk1));
1098 std::vector<Tracklet> UniqueTracks;
1099 std::vector<unsigned int> AmbigTrks;
1100 for (
unsigned int tk1 = 0; tk1 < tracks.size(); ++tk1) {
1103 bool isResolved =
false;
1104 for (
unsigned int ck = 0; ck < AmbigTrks.size(); ++ck) {
1105 if (tk1 == AmbigTrks.at(ck)) {
1110 if (isResolved)
continue;
1111 std::vector<Tracklet> AmbigTracks;
1112 AmbigTracks.push_back(tracks.at(tk1));
1114 float Trk1ML1R = tracks.at(tk1).getML1seg().globalPosition().perp();
1115 float Trk1ML1Z = tracks.at(tk1).getML1seg().globalPosition().z();
1116 float Trk1ML2R = tracks.at(tk1).getML2seg().globalPosition().perp();
1117 float Trk1ML2Z = tracks.at(tk1).getML2seg().globalPosition().z();
1120 for (
unsigned int tk2 = (tk1 + 1); tk2 < tracks.size(); ++tk2) {
1121 if (tracks.at(tk1).mdtChamber() == tracks.at(tk2).mdtChamber() && tracks.at(tk1).mdtChPhi() == tracks.at(tk2).mdtChPhi() &&
1122 (tracks.at(tk1).mdtChEta()) * (tracks.at(tk2).mdtChEta()) > 0) {
1124 for (
unsigned int ck = 0; ck < AmbigTrks.size(); ++ck) {
1125 if (tk2 == AmbigTrks.at(ck)) {
1130 if (isResolved)
continue;
1132 float Trk2ML1R = tracks.at(tk2).getML1seg().globalPosition().perp();
1133 float Trk2ML1Z = tracks.at(tk2).getML1seg().globalPosition().z();
1134 float Trk2ML2R = tracks.at(tk2).getML2seg().globalPosition().perp();
1135 float Trk2ML2Z = tracks.at(tk2).getML2seg().globalPosition().z();
1138 float DistML1(1000), DistML2(1000);
1139 if (tracks.at(tk1).mdtChamber() <= 11 || tracks.at(tk1).mdtChamber() == 52) {
1140 DistML1 = std::abs(Trk1ML1Z - Trk2ML1Z);
1141 DistML2 = std::abs(Trk1ML2Z - Trk2ML2Z);
1142 }
else if (tracks.at(tk1).mdtChamber() <= 21 || tracks.at(tk1).mdtChamber() == 49) {
1143 DistML1 = std::abs(Trk1ML1R - Trk2ML1R);
1144 DistML2 = std::abs(Trk1ML2R - Trk2ML2R);
1146 if (DistML1 < 40 || DistML2 < 40) {
1148 std::vector<const Muon::MdtPrepData*> mdt1 = tracks.at(tk1).mdtHitsOnTrack();
1149 std::vector<const Muon::MdtPrepData*> mdt2 = tracks.at(tk2).mdtHitsOnTrack();
1151 for (
unsigned int m1 = 0;
m1 < mdt1.size(); ++
m1) {
1152 for (
unsigned int m2 = 0;
m2 < mdt2.size(); ++
m2) {
1153 if (mdt1.at(
m1)->identify() == mdt2.at(
m2)->identify()) {
1160 if (nShared <= 1)
continue;
1162 AmbigTracks.push_back(tracks.at(tk2));
1163 AmbigTrks.push_back(tk2);
1168 if (AmbigTracks.size() == 1) {
1169 UniqueTracks.push_back(tracks.at(tk1));
1174 if (tracks.at(tk1).mdtChamber() <= 11 || tracks.at(tk1).mdtChamber() == 52) {
1175 bool hasMomentum =
true;
1176 if (tracks.at(tk1).charge() == 0) hasMomentum =
false;
1177 float aveX(0), aveY(0), aveZ(0), aveAlpha(0);
1178 float aveP(0), nAmbigP(0), TrkCharge(tracks.at(tk1).charge());
1179 bool allSameSign(
true);
1180 for (
unsigned int i = 0;
i < AmbigTracks.size(); ++
i) {
1182 aveX += AmbigTracks.at(
i).globalPosition().x();
1183 aveY += AmbigTracks.at(
i).globalPosition().y();
1184 aveZ += AmbigTracks.at(
i).globalPosition().z();
1185 aveAlpha += AmbigTracks.at(
i).getML1seg().alpha();
1188 if (std::abs(AmbigTracks.at(
i).charge() - TrkCharge) > 0.1) allSameSign =
false;
1190 aveP += AmbigTracks.at(
i).momentum().mag();
1192 aveAlpha += AmbigTracks.at(
i).alpha();
1193 aveX += AmbigTracks.at(
i).globalPosition().x();
1194 aveY += AmbigTracks.at(
i).globalPosition().y();
1195 aveZ += AmbigTracks.at(
i).globalPosition().z();
1199 aveX = aveX / (
float)AmbigTracks.size();
1200 aveY = aveY / (
float)AmbigTracks.size();
1201 aveZ = aveZ / (
float)AmbigTracks.size();
1203 aveAlpha = aveAlpha / (
float)AmbigTracks.size();
1204 float alphaErr = tracks.at(tk1).getML1seg().alphaError();
1205 float rErr = tracks.at(tk1).getML1seg().rError();
1206 float zErr = tracks.at(tk1).getML1seg().zError();
1207 int Chamber = tracks.at(tk1).mdtChamber();
1208 int ChEta = tracks.at(tk1).mdtChEta();
1209 int ChPhi = tracks.at(tk1).mdtChPhi();
1211 TrackletSegment aveSegML1(Chamber, ChEta, ChPhi, tracks.at(tk1).getML1seg().getChMidPoint(), aveAlpha, alphaErr, gpos,
1212 rErr, zErr, tracks.at(tk1).getML1seg().mdtHitsOnTrack(), 0);
1219 matrix(0, 0) =
sq(tracks.at(tk1).getML1seg().rError());
1220 matrix(1, 1) =
sq(tracks.at(tk1).getML1seg().zError());
1222 matrix(3, 3) =
sq(tracks.at(tk1).getML1seg().alphaError());
1225 UniqueTracks.push_back(aveTrack);
1226 }
else if (allSameSign) {
1227 aveP = aveP / nAmbigP;
1228 float pT = aveP *
std::sin(tracks.at(tk1).getML1seg().alpha());
1229 float pz = aveP *
std::cos(tracks.at(tk1).getML1seg().alpha());
1231 pT *
std::sin(tracks.at(tk1).globalPosition().phi()),
pz);
1234 MyTrack.
charge(tracks.at(tk1).charge());
1235 UniqueTracks.push_back(MyTrack);
1237 aveX = aveX / (
float)AmbigTracks.size();
1238 aveY = aveY / (
float)AmbigTracks.size();
1239 aveZ = aveZ / (
float)AmbigTracks.size();
1241 aveAlpha = aveAlpha / (
float)AmbigTracks.size();
1242 float alphaErr = tracks.at(tk1).getML1seg().alphaError();
1243 float rErr = tracks.at(tk1).getML1seg().rError();
1244 float zErr = tracks.at(tk1).getML1seg().zError();
1245 int Chamber = tracks.at(tk1).mdtChamber();
1246 int ChEta = tracks.at(tk1).mdtChEta();
1247 int ChPhi = tracks.at(tk1).mdtChPhi();
1248 TrackletSegment aveSegML1(Chamber, ChEta, ChPhi, tracks.at(tk1).getML1seg().getChMidPoint(), aveAlpha, alphaErr, gpos,
1249 rErr, zErr, tracks.at(tk1).getML1seg().mdtHitsOnTrack(), 0);
1256 matrix(0, 0) =
sq(tracks.at(tk1).getML1seg().rError());
1257 matrix(1, 1) =
sq(tracks.at(tk1).getML1seg().zError());
1259 matrix(3, 3) =
sq(tracks.at(tk1).getML1seg().alphaError());
1262 UniqueTracks.push_back(aveTrack);
1267 else if ((tracks.at(tk1).mdtChamber() > 11 && tracks.at(tk1).mdtChamber() <= 21) || tracks.at(tk1).mdtChamber() == 49) {
1268 std::vector<const Muon::MdtPrepData*> AllMdts;
1269 for (
unsigned int i = 0;
i < AmbigTracks.size(); ++
i) {
1270 std::vector<const Muon::MdtPrepData*> mdts = AmbigTracks.at(
i).mdtHitsOnTrack();
1271 std::vector<const Muon::MdtPrepData*> tmpAllMdt = AllMdts;
1272 for (
unsigned int m1 = 0;
m1 < mdts.size(); ++
m1) {
1273 bool isNewHit =
true;
1274 for (
unsigned int m2 = 0;
m2 < tmpAllMdt.size(); ++
m2) {
1275 if (mdts.at(
m1)->identify() == tmpAllMdt.at(
m2)->identify()) {
1280 if (isNewHit) AllMdts.push_back(mdts.at(
m1));
1285 if (!MyECsegs.empty()) {
1299 UniqueTracks.push_back(MyCombTrack);
1301 UniqueTracks.push_back(tracks.at(tk1));
1306 return UniqueTracks;