File indexing completed on 2025-01-18 09:11:43
0001
0002
0003
0004
0005
0006
0007
0008
0009 #include "ActsExamples/Vertexing/VertexFitterAlgorithm.hpp"
0010
0011 #include "Acts/Definitions/Algebra.hpp"
0012 #include "Acts/MagneticField/MagneticFieldProvider.hpp"
0013 #include "Acts/Propagator/SympyStepper.hpp"
0014 #include "Acts/Propagator/VoidNavigator.hpp"
0015 #include "Acts/Utilities/Result.hpp"
0016 #include "Acts/Vertexing/TrackAtVertex.hpp"
0017 #include "Acts/Vertexing/Vertex.hpp"
0018 #include "ActsExamples/EventData/ProtoVertex.hpp"
0019 #include "ActsExamples/EventData/Vertex.hpp"
0020 #include "ActsExamples/Framework/AlgorithmContext.hpp"
0021
0022 #include <ostream>
0023 #include <stdexcept>
0024 #include <system_error>
0025
0026 #include "VertexingHelpers.hpp"
0027
0028 ActsExamples::VertexFitterAlgorithm::VertexFitterAlgorithm(
0029 const Config& cfg, Acts::Logging::Level lvl)
0030 : ActsExamples::IAlgorithm("VertexFit", lvl), m_cfg(cfg) {
0031 if (m_cfg.inputTrackParameters.empty()) {
0032 throw std::invalid_argument("Missing input track parameter collection");
0033 }
0034 if (m_cfg.inputProtoVertices.empty()) {
0035 throw std::invalid_argument("Missing input proto vertices collection");
0036 }
0037
0038 m_inputTrackParameters.initialize(m_cfg.inputTrackParameters);
0039 m_inputProtoVertices.initialize(m_cfg.inputProtoVertices);
0040 m_outputVertices.initialize(m_cfg.outputVertices);
0041 }
0042
0043 ActsExamples::ProcessCode ActsExamples::VertexFitterAlgorithm::execute(
0044 const ActsExamples::AlgorithmContext& ctx) const {
0045 using Propagator = Acts::Propagator<Acts::SympyStepper>;
0046 using PropagatorOptions = Propagator::Options<>;
0047 using Linearizer = Acts::HelicalTrackLinearizer;
0048 using VertexFitter = Acts::FullBilloirVertexFitter;
0049 using VertexFitterOptions = Acts::VertexingOptions;
0050
0051
0052 Acts::SympyStepper stepper(m_cfg.bField);
0053
0054
0055 auto propagator = std::make_shared<Propagator>(
0056 stepper, Acts::VoidNavigator{}, logger().cloneWithSuffix("Prop"));
0057
0058
0059 Linearizer::Config ltConfig;
0060 ltConfig.bField = m_cfg.bField;
0061 ltConfig.propagator = propagator;
0062 Linearizer linearizer(ltConfig, logger().cloneWithSuffix("HelLin"));
0063
0064 PropagatorOptions propagatorOpts(ctx.geoContext, ctx.magFieldContext);
0065
0066 VertexFitter::Config vertexFitterCfg;
0067 vertexFitterCfg.extractParameters
0068 .connect<&Acts::InputTrack::extractParameters>();
0069 vertexFitterCfg.trackLinearizer.connect<&Linearizer::linearizeTrack>(
0070 &linearizer);
0071 VertexFitter vertexFitter(vertexFitterCfg);
0072 auto fieldCache = m_cfg.bField->makeCache(ctx.magFieldContext);
0073
0074 ACTS_VERBOSE("Read from '" << m_cfg.inputTrackParameters << "'");
0075 ACTS_VERBOSE("Read from '" << m_cfg.inputProtoVertices << "'");
0076
0077 const auto& inputTrackParameters = m_inputTrackParameters(ctx);
0078 ACTS_VERBOSE("Have " << inputTrackParameters.size() << " track parameters");
0079 const auto& protoVertices = m_inputProtoVertices(ctx);
0080 ACTS_VERBOSE("Have " << protoVertices.size() << " proto vertices");
0081
0082 std::vector<Acts::InputTrack> inputTracks;
0083
0084 VertexContainer fittedVertices;
0085
0086 for (const auto& protoVertex : protoVertices) {
0087
0088 if ((!m_cfg.doConstrainedFit) && (protoVertex.size() < 2)) {
0089 ACTS_INFO(
0090 "Skip un-constrained vertex fit on proto-vertex with less than two "
0091 "tracks");
0092 continue;
0093 }
0094
0095
0096 inputTracks.clear();
0097 inputTracks.reserve(protoVertex.size());
0098 for (const auto& trackIdx : protoVertex) {
0099 if (trackIdx >= inputTrackParameters.size()) {
0100 ACTS_ERROR("track parameters " << trackIdx << " does not exist");
0101 continue;
0102 }
0103
0104 inputTracks.emplace_back(&inputTrackParameters[trackIdx]);
0105 }
0106
0107 if (!m_cfg.doConstrainedFit) {
0108 VertexFitterOptions vfOptions(ctx.geoContext, ctx.magFieldContext);
0109
0110 auto fitRes = vertexFitter.fit(inputTracks, vfOptions, fieldCache);
0111 if (fitRes.ok()) {
0112 fittedVertices.push_back(*fitRes);
0113 } else {
0114 ACTS_ERROR("Error in vertex fitter: " << fitRes.error().message());
0115 }
0116 } else {
0117
0118 Acts::Vertex theConstraint;
0119
0120 theConstraint.setFullCovariance(m_cfg.constraintCov);
0121 theConstraint.setFullPosition(m_cfg.constraintPos);
0122
0123
0124 VertexFitterOptions vfOptionsConstr(ctx.geoContext, ctx.magFieldContext,
0125 theConstraint);
0126
0127 auto fitRes = vertexFitter.fit(inputTracks, vfOptionsConstr, fieldCache);
0128 if (fitRes.ok()) {
0129 fittedVertices.push_back(*fitRes);
0130 } else {
0131 ACTS_ERROR(
0132 "Error in constrained vertex fitter: " << fitRes.error().message());
0133 }
0134 }
0135
0136 if (fittedVertices.empty()) {
0137 ACTS_DEBUG("No fitted vertex");
0138 } else {
0139 ACTS_DEBUG("Fitted Vertex "
0140 << fittedVertices.back().fullPosition().transpose());
0141 ACTS_DEBUG(
0142 "Tracks at fitted Vertex: " << fittedVertices.back().tracks().size());
0143 }
0144 }
0145
0146 m_outputVertices(ctx, std::move(fittedVertices));
0147 return ProcessCode::SUCCESS;
0148 }