42 declareInterface<IMuonRefitTool>(
this);
132 return StatusCode::SUCCESS;
142 <<
"Failed Refit " << scaleRefit *
m_failedRefit << std::endl
144 return StatusCode::SUCCESS;
151 std::unique_ptr<Trk::Track> newTrack;
158 return std::make_unique<Trk::Track>(
track);
163 newTrack.swap(cleanedTrack);
165 newTrack = std::make_unique<Trk::Track>(
track);
169 std::unique_ptr<Trk::Track> updateErrorTrack =
171 if (!updateErrorTrack) {
176 newTrack.swap(updateErrorTrack);
179 if (settings.
refit) {
184 std::unique_ptr<Trk::Track> refittedTrack;
185 if (
track.fitQuality() &&
track.fitQuality()->chiSquared() < 10000 *
track.fitQuality()->numberDoF())
187 if (!refittedTrack) {
191 return std::make_unique<Trk::Track>(
track);
195 newTrack.swap(refittedTrack);
200 if (!extrapolatedTrack) {
206 newTrack.swap(extrapolatedTrack);
212 std::vector<std::unique_ptr<Trk::Track>>
MuonRefitTool::refit(
const std::vector<Trk::Track*>& tracks,
const EventContext& ctx,
214 std::vector<std::unique_ptr<Trk::Track>> refittedTracks;
215 refittedTracks.reserve(tracks.size());
218 return refittedTracks;
229 return updatedAEOTsTrack;
240 std::map<std::vector<Identifier>, std::pair<double, double>> alignerrmap;
242 std::vector<Trk::AlignmentDeviation*> align_deviations;
246 bool isSmallChamber =
false;
247 bool isLargeChamber =
false;
248 bool isEndcap =
false;
250 std::vector<int> usedRotations;
254 double angleError = 0.;
255 double translationError = 0.;
256 bool differentChambers =
false;
258 isSmallChamber =
false;
259 isLargeChamber =
false;
264 translationError = std::sqrt(
it->getCovariance(0, 0));
266 std::vector<Identifier> hitids;
267 const auto& vec_riowithdev =
it->getListOfHits();
270 const Identifier id_riowithdev = riowithdev->identify();
277 isSmallChamber =
true;
279 isLargeChamber =
true;
281 hitids.push_back(id_riowithdev);
283 differentChambers =
true;
284 jdifferent = hitids.size() - 1;
287 bool matchFound =
false;
288 if (!hitids.empty()) {
293 if (itRot->hasValidHashOfHits() &&
it->hasValidHashOfHits()) {
294 if (itRot->getHashOfHits() ==
it->getHashOfHits()) {
295 angleError = std::sqrt(itRot->getCovariance(0, 0));
297 usedRotations.push_back(iRot);
300 ATH_MSG_ERROR(
"One of the alignment deviations has an invalid hash created from the hits.");
303 if (matchFound)
break;
310 alignerrmap.insert(std::pair<std::vector<Identifier>, std::pair<double, double>>(
311 hitids, std::pair<double, double>(translationError, angleError)));
314 ATH_MSG_DEBUG(
" AlignmentMap entry " << iok <<
" filled with nr hitids " << hitids.size() <<
" "
315 <<
m_idHelperSvc->toString(hitids[0]) <<
" translationError " << translationError
316 <<
" angleError " << angleError);
318 ATH_MSG_DEBUG(
" AlignmentMap entry No angleError" << iok <<
" filled with nr hitids " << hitids.size() <<
" "
319 <<
m_idHelperSvc->toString(hitids[0]) <<
" translationError "
320 << translationError <<
" angleError " << angleError);
321 if (isEndcap)
ATH_MSG_DEBUG(
" AlignmentMap Endcap Chamber ");
323 if (isSmallChamber)
ATH_MSG_DEBUG(
" AlignmentMap Small Chamber ");
324 if (isLargeChamber)
ATH_MSG_DEBUG(
" AlignmentMap Large Chamber ");
325 if (differentChambers)
326 ATH_MSG_DEBUG(
" AlignmentMap entry " << iok <<
" for different Chamber "
336 isSmallChamber =
false;
337 isLargeChamber =
false;
341 bool used =
std::find(usedRotations.begin(), usedRotations.end(), iRot) != usedRotations.end();
343 ATH_MSG_ERROR(
"This following code should not be reached anymore!");
344 const auto& vec_riowithdev = itRot->getListOfHits();
346 std::vector<Identifier> hitids;
349 Identifier id_riowithdev = riowithdev->identify();
356 isSmallChamber =
true;
358 isLargeChamber =
true;
360 hitids.push_back(id_riowithdev);
363 double translationError = 0.;
364 double angleError = std::sqrt(itRot->getCovariance(0, 0));
367 alignerrmap.insert(std::pair<std::vector<Identifier>, std::pair<double, double>>(
368 hitids, std::pair<double, double>(translationError, angleError)));
369 ATH_MSG_DEBUG(
" AlignmentMap entry No Translation Error " << iok <<
" filled with nr hitids " << hitids.size() <<
" "
370 <<
m_idHelperSvc->toString(hitids[0]) <<
" translationError "
371 << translationError <<
" angleError " << angleError);
374 if (isSmallChamber)
ATH_MSG_DEBUG(
" AlignmentMap Small Chamber ");
375 if (isLargeChamber)
ATH_MSG_DEBUG(
" AlignmentMap Large Chamber ");
380 for (
auto*
it : align_deviations)
delete it;
381 align_deviations.clear();
389 std::bitset<Trk::TrackStateOnSurface::NumberOfTrackStateOnSurfaceTypes> typePattern(0);
392 std::vector<int> indexAEOTs;
393 std::vector<std::unique_ptr<Trk::TrackStateOnSurface>> tsosAEOTs;
397 std::set<MuonStationIndex::ChIndex> stationIds;
399 for (
const auto& itAli : alignerrmap) {
400 unsigned int imiddle = (itAli.first.size()) / 2;
407 if (!meas) {
continue; }
409 if (!
id.is_valid())
continue;
415 if (idMiddle ==
id) {
417 const double deltaError =
std::max(itAli.second.first, 0.01);
418 const double angleError =
std::max(itAli.second.second, 0.000001);
419 auto aEOT = std::make_unique<Trk::AlignmentEffectsOnTrack>(
425 tsit->measurementOnTrack()->associatedSurface());
426 std::unique_ptr<Trk::TrackStateOnSurface> tsosAEOT =
427 std::make_unique<Trk::TrackStateOnSurface>(
429 tsit->trackParameters()->uniqueClone(),
433 indexAEOTs.push_back(
index);
434 tsosAEOTs.emplace_back(std::move(tsosAEOT));
439 if (!
found)
ATH_MSG_WARNING(
" This should not happen Identifier from AlignmentErrorTool is not found");
445 auto trackStateOnSurfaces = std::make_unique<Trk::TrackStates>();
446 trackStateOnSurfaces->reserve(
states->size() + indexAEOTs.size());
450 for (
unsigned int i = 0;
i < indexAEOTs.size();
i++) {
451 if (
index == indexAEOTs[
i]) {
453 trackStateOnSurfaces->push_back(std::move(tsosAEOTs[
i]));
455 ATH_MSG_WARNING(
"There's a trial to push back the same AEOT twice to the track...");
461 if (tsit->alignmentEffectsOnTrack()) {
465 trackStateOnSurfaces->push_back(tsit->clone());
468 if (indexAEOTs.empty() && stationIds.size() > 1)
ATH_MSG_WARNING(
" Track without AEOT ");
470 std::unique_ptr<Trk::Track> newTrack = std::make_unique<Trk::Track>(
track.info(), std::move(trackStateOnSurfaces),
471 track.fitQuality() ?
track.fitQuality()->uniqueClone() :
nullptr);
491 auto trackStateOnSurfaces = std::make_unique<Trk::TrackStates>();
492 trackStateOnSurfaces->reserve(
states->size() + 1);
496 std::vector<const Trk::TrackStateOnSurface*> indicesOfAffectedTSOS;
497 std::vector<const Trk::TrackStateOnSurface*> indicesOfAffectedTSOSInner;
498 std::vector<Identifier> indicesOfAffectedIds;
499 std::vector<Identifier> indicesOfAffectedIdsInner;
500 int index {-1}, indexFirst {-1}, indexFirstInner {-1};
510 if (!meas) {
continue; }
514 if (tsit->alignmentEffectsOnTrack()) {
515 ATH_MSG_WARNING(
" AlignmentEffectOnTrack is already on track skip it");
529 if (indexFirst == -1) indexFirst =
index;
530 indicesOfAffectedTSOS.push_back(tsit);
531 indicesOfAffectedIds.push_back(
id);
536 if (indexFirst == -1) indexFirst =
index;
537 indicesOfAffectedTSOS.push_back(tsit);
538 indicesOfAffectedIds.push_back(
id);
541 if (indexFirstInner == -1) indexFirstInner =
index;
542 indicesOfAffectedTSOSInner.push_back(tsit);
543 indicesOfAffectedIdsInner.push_back(
id);
547 if (indexFirstInner == -1) indexFirstInner =
index;
548 indicesOfAffectedTSOSInner.push_back(tsit);
549 indicesOfAffectedIdsInner.push_back(
id);
554 if (indicesOfAffectedTSOS.empty() && indicesOfAffectedTSOSInner.empty()) {
555 std::unique_ptr<Trk::Track> newTrack = std::make_unique<Trk::Track>(
track.info(), std::move(trackStateOnSurfaces),
556 track.fitQuality() ?
track.fitQuality()->uniqueClone() :
nullptr);
560 std::bitset<Trk::TrackStateOnSurface::NumberOfTrackStateOnSurfaceTypes> typePattern(0);
563 std::unique_ptr<Trk::TrackStateOnSurface> tsosAEOT;
565 int middle = indicesOfAffectedTSOS.size() / 2;
567 auto aEOT = std::make_unique<Trk::AlignmentEffectsOnTrack>(
572 indicesOfAffectedIds,
575 << aEOT->associatedSurface()
576 <<
" nr of tsos affected "
577 << indicesOfAffectedTSOS.size());
578 tsosAEOT = std::make_unique<Trk::TrackStateOnSurface>(
586 std::unique_ptr<Trk::TrackStateOnSurface> tsosAEOTInner;
588 int middle = indicesOfAffectedTSOSInner.size() / 2;
590 auto aEOTInner = std::make_unique<Trk::AlignmentEffectsOnTrack>(
595 indicesOfAffectedIdsInner,
597 tsosAEOTInner = std::make_unique<Trk::TrackStateOnSurface>(
602 std::move(aEOTInner));
605 auto trackStateOnSurfacesAEOT = std::make_unique<Trk::TrackStates>();
606 trackStateOnSurfacesAEOT->reserve(
states->size() + 2);
610 if (
index == indexFirst && tsosAEOT) {
611 trackStateOnSurfacesAEOT->push_back(std::move(tsosAEOT));
612 if (!
m_addAll)
ATH_MSG_DEBUG(
" AlignmentEffectsOnTrack for Middle added to trackStateOnSurfacesAEOT ");
613 if (
m_addAll)
ATH_MSG_DEBUG(
" AlignmentEffectsOnTrack for All stations added to trackStateOnSurfacesAEOT ");
615 if (
index == indexFirstInner && tsosAEOTInner) {
616 trackStateOnSurfacesAEOT->push_back(std::move(tsosAEOTInner));
617 ATH_MSG_DEBUG(
" AlignmentEffectsOnTrack for Inner added to trackStateOnSurfacesAEOT ");
618 if (
m_addTwo)
ATH_MSG_DEBUG(
" also AlignmentEffectsOnTrack for Middle added to trackStateOnSurfacesAEOT ");
620 trackStateOnSurfacesAEOT->push_back(tsit);
622 std::unique_ptr<Trk::Track> newTrack = std::make_unique<Trk::Track>(
track.info(), std::move(trackStateOnSurfacesAEOT),
623 track.fitQuality() ?
track.fitQuality()->uniqueClone() :
nullptr);
641 std::vector<std::unique_ptr<Trk::TrackStateOnSurface>> newStates;
642 newStates.reserve(
states->size() + 5);
645 std::map<int, std::set<MuonStationIndex::StIndex>> stationsPerSector;
667 if (!meas) {
continue; }
678 stationsPerSector[sector].insert(stIndex);
682 if (!
track.trackParameters() ||
track.trackParameters()->empty()) {
686 startPars =
track.trackParameters()->front();
691 std::vector<int> sectorsWithMostStations;
692 unsigned int nmaxStations = 0;
693 std::map<int, std::set<MuonStationIndex::StIndex>>
::iterator stit = stationsPerSector.begin();
694 std::map<int, std::set<MuonStationIndex::StIndex>>
::iterator stit_end = stationsPerSector.end();
695 for (; stit != stit_end; ++stit) {
702 if (stit->second.size() > nmaxStations) {
703 nmaxStations = stit->second.size();
704 sectorsWithMostStations.clear();
705 sectorsWithMostStations.push_back(stit->first);
706 }
else if (stit->second.size() == nmaxStations) {
707 sectorsWithMostStations.push_back(stit->first);
710 int selectedSector = -1;
711 if (sectorsWithMostStations.empty()) {
713 }
else if (sectorsWithMostStations.size() == 1) {
714 selectedSector = sectorsWithMostStations.front();
716 ATH_MSG_DEBUG(
"Found track with special sector configuration " << sectorsWithMostStations.size() <<
" ch per sector "
717 << nmaxStations <<
" using first sector");
718 selectedSector = sectorsWithMostStations.front();
719 if (selectedSector % 2 == 1 && sectorsWithMostStations.back() % 2 != 1) {
720 ATH_MSG_DEBUG(
"Revising sector choice, picking small sector ");
721 selectedSector = sectorsWithMostStations.back();
729 const std::set<MuonStationIndex::StIndex>& selected_set = stationsPerSector[selectedSector];
731 return (selected_set.count(idx) > 0) + n;
734 return (selected_set.count(idx) > 0) + n;
736 bool barrelEndcap {
false}, deweightBarrel{
false}, deweightEndcap{
false};
737 if (nbarrel > 0 && nendcap > 0) {
738 if (nbarrel < nendcap)
739 deweightBarrel =
true;
741 deweightEndcap =
true;
745 ATH_MSG_DEBUG(
" Selected sector " << selectedSector <<
" nstations " << nmaxStations <<
" barrel " << nbarrel <<
" endcap "
754 unsigned int deweightHits = 0;
755 unsigned int removedSectorHits = 0;
756 bool addedPerigee =
false;
765 newStates.emplace_back(tsos->clone());
775 if (
pars == startPars) {
789 newStates.emplace_back(tsos->clone());
795 double sign =
pars->position().dot(
pars->momentum()) > 0 ? 1. : -1.;
799 double phi =
pars->momentum().phi();
800 double theta =
pars->momentum().theta();
801 double qoverp =
pars->charge() /
pars->momentum().mag();
803 std::unique_ptr<Trk::Perigee> perigee = std::make_unique<Trk::Perigee>(0, 0, phi, theta, qoverp, persurf);
806 ATH_MSG_DEBUG(
"Adding perigee in front of first measurement");
813 newStates.emplace_back(tsos->clone());
818 newStates.emplace_back(tsos->clone());
825 ATH_MSG_WARNING(
" Measurement with MDT identifier that is not a MdtDriftCircleOnTrack ");
829 bool hasT0Fit =
false;
832 std::unique_ptr<MdtDriftCircleOnTrack> rot{};
848 }
else if (deweightBarrel &&
849 std::find(barel_stations.begin(),barel_stations.end(),stIndex) != barel_stations.end()) {
853 }
else if (deweightEndcap &&
854 std::find(endcap_stations.begin(), endcap_stations.end(), stIndex) != endcap_stations.end()) {
896 rot.reset(mdt->
clone());
900 if (sector != selectedSector) {
911 <<
" radius " << rot->driftRadius() <<
" new err "
919 if (std::abs(rot->driftRadius() - mdt->
driftRadius()) > 0.1)
924 newStates.emplace_back(std::move(new_tsos));
928 newStates.emplace_back(std::move(new_tsos));
931 newStates.emplace_back(tsos->clone());
939 newStates.emplace_back(std::move(new_tsos));
942 newStates.emplace_back(tsos->clone());
947 newStates.emplace_back(tsos->clone());
950 newStates.emplace_back(tsos->clone());
954 newStates.emplace_back(tsos->clone());
962 if (deweightHits > 0)
ATH_MSG_DEBUG(
" de-weighted " << deweightHits <<
" MDT hits from neighbouring sectors");
963 if (removedSectorHits > 0)
ATH_MSG_DEBUG(
" removed " << removedSectorHits <<
" MDT hits from neighbouring sectors");
965 ATH_MSG_VERBOSE(
" original track had " <<
states->size() <<
" TSOS, adding " << newStates.size() -
states->size() <<
" new TSOS ");
968 auto trackStateOnSurfaces = std::make_unique<Trk::TrackStates>();
969 trackStateOnSurfaces->reserve(newStates.size());
970 for (std::unique_ptr<Trk::TrackStateOnSurface>& new_state : newStates) {
971 trackStateOnSurfaces->push_back(std::move(new_state));
973 std::unique_ptr<Trk::Track> newTrack = std::make_unique<Trk::Track>(
track.info(), std::move(trackStateOnSurfaces),
974 track.fitQuality() ?
track.fitQuality()->uniqueClone() :
nullptr);
993 std::vector<std::unique_ptr<Trk::TrackStateOnSurface>> newStates;
994 newStates.reserve(
states->size() + 5);
1000 if (!tsos)
continue;
1003 if (!
pars)
continue;
1017 if (!meas) {
continue; }
1029 if (!
track.trackParameters() ||
track.trackParameters()->empty()) {
1033 startPars =
track.trackParameters()->front();
1037 bool addedPerigee =
false;
1040 if (!tsos)
continue;
1046 newStates.emplace_back(tsos->clone());
1057 if (
pars == startPars) {
1061 addedPerigee =
true;
1071 newStates.emplace_back(tsos->clone());
1077 double sign =
pars->position().dot(
pars->momentum()) > 0 ? 1. : -1.;
1081 double phi =
pars->momentum().phi();
1082 double theta =
pars->momentum().theta();
1083 double qoverp =
pars->charge() /
pars->momentum().mag();
1085 std::unique_ptr<Trk::Perigee> perigee = std::make_unique<Trk::Perigee>(0, 0, phi, theta, qoverp, persurf);
1087 addedPerigee =
true;
1088 ATH_MSG_DEBUG(
"Adding perigee in front of first measurement");
1095 newStates.emplace_back(tsos->clone());
1100 newStates.emplace_back(tsos->clone());
1107 ATH_MSG_WARNING(
" Measurement with MDT identifier that is not a MdtDriftCircleOnTrack ");
1111 bool hasT0Fit =
false;
1129 newMdt = mdt->
clone();
1149 std::unique_ptr<MdtDriftCircleOnTrack> newUniqueMdt {newMdt};
1151 newStates.emplace_back(std::move(new_tsos));
1155 newStates.emplace_back(std::move(new_tsos));
1158 newStates.emplace_back(tsos->clone());
1166 newStates.emplace_back(std::move(new_tsos));
1169 newStates.emplace_back(tsos->clone());
1174 newStates.emplace_back(tsos->clone());
1177 newStates.emplace_back(tsos->clone());
1181 newStates.emplace_back(tsos->clone());
1189 ATH_MSG_VERBOSE(
" original track had " <<
states->size() <<
" TSOS, adding " << newStates.size() -
states->size() <<
" new TSOS ");
1192 auto trackStateOnSurfaces = std::make_unique<Trk::TrackStates>();
1193 trackStateOnSurfaces->reserve(newStates.size());
1194 for ( std::unique_ptr<Trk::TrackStateOnSurface>& state : newStates) {
1196 trackStateOnSurfaces->push_back(std::move(state));
1198 std::unique_ptr<Trk::Track> newTrack = std::make_unique<Trk::Track>(
track.info(), std::move(trackStateOnSurfaces),
1199 track.fitQuality() ?
track.fitQuality()->uniqueClone() :
nullptr);
1212 std::set<Identifier> removedIdentifiers;
1213 std::vector<const MdtDriftCircleOnTrack*> mdts;
1219 for (; tsit != tsit_end; ++tsit) {
1220 if (!*tsit)
continue;
1224 if (!
pars) {
continue; }
1230 if (!meas) {
continue; }
1235 if (!
id.is_valid()) {
continue; }
1240 ATH_MSG_WARNING(
" Measurement with MDT identifier that is not a MdtDriftCircleOnTrack ");
1247 if (chId != currentMdtChId) {
1252 if (mdts.size() > 4)
1254 <<
" hits " << mdts.size());
1261 currentMdtChId = chId;
1264 mdts.push_back(mdt);
1271 if (mdts.size() > 4)
1278 if (removedIdentifiers.empty()) {
1280 return std::make_unique<Trk::Track>(
track);
1284 auto trackStateOnSurfaces = std::make_unique<Trk::TrackStates>();
1285 trackStateOnSurfaces->reserve(
states->size());
1287 ATH_MSG_DEBUG(
"Removing nhits: " << removedIdentifiers.size());
1290 if (!*tsit)
continue;
1297 if (removedIdentifiers.count(
id)) {
1299 trackStateOnSurfaces->push_back(std::move(new_tsos));
1303 trackStateOnSurfaces->push_back(tsos->clone());
1306 std::unique_ptr<Trk::Track> newTrack = std::make_unique<Trk::Track>(
track.info(), std::move(trackStateOnSurfaces),
1307 track.fitQuality() ?
track.fitQuality()->uniqueClone() :
nullptr);
1313 if (
hits.size() < 3) {
1341 detEl = mdt->prepRawData()->detectorElement();
1349 Amg::Vector3D locPos = gToStation * mdt->prepRawData()->globalPosition();
1352 double r = std::abs(mdt->localParameters()[
Trk::locR]);
1363 dcsOnTrack.emplace_back(dc, 1., 1.);
1364 dcs.emplace_back(std::move(dc));
1367 if (!detEl)
return false;
1373 surfaceTransform.pretranslate(
pars.position());
1374 double surfDim = 500.;
1375 const std::unique_ptr<Trk::PlaneSurface> surf = std::make_unique<Trk::PlaneSurface>(surfaceTransform, surfDim, surfDim);
1378 if (
dir.y() *
pars.position().y() < 0.) {
dir *= -1.; }
1383 double track_angleYZ = std::atan2(locDirTrack.z(), locDirTrack.y());
1387 double chamber_angleYZ = std::atan2(dirCh.z(), dirCh.y());
1388 double angleYZ =
locDir.angleYZ();
1395 ATH_MSG_DEBUG(
"Seeding angles " << track_angleYZ <<
" from surf " << angleYZ <<
" ch angle " << chamber_angleYZ <<
" pos "
1397 segFinder.
setPhiRoad(track_angleYZ, chamber_angleYZ, 0.14);
1401 if (dcslFitter.
fit(
segment, segPars, dcsOnTrack)) {
1402 segment.hitsOnTrack(dcsOnTrack.size());
1412 if (!segments.empty()) {
ATH_MSG_DEBUG(
"Found segments " << segments.size()); }
1414 if (segments.size() != 1) {
1415 if (
hits.size() > 3)
1419 double dthetaBest = 10000.;
1424 for (; sit != sit_end; ++sit, ++
index) {
1425 double dtheta = std::abs(sit->line().phi() - track_angleYZ);
1426 if (dtheta < dthetaBest) {
1427 dthetaBest = dtheta;
1430 if (sit->hitsOnTrack() > 4) {
ATH_MSG_DEBUG(
"Recoverable segment " << *sit); }
1432 if (indexBest != -1) {
1434 selectedSegments.push_back(segments[indexBest]);
1435 segments = selectedSegments;
1448 if (dcs.size() ==
segment.hitsOnTrack()) {
1451 }
else if (dcs.size() >
segment.hitsOnTrack() + 1) {
1453 if (
segment.hitsOnTrack() < 4)
return false;
1465 if (std::abs(dcit->r()) - std::abs(dcit->rot()->driftRadius()) > 0.1) {
1466 ATH_MSG_DEBUG(
"Large change in drift radius: r_old " << dcit->rot()->driftRadius() <<
" r_new " << dcit->r());
1470 removedIdentifiers.insert(dcit->rot()->identify());
1476 std::unique_ptr<Trk::Perigee>
1478 std::unique_ptr<Trk::Perigee> perigee;
1481 std::unique_ptr<Trk::TrackParameters> exPars{
m_muonExtrapolator->extrapolateDirectly(ctx,
pars, persurf)};
1482 perigee.reset (
dynamic_cast<Trk::Perigee*
>(exPars.release()));
1484 ATH_MSG_WARNING(
" Extrapolation to Perigee surface did not return a perigee!! ");