Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-09-22 07:59:37

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