630 {
631
633 if (!states) {
635 return nullptr;
636 }
637
638
639
640 std::vector<std::unique_ptr<Trk::TrackStateOnSurface>> newStates;
641 newStates.reserve(
states->size() + 5);
642
644 std::map<int, std::set<StIndex>> stationsPerSector;
645
646
647 for (const Trk::TrackStateOnSurface* tsit : *states) {
648
649 if (!tsit) continue;
650
652 if (!pars) continue;
653
656 if (!startPars) {
658 } else {
660 }
661 }
662 }
663
664
665 const Trk::MeasurementBase* meas = tsit->measurementOnTrack();
666 if (!meas) { continue; }
667
668
670
672
677 stationsPerSector[sector].insert(stIndex);
678 }
679
680 if (!startPars) {
681 if (!
track.trackParameters() ||
track.trackParameters()->empty()) {
683 return nullptr;
684 }
685 startPars =
track.trackParameters()->front();
687 }
688
689
690 std::vector<int> sectorsWithMostStations;
691 unsigned int nmaxStations = 0;
692 std::map<int, std::set<StIndex>>::iterator stit = stationsPerSector.begin();
693 std::map<int, std::set<StIndex>>::iterator stit_end = stationsPerSector.end();
694 for (; stit != stit_end; ++stit) {
695 if (
msgLvl(MSG::VERBOSE)) {
697 for (std::set<StIndex>::iterator ssit = stit->second.begin(); ssit != stit->second.end(); ++ssit) {
699 }
700 }
701 if (stit->second.size() > nmaxStations) {
702 nmaxStations = stit->second.size();
703 sectorsWithMostStations.clear();
704 sectorsWithMostStations.push_back(stit->first);
705 } else if (stit->second.size() == nmaxStations) {
706 sectorsWithMostStations.push_back(stit->first);
707 }
708 }
709 int selectedSector = -1;
710 if (sectorsWithMostStations.empty()) {
712 } else if (sectorsWithMostStations.size() == 1) {
713 selectedSector = sectorsWithMostStations.front();
714 } else {
715 ATH_MSG_DEBUG(
"Found track with special sector configuration " << sectorsWithMostStations.size() <<
" ch per sector "
716 << nmaxStations << " using first sector");
717 selectedSector = sectorsWithMostStations.front();
718 if (selectedSector % 2 == 1 && sectorsWithMostStations.back() % 2 != 1) {
719 ATH_MSG_DEBUG(
"Revising sector choice, picking small sector ");
720 selectedSector = sectorsWithMostStations.back();
721 }
722 }
723
724
725
726 static constexpr std::array<StIndex, 3> barel_stations{StIndex::BI, StIndex::BM, StIndex::BO};
727 static constexpr std::array<StIndex, 5> endcap_stations{StIndex::EI,StIndex::EM, StIndex::EO, StIndex::EE, StIndex::BE};
728 const std::set<StIndex>& selected_set = stationsPerSector[selectedSector];
729 const int nbarrel = std::accumulate(barel_stations.begin(),barel_stations.end(),0, [&selected_set](
int n,
const StIndex& idx){
730 return (selected_set.count(idx) > 0) + n;
731 });
732 const int nendcap = std::accumulate(endcap_stations.begin(),endcap_stations.end(),0, [&selected_set](
int n,
const StIndex& idx){
733 return (selected_set.count(idx) > 0) + n;
734 });
735 bool barrelEndcap {false}, deweightBarrel{false}, deweightEndcap{false};
736 if (nbarrel > 0 && nendcap > 0) {
737 if (nbarrel < nendcap)
738 deweightBarrel = true;
739 else
740 deweightEndcap = true;
741 barrelEndcap = true;
742 }
744 ATH_MSG_DEBUG(
" Selected sector " << selectedSector <<
" nstations " << nmaxStations <<
" barrel " << nbarrel <<
" endcap "
745 << nendcap);
746 if (barrelEndcap) {
750 }
751 }
752
753 unsigned int deweightHits = 0;
754 unsigned int removedSectorHits = 0;
755 bool addedPerigee = false;
756
757 for (const Trk::TrackStateOnSurface* tsos : * states) {
758 if (!tsos) continue;
759
760
762 if (settings.prepareForFit && !pars) {
763 if (addedPerigee) {
764 newStates.emplace_back(tsos->clone());
765 } else {
767 }
768 continue;
769 }
770
771
772
774 if (pars == startPars) {
776 std::unique_ptr<Trk::Perigee> perigee =
createPerigee(*pars, ctx);
778 addedPerigee = true;
779 continue;
780 } else {
782 }
783 }
784
785
786 const Trk::MeasurementBase* meas = tsos->measurementOnTrack();
787 if (!meas) {
788 newStates.emplace_back(tsos->clone());
789 continue;
790 }
791
792 if (settings.prepareForFit && settings.recreateStartingParameters && !addedPerigee) {
793
794 double sign =
pars->position().dot(
pars->momentum()) > 0 ? 1. : -1.;
796
797
798 double phi =
pars->momentum().phi();
800 double qoverp =
pars->charge() /
pars->momentum().mag();
801 Trk::PerigeeSurface persurf(perpos);
802 std::unique_ptr<Trk::Perigee> perigee = std::make_unique<Trk::Perigee>(0, 0,
phi,
theta, qoverp, persurf);
804 addedPerigee = true;
805 ATH_MSG_DEBUG(
"Adding perigee in front of first measurement");
806 }
807
809
810
812 newStates.emplace_back(tsos->clone());
813 continue;
814 }
815
816 if (!settings.updateErrors) {
817 newStates.emplace_back(tsos->clone());
818 } else {
822 const MdtDriftCircleOnTrack* mdt = dynamic_cast<const MdtDriftCircleOnTrack*>(meas);
823 if (!mdt) {
824 ATH_MSG_WARNING(
" Measurement with MDT identifier that is not a MdtDriftCircleOnTrack ");
825 continue;
826 }
827
828 bool hasT0Fit = false;
830
831 std::unique_ptr<MdtDriftCircleOnTrack> rot{};
836
838
839
843
845
846 } else if (deweightBarrel &&
847 std::find(barel_stations.begin(),barel_stations.end(),stIndex) != barel_stations.end()) {
850
851 } else if (deweightEndcap &&
852 std::find(endcap_stations.begin(), endcap_stations.end(), stIndex) != endcap_stations.end()) {
855
856 } else if (settings.deweightOtherSectors && sector != selectedSector) {
857 ++deweightHits;
859
863
866
870
874
879
880 } else {
886 }
887 } else {
889 }
890
891
892
893 if (!rot) {
894 rot.reset(mdt->
clone());
896 }
897 if (settings.removeOtherSectors) {
898 if (sector != selectedSector) {
899 ++removedSectorHits;
901 }
902 }
903 if (settings.chambersToBeremoved.count(chId) || settings.precisionLayersToBeremoved.count(stIndex)) {
905 }
906
909 << " radius " << rot->driftRadius() << " new err "
912 if (hasT0Fit)
914 else
917 if (std::abs(rot->driftRadius() - mdt->
driftRadius()) > 0.1)
919 }
920
922 newStates.emplace_back(std::move(new_tsos));
924 if (settings.chambersToBeremoved.count(chId) || settings.precisionLayersToBeremoved.count(stIndex)) {
926 newStates.emplace_back(std::move(new_tsos));
927
928 } else {
929 newStates.emplace_back(tsos->clone());
930 }
933 if (settings.chambersToBeremoved.count(chId) || settings.phiLayersToBeremoved.count(
m_idHelperSvc->phiIndex(
id))) {
935 newStates.emplace_back(std::move(new_tsos));
936
937 } else {
938 newStates.emplace_back(tsos->clone());
939 }
940
941 } else {
942 if (settings.updateTriggerErrors) {
943 newStates.emplace_back(tsos->clone());
944
945 } else {
946 newStates.emplace_back(tsos->clone());
947 }
948 }
950 newStates.emplace_back(tsos->clone());
951
952 } else {
954 }
955 }
956 }
957
958 if (deweightHits > 0)
ATH_MSG_DEBUG(
" de-weighted " << deweightHits <<
" MDT hits from neighbouring sectors");
959 if (removedSectorHits > 0)
ATH_MSG_DEBUG(
" removed " << removedSectorHits <<
" MDT hits from neighbouring sectors");
960
961 ATH_MSG_VERBOSE(
" original track had " <<
states->size() <<
" TSOS, adding " << newStates.size() -
states->size() <<
" new TSOS ");
962
963
964 auto trackStateOnSurfaces = std::make_unique<Trk::TrackStates>();
965 trackStateOnSurfaces->reserve(newStates.size());
966 for (std::unique_ptr<Trk::TrackStateOnSurface>& new_state : newStates) {
967 trackStateOnSurfaces->push_back(std::move(new_state));
968 }
969 std::unique_ptr<Trk::Track> newTrack = std::make_unique<Trk::Track>(
track.info(), std::move(trackStateOnSurfaces),
970 track.fitQuality() ?
track.fitQuality()->uniqueClone() :
nullptr);
972
973 return newTrack;
974 }
Scalar phi() const
phi method
Scalar theta() const
theta method
const MuonDriftCircleErrorStrategy & errorStrategy() const
Get information about the creation strategy used by Muon::MdtDriftCircleOnTrackCreator when making th...
double driftRadius() const
Returns the value of the drift radius.
virtual MdtDriftCircleOnTrack * clone() const override final
Pseudo-constructor, needed to avoid excessive RTTI.
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
const Amg::MatrixX & localCovariance() const
Interface method to get the localError.
@ Perigee
This represents a perigee, and so will contain a Perigee object only.
const std::string & stName(StIndex index)
convert StIndex into a string