Back to home page

sPhenix code displayed by LXR

 
 

    


File indexing completed on 2025-08-05 08:09:44

0001 // This file is part of the Acts project.
0002 //
0003 // Copyright (C) 2020 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 http://mozilla.org/MPL/2.0/.
0008 
0009 #include "ActsExamples/Alignment/AlignmentAlgorithm.hpp"
0010 
0011 #include "Acts/Surfaces/PerigeeSurface.hpp"
0012 #include "Acts/TrackFitting/GainMatrixSmoother.hpp"
0013 #include "Acts/TrackFitting/GainMatrixUpdater.hpp"
0014 #include "ActsExamples/EventData/MeasurementCalibration.hpp"
0015 #include "ActsExamples/EventData/ProtoTrack.hpp"
0016 #include "ActsExamples/EventData/Trajectories.hpp"
0017 #include "ActsExamples/Framework/WhiteBoard.hpp"
0018 
0019 ActsExamples::AlignmentAlgorithm::AlignmentAlgorithm(Config cfg,
0020                                                      Acts::Logging::Level lvl)
0021     : ActsExamples::IAlgorithm("AlignmentAlgorithm", lvl),
0022       m_cfg(std::move(cfg)) {
0023   if (m_cfg.inputMeasurements.empty()) {
0024     throw std::invalid_argument("Missing input measurement collection");
0025   }
0026   if (m_cfg.inputSourceLinks.empty()) {
0027     throw std::invalid_argument("Missing input source links collection");
0028   }
0029   if (m_cfg.inputProtoTracks.empty()) {
0030     throw std::invalid_argument("Missing input proto tracks collection");
0031   }
0032   if (m_cfg.inputInitialTrackParameters.empty()) {
0033     throw std::invalid_argument(
0034         "Missing input initial track parameters collection");
0035   }
0036   if (m_cfg.outputAlignmentParameters.empty()) {
0037     throw std::invalid_argument(
0038         "Missing output alignment parameters collection");
0039   }
0040 
0041   m_inputMeasurements.initialize(m_cfg.inputMeasurements);
0042   m_inputSourceLinks.initialize(m_cfg.inputSourceLinks);
0043   m_inputProtoTracks.initialize(m_cfg.inputProtoTracks);
0044   m_inputInitialTrackParameters.initialize(m_cfg.inputInitialTrackParameters);
0045   m_outputAlignmentParameters.initialize(m_cfg.outputAlignmentParameters);
0046 }
0047 
0048 ActsExamples::ProcessCode ActsExamples::AlignmentAlgorithm::execute(
0049     const ActsExamples::AlgorithmContext& ctx) const {
0050   // Read input data
0051   const auto& measurements = m_inputMeasurements(ctx);
0052   const auto& sourceLinks = m_inputSourceLinks(ctx);
0053   const auto& protoTracks = m_inputProtoTracks(ctx);
0054   const auto& initialParameters = m_inputInitialTrackParameters(ctx);
0055 
0056   // Consistency cross checks
0057   if (protoTracks.size() != initialParameters.size()) {
0058     ACTS_FATAL("Inconsistent number of proto tracks and parameters "
0059                << protoTracks.size() << " vs " << initialParameters.size());
0060     return ProcessCode::ABORT;
0061   }
0062 
0063   std::size_t numTracksUsed = protoTracks.size();
0064   if (m_cfg.maxNumTracks > 0 &&
0065       m_cfg.maxNumTracks < static_cast<int>(protoTracks.size())) {
0066     numTracksUsed = m_cfg.maxNumTracks;
0067   }
0068 
0069   // Prepare the input track collection
0070   std::vector<std::vector<IndexSourceLink>> sourceLinkTrackContainer;
0071   sourceLinkTrackContainer.reserve(numTracksUsed);
0072   std::vector<IndexSourceLink> trackSourceLinks;
0073   for (std::size_t itrack = 0; itrack < numTracksUsed; ++itrack) {
0074     // The list of hits and the initial start parameters
0075     const auto& protoTrack = protoTracks[itrack];
0076 
0077     // Clear & reserve the right size
0078     trackSourceLinks.clear();
0079     trackSourceLinks.reserve(protoTrack.size());
0080 
0081     // Fill the source links via their indices from the container
0082     for (auto hitIndex : protoTrack) {
0083       auto sourceLink = sourceLinks.nth(hitIndex);
0084       if (sourceLink == sourceLinks.end()) {
0085         ACTS_FATAL("Proto track " << itrack << " contains invalid hit index"
0086                                   << hitIndex);
0087         return ProcessCode::ABORT;
0088       }
0089       trackSourceLinks.push_back(*sourceLink);
0090     }
0091     sourceLinkTrackContainer.push_back(trackSourceLinks);
0092   }
0093 
0094   // Prepare the output for alignment parameters
0095   AlignmentParameters alignedParameters;
0096 
0097   // Construct a perigee surface as the target surface for the fitter
0098   auto pSurface = Acts::Surface::makeShared<Acts::PerigeeSurface>(
0099       Acts::Vector3{0., 0., 0.});
0100 
0101   Acts::KalmanFitterExtensions<Acts::VectorMultiTrajectory> extensions;
0102   PassThroughCalibrator pcalibrator;
0103   MeasurementCalibratorAdapter calibrator(pcalibrator, measurements);
0104   extensions.calibrator.connect<&MeasurementCalibratorAdapter::calibrate>(
0105       &calibrator);
0106   Acts::GainMatrixUpdater kfUpdater;
0107   Acts::GainMatrixSmoother kfSmoother;
0108   extensions.updater.connect<
0109       &Acts::GainMatrixUpdater::operator()<Acts::VectorMultiTrajectory>>(
0110       &kfUpdater);
0111   extensions.smoother.connect<
0112       &Acts::GainMatrixSmoother::operator()<Acts::VectorMultiTrajectory>>(
0113       &kfSmoother);
0114 
0115   // Set the KalmanFitter options
0116   TrackFitterOptions kfOptions(ctx.geoContext, ctx.magFieldContext,
0117                                ctx.calibContext, extensions,
0118                                Acts::PropagatorPlainOptions(), &(*pSurface));
0119 
0120   // Set the alignment options
0121   ActsAlignment::AlignmentOptions<TrackFitterOptions> alignOptions(
0122       kfOptions, m_cfg.alignedTransformUpdater, m_cfg.alignedDetElements,
0123       m_cfg.chi2ONdfCutOff, m_cfg.deltaChi2ONdfCutOff, m_cfg.maxNumIterations);
0124 
0125   ACTS_DEBUG("Invoke track-based alignment with " << numTracksUsed
0126                                                   << " input tracks");
0127   auto result =
0128       (*m_cfg.align)(sourceLinkTrackContainer, initialParameters, alignOptions);
0129   if (result.ok()) {
0130     const auto& alignOutput = result.value();
0131     alignedParameters = alignOutput.alignedParameters;
0132     ACTS_VERBOSE(
0133         "Alignment finished with deltaChi2 = " << result.value().deltaChi2);
0134   } else {
0135     ACTS_WARNING("Alignment failed with " << result.error());
0136   }
0137 
0138   // add alignment parameters to event store
0139   m_outputAlignmentParameters(ctx, std::move(alignedParameters));
0140   return ActsExamples::ProcessCode::SUCCESS;
0141 }