42 declareInterface<IMuonRefitTool>(
this);
134 return StatusCode::SUCCESS;
144 <<
"Failed Refit " << scaleRefit *
m_failedRefit << std::endl
146 return StatusCode::SUCCESS;
153 std::unique_ptr<Trk::Track> newTrack;
160 return std::make_unique<Trk::Track>(
track);
165 newTrack.swap(cleanedTrack);
167 newTrack = std::make_unique<Trk::Track>(
track);
171 std::unique_ptr<Trk::Track> updateErrorTrack =
173 if (!updateErrorTrack) {
178 newTrack.swap(updateErrorTrack);
181 if (settings.
refit) {
186 std::unique_ptr<Trk::Track> refittedTrack;
187 if (
track.fitQuality() &&
track.fitQuality()->chiSquared() < 10000 *
track.fitQuality()->numberDoF())
189 if (!refittedTrack) {
193 return std::make_unique<Trk::Track>(
track);
197 newTrack.swap(refittedTrack);
202 if (!extrapolatedTrack) {
208 newTrack.swap(extrapolatedTrack);
214 std::vector<std::unique_ptr<Trk::Track>>
MuonRefitTool::refit(
const std::vector<Trk::Track*>& tracks,
const EventContext& ctx,
216 std::vector<std::unique_ptr<Trk::Track>> refittedTracks;
217 refittedTracks.reserve(tracks.size());
220 return refittedTracks;
231 return updatedAEOTsTrack;
242 std::map<std::vector<Identifier>, std::pair<double, double>> alignerrmap;
244 std::vector<Trk::AlignmentDeviation*> align_deviations;
248 bool isSmallChamber =
false;
249 bool isLargeChamber =
false;
250 bool isEndcap =
false;
252 std::vector<int> usedRotations;
256 double angleError = 0.;
257 double translationError = 0.;
258 bool differentChambers =
false;
260 isSmallChamber =
false;
261 isLargeChamber =
false;
266 translationError = std::sqrt(
it->getCovariance(0, 0));
268 std::vector<Identifier> hitids;
269 const auto& vec_riowithdev =
it->getListOfHits();
272 const Identifier id_riowithdev = riowithdev->identify();
279 isSmallChamber =
true;
281 isLargeChamber =
true;
283 hitids.push_back(id_riowithdev);
285 differentChambers =
true;
286 jdifferent = hitids.size() - 1;
289 bool matchFound =
false;
290 if (!hitids.empty()) {
295 if (itRot->hasValidHashOfHits() &&
it->hasValidHashOfHits()) {
296 if (itRot->getHashOfHits() ==
it->getHashOfHits()) {
297 angleError = std::sqrt(itRot->getCovariance(0, 0));
299 usedRotations.push_back(iRot);
302 ATH_MSG_ERROR(
"One of the alignment deviations has an invalid hash created from the hits.");
305 if (matchFound)
break;
312 alignerrmap.insert(std::pair<std::vector<Identifier>, std::pair<double, double>>(
313 hitids, std::pair<double, double>(translationError, angleError)));
316 ATH_MSG_DEBUG(
" AlignmentMap entry " << iok <<
" filled with nr hitids " << hitids.size() <<
" "
317 <<
m_idHelperSvc->toString(hitids[0]) <<
" translationError " << translationError
318 <<
" angleError " << angleError);
320 ATH_MSG_DEBUG(
" AlignmentMap entry No angleError" << iok <<
" filled with nr hitids " << hitids.size() <<
" "
321 <<
m_idHelperSvc->toString(hitids[0]) <<
" translationError "
322 << translationError <<
" angleError " << angleError);
323 if (isEndcap)
ATH_MSG_DEBUG(
" AlignmentMap Endcap Chamber ");
325 if (isSmallChamber)
ATH_MSG_DEBUG(
" AlignmentMap Small Chamber ");
326 if (isLargeChamber)
ATH_MSG_DEBUG(
" AlignmentMap Large Chamber ");
327 if (differentChambers)
328 ATH_MSG_DEBUG(
" AlignmentMap entry " << iok <<
" for different Chamber "
338 isSmallChamber =
false;
339 isLargeChamber =
false;
343 bool used =
std::find(usedRotations.begin(), usedRotations.end(), iRot) != usedRotations.end();
345 ATH_MSG_ERROR(
"This following code should not be reached anymore!");
346 const auto& vec_riowithdev = itRot->getListOfHits();
348 std::vector<Identifier> hitids;
351 Identifier id_riowithdev = riowithdev->identify();
358 isSmallChamber =
true;
360 isLargeChamber =
true;
362 hitids.push_back(id_riowithdev);
365 double translationError = 0.;
366 double angleError = std::sqrt(itRot->getCovariance(0, 0));
369 alignerrmap.insert(std::pair<std::vector<Identifier>, std::pair<double, double>>(
370 hitids, std::pair<double, double>(translationError, angleError)));
371 ATH_MSG_DEBUG(
" AlignmentMap entry No Translation Error " << iok <<
" filled with nr hitids " << hitids.size() <<
" "
372 <<
m_idHelperSvc->toString(hitids[0]) <<
" translationError "
373 << translationError <<
" angleError " << angleError);
376 if (isSmallChamber)
ATH_MSG_DEBUG(
" AlignmentMap Small Chamber ");
377 if (isLargeChamber)
ATH_MSG_DEBUG(
" AlignmentMap Large Chamber ");
382 for (
auto*
it : align_deviations)
delete it;
383 align_deviations.clear();
391 std::bitset<Trk::TrackStateOnSurface::NumberOfTrackStateOnSurfaceTypes> typePattern(0);
394 std::vector<int> indexAEOTs;
395 std::vector<std::unique_ptr<Trk::TrackStateOnSurface>> tsosAEOTs;
399 std::set<MuonStationIndex::ChIndex> stationIds;
401 for (
const auto& itAli : alignerrmap) {
402 unsigned int imiddle = (itAli.first.size()) / 2;
409 if (!meas) {
continue; }
411 if (!
id.is_valid())
continue;
417 if (idMiddle ==
id) {
419 const double deltaError =
std::max(itAli.second.first, 0.01);
420 const double angleError =
std::max(itAli.second.second, 0.000001);
421 auto aEOT = std::make_unique<Trk::AlignmentEffectsOnTrack>(
427 tsit->measurementOnTrack()->associatedSurface());
428 std::unique_ptr<Trk::TrackStateOnSurface> tsosAEOT =
429 std::make_unique<Trk::TrackStateOnSurface>(
431 tsit->trackParameters()->uniqueClone(),
435 indexAEOTs.push_back(
index);
436 tsosAEOTs.emplace_back(std::move(tsosAEOT));
441 if (!
found)
ATH_MSG_WARNING(
" This should not happen Identifier from AlignmentErrorTool is not found");
447 auto trackStateOnSurfaces = std::make_unique<Trk::TrackStates>();
448 trackStateOnSurfaces->reserve(
states->size() + indexAEOTs.size());
452 for (
unsigned int i = 0;
i < indexAEOTs.size();
i++) {
453 if (
index == indexAEOTs[
i]) {
455 trackStateOnSurfaces->push_back(std::move(tsosAEOTs[
i]));
457 ATH_MSG_WARNING(
"There's a trial to push back the same AEOT twice to the track...");
463 if (tsit->alignmentEffectsOnTrack()) {
467 trackStateOnSurfaces->push_back(tsit->clone());
470 if (indexAEOTs.empty() && stationIds.size() > 1)
ATH_MSG_WARNING(
" Track without AEOT ");
472 std::unique_ptr<Trk::Track> newTrack = std::make_unique<Trk::Track>(
track.info(), std::move(trackStateOnSurfaces),
473 track.fitQuality() ?
track.fitQuality()->uniqueClone() :
nullptr);
493 auto trackStateOnSurfaces = std::make_unique<Trk::TrackStates>();
494 trackStateOnSurfaces->reserve(
states->size() + 1);
498 std::vector<const Trk::TrackStateOnSurface*> indicesOfAffectedTSOS;
499 std::vector<const Trk::TrackStateOnSurface*> indicesOfAffectedTSOSInner;
500 std::vector<Identifier> indicesOfAffectedIds;
501 std::vector<Identifier> indicesOfAffectedIdsInner;
502 int index {-1}, indexFirst {-1}, indexFirstInner {-1};
512 if (!meas) {
continue; }
516 if (tsit->alignmentEffectsOnTrack()) {
517 ATH_MSG_WARNING(
" AlignmentEffectOnTrack is already on track skip it");
531 if (indexFirst == -1) indexFirst =
index;
532 indicesOfAffectedTSOS.push_back(tsit);
533 indicesOfAffectedIds.push_back(
id);
538 if (indexFirst == -1) indexFirst =
index;
539 indicesOfAffectedTSOS.push_back(tsit);
540 indicesOfAffectedIds.push_back(
id);
543 if (indexFirstInner == -1) indexFirstInner =
index;
544 indicesOfAffectedTSOSInner.push_back(tsit);
545 indicesOfAffectedIdsInner.push_back(
id);
549 if (indexFirstInner == -1) indexFirstInner =
index;
550 indicesOfAffectedTSOSInner.push_back(tsit);
551 indicesOfAffectedIdsInner.push_back(
id);
556 if (indicesOfAffectedTSOS.empty() && indicesOfAffectedTSOSInner.empty()) {
557 std::unique_ptr<Trk::Track> newTrack = std::make_unique<Trk::Track>(
track.info(), std::move(trackStateOnSurfaces),
558 track.fitQuality() ?
track.fitQuality()->uniqueClone() :
nullptr);
562 std::bitset<Trk::TrackStateOnSurface::NumberOfTrackStateOnSurfaceTypes> typePattern(0);
565 std::unique_ptr<Trk::TrackStateOnSurface> tsosAEOT;
567 int middle = indicesOfAffectedTSOS.size() / 2;
569 auto aEOT = std::make_unique<Trk::AlignmentEffectsOnTrack>(
574 indicesOfAffectedIds,
577 << aEOT->associatedSurface()
578 <<
" nr of tsos affected "
579 << indicesOfAffectedTSOS.size());
580 tsosAEOT = std::make_unique<Trk::TrackStateOnSurface>(
588 std::unique_ptr<Trk::TrackStateOnSurface> tsosAEOTInner;
590 int middle = indicesOfAffectedTSOSInner.size() / 2;
592 auto aEOTInner = std::make_unique<Trk::AlignmentEffectsOnTrack>(
597 indicesOfAffectedIdsInner,
599 tsosAEOTInner = std::make_unique<Trk::TrackStateOnSurface>(
604 std::move(aEOTInner));
607 auto trackStateOnSurfacesAEOT = std::make_unique<Trk::TrackStates>();
608 trackStateOnSurfacesAEOT->reserve(
states->size() + 2);
612 if (
index == indexFirst && tsosAEOT) {
613 trackStateOnSurfacesAEOT->push_back(std::move(tsosAEOT));
614 if (!
m_addAll)
ATH_MSG_DEBUG(
" AlignmentEffectsOnTrack for Middle added to trackStateOnSurfacesAEOT ");
615 if (
m_addAll)
ATH_MSG_DEBUG(
" AlignmentEffectsOnTrack for All stations added to trackStateOnSurfacesAEOT ");
617 if (
index == indexFirstInner && tsosAEOTInner) {
618 trackStateOnSurfacesAEOT->push_back(std::move(tsosAEOTInner));
619 ATH_MSG_DEBUG(
" AlignmentEffectsOnTrack for Inner added to trackStateOnSurfacesAEOT ");
620 if (
m_addTwo)
ATH_MSG_DEBUG(
" also AlignmentEffectsOnTrack for Middle added to trackStateOnSurfacesAEOT ");
622 trackStateOnSurfacesAEOT->push_back(tsit);
624 std::unique_ptr<Trk::Track> newTrack = std::make_unique<Trk::Track>(
track.info(), std::move(trackStateOnSurfacesAEOT),
625 track.fitQuality() ?
track.fitQuality()->uniqueClone() :
nullptr);
643 std::vector<std::unique_ptr<Trk::TrackStateOnSurface>> newStates;
644 newStates.reserve(
states->size() + 5);
647 std::map<int, std::set<MuonStationIndex::StIndex>> stationsPerSector;
669 if (!meas) {
continue; }
680 stationsPerSector[sector].insert(stIndex);
684 if (!
track.trackParameters() ||
track.trackParameters()->empty()) {
688 startPars =
track.trackParameters()->front();
693 std::vector<int> sectorsWithMostStations;
694 unsigned int nmaxStations = 0;
695 std::map<int, std::set<MuonStationIndex::StIndex>>
::iterator stit = stationsPerSector.begin();
696 std::map<int, std::set<MuonStationIndex::StIndex>>
::iterator stit_end = stationsPerSector.end();
697 for (; stit != stit_end; ++stit) {
704 if (stit->second.size() > nmaxStations) {
705 nmaxStations = stit->second.size();
706 sectorsWithMostStations.clear();
707 sectorsWithMostStations.push_back(stit->first);
708 }
else if (stit->second.size() == nmaxStations) {
709 sectorsWithMostStations.push_back(stit->first);
712 int selectedSector = -1;
713 if (sectorsWithMostStations.empty()) {
715 }
else if (sectorsWithMostStations.size() == 1) {
716 selectedSector = sectorsWithMostStations.front();
718 ATH_MSG_DEBUG(
"Found track with special sector configuration " << sectorsWithMostStations.size() <<
" ch per sector "
719 << nmaxStations <<
" using first sector");
720 selectedSector = sectorsWithMostStations.front();
721 if (selectedSector % 2 == 1 && sectorsWithMostStations.back() % 2 != 1) {
722 ATH_MSG_DEBUG(
"Revising sector choice, picking small sector ");
723 selectedSector = sectorsWithMostStations.back();
731 const std::set<MuonStationIndex::StIndex>& selected_set = stationsPerSector[selectedSector];
733 return (selected_set.count(idx) > 0) + n;
736 return (selected_set.count(idx) > 0) + n;
738 bool barrelEndcap {
false}, deweightBarrel{
false}, deweightEndcap{
false};
739 if (nbarrel > 0 && nendcap > 0) {
740 if (nbarrel < nendcap)
741 deweightBarrel =
true;
743 deweightEndcap =
true;
747 ATH_MSG_DEBUG(
" Selected sector " << selectedSector <<
" nstations " << nmaxStations <<
" barrel " << nbarrel <<
" endcap "
756 unsigned int deweightHits = 0;
757 unsigned int removedSectorHits = 0;
758 bool addedPerigee =
false;
767 newStates.emplace_back(tsos->clone());
777 if (
pars == startPars) {
791 newStates.emplace_back(tsos->clone());
797 double sign =
pars->position().dot(
pars->momentum()) > 0 ? 1. : -1.;
801 double phi =
pars->momentum().phi();
803 double qoverp =
pars->charge() /
pars->momentum().mag();
805 std::unique_ptr<Trk::Perigee> perigee = std::make_unique<Trk::Perigee>(0, 0,
phi,
theta, qoverp, persurf);
808 ATH_MSG_DEBUG(
"Adding perigee in front of first measurement");
815 newStates.emplace_back(tsos->clone());
820 newStates.emplace_back(tsos->clone());
827 ATH_MSG_WARNING(
" Measurement with MDT identifier that is not a MdtDriftCircleOnTrack ");
831 bool hasT0Fit =
false;
834 std::unique_ptr<MdtDriftCircleOnTrack> rot{};
850 }
else if (deweightBarrel &&
851 std::find(barel_stations.begin(),barel_stations.end(),stIndex) != barel_stations.end()) {
855 }
else if (deweightEndcap &&
856 std::find(endcap_stations.begin(), endcap_stations.end(), stIndex) != endcap_stations.end()) {
898 rot.reset(mdt->
clone());
902 if (sector != selectedSector) {
913 <<
" radius " << rot->driftRadius() <<
" new err "
921 if (std::abs(rot->driftRadius() - mdt->
driftRadius()) > 0.1)
926 newStates.emplace_back(std::move(new_tsos));
930 newStates.emplace_back(std::move(new_tsos));
933 newStates.emplace_back(tsos->clone());
941 newStates.emplace_back(std::move(new_tsos));
944 newStates.emplace_back(tsos->clone());
949 newStates.emplace_back(tsos->clone());
952 newStates.emplace_back(tsos->clone());
956 newStates.emplace_back(tsos->clone());
964 if (deweightHits > 0)
ATH_MSG_DEBUG(
" de-weighted " << deweightHits <<
" MDT hits from neighbouring sectors");
965 if (removedSectorHits > 0)
ATH_MSG_DEBUG(
" removed " << removedSectorHits <<
" MDT hits from neighbouring sectors");
967 ATH_MSG_VERBOSE(
" original track had " <<
states->size() <<
" TSOS, adding " << newStates.size() -
states->size() <<
" new TSOS ");
970 auto trackStateOnSurfaces = std::make_unique<Trk::TrackStates>();
971 trackStateOnSurfaces->reserve(newStates.size());
972 for (std::unique_ptr<Trk::TrackStateOnSurface>& new_state : newStates) {
973 trackStateOnSurfaces->push_back(std::move(new_state));
975 std::unique_ptr<Trk::Track> newTrack = std::make_unique<Trk::Track>(
track.info(), std::move(trackStateOnSurfaces),
976 track.fitQuality() ?
track.fitQuality()->uniqueClone() :
nullptr);
995 std::vector<std::unique_ptr<Trk::TrackStateOnSurface>> newStates;
996 newStates.reserve(
states->size() + 5);
1002 if (!tsos)
continue;
1005 if (!
pars)
continue;
1019 if (!meas) {
continue; }
1031 if (!
track.trackParameters() ||
track.trackParameters()->empty()) {
1035 startPars =
track.trackParameters()->front();
1039 bool addedPerigee =
false;
1042 if (!tsos)
continue;
1048 newStates.emplace_back(tsos->clone());
1059 if (
pars == startPars) {
1063 addedPerigee =
true;
1073 newStates.emplace_back(tsos->clone());
1079 double sign =
pars->position().dot(
pars->momentum()) > 0 ? 1. : -1.;
1083 double phi =
pars->momentum().phi();
1084 double theta =
pars->momentum().theta();
1085 double qoverp =
pars->charge() /
pars->momentum().mag();
1087 std::unique_ptr<Trk::Perigee> perigee = std::make_unique<Trk::Perigee>(0, 0,
phi,
theta, qoverp, persurf);
1089 addedPerigee =
true;
1090 ATH_MSG_DEBUG(
"Adding perigee in front of first measurement");
1097 newStates.emplace_back(tsos->clone());
1102 newStates.emplace_back(tsos->clone());
1109 ATH_MSG_WARNING(
" Measurement with MDT identifier that is not a MdtDriftCircleOnTrack ");
1113 bool hasT0Fit =
false;
1131 newMdt = mdt->
clone();
1151 std::unique_ptr<MdtDriftCircleOnTrack> newUniqueMdt {newMdt};
1153 newStates.emplace_back(std::move(new_tsos));
1157 newStates.emplace_back(std::move(new_tsos));
1160 newStates.emplace_back(tsos->clone());
1168 newStates.emplace_back(std::move(new_tsos));
1171 newStates.emplace_back(tsos->clone());
1176 newStates.emplace_back(tsos->clone());
1179 newStates.emplace_back(tsos->clone());
1183 newStates.emplace_back(tsos->clone());
1191 ATH_MSG_VERBOSE(
" original track had " <<
states->size() <<
" TSOS, adding " << newStates.size() -
states->size() <<
" new TSOS ");
1194 auto trackStateOnSurfaces = std::make_unique<Trk::TrackStates>();
1195 trackStateOnSurfaces->reserve(newStates.size());
1196 for ( std::unique_ptr<Trk::TrackStateOnSurface>& state : newStates) {
1198 trackStateOnSurfaces->push_back(std::move(state));
1200 std::unique_ptr<Trk::Track> newTrack = std::make_unique<Trk::Track>(
track.info(), std::move(trackStateOnSurfaces),
1201 track.fitQuality() ?
track.fitQuality()->uniqueClone() :
nullptr);
1214 std::set<Identifier> removedIdentifiers;
1215 std::vector<const MdtDriftCircleOnTrack*> mdts;
1221 for (; tsit != tsit_end; ++tsit) {
1222 if (!*tsit)
continue;
1226 if (!
pars) {
continue; }
1232 if (!meas) {
continue; }
1237 if (!
id.is_valid()) {
continue; }
1242 ATH_MSG_WARNING(
" Measurement with MDT identifier that is not a MdtDriftCircleOnTrack ");
1249 if (chId != currentMdtChId) {
1254 if (mdts.size() > 4)
1256 <<
" hits " << mdts.size());
1263 currentMdtChId = chId;
1266 mdts.push_back(mdt);
1273 if (mdts.size() > 4)
1280 if (removedIdentifiers.empty()) {
1282 return std::make_unique<Trk::Track>(
track);
1286 auto trackStateOnSurfaces = std::make_unique<Trk::TrackStates>();
1287 trackStateOnSurfaces->reserve(
states->size());
1289 ATH_MSG_DEBUG(
"Removing nhits: " << removedIdentifiers.size());
1292 if (!*tsit)
continue;
1299 if (removedIdentifiers.count(
id)) {
1301 trackStateOnSurfaces->push_back(std::move(new_tsos));
1305 trackStateOnSurfaces->push_back(tsos->clone());
1308 std::unique_ptr<Trk::Track> newTrack = std::make_unique<Trk::Track>(
track.info(), std::move(trackStateOnSurfaces),
1309 track.fitQuality() ?
track.fitQuality()->uniqueClone() :
nullptr);
1315 if (
hits.size() < 3) {
1343 detEl = mdt->prepRawData()->detectorElement();
1351 Amg::Vector3D locPos = gToStation * mdt->prepRawData()->globalPosition();
1354 double r = std::abs(mdt->localParameters()[
Trk::locR]);
1365 dcsOnTrack.emplace_back(dc, 1., 1.);
1366 dcs.emplace_back(std::move(dc));
1369 if (!detEl)
return false;
1375 surfaceTransform.pretranslate(
pars.position());
1376 double surfDim = 500.;
1377 const std::unique_ptr<Trk::PlaneSurface> surf = std::make_unique<Trk::PlaneSurface>(surfaceTransform, surfDim, surfDim);
1380 if (
dir.y() *
pars.position().y() < 0.) {
dir *= -1.; }
1385 double track_angleYZ = std::atan2(locDirTrack.z(), locDirTrack.y());
1389 double chamber_angleYZ = std::atan2(dirCh.z(), dirCh.y());
1390 double angleYZ =
locDir.angleYZ();
1397 ATH_MSG_DEBUG(
"Seeding angles " << track_angleYZ <<
" from surf " << angleYZ <<
" ch angle " << chamber_angleYZ <<
" pos "
1399 segFinder.
setPhiRoad(track_angleYZ, chamber_angleYZ, 0.14);
1403 if (dcslFitter.
fit(
segment, segPars, dcsOnTrack)) {
1404 segment.hitsOnTrack(dcsOnTrack.size());
1414 if (!segments.empty()) {
ATH_MSG_DEBUG(
"Found segments " << segments.size()); }
1416 if (segments.size() != 1) {
1417 if (
hits.size() > 3)
1421 double dthetaBest = 10000.;
1426 for (; sit != sit_end; ++sit, ++
index) {
1427 double dtheta = std::abs(sit->line().phi() - track_angleYZ);
1428 if (dtheta < dthetaBest) {
1429 dthetaBest = dtheta;
1432 if (sit->hitsOnTrack() > 4) {
ATH_MSG_DEBUG(
"Recoverable segment " << *sit); }
1434 if (indexBest != -1) {
1436 selectedSegments.push_back(segments[indexBest]);
1437 segments = selectedSegments;
1450 if (dcs.size() ==
segment.hitsOnTrack()) {
1453 }
else if (dcs.size() >
segment.hitsOnTrack() + 1) {
1455 if (
segment.hitsOnTrack() < 4)
return false;
1467 if (std::abs(dcit->r()) - std::abs(dcit->rot()->driftRadius()) > 0.1) {
1468 ATH_MSG_DEBUG(
"Large change in drift radius: r_old " << dcit->rot()->driftRadius() <<
" r_new " << dcit->r());
1472 removedIdentifiers.insert(dcit->rot()->identify());
1478 std::unique_ptr<Trk::Perigee>
1480 std::unique_ptr<Trk::Perigee> perigee;
1483 std::unique_ptr<Trk::TrackParameters> exPars{
m_muonExtrapolator->extrapolateDirectly(ctx,
pars, persurf)};
1484 perigee.reset (
dynamic_cast<Trk::Perigee*
>(exPars.release()));
1486 ATH_MSG_WARNING(
" Extrapolation to Perigee surface did not return a perigee!! ");