384 if (
msgLvl(MSG::DEBUG))
msg(MSG::DEBUG) << MSG::DEBUG <<
"track segment match:";
390 double closestSegmentDist = 1E9;
391 std::vector<MuPatSegment*>::const_iterator itS = info.MCTBTrack->segments().begin(), itS_end = info.MCTBTrack->segments().end();
392 for (; itS != itS_end; ++itS) {
395 (info.MCTBSegment->entryPars().position() - (*itS)->entryPars().position()).dot((*itS)->entryPars().momentum().unit());
397 if (std::abs(dist) < std::abs(closestSegmentDist)) {
398 closestSegmentDist = dist;
399 closestSegment = *itS;
403 if (!closestSegment) {
408 if (cuts.useTightCuts) {
415 msg(MSG::DEBUG) << MSG::DEBUG <<
" -> Passed";
417 msg(MSG::DEBUG) << MSG::DEBUG <<
" -> Failed";
419 msg(MSG::DEBUG) <<
" segment match between segment-on-track "
424 info.trackChamberId = closestSegment->
chid;
430 if (
msgLvl(MSG::VERBOSE)) {
431 msg(MSG::DEBUG) << MSG::VERBOSE << std::fixed;
432 if (info.havePosXError) {
433 double diff = info.localPosXDiff;
434 double totErr = std::sqrt(info.posXTotalErr2);
435 double pull = totErr != 0.0 ?
diff / totErr : 0.0;
436 msg(MSG::DEBUG) << std::endl
437 << std::setprecision(3) <<
"deltaPosX =" << std::setw(8) <<
diff <<
" +- " << std::left << std::setw(8)
438 << totErr << std::right << std::setprecision(2) <<
" pull=" << std::setw(5) << pull << std::setprecision(3)
439 <<
" (align=" <<
m_alignErrorPosX <<
" meas=" << std::sqrt(info.posXMeasErr2)
440 <<
" pred=" << std::sqrt(info.posXPredErr2) <<
")";
442 if (info.havePosYError) {
443 double diff = info.localPosYDiff;
444 double totErr = std::sqrt(info.posYTotalErr2);
445 double pull = totErr != 0.0 ?
diff / totErr : 0.0;
446 msg(MSG::DEBUG) << std::endl
447 << std::setprecision(3) <<
"deltaPosY =" << std::setw(8) <<
diff <<
" +- " << std::left << std::setw(8)
448 << totErr << std::right << std::setprecision(2) <<
" pull=" << std::setw(5) << pull
449 <<
" (align=" <<
m_alignErrorPosY <<
" meas=" << std::sqrt(info.posYMeasErr2)
450 <<
" pred=" << std::sqrt(info.posYPredErr2) <<
")";
452 if (info.haveAngleXError) {
453 double diff = info.localAngleXDiff;
454 double totErr = std::sqrt(info.angleXTotalErr2);
455 double pull = totErr != 0.0 ?
diff / totErr : 0.0;
456 msg(MSG::DEBUG) << std::endl
457 << std::setprecision(5) <<
"deltaAngleX=" << std::setw(8) <<
diff <<
" +- " << std::left << std::setw(8)
458 << totErr << std::right << std::setprecision(2) <<
" pull=" << std::setw(5) << pull << std::setprecision(5)
460 <<
" pred=" << std::sqrt(info.angleXPredErr2) <<
")";
462 if (info.haveAngleYError) {
463 double diff = info.localAngleYDiff;
464 double totErr = std::sqrt(info.angleYTotalErr2);
465 double pull = totErr != 0.0 ?
diff / totErr : 0.0;
466 msg(MSG::DEBUG) << std::endl
467 << std::setprecision(5) <<
"deltaAngleY=" << std::setw(8) <<
diff <<
" +- " << std::left << std::setw(8)
468 << totErr << std::right << std::setprecision(2) <<
" pull=" << std::setw(5) << pull << std::setprecision(5)
470 <<
" pred=" << std::sqrt(info.angleYPredErr2) <<
")";
473 msg(MSG::DEBUG) << std::endl << std::setprecision(5) <<
"Difference vector:" << info.diffVector;
474 msg(MSG::DEBUG) << printCovCorr(info.measuredCovariance,
"Measured") << printCovCorr(info.predictionCovariance,
"Predicted")
475 << printCovCorr(info.totalCovariance,
"Total") <<
"Match chi-squared: " << info.matchChiSquared
476 <<
" sqrt=" << std::sqrt(info.matchChiSquared);
479 if (info.havePosXError || info.havePosYError || info.haveAngleXError || info.haveAngleYError) {
msg(MSG::DEBUG) << std::endl; }
489 double scaledPosXErr2 = cuts.posXPullCut * cuts.posXPullCut * info.posXTotalErr2;
492 if (cuts.cutOnPosX && info.havePosX) {
493 double posXCut2 = cuts.posXCut * cuts.posXCut + scaledPosXErr2;
494 if (info.localPosXDiff * info.localPosXDiff > posXCut2) {
496 msg(MSG::DEBUG) << MSG::DEBUG <<
" -> Failed "
498 <<
" X position cut: " << info.localPosXDiff <<
" > " << std::sqrt(posXCut2) <<
endmsg;
506 double scaledPosYErr2 = cuts.posYPullCut * cuts.posYPullCut * info.posYTotalErr2;
509 if (cuts.cutOnPosY && info.havePosY) {
510 double posYCut2 = cuts.posYCut * cuts.posYCut + scaledPosYErr2;
511 if (info.localPosYDiff * info.localPosYDiff > posYCut2) {
513 msg(MSG::DEBUG) << MSG::DEBUG <<
" -> Failed "
515 <<
" Y position cut: " << info.localPosYDiff <<
" > " << std::sqrt(posYCut2) <<
endmsg;
524 if (cuts.cutOnPosXPull && info.havePosX && info.posXTotalErr2 > 0.0) {
525 if (info.localPosXDiff * info.localPosXDiff > scaledPosXErr2) {
527 double pull = info.localPosXDiff / std::sqrt(info.posXTotalErr2);
528 msg(MSG::DEBUG) << MSG::DEBUG <<
" -> Failed "
530 <<
" X position pull cut: |" << pull <<
"| > " << cuts.posXPullCut <<
endmsg;
539 if (cuts.cutOnPosYPull && info.havePosY && info.posYTotalErr2 > 0.0) {
540 if (info.localPosYDiff * info.localPosYDiff > scaledPosYErr2) {
542 double pull = info.localPosYDiff / std::sqrt(info.posYTotalErr2);
543 msg(MSG::DEBUG) << MSG::DEBUG <<
" -> Failed "
545 <<
" Y position pull cut: |" << pull <<
"| > " << cuts.posYPullCut <<
endmsg;
556 double scaledAngleXErr2 = cuts.angleXPullCut * cuts.angleXPullCut * info.angleXTotalErr2;
559 if (cuts.cutOnAngleX && info.haveAngleX) {
560 double angleXCut2 = cuts.angleXCut * cuts.angleXCut + scaledAngleXErr2;
561 if (info.localAngleXDiff * info.localAngleXDiff > angleXCut2) {
563 msg(MSG::DEBUG) << MSG::DEBUG <<
" -> Failed "
565 <<
" X angle cut: " << info.localAngleXDiff <<
" > " << std::sqrt(angleXCut2) <<
endmsg;
573 double scaledAngleYErr2 = cuts.angleYPullCut * cuts.angleYPullCut * info.angleYTotalErr2;
576 if (cuts.cutOnAngleY && info.haveAngleY) {
577 double angleYCut2 = cuts.angleYCut * cuts.angleYCut + scaledAngleYErr2;
578 if (info.localAngleYDiff * info.localAngleYDiff > angleYCut2) {
580 msg(MSG::DEBUG) << MSG::DEBUG <<
" -> Failed "
582 <<
" Y angle cut: " << info.localAngleYDiff <<
" > " << std::sqrt(angleYCut2) <<
endmsg;
591 if (cuts.cutOnAngleXPull && info.haveAngleX && info.angleXTotalErr2 > 0.0) {
592 if (info.localAngleXDiff * info.localAngleXDiff > scaledAngleXErr2) {
594 double pull = info.localAngleXDiff / std::sqrt(info.angleXTotalErr2);
595 msg(MSG::DEBUG) << MSG::DEBUG <<
" -> Failed "
597 <<
" X angle pull cut: |" << pull <<
"| > " << cuts.angleXPullCut <<
endmsg;
605 if (cuts.cutOnAngleYPull && info.haveAngleY && info.angleYTotalErr2 > 0.0) {
607 if (info.localAngleYDiff * info.localAngleYDiff > scaledAngleYErr2) {
609 double pull = info.localAngleYDiff / std::sqrt(info.angleYTotalErr2);
610 msg(MSG::DEBUG) << MSG::DEBUG <<
" -> Failed "
612 <<
" Y angle pull cut: |" << pull <<
"| > " << cuts.angleYPullCut <<
endmsg;
623 if (cuts.cutOnMatchChiSquared && info.haveMatchChiSquared) {
625 if (info.matchChiSquared > cuts.matchChiSquaredCut) {
627 msg(MSG::DEBUG) << MSG::DEBUG <<
" -> Failed "
629 <<
" match chi-squared cut: " << info.matchChiSquared <<
" > " << cuts.matchChiSquaredCut <<
endmsg;
642 info.matchOK =
false;
644 if (info.appliedAnyCut()) {
645 if (info.passedAllCuts()) {
648 if (
msgLvl(MSG::DEBUG))
msg(MSG::DEBUG) << MSG::DEBUG <<
" -> Passed all cuts";
652 if (
msgLvl(MSG::DEBUG))
msg(MSG::DEBUG) << MSG::DEBUG <<
" -> Passed match chi-quared cut";
659 if (
msgLvl(MSG::DEBUG))
msg(MSG::DEBUG) << MSG::DEBUG <<
" -> Passed cuts " << info.passedCutsString();
660 if (
msgLvl(MSG::DEBUG))
msg(MSG::DEBUG) << MSG::DEBUG <<
" -> Failed cuts " << info.failedCutsString();
663 if (
msgLvl(MSG::DEBUG))
msg(MSG::DEBUG) << MSG::DEBUG <<
" -> Failed cuts " << info.failedCutsString();
668 if (
msgLvl(MSG::DEBUG)) {
msg(MSG::DEBUG) << MSG::DEBUG <<
". No cuts applied"; }
674 msg(MSG::DEBUG) << MSG::DEBUG <<
" -> Accepted because " << info.reasonString() <<
endmsg;
676 msg(MSG::DEBUG) << MSG::DEBUG <<
" -> Rejected because " << info.reasonString() <<
endmsg;
686 info.MCTBTrack = &entry1;
687 info.MCTBSegment = &entry2;
688 info.track = &entry1.
track();
690 info.segmentChamberId = entry2.
chid;
692 ATH_MSG_WARNING(__FUNCTION__ <<
" entry2 does not have segment pointer.");
697 bool hasStereoAngle =
false;
701 double closestParsDist = 1E9;
703 double closestMeasParsDist = 1E9;
706 double closestIdDist = 1E9;
707 bool trackHasPhi =
true;
714 if (fieldCondObj ==
nullptr) {
724 for (; tit != tit_end; ++tit) {
745 if (!pars) {
continue; }
750 if (std::abs(dist) < std::abs(closestParsDist)) {
752 closestParsDist = dist;
754 if (pars->covariance()) {
755 closestMeasParsDist = dist;
756 closestMeasPars = pars;
760 if (std::abs(dist) < std::abs(closestIdDist)) {
763 closestIdDist = dist;
769 if (entry1.
phiHits().size() > 1) {
776 double distance = entry1.
hasEndcap() ? fabs(globalDistance.z()) : globalDistance.perp();
778 if (distance > 500) trackHasPhi =
true;
782 ATH_MSG_DEBUG(
"track-segment match: No closest track parameters found.");
788 if (closestPars && closestId.
is_valid()) { info.trackChamberId =
m_idHelperSvc->chamberId(closestId); }
790 if (
msgLvl(MSG::VERBOSE)) {
791 msg(MSG::DEBUG) << MSG::VERBOSE <<
"match Closest chamber: " <<
m_idHelperSvc->toStringChamber(info.trackChamberId)
792 <<
" Segment: " <<
m_idHelperSvc->toStringChamber(info.segmentChamberId);
794 if (closestMeasPars) tmpPars = closestMeasPars->covariance() ? closestMeasPars :
nullptr;
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;
800 if (!tmpPars || tmpPars != closestPars) {
801 msg(MSG::DEBUG) << std::endl
802 <<
"Closest track parameters : " <<
m_printer->print(*closestPars)
803 <<
" distance=" << closestParsDist;
808 bool straightLineMatch = !fieldCache.
toroidOn();
809 if (hasStereoAngle && !trackHasPhi && (straightLineMatch || entry1.
hasMomentum())) {
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)) &&
822 straightLineMatch =
true;
825 <<
" => doing straight line extrapolation match");
834 std::unique_ptr<const Trk::TrackParameters> exPars;
836 if (closestMeasPars) {
837 const Trk::TrackParameters* tmpPars = closestMeasPars->covariance() ? closestMeasPars :
nullptr;
845 int trackSector =
m_idHelperSvc->sector(info.trackChamberId);
846 int segmentSector =
m_idHelperSvc->sector(info.segmentChamberId);
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 ");
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;
876 exMeasPars = exPars->covariance() ? exPars.get() :
nullptr;
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 "
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;
912 if (posXMeasErr2 <= 999.0) {
913 info.havePosX =
true;
914 info.havePosXError =
true;
915 info.posXMeasErr2 = posXMeasErr2;
916 info.posXTotalErr2 += posXMeasErr2;
920 if (info.posYMeasErr2 <= 999.0) {
921 info.havePosY =
true;
922 info.havePosYError =
true;
923 info.posYMeasErr2 = posYMeasErr2;
924 info.posYTotalErr2 += posYMeasErr2;
928 if (phiMeasErr2 <= 999.0) {
929 info.haveAngleX =
true;
930 info.haveAngleXError =
true;
931 info.angleXMeasErr2 = phiMeasErr2;
932 info.angleXTotalErr2 += phiMeasErr2;
934 if (thetaMeasErr2 <= 999.0) {
935 info.haveAngleY =
true;
936 info.haveAngleYError =
true;
937 info.angleYMeasErr2 = thetaMeasErr2;
938 info.angleYTotalErr2 += thetaMeasErr2;
943 info.haveAngleXError =
false;
944 info.haveAngleYError =
false;
945 info.havePosXError =
false;
946 info.havePosYError =
false;
960 info.localAngleXDiff = phi_diff(locDirEx.
angleXZ() - locDirSeg.
angleXZ());
961 info.localAngleYDiff = theta_diff(locDirEx.
angleYZ() - locDirSeg.
angleYZ());
964 localPredCovar.setIdentity();
966 if (info.haveAngleXError || info.haveAngleYError || info.havePosXError || info.havePosYError) {
975 globalToLocalPredJacobian.setIdentity();
978 globalToLocalPredJacobian(
Trk::phi,
Trk::phi) = globalToLocalPredAnglesJacobian(0, 0);
981 globalToLocalPredAnglesJacobian(0, 1);
984 const AmgSymMatrix(5)& globalPredCovar = *exMeasPars->covariance();
985 localPredCovar = globalPredCovar.similarity(globalToLocalPredJacobian);
988 if (info.haveAngleXError && info.haveAngleYError && info.havePosXError && info.havePosYError) {
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;
1006 info.diffVector = diffVec;
1009 Amg::MatrixX weightMatrix = info.totalCovariance.inverse();
1010 info.matchChiSquared = info.diffVector.transpose() * weightMatrix * info.diffVector;
1011 info.haveMatchChiSquared =
true;
1019 info.posXTotalErr2 += info.posXPredErr2;
1020 info.posYTotalErr2 += info.posYPredErr2;
1021 info.angleXTotalErr2 += info.angleXPredErr2;
1022 info.angleYTotalErr2 += info.angleYPredErr2;
1028 }
else if (info.haveAngleYError && info.havePosYError) {
1037 predCovar(0, 1) = predCovar(1, 0);
1038 info.predictionCovariance = predCovar;
1042 measCovar.setIdentity();
1046 measCovar(0, 1) = measCovar(1, 0);
1048 info.measuredCovariance = measCovar;
1049 info.totalCovariance = info.predictionCovariance + info.measuredCovariance;
1053 if (std::abs(info.totalCovariance.determinant()) <
1054 std::numeric_limits<float>::epsilon()){
1060 diffVec[0] = info.localPosYDiff;
1061 diffVec[1] = info.localAngleYDiff;
1062 info.diffVector = diffVec;
1065 Amg::MatrixX weightMatrix = info.totalCovariance.inverse();
1066 info.matchChiSquared = info.diffVector.transpose() * weightMatrix * info.diffVector;
1067 info.haveMatchChiSquared =
true;
1075 info.posYTotalErr2 += info.posYPredErr2;
1076 info.angleYTotalErr2 += info.angleYPredErr2;