51 template <
typename outlier_finder_t = Vo
idOutlierFinder>
72 std::reference_wrapper<const MagneticFieldContext> mctx,
73 std::reference_wrapper<const CalibrationContext> cctx,
77 const Surface* rSurface =
nullptr,
78 bool mScattering =
true,
bool eLoss =
true,
79 bool bwdFiltering =
false)
92 std::reference_wrapper<const GeometryContext>
geoContext;
120 template <
typename source_link_t>
191 template <
typename propagator_t,
typename updater_t = VoidKalmanUpdater,
192 typename smoother_t = VoidKalmanSmoother,
193 typename outlier_finder_t = VoidOutlierFinder,
194 typename calibrator_t = VoidMeasurementCalibrator>
224 template <
typename source_link_t,
typename parameters_t>
253 template <
typename propagator_state_t,
typename stepper_t>
256 const auto& logger = state.options.logger;
274 if (result.
reset and state.navigation.navSurfaceIter ==
275 state.navigation.navSurfaces.end()) {
278 state.navigation.navigationStage =
279 KalmanNavigator::Stage::layerTarget;
282 result.
reset =
false;
287 auto surface = state.navigation.currentSurface;
298 ACTS_VERBOSE(
"Perform forward filter step with surface ");
302 ACTS_ERROR(
"Error in forward filter: " << res.error());
303 result.
result = res.error();
305 }
else if (state.stepping.navDir ==
backward and
310 ACTS_ERROR(
"Error in backward filter: " << res.error());
311 result.
result = res.error();
320 if (state.stepping.navDir ==
forward) {
323 state.navigation.navigationBreak)) {
331 reverse(state, stepper, result);
338 auto res =
finalize(state, stepper, result);
340 ACTS_ERROR(
"Error in finalize: " << res.error());
341 result.
result = res.error();
357 "The target surface needed for aborting backward propagation "
363 "No target surface set. Completing without fitted track "
371 auto fittedState = stepper.boundState(state.stepping, *
targetSurface);
378 result.
trackTip, [&](
auto trackState) {
379 auto fSurface = &trackState.referenceSurface();
380 auto surface_it = std::find_if(
383 [=](
const Surface*
s) {
return s == fSurface; });
387 trackState.data().ismoothed =
406 template <
typename propagator_state_t,
typename stepper_t>
407 void reverse(propagator_state_t& state, stepper_t&
stepper,
413 state.options.maxStepSize = -1.0 * state.options.maxStepSize;
415 state.options.pathLimit = -1.0 * state.options.pathLimit;
419 state.navigation =
typename propagator_t::NavigatorState();
423 state.navigation.startSurface = &st.referenceSurface();
424 if (state.navigation.startSurface->associatedLayer() !=
nullptr) {
425 state.navigation.startLayer =
426 state.navigation.startSurface->associatedLayer();
429 state.navigation.startVolume =
430 state.navigation.startLayer->trackingVolume();
431 state.navigation.targetSurface = targetSurface;
432 state.navigation.currentSurface = state.navigation.startSurface;
433 state.navigation.currentVolume = state.navigation.startVolume;
436 stepper.resetState(state.stepping, st.filtered(),
437 st.filteredCovariance(), st.referenceSurface(),
438 backward, state.options.maxStepSize);
441 st.smoothed() = st.filtered();
442 st.smoothedCovariance() = st.filteredCovariance();
447 materialInteractor(state.navigation.currentSurface, state, stepper);
464 template <
typename propagator_state_t,
typename stepper_t>
467 const auto& logger = state.options.logger;
469 auto sourcelink_it = inputMeasurements.find(surface);
470 if(sourcelink_it != inputMeasurements.end()){
473 ACTS_VERBOSE(
"Couldn't find source link in measurement list");
475 if (sourcelink_it != inputMeasurements.end()) {
482 stepper.boundState(state.stepping, *surface);
485 materialInteractor(surface, state, stepper,
preUpdate);
490 TrackStatePropMask::All, result.
trackTip);
493 auto trackStateProxy =
497 trackStateProxy.uncalibrated() = sourcelink_it->second;
500 trackStateProxy.predicted() = std::move(boundParams.parameters());
501 trackStateProxy.predictedCovariance() =
502 std::move(*boundParams.covariance());
503 trackStateProxy.jacobian() = std::move(jacobian);
504 trackStateProxy.pathLength() = std::move(
pathLength);
509 [&](
const auto& calibrated) {
510 trackStateProxy.setCalibrated(calibrated);
512 m_calibrator(trackStateProxy.uncalibrated(),
513 trackStateProxy.predicted()));
516 auto& typeFlags = trackStateProxy.typeFlags();
524 if (not m_outlierFinder(trackStateProxy)) {
527 m_updater(state.geoContext, trackStateProxy,
forward);
528 if (!updateRes.ok()) {
529 ACTS_ERROR(
"Update step failed: " << updateRes.error());
530 return updateRes.error();
535 ACTS_VERBOSE(
"Filtering step successful, updated parameters are : \n"
536 << trackStateProxy.filtered().transpose());
538 stepper.update(state.stepping,
540 state.options.geoContext, trackStateProxy),
541 trackStateProxy.filteredCovariance());
546 "Filtering step successful. But measurement is deterimined "
548 "be an outlier. Stepping state is not updated.")
554 materialInteractor(surface, state, stepper,
postUpdate);
565 ~(TrackStatePropMask::Uncalibrated |
566 TrackStatePropMask::Calibrated | TrackStatePropMask::Filtered),
570 auto trackStateProxy =
574 trackStateProxy.setReferenceSurface(surface->
getSharedPtr());
577 auto& typeFlags = trackStateProxy.typeFlags();
591 stepper.boundState(state.stepping, *surface);
594 trackStateProxy.predicted() = std::move(boundParams.parameters());
595 trackStateProxy.predictedCovariance() =
596 std::move(*boundParams.covariance());
597 trackStateProxy.jacobian() = std::move(jacobian);
598 trackStateProxy.pathLength() = std::move(
pathLength);
604 auto [curvilinearParams, jacobian,
pathLength] =
605 stepper.curvilinearState(state.stepping);
608 trackStateProxy.predicted() =
609 std::move(curvilinearParams.parameters());
610 trackStateProxy.predictedCovariance() =
611 std::move(*curvilinearParams.covariance());
612 trackStateProxy.jacobian() = std::move(jacobian);
613 trackStateProxy.pathLength() = std::move(
pathLength);
618 trackStateProxy.data().ifiltered = trackStateProxy.data().ipredicted;
625 materialInteractor(surface, state, stepper,
fullUpdate);
639 template <
typename propagator_state_t,
typename stepper_t>
641 propagator_state_t& state,
644 const auto& logger = state.options.logger;
646 auto sourcelink_it = inputMeasurements.find(surface);
647 if (sourcelink_it != inputMeasurements.end()) {
651 <<
" detected in backward propagation.");
655 if (state.stepping.navDir ==
backward and
656 surface == state.navigation.startSurface) {
657 materialInteractor(surface, state, stepper);
663 stepper.boundState(state.stepping, *surface);
666 materialInteractor(surface, state, stepper,
preUpdate);
670 result.
fittedStates.addTrackState(TrackStatePropMask::All);
673 auto trackStateProxy = result.
fittedStates.getTrackState(tempTrackTip);
676 trackStateProxy.uncalibrated() = sourcelink_it->second;
679 trackStateProxy.predicted() = std::move(boundParams.parameters());
680 trackStateProxy.predictedCovariance() =
681 std::move(*boundParams.covariance());
682 trackStateProxy.jacobian() = std::move(jacobian);
683 trackStateProxy.pathLength() = std::move(
pathLength);
688 [&](
const auto& calibrated) {
689 trackStateProxy.setCalibrated(calibrated);
691 m_calibrator(trackStateProxy.uncalibrated(),
692 trackStateProxy.predicted()));
696 m_updater(state.geoContext, trackStateProxy,
backward, logger);
697 if (!updateRes.ok()) {
698 ACTS_ERROR(
"Backward update step failed: " << updateRes.error());
699 return updateRes.error();
703 "Backward Filtering step successful, updated parameters are : "
705 << trackStateProxy.filtered().transpose());
709 result.
trackTip, [&](
auto trackState) {
710 auto fSurface = &trackState.referenceSurface();
711 if (fSurface == surface) {
713 trackState.smoothed() = trackStateProxy.filtered();
714 trackState.smoothedCovariance() =
715 trackStateProxy.filteredCovariance();
724 stepper.update(state.stepping,
726 state.options.geoContext, trackStateProxy),
727 trackStateProxy.filteredCovariance());
730 materialInteractor(surface, state, stepper,
postUpdate);
732 }
else if (
surface->surfaceMaterial() !=
nullptr) {
734 if (
surface->associatedDetectorElement() !=
nullptr) {
736 <<
" in backward filtering");
737 if (state.stepping.covTransport) {
742 <<
surface->geometryId() <<
" in backward filtering");
743 if (state.stepping.covTransport) {
744 stepper.covarianceTransport(state.stepping);
750 state.stepping.jacobian = BoundMatrix::Identity();
756 return Result<void>::success();
769 template <
typename propagator_state_t,
typename stepper_t>
770 void materialInteractor(
773 const auto& logger = state.options.logger;
775 bool hasMaterial =
false;
793 <<
" at update stage: " << updateStage <<
" are :");
795 << interaction.
Eloss <<
", "
796 <<
"variancePhi = " << interaction.
variancePhi <<
", "
806 if (not hasMaterial) {
809 <<
" at update stage: "
822 template <
typename propagator_state_t,
typename stepper_t>
825 const auto& logger = state.options.logger;
830 std::vector<size_t> measurementIndices;
838 measurementIndices.emplace_back(st.index());
839 }
else if (measurementIndices.empty()) {
842 st.data().ismoothed = detail_lt::IndexData::kInvalid;
845 if (not measurementIndices.empty()) {
851 if (measurementIndices.empty()) {
852 ACTS_ERROR(
"Smoothing for a track without measurements.");
853 return KalmanFitterError::SmoothFailed;
858 <<
" filtered track states.");
862 auto smoothRes = m_smoother(state.geoContext, result.fittedStates,
863 measurementIndices.front(), logger);
864 if (!smoothRes.ok()) {
865 ACTS_ERROR(
"Smoothing step failed: " << smoothRes.error());
866 return smoothRes.error();
869 auto firstMeasurement =
870 result.fittedStates.getTrackState(measurementIndices.back());
874 "Smoothing successful, updating stepping state, "
875 "set target surface.");
878 state.options.geoContext, firstMeasurement),
879 firstMeasurement.smoothedCovariance());
881 state.stepping.stepSize =
882 ConstrainedStep(-1. * state.options.maxStepSize);
885 state.stepping.pathAccumulated = 0.;
887 return Result<void>::success();
906 template <
typename source_link_t,
typename parameters_t>
912 template <
typename propagator_state_t,
typename stepper_t,
914 bool operator()(propagator_state_t& ,
const stepper_t& ,
915 const result_t& result)
const {
916 if (!result.result.ok() or result.finished) {
941 template <
typename source_link_t,
typename start_parameters_t,
943 auto fit(
const std::vector<source_link_t>& sourcelinks,
944 const start_parameters_t& sParameters,
948 const auto& logger = kfOptions.logger;
950 static_assert(SourceLinkConcept<source_link_t>,
951 "Source link does not fulfill SourceLinkConcept");
955 ACTS_VERBOSE(
"Preparing " << sourcelinks.size() <<
" input measurements");
956 std::map<const Surface*, source_link_t> inputMeasurements;
957 for (
const auto& sl : sourcelinks) {
958 const Surface* srf = &sl.referenceSurface();
961 inputMeasurements.emplace(srf, sl);
967 using KalmanResult =
typename KalmanActor::result_type;
973 kfOptions.geoContext, kfOptions.magFieldContext, logger);
979 auto& kalmanActor = kalmanOptions.
actionList.template get<KalmanActor>();
980 kalmanActor.inputMeasurements = std::move(inputMeasurements);
981 kalmanActor.targetSurface = kfOptions.referenceSurface;
982 kalmanActor.multipleScattering = kfOptions.multipleScattering;
983 kalmanActor.energyLoss = kfOptions.energyLoss;
984 kalmanActor.backwardFiltering = kfOptions.backwardFiltering;
987 kalmanActor.m_outlierFinder = kfOptions.outlierFinder;
990 auto result = m_propagator.template propagate(sParameters, kalmanOptions);
994 return result.error();
997 const auto& propRes = *result;
1000 auto kalmanResult = propRes.template get<KalmanResult>();
1004 if (kalmanResult.result.ok() and not kalmanResult.processedStates) {
1005 kalmanResult.result =
Result<void>(KalmanFitterError::NoMeasurementFound);
1008 if (!kalmanResult.result.ok()) {
1009 ACTS_VERBOSE(
"KalmanFilter failed: " << kalmanResult.result.error());
1010 return kalmanResult.result.error();
1014 return kalmanResult;
1035 template <
typename source_link_t,
typename start_parameters_t,
1037 auto fit(
const std::vector<source_link_t>& sourcelinks,
1038 const start_parameters_t& sParameters,
1040 const std::vector<const Surface*>& sSequence)
const
1043 const auto& logger = kfOptions.logger;
1044 static_assert(SourceLinkConcept<source_link_t>,
1045 "Source link does not fulfill SourceLinkConcept");
1049 ACTS_VERBOSE(
"Preparing " << sourcelinks.size() <<
" input measurements");
1050 std::map<const Surface*, source_link_t> inputMeasurements;
1051 for (
const auto& sl : sourcelinks) {
1052 const Surface* srf = &sl.referenceSurface();
1053 inputMeasurements.emplace(srf, sl);
1059 using KalmanResult =
typename KalmanActor::result_type;
1065 kfOptions.geoContext, kfOptions.magFieldContext, logger);
1071 auto& kalmanActor = kalmanOptions.
actionList.template get<KalmanActor>();
1072 kalmanActor.inputMeasurements = std::move(inputMeasurements);
1073 kalmanActor.targetSurface = kfOptions.referenceSurface;
1074 kalmanActor.multipleScattering = kfOptions.multipleScattering;
1075 kalmanActor.energyLoss = kfOptions.energyLoss;
1076 kalmanActor.backwardFiltering = kfOptions.backwardFiltering;
1078 kalmanActor.m_outlierFinder = kfOptions.outlierFinder;
1081 auto& dInitializer =
1082 kalmanOptions.
actionList.template get<DirectNavigator::Initializer>();
1083 dInitializer.navSurfaces = sSequence;
1086 auto result = m_propagator.template propagate(sParameters, kalmanOptions);
1089 ACTS_ERROR(
"Propapation failed: " << result.error());
1090 return result.error();
1093 const auto& propRes = *result;
1096 auto kalmanResult = propRes.template get<KalmanResult>();
1100 if (kalmanResult.result.ok() and not kalmanResult.processedStates) {
1101 kalmanResult.result =
Result<void>(KalmanFitterError::NoMeasurementFound);
1104 if (!kalmanResult.result.ok()) {
1105 ACTS_ERROR(
"KalmanFilter failed: " << kalmanResult.result.error());
1106 return kalmanResult.result.error();
1110 return kalmanResult;