44 const double FiftyOverSqrt12 = 50. / std::sqrt(12);
47 void operator()(
const Muon::MuonSegment*)
const {};
54 declareInterface<MooTrackFitter>(
this);
76 return StatusCode::SUCCESS;
95 <<
"| extract | phi range | startPars | clean phi | add fake | fit | no perigee | low mom | extract | "
96 "add fake | final fit | passed |"
98 << std::setprecision(2) << std::setw(12) << nfailedExtractInital << std::setw(12) << nfailedMinMaxPhi << std::setw(12)
99 << nfailedParsInital << std::setw(12) << nfailedExtractCleaning << std::setw(12) << nfailedFakeInitial << std::setw(12)
100 << nfailedTubeFit << std::setw(13) << noPerigee << std::setw(12) << nlowMomentum << std::setw(12)
101 << nfailedExtractPrecise << std::setw(12) << nfailedFakePrecise << std::setw(12) << nfailedFitPrecise << std::setw(12)
104 return StatusCode::SUCCESS;
108 if (entry.hits().size() < entry.etaHits().size()) {
112 if (entry.etaHits().size() < 3) {
return (entry.ncscHitsEta < 2); }
125 if (!
extractData(fitterData,
true))
return nullptr;
129 if (!pp)
return nullptr;
136 std::set<Identifier> excludedChambers;
138 if (cleanTrack && !(*cleanTrack->perigeeParameters() == *track->perigeeParameters())) track.swap(cleanTrack);
149 if (states) nStates = states->size();
150 msg(MSG::DEBUG) << MSG::DEBUG <<
"refit: fitting track with hits: " << nStates;
151 if (
msgLvl(MSG::VERBOSE)) {
msg(MSG::VERBOSE) << std::endl <<
m_printer->printMeasurements(track); }
159 std::set<Identifier> excludedChambers;
164 if (!(*cleanTrack->perigeeParameters() == *newTrack->perigeeParameters())) newTrack.swap(cleanTrack);
177 const PrepVec& externalPhiHits)
const {
191 ATH_MSG_DEBUG(
" Phi range check failed, candidate stations not pointing. Will not fit track");
199 std::unique_ptr<Trk::Perigee>& startPars = fitterData.
startPars;
214 ATH_MSG_DEBUG(
" Failed to extract data after phi hit cleaning");
222 ATH_MSG_DEBUG(
" Failed to add fake phi hits for precise fit");
281 ATH_MSG_DEBUG(
" Failed to add fake phi hits for precise fit");
289 track.swap(newTrack);
294 ATH_MSG_DEBUG(
" Precise fit failed, keep fit with broad errors");
298 fitterData.
garbage.insert(fitterData.
garbage.end(), std::make_move_iterator(fitterDataRefit.
garbage.begin()),
299 std::make_move_iterator(fitterDataRefit.
garbage.end()));
300 fitterDataRefit.
garbage.clear();
305 std::set<Identifier> excludedChambers;
313 if (!excludedChambers.empty()) {
ATH_MSG_DEBUG(
" Using exclusion list for cleaning"); }
316 if (!(*cleanTrack->perigeeParameters() == *track->perigeeParameters())) track.swap(cleanTrack);
323 if (
msgLvl(MSG::DEBUG) && track)
msg(MSG::DEBUG) << MSG::DEBUG <<
" Track found " <<
endmsg;
331 ATH_MSG_DEBUG(
" corrupt first entry, cannot perform fit: eta hits " << entry1.
etaHits().size());
335 ATH_MSG_DEBUG(
" corrupt second entry, cannot perform fit: eta hits " << entry2.
etaHits().size());
345 bool entry1IsFirst = sortMeasurements(entry1.
hits().front(), entry2.
hits().front());
349 if (distToSecond < 0) entry1IsFirst =
false;
374 msg(MSG::DEBUG) << MSG::DEBUG <<
" entering fitter: etaHits, first entry: ";
376 msg(MSG::DEBUG) <<
" track ";
378 msg(MSG::DEBUG) <<
" segment ";
381 <<
" second entry: ";
383 msg(MSG::DEBUG) <<
" track ";
385 msg(MSG::DEBUG) <<
" segment ";
391 msg(MSG::DEBUG) << MSG::DEBUG <<
" merged hit lists, new list size: " << fitterData.
hitList.size();
392 if (usePrecise)
msg(MSG::DEBUG) <<
" using precise errors" <<
endmsg;
401 ATH_MSG_DEBUG(
" extracting hits from hit list, using " << (usePreciseHits ?
"precise measurements" :
"broad measurements"));
405 unsigned int nhits = hitList.size();
416 StIndex firstStation = StIndex::StUnknown;
417 ChIndex currentChIndex = ChIndex::ChUnknown;
418 bool currentMeasPhi =
false;
431 <<
") is not a muon Identifier, continuing");
437 fitterData.
stations.insert(stIndex);
439 if (firstStation == StIndex::StUnknown) {
440 firstStation = stIndex;
443 const bool measuresPhi = hit->info().measuresPhi;
456 const Trk::MeasurementBase* meas = usePreciseHits ? &hit->preciseMeasurement() : &hit->broadMeasurement();
462 fitterData.
phiHits.push_back(meas);
464 fitterData.
etaHits.push_back(meas);
469 if (usePreciseHits &&
m_idHelperSvc->isMdt(
id) && std::abs(rDrift) < 0.01 && rError > 4.) {
480 currentMeasPhi = measuresPhi;
482 }
else if (currentChIndex ==
chIndex && currentMeasPhi == measuresPhi) {
486 currentMeasPhi = measuresPhi;
503 if (fitterData.
etaHits.size() < 7) {
519 if (nphiConstraints >= 2) {
523 ATH_MSG_VERBOSE(
" Special treatment of the forward region: adding fake at ip ");
530 std::unique_ptr<Amg::Vector3D> overlapPos;
531 std::unique_ptr<const Amg::Vector3D> phiPos;
536 overlapPos = std::make_unique<Amg::Vector3D>(1., 1., 1.);
551 phiPos = std::make_unique<Amg::Vector3D>(fitterData.
startPars->momentum());
553 phiPos = std::make_unique<Amg::Vector3D>(*overlapPos);
556 if (
msgLvl(MSG::VERBOSE)) {
558 if (fitterData.
stations.size() == 1)
559 msg(MSG::VERBOSE) <<
" one station fit with SL overlap, using overlapPos " << *overlapPos <<
endmsg;
561 msg(MSG::VERBOSE) <<
" multi station fit with SL overlap, using overlapPos " << *overlapPos <<
endmsg;
563 msg(MSG::VERBOSE) <<
" multi station fit, SL overlap not in same station, using overlapPos " << *overlapPos <<
endmsg;
569 if (fitterData.
phiHits.empty()) {
577 ATH_MSG_VERBOSE(
" Special treatment for tracks with one station, a SL overlap and no phi hits ");
582 if (!
result.goodMatch()) {
587 double locx1 =
result.segmentResult1.positionInTube1;
590 Trk::AtaPlane segPars1(locx1, locy1,
result.phiResult.segmentDirection1.phi(),
result.phiResult.segmentDirection1.theta(),
593 std::unique_ptr<Trk::TrackParameters> exPars1 =
m_propagator->propagate(ctx,
598 std::unique_ptr<Trk::MeasurementBase> fake =
601 fitterData.
phiHits.push_back(fake.get());
604 fitterData.
garbage.push_back(std::move(fake));
610 double locx2 =
result.segmentResult2.positionInTube1;
613 Trk::AtaPlane segPars2(locx2, locy2,
result.phiResult.segmentDirection2.phi(),
result.phiResult.segmentDirection2.theta(),
621 std::unique_ptr<Trk::MeasurementBase> fake =
624 fitterData.
phiHits.push_back(fake.get());
627 fitterData.
garbage.push_back(std::move(fake));
633 }
else if (nphiConstraints == 0 || (fitterData.
stations.size() == 1) ||
638 overlapPos.get(), phiPos.get(), 100.);
640 fitterData.
phiHits.push_back(fake.get());
643 fitterData.
garbage.push_back(std::move(fake));
649 overlapPos.get(), phiPos.get(), 100.);
651 fitterData.
phiHits.push_back(fake.get());
654 fitterData.
garbage.push_back(std::move(fake));
660 ATH_MSG_VERBOSE(
" Special treatment for tracks with one SL overlap and no phi hits ");
662 StIndex overlapStation = StIndex::StUnknown;
665 for (; it != it_end; ++it) {
666 if (it->second.first && it->second.second) {
667 overlapStation = it->first;
671 if (overlapStation == StIndex::StUnknown) {
678 ATH_MSG_WARNING(
" unexpected condition, first measurement has no identifier ");
682 if (overlapStation == firstSt) {
687 overlapPos.get(), phiPos.get(), 100.);
689 fitterData.
phiHits.push_back(fake.get());
692 fitterData.
garbage.push_back(std::move(fake));
698 overlapPos.get(), phiPos.get(), 100.);
700 fitterData.
phiHits.push_back(fake.get());
703 fitterData.
garbage.push_back(std::move(fake));
713 double distFirstEtaPhi =
714 (fitterData.
measurements.front()->globalPosition() - fitterData.
phiHits.front()->globalPosition()).mag();
715 double distLastEtaPhi = (fitterData.
measurements.back()->globalPosition() - fitterData.
phiHits.back()->globalPosition()).mag();
719 phiPos = std::make_unique<Amg::Vector3D>(fitterData.
phiHits.back()->globalPosition());
720 ATH_MSG_VERBOSE(
" using pointing constraint to calculate fake phi hit ");
724 const Trk::Surface *firstmdtsurf =
nullptr, *lastmdtsurf =
nullptr;
726 int indexfirst = 0, indexlast = (int)fitterData.
measurements.size();
728 for (; hitit != fitterData.
hitList.end(); hitit++) {
729 if ((**hitit).info().measuresPhi)
break;
731 firstmdtsurf = &(**hitit).measurement().associatedSurface();
736 hitit = fitterData.
hitList.end();
738 for (; hitit != fitterData.
hitList.begin(); hitit--) {
739 if ((**hitit).info().measuresPhi)
break;
741 lastmdtsurf = &(**hitit).measurement().associatedSurface();
742 lastmdtpar = &(**hitit).parameters();
749 indexlast = std::max(indexlast, 0);
750 bool phifromextrapolation =
false;
753 const Trk::Surface *firstphisurf =
nullptr, *lastphisurf =
nullptr;
754 Amg::Vector3D firstphinormal{Amg::Vector3D::Zero()}, lastphinormal{Amg::Vector3D::Zero()};
755 if (!fitterData.
phiHits.empty()) {
756 firstphisurf = &fitterData.
phiHits.front()->associatedSurface();
757 lastphisurf = &fitterData.
phiHits.back()->associatedSurface();
758 firstphinormal = firstphisurf->
normal();
759 lastphinormal = lastphisurf->normal();
760 if (firstphinormal.dot(startpar.
momentum()) < 0) firstphinormal = -firstphinormal;
761 if (lastphinormal.dot(startpar.
momentum()) < 0) lastphinormal = -lastphinormal;
763 if (lastmdtsurf && (!firstphisurf || (lastmdtsurf->center() - lastphisurf->center()).dot(lastphinormal) > 1000)) {
764 ATH_MSG_VERBOSE(
" Adding fake at last hit: dist first phi/first eta " << distFirstEtaPhi <<
" dist last phi/last eta "
766 std::unique_ptr<Trk::MeasurementBase> fake{};
769 std::unique_ptr<Trk::TrackParameters> mdtpar{};
773 mdtpar =
m_propagator->propagateParameters(ctx, startpar, *lastmdtsurf,
779 fake = std::make_unique<Trk::PseudoMeasurementOnTrack>(
782 mdtpar->associatedSurface());
789 fitterData.
phiHits.push_back(fake.get());
792 fitterData.
garbage.push_back(std::move(fake));
796 if (firstmdtsurf && (!firstphisurf || (firstmdtsurf->
center() - firstphisurf->
center()).dot(firstphinormal) < -1000)) {
797 ATH_MSG_VERBOSE(
" Adding fake at first hit: dist first phi/first eta " << distFirstEtaPhi <<
" dist last phi/last eta "
799 std::unique_ptr<Trk::MeasurementBase> fake{};
800 if (phifromextrapolation) {
802 auto mdtpar =
m_propagator->propagateParameters(ctx, startpar,
807 fake = std::make_unique<Trk::PseudoMeasurementOnTrack>(
810 mdtpar->associatedSurface());
816 fitterData.
phiHits.insert(fitterData.
phiHits.begin(), fake.get());
819 fitterData.
garbage.push_back(std::move(fake));
828 double errPos)
const {
832 ATH_MSG_WARNING(
" Cannot create fake phi hit from a measurement without Identifier ");
862 std::optional<Amg::Vector2D> lpos = std::nullopt;
874 if (!intersect.valid) {
877 <<
" theta " << dir.theta() <<
" seed: phi " << phiPos->phi() <<
" theta "
899 double halfLength = ly < 0 ? halfLengthL : halfLengthR;
900 bool shiftedPos =
false;
902 if (std::abs(ly) > halfLength) {
904 ly = ly < 0 ? -halfLength : halfLength;
905 ATH_MSG_DEBUG(
" extrapolated position outside detector, shifting it back: " << lyold <<
" size " << halfLength <<
" new pos "
907 if (phiPos && std::abs(lyold) - halfLength > 1000.) {
923 std::optional<Amg::Vector2D> loverlapPos = surf.
globalToLocal(*overlapPos, 3000.);
927 double lyfake = halfLength - 50.;
928 if (ly < 0.) lyfake *= -1.;
930 errPos = FiftyOverSqrt12;
932 if (
msgLvl(MSG::VERBOSE)){
938 double phi_min = fakePos_min.phi();
939 double phi_plus = fakePos_plus.phi();
940 double phi_overlap = phiPos->phi();
941 ATH_MSG_VERBOSE(
" fake lpos " << lyfake <<
" ch half length " << halfLength <<
" phi+ " << phi_plus <<
" phi- " << phi_min
942 <<
" phi overlap " << phi_overlap <<
" err " << errPos);
947 halfLength = ly < 0 ? halfLengthL : halfLengthR;
948 if (std::abs(ly) > halfLength) { ly = ly < 0 ? -halfLength : halfLength; }
949 ATH_MSG_VERBOSE(
" fake from overlap: lpos " << ly <<
" ch half length " << halfLength <<
" overlapPos " << *overlapPos);
956 cov(0, 0) = errPos * errPos;
957 std::unique_ptr<Trk::PseudoMeasurementOnTrack> fake = std::make_unique<Trk::PseudoMeasurementOnTrack>(std::move(locPars),
958 std::move(cov), surf);
964 msg(MSG::DEBUG) << MSG::DEBUG <<
" createFakePhiForMeasurement for: " <<
m_idHelperSvc->toStringChamber(
id) <<
" locY " << ly
965 <<
" errpr " << errPos <<
" phi " << fakePos.phi() <<
endmsg;
967 if (!shiftedPos && !overlapPos && phiPos && std::abs(phiPos->phi() - fakePos.phi()) > 0.01) {
970 ATH_MSG_WARNING(
" Problem calculating fake from IP seed: phi fake " << fakePos.phi() <<
" IP phi " << phiPos->phi()
971 <<
" local meas pos " << locMeas);
985 unsigned int nphiConstraints = fitterData.
phiHits.size();
995 double distanceMin = 400.;
996 double distance = 0.;
998 if (fitterData.
phiHits.size() > 1) {
1002 double distFirstEtaPhi =
1003 (fitterData.
measurements.front()->globalPosition() - fitterData.
phiHits.front()->globalPosition()).mag();
1004 double distLastEtaPhi = (fitterData.
measurements.back()->globalPosition() - fitterData.
phiHits.back()->globalPosition()).mag();
1010 distance = fitterData.
hasEndcap ? std::abs(globalDistance.z()) : globalDistance.perp();
1013 if (distance < distanceMin || distFirstEtaPhi > 1000 || distLastEtaPhi > 1000) {
1014 nphiConstraints -= fitterData.
phiHits.size();
1015 nphiConstraints += 1;
1016 ATH_MSG_VERBOSE(
" distance between phi hits too small, updating phi constraints ");
1018 ATH_MSG_VERBOSE(
" distance between phi hits sufficient, no fake hits needed ");
1021 if (
msgLvl(MSG::DEBUG)) {
1022 msg(MSG::DEBUG) << MSG::DEBUG <<
" Check phi: " << std::endl
1023 <<
" | nphi hits | distance | SL station overlaps | small ch | large ch | nphiConstraints " << std::endl
1024 << std::setw(12) << fitterData.
phiHits.size() << std::setw(11) << (int)distance << std::setw(22)
1029 return nphiConstraints;
1033 std::map<MuonStationIndex::StIndex, StationPhiData> stationDataMap;
1039 if (summary->muonTrackSummary()) {
1040 muonSummary = *summary->muonTrackSummary();
1052 std::vector<Trk::MuonTrackSummary::ChamberHitSummary>::const_iterator chit = muonSummary.
chamberHitSummary().begin();
1053 std::vector<Trk::MuonTrackSummary::ChamberHitSummary>::const_iterator chit_end = muonSummary.
chamberHitSummary().end();
1054 for (; chit != chit_end; ++chit) {
1059 if (chit->isMdt()) {
1065 if (chit->phiProjection().nhits) ++stData.
nphiHits;
1069 unsigned int phiConstraints = 0;
1070 unsigned int stationsWithSmall = 0;
1071 unsigned int stationsWithLarge = 0;
1073 std::map<MuonStationIndex::StIndex, StationPhiData>::iterator sit = stationDataMap.begin();
1074 std::map<MuonStationIndex::StIndex, StationPhiData>::iterator sit_end = stationDataMap.end();
1075 for (; sit != sit_end; ++sit) {
1084 ++stationsWithSmall;
1086 ++stationsWithLarge;
1089 if (stationsWithSmall > 0 && stationsWithLarge > 0) { ++phiConstraints; }
1091 return phiConstraints;
1096 if (!mdtDetEl){
return std::make_pair(0., 0.); }
1099 return std::make_pair(halfLength, halfLength);
1103 if (!cscDetEl) {
return std::make_pair(0., 0.);}
1104 const double halfLenghth = 0.5 * cscDetEl->
stripLength(
id);
1105 return std::make_pair(halfLenghth, halfLenghth);
1108 if (!rpcDetEl) {
return std::make_pair(0, 0);}
1109 const double halfLength = 0.5 * rpcDetEl->
StripLength(
false);
1110 return std::make_pair(halfLength, halfLength);
1113 if (!tgcDetEl) {
return std::make_pair(0.,0.);}
1115 return std::make_pair(halfLength, halfLength);
1118 if (!stgcDetEl || !stgcDetEl->
getDesign(
id)) {
return std::make_pair(0.,0.);}
1120 return std::make_pair(halfLength, halfLength);
1129 return std::make_pair(0.,0.);
1132 double phiStart = fitterData.
etaHits.front()->globalPosition().phi();
1133 double phiOffset = 0.;
1134 double phiRange = 0.75 *
M_PI;
1135 double phiRange2 = 0.25 *
M_PI;
1136 if (phiStart > phiRange || phiStart < -phiRange)
1137 phiOffset = 2 *
M_PI;
1138 else if (phiStart > -phiRange2 && phiStart < phiRange2)
1141 double phiMin = -999.;
1142 double phiMax = 999.;
1169 double phiLeft = gposLeft.phi();
1173 double phiRight = gposRight.phi();
1175 if (phiOffset > 1.5 *
M_PI) {
1176 if (phiLeft < 0) phiLeft = phiOffset + phiLeft;
1177 if (phiRight < 0) phiRight = phiOffset + phiRight;
1178 }
else if (phiOffset > 0.) {
1179 phiLeft = phiLeft + phiOffset;
1180 phiRight = phiRight + phiOffset;
1183 bool leftSmaller = phiLeft < phiRight;
1185 double phiMinMeas = leftSmaller ? phiLeft : phiRight;
1186 double phiMaxMeas = leftSmaller ? phiRight : phiLeft;
1187 double orgPhiMin = phiMinMeas;
1188 double orgPhiMax = phiMaxMeas;
1190 if (phiOffset > 1.5 *
M_PI) {
1191 if (orgPhiMin >
M_PI) orgPhiMin = orgPhiMin - phiOffset;
1192 if (orgPhiMax >
M_PI) orgPhiMax = orgPhiMax - phiOffset;
1193 }
else if (phiOffset > 0.) {
1194 orgPhiMin = orgPhiMin - phiOffset;
1195 orgPhiMax = orgPhiMax - phiOffset;
1198 if (phiMinMeas > phiMin) { phiMin = phiMinMeas; }
1199 if (phiMaxMeas < phiMax) { phiMax = phiMaxMeas; }
1201 if (phiMin < -998 || phiMax > 998) {
1206 double diffPhi = phiMax - phiMin;
1207 double avePhi = phiMin + 0.5 * diffPhi;
1209 ATH_MSG_VERBOSE(
"Phi ranges: min " << phiMin <<
" max " << phiMax <<
" average phi " << avePhi);
1218 if (!fitterData.
phiHits.empty()) {
1220 const double minPhi = std::min(phiMin, phiMax);
1221 const double maxPhi = std::max(phiMin, phiMax);
1223 if (phiOffset > 1.5 *
M_PI) {
1224 if (phiMeas < 0.) phiMeas = phiOffset + phiMeas;
1225 }
else if (phiOffset > 0.) {
1226 phiMeas = phiMeas + phiOffset;
1228 double diffMin = phiMeas - minPhi;
1229 double diffMax = phiMeas - maxPhi;
1230 if (diffMin < 0. || diffMax > 0.) {
1232 ATH_MSG_VERBOSE(
" Phi hits inconsistent with min/max, rejecting track: phi meas " << phiMeas);
1239 if (phiOffset > 1.5 *
M_PI) {
1240 if (phiMax >
M_PI) phiMax = phiMax - phiOffset;
1241 if (phiMin >
M_PI) phiMin = phiMin - phiOffset;
1242 if (avePhi >
M_PI) avePhi = avePhi - phiOffset;
1243 }
else if (phiOffset > 0.) {
1244 phiMax = phiMax - phiOffset;
1245 phiMin = phiMin - phiOffset;
1246 avePhi = avePhi - phiOffset;
1249 fitterData.
avePhi = avePhi;
1250 fitterData.
phiMin = phiMin;
1251 fitterData.
phiMax = phiMax;
1267 return std::shared_ptr<const MuonSegment> {segEntry->
segment, Unowned()};
1274 return entry.entryPars().charge() / entry.entryPars().momentum().mag();
1288 std::shared_ptr<const MuonSegment> segFirst =
segmentFromEntry(ctx, firstEntry);
1290 ATH_MSG_WARNING(
" failed to get segment for first entry, this should not happen ");
1294 std::shared_ptr<const MuonSegment> segSecond =
segmentFromEntry(ctx, secondEntry);
1296 ATH_MSG_WARNING(
" failed to get segment for second entry, this should not happen ");
1300 std::vector<const MuonSegment*> segments{segFirst.get(), segSecond.get()};
1302 double momentum{1.};
1306 if (momentum == 0.)
return 0.;
1308 qOverP = 1. / momentum;
1333 if (!
result.goodMatch()) {
1337 double overlapPhi =
result.phiResult.segmentDirection1.phi();
1346 if (difPos.y() > 0) difPos *= -1.;
1350 if (std::abs(dphi) > 0.2) {
1351 ATH_MSG_DEBUG(
"Large diff between phi of segment direction and of position "
1353 return difPos.phi();
1367 Amg::Vector3D difPos = etaHits.back()->globalPosition() - etaHits.front()->globalPosition();
1368 if (difPos.mag() > 3000) {
1369 ATH_MSG_DEBUG(
"Seeding phi using average phi of eta hits ");
1378 if (phiHits.empty()) {
1381 return fitterData.
avePhi;
1385 if (phiHits.size() == 1) {
return phiHits.front()->globalPosition().phi(); }
1400 MeasCit hit = phiHits.begin();
1401 MeasCit hit_end = phiHits.end();
1403 for (; hit != hit_end; ++hit) avePos += (*hit)->globalPosition();
1404 avePos /= phiHits.size();
1408 Amg::Vector3D difPos = phiHits.back()->globalPosition() - phiHits.front()->globalPosition();
1417 if (etaHits.empty()) {
1424 theta = entry.entryPars().momentum().theta();
1427 if (etaHits.size() == 1) {
1428 theta = etaHits.front()->globalPosition().theta();
1431 Amg::Vector3D difPos = etaHits.back()->globalPosition() - etaHits.front()->globalPosition();
1432 theta = difPos.theta();
1442 std::unique_ptr<Trk::Perigee> startPars{
nullptr};
1450 Amg::Vector3D dir1{Amg::Vector3D::Zero()}, dir2{Amg::Vector3D::Zero()};
1451 Amg::Vector3D point1{Amg::Vector3D::Zero()}, point2{Amg::Vector3D::Zero()};
1474 if (dir1.dot(point2 - point1) < 0) {
1479 trkEntry1 =
dynamic_cast<const MuPatTrack*
>(entry1);
1480 trkEntry2 =
dynamic_cast<const MuPatTrack*
>(entry2);
1486 double dist1 = -1, dist2 = -1;
1487 MuPatHitPtr firstphi1{
nullptr}, lastphi1{
nullptr}, firstphi2{
nullptr}, lastphi2{
nullptr};
1491 if (!firstphi1) firstphi1 = hit;
1495 for (
const MuPatHitPtr& hit : entry2->hitList()) {
1497 if (!firstphi2) firstphi2 = hit;
1501 if (firstphi1) dist1 = std::abs((firstphi1->measurement().globalPosition() - lastphi1->measurement().globalPosition()).dot(dir1));
1502 if (firstphi2) dist2 = std::abs((firstphi2->measurement().globalPosition() - lastphi2->measurement().globalPosition()).dot(dir2));
1503 if (dist2 > dist1) { bestentry = entry2; }
1520 startPars = std::make_unique<Trk::Perigee>(0, 0, newpar[
Trk::phi], newpar[
Trk::theta], qOverP,
1534 startPars = std::make_unique<Trk::Perigee>(0, 0,
phi,
theta, qOverP, persurf);
1541 fitterData.
startPars = std::move(startPars);
1550 std::unique_ptr<Trk::TrackParameters> garbage;
1560 exPars = garbage.get();
1581 std::unique_ptr<Trk::Perigee> perigee = std::make_unique<Trk::Perigee>(0, 0,
phi,
theta, qoverp, persurf);
1583 ATH_MSG_DEBUG( std::setprecision(5) <<
" creating perigee: phi " <<
phi <<
" theta " <<
theta <<
" q*mom "
1584 << perigee->charge() * perigee->momentum().mag() <<
" r " << perigee->position().perp() <<
" z "
1585 << perigee->position().z() <<
" input q*mom " << firstPars.
charge() * firstPars.
momentum().mag());
1592 if (momentum > 20000.)
1594 else if (momentum < 2000)
1597 if (momentum < -20000.)
1599 else if (momentum > -2000.)
1608 if (hits.empty())
return nullptr;
1609 std::unique_ptr<Trk::Perigee> perigee{};
1610 ATH_MSG_VERBOSE(std::setprecision(5) <<
" track start parameter: phi " << startPars.
momentum().phi() <<
" theta "
1612 <<
" r " << startPars.
position().perp() <<
" z " << startPars.
position().z() << std::endl
1613 <<
" start par is a perigee "
1614 <<
" partHypo " << partHypo << std::endl
1620 double dist = distAlongPars(startPars, *hits.front());
1623 ATH_MSG_DEBUG(
" start parameters after first hit, shifting them.... ");
1626 pars = perigee.get();
1636 ATH_MSG_VERBOSE(
"fit: " << (prefit ?
"prefit" :
"fit") <<
"track with hits: " << hits.size() << std::endl
1653 std::unique_ptr<Trk::Track> track =
fit(ctx, startPars, hits,
Trk::muon,
false);
1666 if (std::abs(difMom) > 5000.) {
1667 ATH_MSG_DEBUG(
" absolute difference in momentum too large, refitting track. Dif momentum= " << difMom);
1668 ATH_MSG_DEBUG(
"fitWithRefit: refitting track with hits: " << hits.size() << std::endl <<
m_printer->print(hits));
1670 if (refittedTrack) {
1671 track.swap(refittedTrack);
1673 if (
msgLvl(MSG::DEBUG)) {
1688 const std::vector<const Trk::PrepRawData*>& patternPhiHits)
const {
1694 std::vector<const Trk::RIO_OnTrack*> rots;
1695 std::vector<std::unique_ptr<const Trk::RIO_OnTrack>> rotsNSW;
1696 std::set<Identifier> ids;
1697 std::set<MuonStationIndex::StIndex> stations;
1698 rots.reserve(phiHits.size() + 5);
1707 rots.push_back(rot);
1714 rots.push_back(mit);
1715 ids.insert(mit->identify());
1717 stations.insert(stIndex);
1720 ATH_MSG_WARNING(
" phi hits should be ROTs or competing ROTs! Dropping hit ");
1724 if (rots.empty())
return false;
1727 ATH_MSG_DEBUG(
" too many phi hits, not running cleaning " << rots.size());
1731 if (
msgLvl(MSG::VERBOSE)) {
1732 msg(MSG::VERBOSE) <<
" contained phi hits ";
1738 std::vector<const Trk::PrepRawData*> roadPhiHits;
1739 std::copy_if(patternPhiHits.begin(), patternPhiHits.end(), std::back_inserter(roadPhiHits), [&ids,
this](
const Trk::PrepRawData* prd){
1740 return !(ids.count(prd->identify()) ||
1742 m_idHelperSvc->isCsc(prd->identify()) || m_idHelperSvc->issTgc(prd->identify()));
1747 ATH_MSG_VERBOSE(
" too many pattern phi hits, not adding any " << roadPhiHits.size());
1748 roadPhiHits.clear();
1750 if (
msgLvl(MSG::VERBOSE)) {
1751 if (!roadPhiHits.empty()) {
1752 msg(MSG::VERBOSE) <<
" additional pattern phi hits " << std::endl;
1753 std::vector<const Trk::PrepRawData*>::const_iterator pit = roadPhiHits.begin();
1754 std::vector<const Trk::PrepRawData*>::const_iterator pit_end = roadPhiHits.end();
1755 for (; pit != pit_end; ++pit) {
1757 if (pit + 1 != pit_end)
1758 msg(MSG::DEBUG) << std::endl;
1765 std::vector<std::unique_ptr<const Trk::MeasurementBase>> newMeasurements{
m_phiHitSelector->select_rio(momentum, rots, roadPhiHits)};
1767 newMeasurements.insert(newMeasurements.end(),
1768 std::make_move_iterator(rotsNSW.begin()),
1769 std::make_move_iterator(rotsNSW.end()));
1773 if (newMeasurements.empty()) {
1774 ATH_MSG_DEBUG(
" empty list of phi hits return from phi hit selector: input size " << phiHits.size());
1780 constexpr double maxDistCut = 800.;
1781 std::vector<const Trk::MeasurementBase*> measurementsToBeAdded{};
1782 measurementsToBeAdded.reserve(newMeasurements.size());
1783 for (std::unique_ptr<const Trk::MeasurementBase>& meas : newMeasurements) {
1785 if (!
id.is_valid()) {
1792 if (fitterData.
hitList.empty()) {
1799 double dist = distAlongPars(fitterData.
hitList.front()->parameters(), *meas);
1800 if (dist < -maxDistCut) {
1801 ATH_MSG_VERBOSE(
" discarded phi hit, distance to first hit too large " << dist);
1807 double distBack = distAlongPars(fitterData.
hitList.back()->parameters(), *meas);
1808 if (distBack > maxDistCut) {
1809 ATH_MSG_VERBOSE(
" discarded phi hit, distance to last hit too large " << distBack);
1813 ATH_MSG_VERBOSE(
" new phi hit, distance from start pars " << dist <<
" distance to last pars " << distBack);
1815 measurementsToBeAdded.push_back(meas.get());
1816 fitterData.
garbage.push_back(std::move(meas));
1828 if (!measurementsToBeAdded.empty()) {
1841 const std::set<Identifier>& excludedChambers)
const {
1849 std::unique_ptr<Trk::Track> cleanTrack;
1850 if (excludedChambers.empty())
1851 cleanTrack =
m_cleaner->clean(track, ctx);
1853 ATH_MSG_DEBUG(
" Cleaning with exclusion list " << excludedChambers.size());
1854 cleanTrack =
m_cleaner->clean(track, excludedChambers, ctx);
1857 ATH_MSG_DEBUG(
" Cleaner returned a zero pointer, reject track ");
1872 const double p = pars.momentum().mag();
1874 ATH_MSG_DEBUG(
" momentum below threshold: momentum " << pars.momentum().mag() <<
" p " << pars.momentum().perp());
1883 if (segEntry && segEntry->
segment) {
1884 if (entry.hasSmallChamber() && entry.hasLargeChamber()) {
1885 ATH_MSG_DEBUG(
" Segment with SL overlap, cannot perform cleaning ");
1901 float tubeRadius = 14.6;
1907 if (!mdt) {
continue; }
1937 dcs.push_back(dcOnTrack);
1945 <<
" local parameters " << lpos.y() <<
" " << lpos.z() <<
" phi " << angleYZ <<
" with "
1946 << dcs.size() <<
" hits ");
1953 fitter.
fit(segment, segPars, dcs);
1955 ATH_MSG_DEBUG(
" segment after fit " << segment.
chi2() <<
" ndof " << segment.
ndof() <<
" local parameters " << segment.
line().
x0()
1956 <<
" " << segment.
line().
y0() <<
" phi " << segment.
line().
phi());
1958 bool hasDroppedHit =
false;
1959 unsigned int dropDepth = 0;
1961 bool success = finder.dropHits(segment, hasDroppedHit, dropDepth);
1967 if (dcs.size() == segment.
ndof() + 2) {
1969 }
else if (dcs.size() != segment.
ndof() + 3) {
1970 ATH_MSG_DEBUG(
" more than one hit removed, keeping old segment ");
1979 removedIdentifiers.insert(dcit.rot()->identify());
1986 if (fitterData.
startPars->momentum().mag() < 4000.)
return;
1988 std::set<Identifier> removedIdentifiers;
1992 ATH_MSG_DEBUG(
" removing hits " << removedIdentifiers.size());
1994 for (
const Identifier&
id : removedIdentifiers) {
2004 if (!oldTSOT)
return std::make_pair<std::unique_ptr<Trk::Track>, std::unique_ptr<Trk::Track>>(
nullptr,
nullptr);
2007 const Trk::Perigee* perigee = track.perigeeParameters();
2009 bool atIP = std::abs(perigee->position().dot(perigee->momentum().unit())) < 10;
2011 ATH_MSG_DEBUG(
" track extressed at perigee, cannot split it ");
2012 return std::make_pair<std::unique_ptr<Trk::Track>, std::unique_ptr<Trk::Track>>(
nullptr,
nullptr);
2017 unsigned int nperigees(0);
2020 for (; tit != tit_end; ++tit) {
2025 if (nperigees != 2) {
2026 ATH_MSG_DEBUG(
" Number of perigees is not one, cannot split it " << nperigees);
2027 return std::make_pair<std::unique_ptr<Trk::Track>, std::unique_ptr<Trk::Track>>(
nullptr,
nullptr);
2030 struct TrackContent {
2031 TrackContent() : firstParameters(
nullptr), tsos(), track() {}
2033 std::vector<const Trk::TrackStateOnSurface*> tsos;
2034 std::unique_ptr<Trk::Track> track;
2035 std::set<MuonStationIndex::StIndex> stations;
2039 TrackContent firstTrack;
2040 firstTrack.tsos.reserve(oldTSOT->
size());
2042 TrackContent secondTrack;
2043 secondTrack.tsos.reserve(oldTSOT->
size());
2046 TrackContent* currentTrack = &firstTrack;
2052 tit = oldTSOT->
begin();
2053 tit_end = oldTSOT->
end();
2054 for (; tit != tit_end; ++tit) {
2061 if (
msgLvl(MSG::DEBUG) && nperigees == 1)
msg(MSG::DEBUG) << MSG::DEBUG <<
" found first perigee on track " <<
endmsg;
2064 if (nperigees == 2) {
2065 ATH_MSG_DEBUG(
" found second perigee, switch to second track");
2066 currentTrack = &secondTrack;
2068 }
else if (nperigees > 2) {
2074 if (nperigees == 1) {
ATH_MSG_VERBOSE(
" state between the two perigees "); }
2077 if (!currentTrack->firstParameters) {
2079 currentTrack->firstParameters = pars;
2085 currentTrack->tsos.push_back(*tit);
2093 currentTrack->tsos.push_back(*tit);
2101 currentTrack->tsos.push_back(*tit);
2105 if (nperigees == 1)
ATH_MSG_WARNING(
" found muon measurement inbetween the two perigees, this should not happen ");
2112 currentTrack->tsos.push_back(*tit);
2115 if (firstTrack.firstParameters)
2116 ATH_MSG_DEBUG(
" first track content: states " << firstTrack.tsos.size() <<
" stations " << firstTrack.stations.size() <<
endmsg
2117 <<
" first pars " <<
m_printer->print(*firstTrack.firstParameters));
2119 else if (secondTrack.firstParameters)
2120 ATH_MSG_DEBUG(
" second track content: states " << secondTrack.tsos.size() <<
" stations " << secondTrack.stations.size()
2121 <<
endmsg <<
" first pars " <<
m_printer->print(*secondTrack.firstParameters));
2124 if ((firstTrack.firstParameters && firstTrack.stations.size() > 1) &&
2125 (secondTrack.firstParameters && secondTrack.stations.size() > 1)) {
2126 ATH_MSG_DEBUG(
" track candidate can be split, trying to fit split tracks ");
2128 firstTrack.track =
fitSplitTrack(ctx, *firstTrack.firstParameters, firstTrack.tsos);
2129 if (firstTrack.track) {
2132 secondTrack.track =
fitSplitTrack(ctx, *secondTrack.firstParameters, secondTrack.tsos);
2134 if (secondTrack.track) {
2139 firstTrack.track.reset();
2146 return std::make_pair<std::unique_ptr<Trk::Track>, std::unique_ptr<Trk::Track>>(std::move(firstTrack.track),
2147 std::move(secondTrack.track));
2151 const std::vector<const Trk::TrackStateOnSurface*>& tsos)
const {
2158 std::unique_ptr<Trk::Perigee> perigee = std::make_unique<Trk::Perigee>(0, 0,
phi,
theta, qoverp, persurf);
2160 auto trackStateOnSurfaces = std::make_unique<Trk::TrackStates>();
2161 trackStateOnSurfaces->reserve(tsos.size() + 1);
2166 std::unique_ptr<Trk::Track> track = std::make_unique<Trk::Track>(
trackInfo, std::move(trackStateOnSurfaces),
nullptr);
2171 ATH_MSG_DEBUG(
"Track has sufficient phi constraints, fitting ");
2179 std::vector<const Trk::TrackStateOnSurface*>::const_iterator tit = tsos.begin();
2180 std::vector<const Trk::TrackStateOnSurface*>::const_iterator tit_end = tsos.end();
2181 for (; tit != tit_end; ++tit) {
2183 if (!(*tit)->trackParameters())
continue;
2186 if (!meas)
continue;
2192 if (!firstMeas) firstMeas = *tit;
2200 ATH_MSG_WARNING(
" failed to find first MDT measurement with track parameters");
2205 ATH_MSG_WARNING(
" failed to find second MDT measurement with track parameters");
2209 if (firstMeas == lastMeas) {
2210 ATH_MSG_WARNING(
" first MDT measurement with track parameters equals to second");
2220 ATH_MSG_DEBUG(
"Track has one phi constraints, adding second: dist to first " << distFirst <<
" dist to second "
2223 if (distFirst < distSecond) {
2224 positionFirstFake = lastMeas;
2226 positionFirstFake = firstMeas;
2230 ATH_MSG_DEBUG(
"Track has no phi constraints, adding one at beginning and one at the end of the track ");
2232 positionFirstFake = firstMeas;
2233 positionSecondFake = lastMeas;
2237 auto uniquePerigee = std::make_unique<Trk::Perigee>(0, 0,
phi,
theta, qoverp, persurf);
2238 auto trackStateOnSurfaces = std::make_unique<Trk::TrackStates>();
2239 trackStateOnSurfaces->reserve(tsos.size() + 3);
2243 tit_end = tsos.end();
2244 for (; tit != tit_end; ++tit) {
2252 trackStateOnSurfaces->push_back((*tit)->clone());
2253 if (*tit == positionFirstFake) {
2254 double fakeError = 100.;
2261 std::unique_ptr<Trk::MeasurementBase> fake =
2271 if (*tit == positionSecondFake && positionSecondFake) {
2272 double fakeError = 100.;
2279 std::unique_ptr<Trk::MeasurementBase> fake =
2292 track = std::make_unique<Trk::Track>(
trackInfo, std::move(trackStateOnSurfaces),
nullptr);
2296 std::unique_ptr<Trk::Track> refittedTrack =
refit(ctx, *track);
2297 if (refittedTrack) refittedTrack->info().setPatternRecognitionInfo(
m_patRecInfo);
2299 return refittedTrack;
Scalar phi() const
phi method
Scalar theta() const
theta method
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_VERBOSE(x)
#define ATH_MSG_WARNING(x)
bool msgLvl(const MSG::Level lvl) const
DataModel_detail::const_iterator< DataVector > const_iterator
Standard const_iterator.
const_iterator end() const noexcept
Return a const_iterator pointing past the end of the collection.
const_iterator begin() const noexcept
Return a const_iterator pointing at the beginning of the collection.
size_type size() const noexcept
Returns the number of elements in the collection.
bool is_valid() const
Check if id is in a valid state.
bool fit(const LArSamples::AbsShape &data, const AbsShape &reference, double &k, double &deltaT, double &chi2, const ScaledErrorData *sed=0) const
double stripLength(int chamberLayer, int measuresPhi, int stripNumber, double &epsilon) const
An MMReadoutElement corresponds to a single STGC module; therefore typicaly a barrel muon station con...
double stripActiveLengthRight(const Identifier &id) const
double stripActiveLengthLeft(const Identifier &id) const
double getActiveTubeLength(const int tubeLayer, const int tube) const
double innerTubeRadius() const
Returns the inner tube radius excluding the aluminium walls.
virtual Amg::Transform3D GlobalToAmdbLRSTransform() const
std::string getStationType() const
An RpcReadoutElement corresponds to a single RPC module; therefore typicaly a barrel muon station con...
double StripLength(bool measphi) const
returns the strip length for the phi or eta plane
A TgcReadoutElement corresponds to a single TGC chamber; therefore typically a TGC station contains s...
double gangCentralWidth(int gasGap, int gang) const
Returns the length of the central wire in the gang.
An sTgcReadoutElement corresponds to a single STGC module; therefore typicaly a barrel muon station c...
const MuonChannelDesign * getDesign(const Identifier &id) const
returns the MuonChannelDesign class for the given identifier
Class for competing MuonClusters, it extends the Trk::CompetingRIOsOnTrack base class.
const std::vector< const MuonClusterOnTrack * > & containedROTs() const
returns the vector of SCT_ClusterOnTrack objects .
const MuonClusterOnTrack & rioOnTrack(unsigned int) const
returns the RIO_OnTrack (also known as ROT) objects depending on the integer
This class represents the corrected MDT measurements, where the corrections include the effects of wi...
virtual const MdtPrepData * prepRawData() const override final
Returns the PrepRawData used to create this corrected measurement.
virtual const MuonGM::MdtReadoutElement * detectorElement() const override
Returns the detector element corresponding to this PRD.
virtual const Amg::Vector3D & globalPosition() const
Returns the global position of the CENTER of the drift tube (i.e.
std::atomic_uint m_nfailedTubeFit
double phiSeeding(const EventContext &ctx, FitterData &fitterData) const
calculate phi used to for seeding the fit
static double qOverPFromEntry(const MuPatCandidateBase &entry)
get q/p from entry
std::pair< int, int > SmallLargeChambers
Gaudi::Property< double > m_chi2Cut
bool validMomentum(const Trk::TrackParameters &pars) const
check whether mometum of start parameter is ok
ServiceHandle< Muon::IMuonIdHelperSvc > m_idHelperSvc
Gaudi::Property< unsigned int > m_phiHitsMax
std::shared_ptr< const MuonSegment > segmentFromEntry(const EventContext &ctx, const MuPatCandidateBase &entry) const
get segment from entry
bool cleanPhiHits(const EventContext &ctx, double momentum, FitterData &phiHits, const PrepVec &patternPhiHits) const
clean phi hits, returns true if anything happened during the cleaning
Gaudi::Property< Trk::RunOutlierRemoval > m_runOutlier
std::atomic_uint m_nsuccess
std::atomic_uint m_nfailedFakePrecise
ToolHandle< Trk::ITrackFitter > m_trackFitter
fitter
Gaudi::Property< bool > m_cleanPhiHits
ToolHandle< IMuonSegmentMomentumEstimator > m_momentumEstimator
tool to estimate track momentum
bool corruptEntry(const MuPatCandidateBase &entry) const
sanity check for entries
Gaudi::Property< bool > m_seedWithSegmentTheta
ToolHandle< IMuonHitSelector > m_phiHitSelector
tool to clean phi hits
Trk::MagneticFieldProperties m_magFieldProperties
magnetic field properties
double qOverPFromEntries(const EventContext &ctx, const MuPatCandidateBase &firstEntry, const MuPatCandidateBase &secondEntry) const
get q/p using angle + position of the two entries
Gaudi::Property< bool > m_seedPhiWithEtaHits
std::pair< std::unique_ptr< Trk::Track >, std::unique_ptr< Trk::Track > > splitTrack(const EventContext &ctx, const Trk::Track &track) const
split given track if it crosses the calorimeter volume, code assumes that the track was already extra...
ToolHandle< IMuonSegmentInOverlapResolvingTool > m_overlapResolver
Gaudi::Property< bool > m_allowFirstFit
void createStartParameters(const EventContext &ctx, FitterData &inputData) const
create a perigee parameter give the input data
StatusCode finalize()
finialize method, method taken from bass-class AlgTool
std::atomic_uint m_nfailedFakeInitial
std::unique_ptr< Trk::Track > fitWithRefit(const EventContext &ctx, const Trk::Perigee &startPars, MeasVec &hits) const
fit track, refit if needed
std::unique_ptr< Trk::MeasurementBase > createFakePhiForMeasurement(const Trk::MeasurementBase &measurement, const Amg::Vector3D *overlapPos, const Amg::Vector3D *phiPos, double error) const
create fake phi hit on the surface of the give measurement
Trk::ParticleHypothesis m_ParticleHypothesis
nomen est omen
Trk::TrackInfo::TrackPatternRecoInfo m_patRecInfo
Gaudi::Property< int > m_matEffects
std::unique_ptr< Trk::Track > fitSplitTrack(const EventContext &ctx, const Trk::TrackParameters &startPars, const std::vector< const Trk::TrackStateOnSurface * > &tsos) const
construct a track from a list of TSOS and a start parameters
Gaudi::Property< bool > m_usePreciseHits
Gaudi::Property< bool > m_seedWithAvePhi
double thetaSeeding(const MuPatCandidateBase &entry, MeasVec &etaHits) const
calculate theta used for seeding the fit
std::unique_ptr< Trk::Track > fit(const EventContext &ctx, const MuPatCandidateBase &firstEntry, const MuPatCandidateBase &secondEntry, const PrepVec &externalPhiHits) const
fit the hits of two MuPatCandidateBase
std::unique_ptr< Trk::Perigee > createPerigee(const EventContext &ctx, const Trk::TrackParameters &firstPars, const Trk::MeasurementBase &firstMeas) const
create perigee parameter to initialize fit
bool getMinMaxPhi(FitterData &fitterData) const
calculate the minimum and maximum phi value a track could have to pass all eta channels
std::atomic_uint m_nfailedExtractCleaning
Gaudi::Property< bool > m_slFit
Gaudi::Property< bool > m_cosmics
std::atomic_uint m_nlowMomentum
std::vector< const Trk::MeasurementBase * > MeasVec
Gaudi::Property< double > m_pThreshold
ToolHandle< IMuonTrackToSegmentTool > m_trackToSegmentTool
helper tool to convert tracks into segments
std::atomic_uint m_nfailedParsInital
ServiceHandle< IMuonEDMHelperSvc > m_edmHelperSvc
multi purpose helper tool
std::pair< double, double > getElementHalfLengths(const Identifier &id, const Trk::TrkDetElementBase *ele) const
void cleanSegment(const MuonSegment &seg, std::set< Identifier > &removedIdentifiers) const
std::atomic_uint m_nfailedExtractPrecise
Gaudi::Property< bool > m_seedAtStartOfTrack
Gaudi::Property< bool > m_slProp
static double restrictedMomentum(double momentum)
impose upper and lower bound on momentum
MeasVec::const_iterator MeasCit
Gaudi::Property< bool > m_usePrefit
std::atomic_uint m_nfailedExtractInital
PublicToolHandle< MuPatHitTool > m_hitHandler
hit handler
Gaudi::Property< double > m_openingAngleCut
ToolHandle< IMuonTrackCleaner > m_cleaner
bool addFakePhiHits(const EventContext &ctx, FitterData &fitterData, const Trk::TrackParameters &referenceParameter) const
check fitterData, add fake phi hits if needed.
unsigned int hasPhiConstrain(FitterData &inputData) const
check whether data has sufficient phi constraints
Gaudi::Property< bool > m_preciseFirstStation
void cleanEntry(const MuPatCandidateBase &entry, std::set< Identifier > &removedIdentifiers) const
Gaudi::Property< double > m_preCleanChi2Cut
bool extractData(const MuPatCandidateBase &entry1, const MuPatCandidateBase &entry2, FitterData &fitterData) const
extract all information needed for the fit from the track
StatusCode initialize()
initialize method, method taken from bass-class AlgTool
std::atomic_uint m_nfailedMinMaxPhi
std::unique_ptr< Trk::Track > refit(const EventContext &ctx, const MuPatTrack &trkCan) const
refit a MuPatTrack
std::atomic_uint m_nfailedFitPrecise
std::atomic_uint m_noPerigee
std::vector< const Trk::PrepRawData * > PrepVec
void removeSegmentOutliers(FitterData &fitterData) const
MooTrackFitter(const std::string &, const std::string &, const IInterface *)
default AlgTool constructor
std::unique_ptr< Trk::Track > cleanAndEvaluateTrack(const EventContext &ctx, Trk::Track &track, const std::set< Identifier > &excludedChambers) const
clean and evaluate the track,
PublicToolHandle< MuonEDMPrinterTool > m_printer
tool to print out EDM objects
ToolHandle< Trk::IPropagator > m_propagator
propagator
ToolHandle< Trk::ITrackSummaryHelperTool > m_trackSummaryTool
track candidate entry object.
virtual const Trk::TrackParameters & entryPars() const =0
return track parameters representing the entry
const MeasVec & etaHits() const
return all eta hits on the entry
const MuPatHitList & hitList() const
returns a reference to the hit list
bool containsStation(MuonStationIndex::StIndex chIndex) const
returns whether the StationIndex is already contained in candidate
const MeasVec & hits() const
return all hits on the entry.
bool containsChamber(MuonStationIndex::ChIndex chIndex) const
returns whether the ChamberIndex is already contained in candidate
const std::set< Identifier > & chamberIds() const
returns set with contained chamber ids
const std::set< MuonStationIndex::StIndex > & stations() const
returns set with contained stationIndices
bool hasEndcap() const
returns whether the entry contains endcap hits
bool hasMomentum() const
returns whether entry has a momentum measurement
bool hasSLOverlap() const
returns whether there is at least one small/large overlap in the same station layer
const MeasVec & phiHits() const
return all phi hits on the entry
segment candidate object.
const MuonSegment * segment
Trk::Track & track() const
access to track
Base class for Muon cluster RIO_OnTracks.
This is the common class for 3D segments used in the muon spectrometer.
const Trk::LocalDirection & localDirection() const
local direction
const Amg::Vector3D & globalDirection() const
global direction
virtual const Amg::Vector3D & globalPosition() const override final
global position
virtual const Trk::PlaneSurface & associatedSurface() const override final
returns the surface for the local to global transformation
static std::unique_ptr< Trk::TrackStateOnSurface > createPerigeeTSOS(std::unique_ptr< Trk::TrackParameters > perigee)
create a perigee TSOS, takes ownership of the Perigee
static std::unique_ptr< Trk::TrackStateOnSurface > createMeasTSOSWithUpdate(const Trk::TrackStateOnSurface &tsos, std::unique_ptr< Trk::MeasurementBase > meas, std::unique_ptr< Trk::TrackParameters > pars, Trk::TrackStateOnSurface::TrackStateOnSurfaceType type)
create a TSOS with a measurement, takes ownership of the pointers
class representing a drift circle meaurement on segment
This class represents a drift time measurement.
@ InTime
drift time too small to be compatible with drift spectrum
Implementation of 2 dimensional vector class.
const DCOnTrackVec & match(const DCVec &dcs)
void hitsOnTrack(unsigned int hitsOnTrack)
const Line & line() const
const DCOnTrackVec & dcs() const
unsigned int ndof() const
double angleYZ() const
access method for angle of local YZ projection
bool contains(ParamDefs par) const
The simple check for the clients whether the parameter is contained.
This class is the pure abstract base class for all fittable tracking measurements.
const LocalParameters & localParameters() const
Interface method to get the LocalParameters.
virtual const Surface & associatedSurface() const =0
Interface method to get the associated Surface.
virtual const Amg::Vector3D & globalPosition() const =0
Interface method to get the global Position.
const Amg::MatrixX & localCovariance() const
Interface method to get the localError.
Detailed track summary for the muon system Give access to hit counts per chamber.
const std::vector< ChamberHitSummary > & chamberHitSummary() const
access to the vector of chamber hit summaries on the track
const Amg::Vector3D & momentum() const
Access method for the momentum.
const Amg::Vector3D & position() const
Access method for the position.
double charge() const
Returns the charge.
std::unique_ptr< ParametersBase< DIM, T > > uniqueClone() const
clone method for polymorphic deep copy returning unique_ptr; it is not overriden, but uses the existi...
virtual ParametersT< DIM, T, S > * clone() const override final
Virtual clone.
Class describing the Line to which the Perigee refers to.
Class to handle pseudo-measurements in fitters and on track objects.
Class to handle RIO On Tracks ROT) for InDet and Muons, it inherits from the common MeasurementBase.
virtual const TrkDetElementBase * detectorElement() const =0
returns the detector element, assoicated with the PRD of this class
Identifier identify() const
return the identifier -extends MeasurementBase
std::unique_ptr< RIO_OnTrack > uniqueClone() const
NVI clone returning unique_ptr.
virtual const Amg::Vector3D & globalPosition() const override=0
Interface method to get the global Position.
const std::vector< const Trk::MeasurementBase * > & containedMeasurements() const
returns the vector of Trk::MeasurementBase objects
Abstract Base Class for tracking surfaces.
virtual bool globalToLocal(const Amg::Vector3D &glob, const Amg::Vector3D &mom, Amg::Vector2D &loc) const =0
Specified by each surface type: GlobalToLocal method without dynamic memory allocation - boolean chec...
virtual const Amg::Vector3D & normal() const
Returns the normal vector of the Surface (i.e.
const Amg::Transform3D & transform() const
Returns HepGeom::Transform3D by reference.
const Amg::Vector3D & center() const
Returns the center position of the Surface.
virtual void localToGlobal(const Amg::Vector2D &locp, const Amg::Vector3D &mom, Amg::Vector3D &glob) const =0
Specified by each surface type: LocalToGlobal method without dynamic memory allocation.
Intersection straightLineIntersection(const T &pars, bool forceDir=false, const Trk::BoundaryCheck &bchk=false) const
fst straight line intersection schema - templated for charged and neutral parameters
Contains information about the 'fitter' of this track.
@ Unknown
Track fitter not defined.
represents the track state (measurement, material, fit parameters and quality) at a surface.
const MeasurementBase * measurementOnTrack() const
returns MeasurementBase const overload
const TrackParameters * trackParameters() const
return ptr to trackparameters const overload
@ Measurement
This is a measurement, and will at least contain a Trk::MeasurementBase.
@ Perigee
This represents a perigee, and so will contain a Perigee object only.
A summary of the information contained by a track.
const MuonTrackSummary * muonTrackSummary() const
returns a pointer to the MuonTrackSummary if available
const DataVector< const TrackParameters > * trackParameters() const
Return a pointer to a vector of TrackParameters.
const Perigee * perigeeParameters() const
return Perigee.
This is the base class for all tracking detector elements with read-out relevant information.
virtual const Amg::Vector3D & center() const =0
Return the center of the element.
virtual const Surface & surface() const =0
Return surface associated with this detector element.
std::string toString(const Translation3D &translation, int precision=4)
GeoPrimitvesToStringConverter.
Eigen::Matrix< double, Eigen::Dynamic, Eigen::Dynamic > MatrixX
Dynamic Matrix - dynamic allocation.
double error(const Amg::MatrixX &mat, int index)
return diagonal error of the matrix caller should ensure the matrix is symmetric and the index is in ...
Eigen::Affine3d Transform3D
Eigen::Matrix< double, 2, 1 > Vector2D
Eigen::Matrix< double, 3, 1 > Vector3D
void setThetaPhi(Amg::Vector3D &v, double theta, double phi)
sets the theta and phi angle of a vector without changing the magnitude
Eigen::Matrix< double, Eigen::Dynamic, 1 > VectorX
Dynamic Vector - dynamic allocation.
StIndex
enum to classify the different station layers in the muon spectrometer
ChIndex chIndex(const std::string &index)
convert ChIndex name string to enum
StIndex toStationIndex(ChIndex index)
convert ChIndex into StIndex
bool isSmall(const ChIndex index)
Returns true if the chamber index is in a small sector.
ChIndex
enum to classify the different chamber layers in the muon spectrometer
NRpcCablingAlg reads raw condition data and writes derived condition data to the condition store.
std::vector< MuPatHitPtr > MuPatHitList
std::shared_ptr< MuPatHit > MuPatHitPtr
MuPatHitList::const_iterator MuPatHitCit
std::vector< DCOnTrack > DCOnTrackVec
constexpr ParticleHypothesis particle[PARTICLEHYPOTHESES]
the array of masses
DataVector< const Trk::TrackStateOnSurface > TrackStates
ParametersT< TrackParametersDim, Charged, PerigeeSurface > Perigee
@ NoField
Field is set to 0., 0., 0.,.
@ FullField
Field is set to be realistic, but within a given Volume.
@ loc2
generic first and second local coordinate
std::pair< double, ParamDefs > DefinedParameter
Typedef to of a std::pair<double, ParamDefs> to identify a passed-through double as a specific type o...
ParticleHypothesis
Enumeration for Particle hypothesis respecting the interaction with material.
ParametersBase< TrackParametersDim, Charged > TrackParameters
ParametersT< TrackParametersDim, Charged, PlaneSurface > AtaPlane
void swap(ElementLinkVector< DOBJ > &lhs, ElementLinkVector< DOBJ > &rhs)
double channelLength(int channel) const
STRIPS ONLY: calculate channel length for a given strip number.
std::set< MuonStationIndex::StIndex > stations
SLStationMap smallLargeChambersPerStation
const MuPatCandidateBase * firstEntry
int numberOfLargeChambers()
std::unique_ptr< Trk::Perigee > startPars
MeasVec firstLastMeasurements
const MuPatCandidateBase * secondEntry
std::vector< std::unique_ptr< const Trk::MeasurementBase > > garbage
int numberOfSmallChambers()
unsigned int nLargeChambers
unsigned int nSmallChambers