From 0ad06d5f8b625c17aa1f3e29b7187e64c96c94ac Mon Sep 17 00:00:00 2001 From: Xiaocong Ai <xiaocong.ai@cern.ch> Date: Tue, 25 Jun 2024 00:03:24 +0200 Subject: [PATCH] update KalmanFitterTool --- .../src/FaserActsTrack.h | 24 + .../src/KalmanFitterTool.cxx | 568 ++++++++++-------- .../src/KalmanFitterTool.h | 75 ++- .../src/TrackFittingFunction.cxx | 3 +- 4 files changed, 387 insertions(+), 283 deletions(-) create mode 100644 Tracking/Acts/FaserActsKalmanFilter/src/FaserActsTrack.h diff --git a/Tracking/Acts/FaserActsKalmanFilter/src/FaserActsTrack.h b/Tracking/Acts/FaserActsKalmanFilter/src/FaserActsTrack.h new file mode 100644 index 000000000..59191a18c --- /dev/null +++ b/Tracking/Acts/FaserActsKalmanFilter/src/FaserActsTrack.h @@ -0,0 +1,24 @@ +// Copyright (C) 2019-2020 CERN for the benefit of the Acts project +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#pragma once + +#include "Acts/EventData/TrackContainer.hpp" +#include "Acts/EventData/TrackParameters.hpp" +#include "Acts/EventData/VectorMultiTrajectory.hpp" +#include "Acts/EventData/VectorTrackContainer.hpp" + +#include <vector> + + +using FaserActsTrackContainer = + Acts::TrackContainer<Acts::VectorTrackContainer, + Acts::VectorMultiTrajectory, std::shared_ptr>; + +using FaserActsConstTrackContainer = + Acts::TrackContainer<Acts::ConstVectorTrackContainer, + Acts::ConstVectorMultiTrajectory, std::shared_ptr>; + diff --git a/Tracking/Acts/FaserActsKalmanFilter/src/KalmanFitterTool.cxx b/Tracking/Acts/FaserActsKalmanFilter/src/KalmanFitterTool.cxx index 5315404c7..c15b29566 100644 --- a/Tracking/Acts/FaserActsKalmanFilter/src/KalmanFitterTool.cxx +++ b/Tracking/Acts/FaserActsKalmanFilter/src/KalmanFitterTool.cxx @@ -1,6 +1,7 @@ #include "KalmanFitterTool.h" #include "FaserActsGeometry/FASERMagneticFieldWrapper.h" +#include "FaserActsKalmanFilter/IndexSourceLink.h" #include "Acts/Propagator/EigenStepper.hpp" #include "Acts/Propagator/Navigator.hpp" @@ -21,9 +22,8 @@ StatusCode KalmanFitterTool::initialize() { ATH_CHECK(m_trackingGeometryTool.retrieve()); ATH_CHECK(m_createTrkTrackTool.retrieve()); ATH_CHECK(detStore()->retrieve(m_idHelper,"FaserSCT_ID")); - if (m_statesWriter && !m_noDiagnostics) ATH_CHECK(m_trajectoryStatesWriterTool.retrieve()); - if (m_summaryWriter && !m_noDiagnostics) ATH_CHECK(m_trajectorySummaryWriterTool.retrieve()); - m_fit = makeTrackFitterFunction(m_trackingGeometryTool->trackingGeometry()); +//todo if (m_statesWriter && !m_noDiagnostics) ATH_CHECK(m_trajectoryStatesWriterTool.retrieve()); +//todo if (m_summaryWriter && !m_noDiagnostics) ATH_CHECK(m_trajectorySummaryWriterTool.retrieve()); if (m_actsLogging == "VERBOSE" && !m_noDiagnostics) { m_logger = Acts::getDefaultLogger("KalmanFitter", Acts::Logging::VERBOSE); } else if (m_actsLogging == "DEBUG" && !m_noDiagnostics) { @@ -31,6 +31,10 @@ StatusCode KalmanFitterTool::initialize() { } else { m_logger = Acts::getDefaultLogger("KalmanFitter", Acts::Logging::INFO); } + auto magneticField = std::make_shared<FASERMagneticFieldWrapper>(); + double reverseFilteringMomThreshold = 0.1; //@todo: needs to be validated + //@todo: the multiple scattering and energy loss are originallly turned off + m_fit = makeTrackFitterFunction(m_trackingGeometryTool->trackingGeometry(), magneticField, false, false, reverseFilteringMomThreshold, Acts::FreeToBoundCorrection(false), *m_logger); return StatusCode::SUCCESS; } @@ -48,7 +52,6 @@ KalmanFitterTool::getUnbiasedResidual(const EventContext &ctx, const Acts::Geome bool /*isMC*/, double origin) const { std::vector<TSOS4Residual> resi; resi.clear(); - std::vector<FaserActsRecMultiTrajectory> myTrajectories; ATH_MSG_DEBUG("start kalmanfilter "<<inputTrack->measurementsOnTrack()->size()<<" "<<origin<<" "<<clusz); if (!inputTrack->measurementsOnTrack() || inputTrack->measurementsOnTrack()->size() < m_minMeasurements) { @@ -61,7 +64,6 @@ KalmanFitterTool::getUnbiasedResidual(const EventContext &ctx, const Acts::Geome return resi; } - auto pSurface = Acts::Surface::makeShared<Acts::PlaneSurface>( Acts::Vector3 {0, 0, origin}, Acts::Vector3{0, 0, -1}); @@ -76,72 +78,63 @@ KalmanFitterTool::getUnbiasedResidual(const EventContext &ctx, const Acts::Geome ATH_MSG_DEBUG("charge: " << trackParameters.charge()); ATH_MSG_DEBUG("size of measurements : " << sourceLinks.size()); + + auto actsTrackContainer = std::make_shared<Acts::VectorTrackContainer>(); + auto actsTrackStateContainer = std::make_shared<Acts::VectorMultiTrajectory>(); + FaserActsTrackContainer tracks(actsTrackContainer, actsTrackStateContainer); + + //@todo: the initialSurface should be targetSurface + KalmanFitterTool::GeneralFitterOptions options{ + gctx, mfContext, calibContext, &(*pSurface), + Acts::PropagatorPlainOptions()}; + + std::vector<Acts::SourceLink> actsSls; + for(const auto& sl: sourceLinks){ + actsSls.push_back(Acts::SourceLink{sl}); + } + + ATH_MSG_DEBUG("Invoke fitter"); FaserActsOutlierFinder faserActsOutlierFinder{0}; faserActsOutlierFinder.cluster_z=clusz; faserActsOutlierFinder.StateChiSquaredPerNumberDoFCut=10000.; - Acts::KalmanFitterOptions<MeasurementCalibrator, FaserActsOutlierFinder, Acts::VoidReverseFilteringLogic> - kfOptions(gctx, mfContext, calibContext, MeasurementCalibrator(measurements), - faserActsOutlierFinder, Acts::VoidReverseFilteringLogic(), Acts::LoggerWrapper{*m_logger}, - //FaserActsOutlierFinder(), Acts::VoidReverseFilteringLogic(), Acts::LoggerWrapper{*m_logger}, - //Acts::VoidOutlierFinder(), Acts::VoidReverseFilteringLogic(), Acts::LoggerWrapper{*m_logger}, - Acts::PropagatorPlainOptions(), &(*pSurface)); - kfOptions.multipleScattering = false; - kfOptions.energyLoss = false; - - ATH_MSG_DEBUG("Invoke fitter"); - auto result = (*m_fit)(sourceLinks, trackParameters, kfOptions); + auto result = (*m_fit)(actsSls, trackParameters, options, MeasurementCalibratorAdapter(MeasurementCalibrator(), measurements), faserActsOutlierFinder, tracks); if (result.ok()) { - const auto& fitOutput = result.value(); - if (fitOutput.fittedParameters) { - const auto& params = fitOutput.fittedParameters.value(); - ATH_MSG_DEBUG("ReFitted parameters"); - ATH_MSG_DEBUG(" params: " << params.parameters().transpose()); - ATH_MSG_DEBUG(" position: " << params.position(gctx).transpose()); - ATH_MSG_DEBUG(" momentum: " << params.momentum().transpose()); - ATH_MSG_DEBUG(" charge: " << params.charge()); - using IndexedParams = std::unordered_map<size_t, Acts::BoundTrackParameters>; - IndexedParams indexedParams; - indexedParams.emplace(fitOutput.lastMeasurementIndex, std::move(params)); - std::vector<size_t> trackTips; - trackTips.reserve(1); - trackTips.emplace_back(fitOutput.lastMeasurementIndex); - myTrajectories.emplace_back(std::move(fitOutput.fittedStates), - std::move(trackTips), - std::move(indexedParams)); - for (const FaserActsRecMultiTrajectory &traj : myTrajectories) { - const auto& mj = traj.multiTrajectory(); - const auto& trackTips = traj.tips(); - if(trackTips.empty())continue; - auto& trackTip = trackTips.front(); - mj.visitBackwards(trackTip, [&](const auto &state) { - auto typeFlags = state.typeFlags(); - if (not typeFlags.test(Acts::TrackStateFlag::OutlierFlag)) - { - return true; - } - - if (state.hasUncalibrated()&&state.hasSmoothed()) { - Acts::BoundTrackParameters parameter( - state.referenceSurface().getSharedPtr(), - state.smoothed(), - state.smoothedCovariance()); - // auto covariance = state.smoothedCovariance(); - auto H = state.effectiveProjector(); - auto residual = state.effectiveCalibrated() - H * state.smoothed(); - const Tracker::FaserSCT_Cluster* cluster = state.uncalibrated().hit(); - // const auto& surface = state.referenceSurface(); - Acts::BoundVector meas = state.projector().transpose() * state.calibrated(); - Acts::Vector2 local(meas[Acts::eBoundLoc0], meas[Acts::eBoundLoc1]); - // const Acts::Vector3 dir = Acts::makeDirectionUnitFromPhiTheta(meas[Acts::eBoundPhi], meas[Acts::eBoundTheta]); - resi.push_back({local.x(),local.y(),parameter.position(gctx).x(), parameter.position(gctx).y(), parameter.position(gctx).z(), cluster,residual(Acts::eBoundLoc0),parameter}); - ATH_MSG_DEBUG(" residual/global position: " << residual(Acts::eBoundLoc0)<<" "<<parameter.position(gctx).x()<<" "<<parameter.position(gctx).y()<<" "<<parameter.position(gctx).z()); - } - return true; - }); - + const auto& track = result.value(); + if (track.hasReferenceSurface()) { + //const auto& params = fitOutput.fittedParameters.value(); + //ATH_MSG_DEBUG("ReFitted parameters"); + //ATH_MSG_DEBUG(" params: " << params.parameters().transpose()); + //ATH_MSG_DEBUG(" position: " << params.position(gctx).transpose()); + //ATH_MSG_DEBUG(" momentum: " << params.momentum().transpose()); + //ATH_MSG_DEBUG(" charge: " << params.charge()); + for (const auto& state : track.trackStatesReversed()) { + auto flag = state.typeFlags(); + //@todo: this only check outlier state? + if (not flag.test(Acts::TrackStateFlag::OutlierFlag)) + { + continue; + } + + if (state.hasUncalibratedSourceLink()&&state.hasSmoothed()) { + //todo: make the particle hypothesis configurable + Acts::BoundTrackParameters parameter( + state.referenceSurface().getSharedPtr(), + state.smoothed(), + state.smoothedCovariance(), Acts::ParticleHypothesis::muon()); + // auto covariance = state.smoothedCovariance(); + auto H = state.effectiveProjector(); + auto residual = state.effectiveCalibrated() - H * state.smoothed(); + IndexSourceLink sl = state.getUncalibratedSourceLink().template get<IndexSourceLink>(); + const Tracker::FaserSCT_Cluster* cluster = sl.hit(); + // const auto& surface = state.referenceSurface(); + Acts::BoundVector meas = state.projector().transpose() * state.effectiveCalibrated(); + Acts::Vector2 local(meas[Acts::eBoundLoc0], meas[Acts::eBoundLoc1]); + // const Acts::Vector3 dir = Acts::makeDirectionUnitFromPhiTheta(meas[Acts::eBoundPhi], meas[Acts::eBoundTheta]); + resi.push_back({local.x(),local.y(),parameter.position(gctx).x(), parameter.position(gctx).y(), parameter.position(gctx).z(), cluster,residual(Acts::eBoundLoc0),parameter}); + ATH_MSG_DEBUG(" residual/global position: " << residual(Acts::eBoundLoc0)<<" "<<parameter.position(gctx).x()<<" "<<parameter.position(gctx).y()<<" "<<parameter.position(gctx).z()); + } } - } else { ATH_MSG_DEBUG("No fitted parameters for track"); } @@ -159,7 +152,6 @@ KalmanFitterTool::getUnbiasedResidual(const EventContext &ctx, const Acts::Geome bool /*isMC*/, double origin, std::vector<const Tracker::FaserSCT_Cluster*>& clusters, const Acts::BoundTrackParameters ini_Param) const { std::vector<TSOS4Residual> resi; resi.clear(); - std::vector<FaserActsRecMultiTrajectory> myTrajectories; if (!inputTrack->measurementsOnTrack() || inputTrack->measurementsOnTrack()->size() < m_minMeasurements) { ATH_MSG_DEBUG("Input track has no or too little measurements and cannot be fitted"); @@ -171,7 +163,6 @@ KalmanFitterTool::getUnbiasedResidual(const EventContext &ctx, const Acts::Geome return resi; } - auto pSurface = Acts::Surface::makeShared<Acts::PlaneSurface>( Acts::Vector3 {0, 0, origin}, Acts::Vector3{0, 0, -1}); @@ -184,69 +175,63 @@ KalmanFitterTool::getUnbiasedResidual(const EventContext &ctx, const Acts::Geome ATH_MSG_DEBUG("momentum: " << ini_Param.momentum().transpose()); ATH_MSG_DEBUG("charge: " << ini_Param.charge()); + auto actsTrackContainer = std::make_shared<Acts::VectorTrackContainer>(); + auto actsTrackStateContainer = std::make_shared<Acts::VectorMultiTrajectory>(); + FaserActsTrackContainer tracks(actsTrackContainer, actsTrackStateContainer); + + //@todo: the initialSurface should be targetSurface + KalmanFitterTool::GeneralFitterOptions options{ + gctx, mfContext, calibContext, &(*pSurface), + Acts::PropagatorPlainOptions()}; + + std::vector<Acts::SourceLink> actsSls; + for(const auto& sl: sourceLinks){ + actsSls.push_back(Acts::SourceLink{sl}); + } + + ATH_MSG_DEBUG("Invoke fitter"); FaserActsOutlierFinder faserActsOutlierFinder{0}; faserActsOutlierFinder.cluster_z=-1000000.; faserActsOutlierFinder.StateChiSquaredPerNumberDoFCut=10000.; - Acts::KalmanFitterOptions<MeasurementCalibrator, FaserActsOutlierFinder, Acts::VoidReverseFilteringLogic> - kfOptions(gctx, mfContext, calibContext, MeasurementCalibrator(measurements), - faserActsOutlierFinder, Acts::VoidReverseFilteringLogic(), Acts::LoggerWrapper{*m_logger}, - Acts::PropagatorPlainOptions(), &(*pSurface)); - kfOptions.multipleScattering = false; - kfOptions.energyLoss = false; - - ATH_MSG_DEBUG("Invoke fitter"); - auto result = (*m_fit)(sourceLinks, ini_Param, kfOptions); + + auto result = (*m_fit)(actsSls, ini_Param, options, MeasurementCalibratorAdapter(MeasurementCalibrator(), measurements), faserActsOutlierFinder, tracks); if (result.ok()) { - const auto& fitOutput = result.value(); - if (fitOutput.fittedParameters) { - const auto& params = fitOutput.fittedParameters.value(); - ATH_MSG_DEBUG("ReFitted parameters"); - ATH_MSG_DEBUG(" params: " << params.parameters().transpose()); - ATH_MSG_DEBUG(" position: " << params.position(gctx).transpose()); - ATH_MSG_DEBUG(" momentum: " << params.momentum().transpose()); - ATH_MSG_DEBUG(" charge: " << params.charge()); - using IndexedParams = std::unordered_map<size_t, Acts::BoundTrackParameters>; - IndexedParams indexedParams; - indexedParams.emplace(fitOutput.lastMeasurementIndex, std::move(params)); - std::vector<size_t> trackTips; - trackTips.reserve(1); - trackTips.emplace_back(fitOutput.lastMeasurementIndex); - myTrajectories.emplace_back(std::move(fitOutput.fittedStates), - std::move(trackTips), - std::move(indexedParams)); - for (const FaserActsRecMultiTrajectory &traj : myTrajectories) { - const auto& mj = traj.multiTrajectory(); - const auto& trackTips = traj.tips(); - if(trackTips.empty())continue; - auto& trackTip = trackTips.front(); - mj.visitBackwards(trackTip, [&](const auto &state) { - auto typeFlags = state.typeFlags(); - if (not typeFlags.test(Acts::TrackStateFlag::OutlierFlag)) - { - return true; - } - - if (state.hasUncalibrated()&&state.hasSmoothed()) { - Acts::BoundTrackParameters parameter( - state.referenceSurface().getSharedPtr(), - state.smoothed(), - state.smoothedCovariance()); - // auto covariance = state.smoothedCovariance(); - auto H = state.effectiveProjector(); - auto residual = state.effectiveCalibrated() - H * state.smoothed(); - const Tracker::FaserSCT_Cluster* cluster = state.uncalibrated().hit(); - // const auto& surface = state.referenceSurface(); - Acts::BoundVector meas = state.projector().transpose() * state.calibrated(); - Acts::Vector2 local(meas[Acts::eBoundLoc0], meas[Acts::eBoundLoc1]); - // const Acts::Vector3 dir = Acts::makeDirectionUnitFromPhiTheta(meas[Acts::eBoundPhi], meas[Acts::eBoundTheta]); - resi.push_back({local.x(),local.y(),parameter.position(gctx).x(), parameter.position(gctx).y(), parameter.position(gctx).z(), cluster,residual(Acts::eBoundLoc0),parameter}); - } - return true; - }); - + const auto& track = result.value(); + if (track.hasReferenceSurface()) { + //const auto& params = fitOutput.fittedParameters.value(); + //ATH_MSG_DEBUG("ReFitted parameters"); + //ATH_MSG_DEBUG(" params: " << params.parameters().transpose()); + //ATH_MSG_DEBUG(" position: " << params.position(gctx).transpose()); + //ATH_MSG_DEBUG(" momentum: " << params.momentum().transpose()); + //ATH_MSG_DEBUG(" charge: " << params.charge()); + for (const auto& state : track.trackStatesReversed()) { + auto flag = state.typeFlags(); + //@todo: this only check outlier state? + if (not flag.test(Acts::TrackStateFlag::OutlierFlag)) + { + continue; + } + + if (state.hasUncalibratedSourceLink()&&state.hasSmoothed()) { + //todo: make the particle hypothesis configurable + Acts::BoundTrackParameters parameter( + state.referenceSurface().getSharedPtr(), + state.smoothed(), + state.smoothedCovariance(), Acts::ParticleHypothesis::muon()); + // auto covariance = state.smoothedCovariance(); + auto H = state.effectiveProjector(); + auto residual = state.effectiveCalibrated() - H * state.smoothed(); + IndexSourceLink sl = state.getUncalibratedSourceLink().template get<IndexSourceLink>(); + const Tracker::FaserSCT_Cluster* cluster = sl.hit(); + // const auto& surface = state.referenceSurface(); + Acts::BoundVector meas = state.projector().transpose() * state.effectiveCalibrated(); + Acts::Vector2 local(meas[Acts::eBoundLoc0], meas[Acts::eBoundLoc1]); + // const Acts::Vector3 dir = Acts::makeDirectionUnitFromPhiTheta(meas[Acts::eBoundPhi], meas[Acts::eBoundTheta]); + resi.push_back({local.x(),local.y(),parameter.position(gctx).x(), parameter.position(gctx).y(), parameter.position(gctx).z(), cluster,residual(Acts::eBoundLoc0),parameter}); + ATH_MSG_DEBUG(" residual/global position: " << residual(Acts::eBoundLoc0)<<" "<<parameter.position(gctx).x()<<" "<<parameter.position(gctx).y()<<" "<<parameter.position(gctx).z()); + } } - } else { ATH_MSG_DEBUG("No fitted parameters for track"); } @@ -264,7 +249,6 @@ KalmanFitterTool::getUnbiasedResidual(const EventContext &ctx, const Acts::Geome bool /*isMC*/, double origin) const { std::vector<TSOS4Residual> resi; resi.clear(); - std::vector<FaserActsRecMultiTrajectory> myTrajectories; if (!inputTrack->measurementsOnTrack() || inputTrack->measurementsOnTrack()->size() < m_minMeasurements) { ATH_MSG_DEBUG("Input track has no or too little measurements and cannot be fitted"); @@ -290,70 +274,63 @@ KalmanFitterTool::getUnbiasedResidual(const EventContext &ctx, const Acts::Geome ATH_MSG_DEBUG("momentum: " << trackParameters.momentum().transpose()); ATH_MSG_DEBUG("charge: " << trackParameters.charge()); + auto actsTrackContainer = std::make_shared<Acts::VectorTrackContainer>(); + auto actsTrackStateContainer = std::make_shared<Acts::VectorMultiTrajectory>(); + FaserActsTrackContainer tracks(actsTrackContainer, actsTrackStateContainer); + + //@todo: the initialSurface should be targetSurface + KalmanFitterTool::GeneralFitterOptions options{ + gctx, mfContext, calibContext, &(*pSurface), + Acts::PropagatorPlainOptions()}; + + std::vector<Acts::SourceLink> actsSls; + for(const auto& sl: sourceLinks){ + actsSls.push_back(Acts::SourceLink{sl}); + } + ATH_MSG_DEBUG("Invoke fitter"); FaserActsOutlierFinder faserActsOutlierFinder{0}; faserActsOutlierFinder.cluster_z=-1000000.; faserActsOutlierFinder.StateChiSquaredPerNumberDoFCut=10000.; - Acts::KalmanFitterOptions<MeasurementCalibrator, FaserActsOutlierFinder, Acts::VoidReverseFilteringLogic> - kfOptions(gctx, mfContext, calibContext, MeasurementCalibrator(measurements), - faserActsOutlierFinder, Acts::VoidReverseFilteringLogic(), Acts::LoggerWrapper{*m_logger}, - Acts::PropagatorPlainOptions(), &(*pSurface)); - kfOptions.multipleScattering = false; - kfOptions.energyLoss = false; - - ATH_MSG_DEBUG("Invoke fitter"); - auto result = (*m_fit)(sourceLinks, trackParameters, kfOptions); + + auto result = (*m_fit)(actsSls, trackParameters, options, MeasurementCalibratorAdapter(MeasurementCalibrator(), measurements), faserActsOutlierFinder, tracks); if (result.ok()) { - const auto& fitOutput = result.value(); - if (fitOutput.fittedParameters) { - const auto& params = fitOutput.fittedParameters.value(); - ATH_MSG_DEBUG("ReFitted parameters"); - ATH_MSG_DEBUG(" params: " << params.parameters().transpose()); - ATH_MSG_DEBUG(" position: " << params.position(gctx).transpose()); - ATH_MSG_DEBUG(" momentum: " << params.momentum().transpose()); - ATH_MSG_DEBUG(" charge: " << params.charge()); - using IndexedParams = std::unordered_map<size_t, Acts::BoundTrackParameters>; - IndexedParams indexedParams; - indexedParams.emplace(fitOutput.lastMeasurementIndex, std::move(params)); - std::vector<size_t> trackTips; - trackTips.reserve(1); - trackTips.emplace_back(fitOutput.lastMeasurementIndex); - myTrajectories.emplace_back(std::move(fitOutput.fittedStates), - std::move(trackTips), - std::move(indexedParams)); - for (const FaserActsRecMultiTrajectory &traj : myTrajectories) { - const auto& mj = traj.multiTrajectory(); - const auto& trackTips = traj.tips(); - if(trackTips.empty())continue; - auto& trackTip = trackTips.front(); - mj.visitBackwards(trackTip, [&](const auto &state) { - auto typeFlags = state.typeFlags(); - if (not typeFlags.test(Acts::TrackStateFlag::OutlierFlag)) - { - return true; - } - - if (state.hasUncalibrated()&&state.hasSmoothed()) { - Acts::BoundTrackParameters parameter( - state.referenceSurface().getSharedPtr(), - state.smoothed(), - state.smoothedCovariance()); - // auto covariance = state.smoothedCovariance(); - auto H = state.effectiveProjector(); - auto residual = state.effectiveCalibrated() - H * state.smoothed(); - const Tracker::FaserSCT_Cluster* cluster = state.uncalibrated().hit(); - // const auto& surface = state.referenceSurface(); - Acts::BoundVector meas = state.projector().transpose() * state.calibrated(); - Acts::Vector2 local(meas[Acts::eBoundLoc0], meas[Acts::eBoundLoc1]); - // const Acts::Vector3 dir = Acts::makeDirectionUnitFromPhiTheta(meas[Acts::eBoundPhi], meas[Acts::eBoundTheta]); -resi.push_back({local.x(),local.y(),parameter.position(gctx).x(), parameter.position(gctx).y(), parameter.position(gctx).z(), cluster,residual(Acts::eBoundLoc0),parameter}); - } - return true; - }); - + const auto& track = result.value(); + if (track.hasReferenceSurface()) { + //const auto& params = track.fittedParameters.value(); + //ATH_MSG_DEBUG("ReFitted parameters"); + //ATH_MSG_DEBUG(" params: " << params.parameters().transpose()); + //ATH_MSG_DEBUG(" position: " << params.position(gctx).transpose()); + //ATH_MSG_DEBUG(" momentum: " << params.momentum().transpose()); + //ATH_MSG_DEBUG(" charge: " << params.charge()); + for (const auto& state : track.trackStatesReversed()) { + auto flag = state.typeFlags(); + //@todo: this only check outlier state? + if (not flag.test(Acts::TrackStateFlag::OutlierFlag)) + { + continue; + } + + if (state.hasUncalibratedSourceLink()&&state.hasSmoothed()) { + //todo: make the particle hypothesis configurable + Acts::BoundTrackParameters parameter( + state.referenceSurface().getSharedPtr(), + state.smoothed(), + state.smoothedCovariance(), Acts::ParticleHypothesis::muon()); + // auto covariance = state.smoothedCovariance(); + auto H = state.effectiveProjector(); + auto residual = state.effectiveCalibrated() - H * state.smoothed(); + IndexSourceLink sl = state.getUncalibratedSourceLink().template get<IndexSourceLink>(); + const Tracker::FaserSCT_Cluster* cluster = sl.hit(); + // const auto& surface = state.referenceSurface(); + Acts::BoundVector meas = state.projector().transpose() * state.effectiveCalibrated(); + Acts::Vector2 local(meas[Acts::eBoundLoc0], meas[Acts::eBoundLoc1]); + // const Acts::Vector3 dir = Acts::makeDirectionUnitFromPhiTheta(meas[Acts::eBoundPhi], meas[Acts::eBoundTheta]); + resi.push_back({local.x(),local.y(),parameter.position(gctx).x(), parameter.position(gctx).y(), parameter.position(gctx).z(), cluster,residual(Acts::eBoundLoc0),parameter}); + ATH_MSG_DEBUG(" residual/global position: " << residual(Acts::eBoundLoc0)<<" "<<parameter.position(gctx).x()<<" "<<parameter.position(gctx).y()<<" "<<parameter.position(gctx).z()); + } } - } else { ATH_MSG_DEBUG("No fitted parameters for track"); } @@ -367,7 +344,6 @@ KalmanFitterTool::fit(const EventContext &ctx, const Acts::GeometryContext &gctx Trk::Track* inputTrack, const Acts::BoundVector& inputVector, bool isMC) const { std::unique_ptr<Trk::Track> newTrack = nullptr; - std::vector<FaserActsRecMultiTrajectory> myTrajectories; if (!inputTrack->measurementsOnTrack() || inputTrack->measurementsOnTrack()->size() < m_minMeasurements) { ATH_MSG_DEBUG("Input track has no or too little measurements and cannot be fitted"); @@ -396,49 +372,58 @@ KalmanFitterTool::fit(const EventContext &ctx, const Acts::GeometryContext &gctx ATH_MSG_DEBUG("momentum: " << trackParameters.momentum().transpose()); ATH_MSG_DEBUG("charge: " << trackParameters.charge()); + auto actsTrackContainer = std::make_shared<Acts::VectorTrackContainer>(); + auto actsTrackStateContainer = std::make_shared<Acts::VectorMultiTrajectory>(); + FaserActsTrackContainer tracks(actsTrackContainer, actsTrackStateContainer); + + //@todo: the initialSurface should be targetSurface + KalmanFitterTool::GeneralFitterOptions options{ + gctx, mfContext, calibContext, &(*pSurface), + Acts::PropagatorPlainOptions()}; + + std::vector<Acts::SourceLink> actsSls; + for(const auto& sl: sourceLinks){ + actsSls.push_back(Acts::SourceLink{sl}); + } + + ATH_MSG_DEBUG("Invoke fitter"); FaserActsOutlierFinder faserActsOutlierFinder{0}; faserActsOutlierFinder.cluster_z=-1000000.; faserActsOutlierFinder.StateChiSquaredPerNumberDoFCut=10000.; - Acts::KalmanFitterOptions<MeasurementCalibrator, FaserActsOutlierFinder, Acts::VoidReverseFilteringLogic> - kfOptions(gctx, mfContext, calibContext, MeasurementCalibrator(measurements), - faserActsOutlierFinder, Acts::VoidReverseFilteringLogic(), Acts::LoggerWrapper{*m_logger}, - Acts::PropagatorPlainOptions(), &(*pSurface)); - kfOptions.multipleScattering = false; - kfOptions.energyLoss = false; - - ATH_MSG_DEBUG("Invoke fitter"); - auto result = (*m_fit)(sourceLinks, trackParameters, kfOptions); + + auto result = (*m_fit)(actsSls, trackParameters, options, MeasurementCalibratorAdapter(MeasurementCalibrator(), measurements), faserActsOutlierFinder, tracks); if (result.ok()) { - const auto& fitOutput = result.value(); - if (fitOutput.fittedParameters) { - const auto& params = fitOutput.fittedParameters.value(); - ATH_MSG_DEBUG("ReFitted parameters"); - ATH_MSG_DEBUG(" params: " << params.parameters().transpose()); - ATH_MSG_DEBUG(" position: " << params.position(gctx).transpose()); - ATH_MSG_DEBUG(" momentum: " << params.momentum().transpose()); - ATH_MSG_DEBUG(" charge: " << params.charge()); - using IndexedParams = std::unordered_map<size_t, Acts::BoundTrackParameters>; - IndexedParams indexedParams; - indexedParams.emplace(fitOutput.lastMeasurementIndex, std::move(params)); - std::vector<size_t> trackTips; - trackTips.reserve(1); - trackTips.emplace_back(fitOutput.lastMeasurementIndex); - myTrajectories.emplace_back(std::move(fitOutput.fittedStates), - std::move(trackTips), - std::move(indexedParams)); - } else { - ATH_MSG_DEBUG("No fitted parameters for track"); - } - newTrack = m_createTrkTrackTool->createTrack(gctx, myTrajectories.back()); + const auto& track = result.value(); + //if (track.hasReferenceSurface()) { + //const auto& params = track.fittedParameters.value(); + //ATH_MSG_DEBUG("ReFitted parameters"); + //ATH_MSG_DEBUG(" params: " << params.parameters().transpose()); + //ATH_MSG_DEBUG(" position: " << params.position(gctx).transpose()); + //ATH_MSG_DEBUG(" momentum: " << params.momentum().transpose()); + //ATH_MSG_DEBUG(" charge: " << params.charge()); + //using IndexedParams = std::unordered_map<size_t, Acts::BoundTrackParameters>; + //IndexedParams indexedParams; + //indexedParams.emplace(fitOutput.lastMeasurementIndex, std::move(params)); + //std::vector<size_t> trackTips; + //trackTips.reserve(1); + //trackTips.emplace_back(fitOutput.lastMeasurementIndex); + //myTrajectories.emplace_back(std::move(fitOutput.fittedStates), + // std::move(trackTips), + // std::move(indexedParams)); + //} else { + // ATH_MSG_DEBUG("No fitted parameters for track"); + //} + newTrack = m_createTrkTrackTool->createTrack(gctx, track); } - if (m_statesWriter && !m_noDiagnostics) { - StatusCode statusStatesWriterTool = m_trajectoryStatesWriterTool->write(gctx, myTrajectories, isMC); - } - if (m_summaryWriter && !m_noDiagnostics) { - StatusCode statusSummaryWriterTool = m_trajectorySummaryWriterTool->write(gctx, myTrajectories, isMC); - } +//todo +// if (m_statesWriter && !m_noDiagnostics) { +// StatusCode statusStatesWriterTool = m_trajectoryStatesWriterTool->write(gctx, myTrajectories, isMC); +// } +// if (m_summaryWriter && !m_noDiagnostics) { +// StatusCode statusSummaryWriterTool = m_trajectorySummaryWriterTool->write(gctx, myTrajectories, isMC); +// } return newTrack; } @@ -446,25 +431,84 @@ KalmanFitterTool::fit(const EventContext &ctx, const Acts::GeometryContext &gctx namespace { -using Updater = Acts::GainMatrixUpdater; -using Smoother = Acts::GainMatrixSmoother; using Stepper = Acts::EigenStepper<>; using Propagator = Acts::Propagator<Stepper, Acts::Navigator>; -using Fitter = Acts::KalmanFitter<Propagator, Updater, Smoother>; +using Fitter = Acts::KalmanFitter<Propagator, Acts::VectorMultiTrajectory>; + + +struct SimpleReverseFilteringLogic { + double momentumThreshold = 0; + + bool doBackwardFiltering( + Acts::VectorMultiTrajectory::ConstTrackStateProxy trackState) const { + auto momentum = fabs(1 / trackState.filtered()[Acts::eBoundQOverP]); + return (momentum <= momentumThreshold); + } +}; + struct TrackFitterFunctionImpl : public KalmanFitterTool::TrackFitterFunction { Fitter trackFitter; - TrackFitterFunctionImpl(Fitter &&f) : trackFitter(std::move(f)) {} + Acts::GainMatrixUpdater kfUpdater; + Acts::GainMatrixSmoother kfSmoother; + SimpleReverseFilteringLogic reverseFilteringLogic; + + bool multipleScattering = false; + bool energyLoss = false; + Acts::FreeToBoundCorrection freeToBoundCorrection; + + IndexSourceLink::SurfaceAccessor slSurfaceAccessor; + + TrackFitterFunctionImpl(Fitter &&f, const Acts::TrackingGeometry& trkGeo) : trackFitter(std::move(f)),slSurfaceAccessor{trkGeo} {} + + template <typename calibrator_t> + auto makeKfOptions(const KalmanFitterTool::GeneralFitterOptions& options, + const calibrator_t& calibrator, const FaserActsOutlierFinder& outlierFinder) const { + Acts::KalmanFitterExtensions<Acts::VectorMultiTrajectory> extensions; + extensions.updater.connect< + &Acts::GainMatrixUpdater::operator()<Acts::VectorMultiTrajectory>>( + &kfUpdater); + extensions.smoother.connect< + &Acts::GainMatrixSmoother::operator()<Acts::VectorMultiTrajectory>>( + &kfSmoother); + extensions.reverseFilteringLogic + .connect<&SimpleReverseFilteringLogic::doBackwardFiltering>( + &reverseFilteringLogic); + //@todo: this needs fix!!! + //extensions.outlierFinder.connect<&FaserActsOutlierFinder::operator()<Acts::ConstVectorMultiTrajectory>>( + // &outlierFinder); + + Acts::KalmanFitterOptions<Acts::VectorMultiTrajectory> kfOptions( + options.geoContext, options.magFieldContext, options.calibrationContext, + extensions, options.propOptions, &(*options.referenceSurface)); + + kfOptions.referenceSurfaceStrategy = + Acts::KalmanFitterTargetSurfaceStrategy::first; + kfOptions.multipleScattering = multipleScattering; + kfOptions.energyLoss = energyLoss; + kfOptions.freeToBoundCorrection = freeToBoundCorrection; + kfOptions.extensions.calibrator.connect<&calibrator_t::calibrate>( + &calibrator); + kfOptions.extensions.surfaceAccessor + .connect<&IndexSourceLink::SurfaceAccessor::operator()>( + &slSurfaceAccessor); + + return kfOptions; + } KalmanFitterTool::TrackFitterResult operator()( - const std::vector<IndexSourceLink> &sourceLinks, + const std::vector<Acts::SourceLink> &sourceLinks, const KalmanFitterTool::TrackParameters &initialParameters, - const KalmanFitterTool::TrackFitterOptions &options) - const override { - return trackFitter.fit(sourceLinks, initialParameters, options); - }; + const KalmanFitterTool::GeneralFitterOptions& options, + const MeasurementCalibratorAdapter& calibrator, + const FaserActsOutlierFinder& outlierFinder, + FaserActsTrackContainer& tracks) const override { + const auto kfOptions = makeKfOptions(options, calibrator, outlierFinder); + return trackFitter.fit(sourceLinks.begin(), sourceLinks.end(), initialParameters, + kfOptions, tracks); + } }; } // namespace @@ -472,20 +516,38 @@ struct TrackFitterFunctionImpl std::shared_ptr<KalmanFitterTool::TrackFitterFunction> KalmanFitterTool::makeTrackFitterFunction( - std::shared_ptr<const Acts::TrackingGeometry> trackingGeometry) { - auto magneticField = std::make_shared<FASERMagneticFieldWrapper>(); - auto stepper = Stepper(std::move(magneticField)); - Acts::Navigator::Config cfg{trackingGeometry}; + std::shared_ptr<const Acts::TrackingGeometry> trackingGeometry, + std::shared_ptr<const Acts::MagneticFieldProvider> magneticField, + bool multipleScattering, bool energyLoss, + double reverseFilteringMomThreshold, + Acts::FreeToBoundCorrection freeToBoundCorrection, + const Acts::Logger& logger) { + // Stepper should be copied into the fitters + const Stepper stepper(std::move(magneticField)); + + // Standard fitter + const auto& geo = *trackingGeometry; + Acts::Navigator::Config cfg{std::move(trackingGeometry)}; cfg.resolvePassive = false; cfg.resolveMaterial = true; cfg.resolveSensitive = true; - Acts::Navigator navigator(cfg); - Propagator propagator(std::move(stepper), std::move(navigator)); - Fitter trackFitter(std::move(propagator)); - return std::make_shared<TrackFitterFunctionImpl>(std::move(trackFitter)); + Acts::Navigator navigator(cfg, logger.cloneWithSuffix("Navigator")); + Propagator propagator(stepper, std::move(navigator), + logger.cloneWithSuffix("Propagator")); + Fitter trackFitter(std::move(propagator), logger.cloneWithSuffix("Fitter")); + + // build the fitter function. owns the fitter object. + auto fitterFunction = std::make_shared<TrackFitterFunctionImpl>( + std::move(trackFitter), geo); + fitterFunction->multipleScattering = multipleScattering; + fitterFunction->energyLoss = energyLoss; + fitterFunction->reverseFilteringLogic.momentumThreshold = + reverseFilteringMomThreshold; + fitterFunction->freeToBoundCorrection = freeToBoundCorrection; + + return fitterFunction; } - Acts::MagneticFieldContext KalmanFitterTool::getMagneticFieldContext(const EventContext& ctx) const { SG::ReadCondHandle<FaserFieldCacheCondObj> readHandle{m_fieldCondObjInputKey, ctx}; if (!readHandle.isValid()) { @@ -501,9 +563,9 @@ Acts::MagneticFieldContext KalmanFitterTool::getMagneticFieldContext(const Event std::tuple<std::vector<IndexSourceLink>, std::vector<Measurement>> KalmanFitterTool::getMeasurementsFromTrack(Trk::Track *track, std::vector<const Tracker::FaserSCT_Cluster*>& clusters) const { const int kSize = 1; - ATH_MSG_DEBUG("clusters in refit "<<clusters.size()); + ATH_MSG_DEBUG("clusters in refit "<<clusters.size()); std::array<Acts::BoundIndices, kSize> Indices = {Acts::eBoundLoc0}; - using ThisMeasurement = Acts::Measurement<IndexSourceLink, Acts::BoundIndices, kSize>; + using ThisMeasurement = Acts::Measurement<Acts::BoundIndices, kSize>; using IdentifierMap = std::map<Identifier, Acts::GeometryIdentifier>; std::shared_ptr<IdentifierMap> identifierMap = m_trackingGeometryTool->getIdentifierMap(); @@ -521,7 +583,7 @@ KalmanFitterTool::getMeasurementsFromTrack(Trk::Track *track, std::vector<const IndexSourceLink sourceLink(geoId, measurements.size(), cluster); Eigen::Matrix<double, 1, 1> pos {cluster->localPosition().x()}; Eigen::Matrix<double, 1, 1> cov {0.08 * 0.08 / 12}; - ThisMeasurement actsMeas(sourceLink, Indices, pos, cov); + ThisMeasurement actsMeas(Acts::SourceLink{std::move(sourceLink)}, Indices, pos, cov); sourceLinks.push_back(sourceLink); measurements.emplace_back(std::move(actsMeas)); } @@ -537,7 +599,7 @@ KalmanFitterTool::getMeasurementsFromTrack(Trk::Track *track, std::vector<const IndexSourceLink sourceLink(geoId, measurements.size(), cluster); Eigen::Matrix<double, 1, 1> pos {meas->localParameters()[Trk::locX],}; Eigen::Matrix<double, 1, 1> cov {0.08 * 0.08 / 12}; - ThisMeasurement actsMeas(sourceLink, Indices, pos, cov); + ThisMeasurement actsMeas(Acts::SourceLink{std::move(sourceLink)}, Indices, pos, cov); sourceLinks.push_back(sourceLink); measurements.emplace_back(std::move(actsMeas)); } @@ -550,7 +612,7 @@ std::tuple<std::vector<IndexSourceLink>, std::vector<Measurement>> KalmanFitterTool::getMeasurementsFromTrack(Trk::Track *track, Identifier& /*wafer_id*/) const { const int kSize = 1; std::array<Acts::BoundIndices, kSize> Indices = {Acts::eBoundLoc0}; - using ThisMeasurement = Acts::Measurement<IndexSourceLink, Acts::BoundIndices, kSize>; + using ThisMeasurement = Acts::Measurement<Acts::BoundIndices, kSize>; using IdentifierMap = std::map<Identifier, Acts::GeometryIdentifier>; std::shared_ptr<IdentifierMap> identifierMap = m_trackingGeometryTool->getIdentifierMap(); @@ -568,7 +630,7 @@ KalmanFitterTool::getMeasurementsFromTrack(Trk::Track *track, Identifier& /*wafe IndexSourceLink sourceLink(geoId, measurements.size(), cluster); Eigen::Matrix<double, 1, 1> pos {meas->localParameters()[Trk::locX],}; Eigen::Matrix<double, 1, 1> cov {0.08 * 0.08 / 12}; - ThisMeasurement actsMeas(sourceLink, Indices, pos, cov); + ThisMeasurement actsMeas(Acts::SourceLink{std::move(sourceLink)}, Indices, pos, cov); sourceLinks.push_back(sourceLink); measurements.emplace_back(std::move(actsMeas)); } @@ -580,7 +642,7 @@ std::tuple<std::vector<IndexSourceLink>, std::vector<Measurement>> KalmanFitterTool::getMeasurementsFromTrack(Trk::Track *track) const { const int kSize = 1; std::array<Acts::BoundIndices, kSize> Indices = {Acts::eBoundLoc0}; - using ThisMeasurement = Acts::Measurement<IndexSourceLink, Acts::BoundIndices, kSize>; + using ThisMeasurement = Acts::Measurement<Acts::BoundIndices, kSize>; using IdentifierMap = std::map<Identifier, Acts::GeometryIdentifier>; std::shared_ptr<IdentifierMap> identifierMap = m_trackingGeometryTool->getIdentifierMap(); @@ -597,7 +659,7 @@ KalmanFitterTool::getMeasurementsFromTrack(Trk::Track *track) const { IndexSourceLink sourceLink(geoId, measurements.size(), cluster); Eigen::Matrix<double, 1, 1> pos {meas->localParameters()[Trk::locX],}; Eigen::Matrix<double, 1, 1> cov {0.08 * 0.08 / 12}; - ThisMeasurement actsMeas(sourceLink, Indices, pos, cov); + ThisMeasurement actsMeas(Acts::SourceLink{std::move(sourceLink)}, Indices, pos, cov); sourceLinks.push_back(sourceLink); measurements.emplace_back(std::move(actsMeas)); } @@ -622,16 +684,16 @@ KalmanFitterTool::getParametersFromTrack(const Trk::TrackParameters *inputParame // 0.}; Acts::BoundVector params; if (inputVector == Acts::BoundVector::Zero()) { - params(0.0) = center[Trk::locY]; - params(1.0) = center[Trk::locX]; - params(2.0) = atlasParam[Trk::phi0]; - params(3.0) = atlasParam[Trk::theta]; - params(4.0) = inputParameters->charge() / (inputParameters->momentum().norm() * 1_MeV); - params(5.0) = 0.; + params(0) = center[Trk::locY]; + params(1) = center[Trk::locX]; + params(2) = atlasParam[Trk::phi0]; + params(3) = atlasParam[Trk::theta]; + params(4) = inputParameters->charge() / (inputParameters->momentum().norm() * 1_MeV); + params(5) = 0.; } else { params = inputVector; } - Acts::BoundSymMatrix cov = Acts::BoundSymMatrix::Identity(); + Acts::BoundSquareMatrix cov = Acts::BoundSquareMatrix::Identity(); cov.topLeftCorner(5, 5) = *inputParameters->covariance(); for(int i=0; i < cov.rows(); i++){ @@ -644,5 +706,5 @@ KalmanFitterTool::getParametersFromTrack(const Trk::TrackParameters *inputParame cov(i,i) = m_seedCovarianceScale * cov(i,i); } - return Acts::BoundTrackParameters(pSurface, params, inputParameters->charge(), cov); + return Acts::BoundTrackParameters(pSurface, params, cov, Acts::ParticleHypothesis::muon()); } diff --git a/Tracking/Acts/FaserActsKalmanFilter/src/KalmanFitterTool.h b/Tracking/Acts/FaserActsKalmanFilter/src/KalmanFitterTool.h index 4901d324f..b58a31269 100644 --- a/Tracking/Acts/FaserActsKalmanFilter/src/KalmanFitterTool.h +++ b/Tracking/Acts/FaserActsKalmanFilter/src/KalmanFitterTool.h @@ -5,6 +5,7 @@ #include "AthenaBaseComps/AthAlgTool.h" #include "Acts/EventData/TrackParameters.hpp" #include "Acts/TrackFitting/KalmanFitter.hpp" +#include "Acts/EventData/MeasurementHelpers.hpp" #include "FaserActsGeometryInterfaces/IFaserActsTrackingGeometryTool.h" #include "FaserActsKalmanFilter/IndexSourceLink.h" #include "FaserActsKalmanFilter/Measurement.h" @@ -17,6 +18,8 @@ #include "CreateTrkTrackTool.h" #include "TrackerIdentifier/FaserSCT_ID.h" #include "Identifier/Identifier.h" +#include "FaserActsTrack.h" +#include "FaserActsGeometry/FASERMagneticFieldWrapper.h" struct TSOS4Residual{ double fit_local_x; @@ -31,39 +34,32 @@ struct TSOS4Residual{ }; class FaserSCT_ID; + + //set the cluster to be removed as outlier in order to get the unbiased residual /// Outlier finder using a Chi2 cut. struct FaserActsOutlierFinder { double StateChiSquaredPerNumberDoFCut = 10000.; double cluster_z = -10000.; - template <typename track_state_t> - bool operator()(const track_state_t& state) const { + + template <typename traj_t> + bool operator()(typename traj_t::ConstTrackStateProxy state) const { //remove the whole IFT if(cluster_z<-10000){ - if(state.uncalibrated().hit()->globalPosition().z()<-100)return true; + IndexSourceLink sl = state.getUncalibratedSourceLink().template get<IndexSourceLink>(); + if(sl.hit()->globalPosition().z()<-100)return true; + if(abs(sl.hit()->globalPosition().z()-cluster_z)<3)return true; } if (not state.hasCalibrated() or not state.hasPredicted()) { return false; } - return Acts::visit_measurement( - state.calibrated(), state.calibratedCovariance(), - state.calibratedSize(), - [&](const auto calibrated, const auto calibratedCovariance) { - //remove the cluster - if(fabs(state.uncalibrated().hit()->globalPosition().z()-cluster_z)<3)return true; - constexpr size_t kMeasurementSize = decltype(calibrated)::RowsAtCompileTime; - const auto H = - state.projector() - .template topLeftCorner<kMeasurementSize, Acts::BoundIndices::eBoundSize>() - .eval(); - const auto residual = calibrated - H * state.predicted(); - double chi2 = (residual.transpose() * ((calibratedCovariance + H * state.predictedCovariance() * H.transpose())).inverse() * residual).value(); - return bool(chi2 > StateChiSquaredPerNumberDoFCut * kMeasurementSize); - }); + + return bool(state.chi2() > StateChiSquaredPerNumberDoFCut * state.calibratedSize()); } }; + class KalmanFitterTool : virtual public AthAlgTool { public: KalmanFitterTool(const std::string &type, const std::string &name, const IInterface *parent); @@ -71,34 +67,55 @@ public: virtual StatusCode initialize() override; virtual StatusCode finalize() override; + struct GeneralFitterOptions { + std::reference_wrapper<const Acts::GeometryContext> geoContext; + std::reference_wrapper<const Acts::MagneticFieldContext> magFieldContext; + std::reference_wrapper<const Acts::CalibrationContext> calibrationContext; + const Acts::Surface* referenceSurface = nullptr; + Acts::PropagatorPlainOptions propOptions; + }; + using TrackFitterResult = Acts::Result<FaserActsTrackContainer::TrackProxy>; using TrackParameters = Acts::BoundTrackParameters; - using IndexedParams = std::unordered_map<size_t, TrackParameters>; - using TrackFitterOptions = - Acts::KalmanFitterOptions<MeasurementCalibrator, FaserActsOutlierFinder, Acts::VoidReverseFilteringLogic>; - //Acts::KalmanFitterOptions<MeasurementCalibrator, Acts::VoidOutlierFinder, Acts::VoidReverseFilteringLogic>; - using TrackFitterResult = Acts::Result<Acts::KalmanFitterResult<IndexSourceLink>>; + //using IndexedParams = std::unordered_map<size_t, TrackParameters>; + class TrackFitterFunction { public: virtual ~TrackFitterFunction() = default; - virtual TrackFitterResult operator()(const std::vector<IndexSourceLink>&, - const TrackParameters&, - const TrackFitterOptions&) const = 0; + virtual TrackFitterResult operator()( + const std::vector<Acts::SourceLink> &sourceLinks, + const TrackParameters &initialParameters, + const GeneralFitterOptions & kfOptions, + const MeasurementCalibratorAdapter& calibrator, + const FaserActsOutlierFinder& outlierFinder, + FaserActsTrackContainer& tracks + ) const = 0; }; + static std::shared_ptr<TrackFitterFunction> makeTrackFitterFunction( - std::shared_ptr<const Acts::TrackingGeometry> trackingGeometry); + std::shared_ptr<const Acts::TrackingGeometry> trackingGeometry, + std::shared_ptr<const Acts::MagneticFieldProvider> magneticField, + bool multipleScattering, bool energyLoss, + double reverseFilteringMomThreshold, + Acts::FreeToBoundCorrection freeToBoundCorrection, + const Acts::Logger& logger); + virtual Acts::MagneticFieldContext getMagneticFieldContext(const EventContext& ctx) const; + std::unique_ptr<Trk::Track> fit(const EventContext &ctx, const Acts::GeometryContext &gctx, Trk::Track *inputTrack, const Acts::BoundVector& inputVector = Acts::BoundVector::Zero(), bool isMC=false) const; + std::vector<TSOS4Residual> getUnbiasedResidual(const EventContext &ctx, const Acts::GeometryContext &gctx, Trk::Track *inputTrack, const Acts::BoundVector& inputVector = Acts::BoundVector::Zero(), bool isMC=false, double origin=0) const; + std::vector<TSOS4Residual> getUnbiasedResidual(const EventContext &ctx, const Acts::GeometryContext &gctx, Trk::Track *inputTrack, double clusz, const Acts::BoundVector& inputVector , bool isMC, double origin) const; + std::vector<TSOS4Residual> getUnbiasedResidual(const EventContext &ctx, const Acts::GeometryContext &gctx, Trk::Track *inputTrack, const Acts::BoundVector& inputVector , @@ -125,8 +142,8 @@ private: SG::ReadCondHandleKey<FaserFieldCacheCondObj> m_fieldCondObjInputKey {this, "FaserFieldCacheCondObj", "fieldCondObj", "Name of the Magnetic Field conditions object key"}; ToolHandle<IFaserActsTrackingGeometryTool> m_trackingGeometryTool {this, "TrackingGeometryTool", "FaserActsTrackingGeometryTool"}; - ToolHandle<RootTrajectoryStatesWriterTool> m_trajectoryStatesWriterTool {this, "RootTrajectoryStatesWriterTool", "RootTrajectoryStatesWriterTool"}; - ToolHandle<RootTrajectorySummaryWriterTool> m_trajectorySummaryWriterTool {this, "RootTrajectorySummaryWriterTool", "RootTrajectorySummaryWriterTool"}; +//todo ToolHandle<RootTrajectoryStatesWriterTool> m_trajectoryStatesWriterTool {this, "RootTrajectoryStatesWriterTool", "RootTrajectoryStatesWriterTool"}; +//todo ToolHandle<RootTrajectorySummaryWriterTool> m_trajectorySummaryWriterTool {this, "RootTrajectorySummaryWriterTool", "RootTrajectorySummaryWriterTool"}; ToolHandle<CreateTrkTrackTool> m_createTrkTrackTool {this, "CreateTrkTrackTool", "CreateTrkTrackTool"}; // Acts::KalmanFitterExtensions<Acts::VectorMultiTrajectory> getExtensions(); diff --git a/Tracking/Acts/FaserActsKalmanFilter/src/TrackFittingFunction.cxx b/Tracking/Acts/FaserActsKalmanFilter/src/TrackFittingFunction.cxx index c8d2bbe95..7a1e31dfc 100644 --- a/Tracking/Acts/FaserActsKalmanFilter/src/TrackFittingFunction.cxx +++ b/Tracking/Acts/FaserActsKalmanFilter/src/TrackFittingFunction.cxx @@ -1,4 +1,5 @@ #include "FaserActsKalmanFilterAlg.h" +#include "FaserActsTrack.h" //#include "FaserActsGeometry/FASERMagneticFieldWrapper.h" //#include "FaserActsKalmanFilter/IndexSourceLink.h" @@ -92,7 +93,7 @@ struct TrackFitterFunctionImpl const FaserActsKalmanFilterAlg::TrackParameters &initialParameters, const FaserActsKalmanFilterAlg::GeneralFitterOptions& options, const MeasurementCalibratorAdapter& calibrator, - FaserActsKalmanFilterAlg::TrackContainer& tracks) const override { + FaserActsTrackContainer& tracks) const override { const auto kfOptions = makeKfOptions(options, calibrator); return trackFitter.fit(sourceLinks.begin(), sourceLinks.end(), initialParameters, kfOptions, tracks); -- GitLab