684 {
686 info.MCTBTrack = &entry1;
687 info.MCTBSegment = &entry2;
688 info.track = &entry1.track();
689 info.segment = entry2.segment;
690 info.segmentChamberId = entry2.chid;
691 if (!entry2.segment) {
692 ATH_MSG_WARNING(__FUNCTION__ <<
" entry2 does not have segment pointer.");
694 return;
695 }
697 bool hasStereoAngle = false;
698
699
701 double closestParsDist = 1E9;
703 double closestMeasParsDist = 1E9;
704
705 Identifier closestId;
706 double closestIdDist = 1E9;
707 bool trackHasPhi = true;
708
709 MagField::AtlasFieldCache fieldCache;
710
712 const AtlasFieldCacheCondObj* fieldCondObj{*readHandle};
713
714 if (fieldCondObj == nullptr) {
716 return;
717 }
719
720
724 for (;
tit != tit_end; ++
tit) {
725 const Trk::MeasurementBase* meas = (*tit)->measurementOnTrack();
726
727
728 const Trk::PseudoMeasurementOnTrack* pseudo = dynamic_cast<const Trk::PseudoMeasurementOnTrack*>(meas);
729 if (pseudo) {
730 trackHasPhi = false;
731 continue;
732 }
733
734
736 if (meas) {
738 if (id.is_valid()) {
741 }
742 }
743
745 if (!pars) { continue; }
746
747
748 double dist = (entry2.entryPars().position() -
pars->position()).dot(entry1.entryPars().momentum().unit());
749
750 if (std::abs(dist) < std::abs(closestParsDist)) {
751
752 closestParsDist = dist;
754 if (
pars->covariance()) {
755 closestMeasParsDist = dist;
756 closestMeasPars =
pars;
757 }
758 }
759
760 if (std::abs(dist) < std::abs(closestIdDist)) {
763 closestIdDist = dist;
764 }
765 }
766 }
767
768
769 if (entry1.phiHits().size() > 1) {
770
771 const Amg::Vector3D& gposFirstPhi = entry1.phiHits().front()->globalPosition();
772 const Amg::Vector3D& gposLastPhi = entry1.phiHits().back()->globalPosition();
774
775
776 double distance = entry1.hasEndcap() ? fabs(globalDistance.z()) : globalDistance.
perp();
777
778 if (distance > 500) trackHasPhi = true;
779 }
780
781 if (!closestPars) {
782 ATH_MSG_DEBUG(
"track-segment match: No closest track parameters found.");
784 return;
785 }
786
787
789
790 if (
msgLvl(MSG::VERBOSE)) {
791 msg(MSG::DEBUG) << MSG::VERBOSE <<
"match Closest chamber: " <<
m_idHelperSvc->toStringChamber(
info.trackChamberId)
794 if (closestMeasPars) tmpPars = closestMeasPars->covariance() ? closestMeasPars : nullptr;
795 if (tmpPars) {
796 msg(MSG::DEBUG) << std::endl
797 <<
"Closest measured track parameters: " <<
m_printer->print(*tmpPars) << std::endl
798 <<
Amg::toString(*tmpPars->covariance(), 10) <<
" distance=" << closestMeasParsDist;
799 }
800 if (!tmpPars || tmpPars != closestPars) {
801 msg(MSG::DEBUG) << std::endl
802 <<
"Closest track parameters : " <<
m_printer->print(*closestPars)
803 << " distance=" << closestParsDist;
804 }
806 }
807
808 bool straightLineMatch = !fieldCache.
toroidOn();
809 if (hasStereoAngle && !trackHasPhi && (straightLineMatch || entry1.hasMomentum())) {
810
812 return;
813 }
814
815
816 if (!straightLineMatch && !entry1.hasMomentum() &&
info.trackChamberId.is_valid()) {
819 if (((trackStationIndex == MuonStationIndex::StIndex::EM && segmentStationIndex == MuonStationIndex::StIndex::EO) ||
820 (trackStationIndex == MuonStationIndex::StIndex::EO && segmentStationIndex == MuonStationIndex::StIndex::EM)) &&
821 closestPars->
position().z() * entry2.entryPars().position().z() > 0.0) {
822 straightLineMatch = true;
825 << " => doing straight line extrapolation match");
826 }
827 }
828
829
830
831
832 if (straightLineMatch || entry1.hasMomentum()) {
833
834 std::unique_ptr<const Trk::TrackParameters> exPars;
836 if (closestMeasPars) {
837 const Trk::TrackParameters* tmpPars = closestMeasPars->covariance() ? closestMeasPars :
nullptr;
838
839 if (tmpPars) {
840
843 return;
844 }
847 int sectorDiff = std::abs(trackSector - segmentSector);
848 if (sectorDiff > 1 && sectorDiff != 15) {
849 ATH_MSG_VERBOSE(
"track sector =" << trackSector <<
" segment sector =" << segmentSector
850 << " => not in neighbouring sectors ");
851
853 return;
854 }
855
856
857 if (straightLineMatch && !entry1.hasMomentum()) {
858 exPars =
m_atlasExtrapolator->extrapolateDirectly(ctx, *tmpPars, entry2.segment->associatedSurface(),
860 } else {
865 }
866 }
867 if (!exPars) {
868 ATH_MSG_DEBUG(
"track-segment match: Failed to extrapolate measured track parameters\n"
870 <<
" to segment surface " <<
m_idHelperSvc->toStringChamber(
info.segmentChamberId));
871 info.matchOK =
false;
873 return;
874 }
875
876 exMeasPars = exPars->covariance() ? exPars.get() : nullptr;
877 if (!exMeasPars) {
878 ATH_MSG_DEBUG(
"track-segment match: Did not get measured track parameters from extrapolation\n"
879 <<
"\nfrom " <<
m_idHelperSvc->toStringChamber(
info.trackChamberId) <<
" to segment surface "
882 return;
883 }
886
887 } else {
888
889
890 if (straightLineMatch && !entry1.hasMomentum()) {
891 exPars =
m_atlasExtrapolator->extrapolateDirectly(ctx, *closestPars, entry2.segment->associatedSurface(),
893 } else {
896 }
897 if (!exPars) {
898 ATH_MSG_DEBUG(
"track-segment match: Failed to extrapolate track parameters without errors\n"
900 <<
" to segment surface " <<
m_idHelperSvc->toStringChamber(
info.segmentChamberId));
901 info.matchOK =
false;
903 return;
904 }
905 }
906
907
908
909 const Amg::MatrixX& measErrors = entry2.segment->localCovariance();
910
912 if (posXMeasErr2 <= 999.0) {
913 info.havePosX =
true;
914 info.havePosXError =
true;
915 info.posXMeasErr2 = posXMeasErr2;
916 info.posXTotalErr2 += posXMeasErr2;
917 }
918
920 if (
info.posYMeasErr2 <= 999.0) {
921 info.havePosY =
true;
922 info.havePosYError =
true;
923 info.posYMeasErr2 = posYMeasErr2;
924 info.posYTotalErr2 += posYMeasErr2;
925 }
928 if (phiMeasErr2 <= 999.0) {
929 info.haveAngleX =
true;
930 info.haveAngleXError =
true;
931 info.angleXMeasErr2 = phiMeasErr2;
932 info.angleXTotalErr2 += phiMeasErr2;
933 }
934 if (thetaMeasErr2 <= 999.0) {
935 info.haveAngleY =
true;
936 info.haveAngleYError =
true;
937 info.angleYMeasErr2 = thetaMeasErr2;
938 info.angleYTotalErr2 += thetaMeasErr2;
939 }
940
941
942 if (!exMeasPars) {
943 info.haveAngleXError =
false;
944 info.haveAngleYError =
false;
945 info.havePosXError =
false;
946 info.havePosYError =
false;
947 }
948
949
952
953
954 Trk::LocalDirection locDirEx;
955 entry2.segment->associatedSurface().globalToLocalDirection(exPars->momentum(), locDirEx);
956
957 const Trk::LocalDirection& locDirSeg = entry2.segment->localDirection();
958
959
962
964 localPredCovar.setIdentity();
965
966 if (info.haveAngleXError || info.haveAngleYError || info.havePosXError || info.havePosYError) {
967
968 Trk::JacobianPhiThetaLocalAngles globalToLocalPredAnglesJacobian(
971
972
973
975 globalToLocalPredJacobian.setIdentity();
976 globalToLocalPredJacobian(Trk::locX, Trk::locX) = 1.0;
977 globalToLocalPredJacobian(Trk::locY, Trk::locY) = 1.0;
978 globalToLocalPredJacobian(Trk::
phi, Trk::
phi) = globalToLocalPredAnglesJacobian(0, 0);
979 globalToLocalPredJacobian(Trk::
theta, Trk::
theta) = globalToLocalPredAnglesJacobian(1, 1);
980 globalToLocalPredJacobian(Trk::
theta, Trk::
phi) =
981 globalToLocalPredAnglesJacobian(0, 1);
982 globalToLocalPredJacobian(Trk::
phi, Trk::
theta) = globalToLocalPredJacobian(Trk::
theta, Trk::
phi);
983 globalToLocalPredJacobian(Trk::qOverP, Trk::qOverP) = 1.0;
984 const
AmgSymMatrix(5)& globalPredCovar = *exMeasPars->covariance();
985 localPredCovar = globalPredCovar.
similarity(globalToLocalPredJacobian);
986 }
987
988 if (info.haveAngleXError && info.haveAngleYError && info.havePosXError && info.havePosYError) {
989
990 info.measuredCovariance = measErrors.block<4, 4>(0, 0);
991 info.predictionCovariance = localPredCovar.block<4, 4>(0, 0);
992 info.totalCovariance =
info.measuredCovariance +
info.predictionCovariance;
993
994
999
1000
1006 info.diffVector = diffVec;
1007
1008
1010 info.matchChiSquared =
info.diffVector.transpose() * weightMatrix *
info.diffVector;
1011 info.haveMatchChiSquared =
true;
1012
1013
1018
1019 info.posXTotalErr2 +=
info.posXPredErr2;
1020 info.posYTotalErr2 +=
info.posYPredErr2;
1021 info.angleXTotalErr2 +=
info.angleXPredErr2;
1022 info.angleYTotalErr2 +=
info.angleYPredErr2;
1027
1028 }
else if (
info.haveAngleYError &&
info.havePosYError) {
1029
1030
1031
1032
1037 predCovar(0, 1) = predCovar(1, 0);
1038 info.predictionCovariance = predCovar;
1039
1040
1042 measCovar.setIdentity();
1046 measCovar(0, 1) = measCovar(1, 0);
1047
1048 info.measuredCovariance = measCovar;
1049 info.totalCovariance =
info.predictionCovariance +
info.measuredCovariance;
1050
1053 if (std::abs(
info.totalCovariance.determinant()) <
1054 std::numeric_limits<float>::epsilon()){
1056 return;
1057 }
1058
1060 diffVec[0] =
info.localPosYDiff;
1061 diffVec[1] =
info.localAngleYDiff;
1062 info.diffVector = diffVec;
1063
1064
1066 info.matchChiSquared =
info.diffVector.transpose() * weightMatrix *
info.diffVector;
1067 info.haveMatchChiSquared =
true;
1068
1069
1074
1075 info.posYTotalErr2 +=
info.posYPredErr2;
1076 info.angleYTotalErr2 +=
info.angleYPredErr2;
1079
1080 } else {
1082 }
1083
1084 } else {
1086
1087
1088
1089
1090
1091 }
1092
1093 }
Scalar perp() const
perp method - perpendicular length
Scalar phi() const
phi method
Scalar theta() const
theta method
Matrix< Scalar, OtherDerived::RowsAtCompileTime, OtherDerived::RowsAtCompileTime > similarity(const MatrixBase< OtherDerived > &m) const
similarity method : yields ms = m*s*m^T
#define ATH_MSG_WARNING(x)
#define AmgSymMatrix(dim)
void getInitializedCache(MagField::AtlasFieldCache &cache) const
get B field cache for evaluation as a function of 2-d or 3-d position.
DataModel_detail::const_iterator< DataVector > 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.
bool is_valid() const
Check if id is in a valid state.
double angleXZ() const
access method for angle of local XZ projection
double angleYZ() const
access method for angle of local YZ projection
const Amg::Vector3D & position() const
Access method for the position.
virtual const Surface & associatedSurface() const override=0
Access to the Surface associated to the Parameters.
const Amg::Transform3D & transform() const
Returns HepGeom::Transform3D by reference.
std::string toString(const Translation3D &translation, int precision=4)
GeoPrimitvesToStringConverter.
Eigen::Matrix< double, Eigen::Dynamic, Eigen::Dynamic > MatrixX
Dynamic Matrix - dynamic allocation.
float distance(const Amg::Vector3D &p1, const Amg::Vector3D &p2)
calculates the distance between two point in 3D space
Eigen::Matrix< double, 3, 1 > Vector3D
Eigen::Matrix< double, Eigen::Dynamic, 1 > VectorX
Dynamic Vector - dynamic allocation.
StIndex
enum to classify the different station layers in the muon spectrometer
DataVector< const Trk::TrackStateOnSurface > TrackStates
ParametersBase< TrackParametersDim, Charged > TrackParameters