Warning, file /EICrecon/src/algorithms/tracking/TrackPropagation.cc was not indexed
or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001
0002
0003
0004 #include <Acts/Definitions/Algebra.hpp>
0005 #include <Acts/Definitions/Direction.hpp>
0006 #include <Acts/Definitions/TrackParametrization.hpp>
0007 #include <Acts/Definitions/Units.hpp>
0008 #include <Acts/EventData/GenericBoundTrackParameters.hpp>
0009 #include <Acts/EventData/MultiTrajectoryHelpers.hpp>
0010 #include <Acts/EventData/ParticleHypothesis.hpp>
0011 #include <Acts/Geometry/GeometryIdentifier.hpp>
0012 #include <Acts/Geometry/TrackingGeometry.hpp>
0013 #include <Acts/MagneticField/MagneticFieldProvider.hpp>
0014 #include <Acts/Propagator/EigenStepper.hpp>
0015 #include <Acts/Propagator/Propagator.hpp>
0016 #include <Acts/Surfaces/CylinderBounds.hpp>
0017 #include <Acts/Surfaces/CylinderSurface.hpp>
0018 #include <Acts/Surfaces/DiscSurface.hpp>
0019 #include <Acts/Surfaces/RadialBounds.hpp>
0020 #include <Acts/Utilities/Logger.hpp>
0021 #include <ActsExamples/EventData/Trajectories.hpp>
0022 #include <DD4hep/Handle.h>
0023 #include <Eigen/Core>
0024 #include <Eigen/Geometry>
0025 #include <Evaluator/DD4hepUnits.h>
0026 #include <algorithm>
0027 #include <boost/container/vector.hpp>
0028 #include <cmath>
0029 #include <cstdint>
0030 #include <edm4hep/Vector3f.h>
0031 #include <edm4hep/utils/vector_utils.h>
0032 #include <fmt/core.h>
0033 #include <functional>
0034 #include <iterator>
0035 #include <map>
0036 #include <optional>
0037 #include <stdexcept>
0038 #include <string>
0039 #include <tuple>
0040 #include <typeinfo>
0041 #include <variant>
0042
0043 #include "algorithms/tracking/ActsGeometryProvider.h"
0044 #include "algorithms/tracking/TrackPropagation.h"
0045 #include "algorithms/tracking/TrackPropagationConfig.h"
0046 #include "extensions/spdlog/SpdlogToActs.h"
0047
0048 namespace eicrecon {
0049
0050 template <typename... L> struct multilambda : L... {
0051 using L::operator()...;
0052 constexpr multilambda(L... lambda) : L(std::move(lambda))... {}
0053 };
0054
0055 void TrackPropagation::init(const dd4hep::Detector* detector,
0056 std::shared_ptr<const ActsGeometryProvider> geo_svc,
0057 std::shared_ptr<spdlog::logger> logger) {
0058 m_geoSvc = geo_svc;
0059 m_log = logger;
0060
0061 std::map<uint32_t, std::size_t> system_id_layers;
0062
0063 multilambda _toDouble = {
0064 [](const std::string& v) { return dd4hep::_toDouble(v); },
0065 [](const double& v) { return v; },
0066 };
0067
0068 auto _toActsSurface =
0069 [&_toDouble, &detector, &system_id_layers](
0070 const std::variant<CylinderSurfaceConfig, DiscSurfaceConfig> surface_variant)
0071 -> std::shared_ptr<Acts::Surface> {
0072 if (std::holds_alternative<CylinderSurfaceConfig>(surface_variant)) {
0073 CylinderSurfaceConfig surface = std::get<CylinderSurfaceConfig>(surface_variant);
0074 const double rmin =
0075 std::visit(_toDouble, surface.rmin) / dd4hep::mm * Acts::UnitConstants::mm;
0076 const double zmin =
0077 std::visit(_toDouble, surface.zmin) / dd4hep::mm * Acts::UnitConstants::mm;
0078 const double zmax =
0079 std::visit(_toDouble, surface.zmax) / dd4hep::mm * Acts::UnitConstants::mm;
0080 const uint32_t system_id = detector->constant<uint32_t>(surface.id);
0081 auto bounds = std::make_shared<Acts::CylinderBounds>(rmin, (zmax - zmin) / 2);
0082 auto t = Acts::Translation3(Acts::Vector3(0, 0, (zmax + zmin) / 2));
0083 auto tf = Acts::Transform3(t);
0084 auto acts_surface = Acts::Surface::makeShared<Acts::CylinderSurface>(tf, bounds);
0085 #if Acts_VERSION_MAJOR >= 40
0086 acts_surface->assignGeometryId(
0087 Acts::GeometryIdentifier().withExtra(system_id).withLayer(++system_id_layers[system_id]));
0088 #else
0089 acts_surface->assignGeometryId(
0090 Acts::GeometryIdentifier().setExtra(system_id).setLayer(++system_id_layers[system_id]));
0091 #endif
0092 return acts_surface;
0093 }
0094 if (std::holds_alternative<DiscSurfaceConfig>(surface_variant)) {
0095 DiscSurfaceConfig surface = std::get<DiscSurfaceConfig>(surface_variant);
0096 const double zmin =
0097 std::visit(_toDouble, surface.zmin) / dd4hep::mm * Acts::UnitConstants::mm;
0098 const double rmin =
0099 std::visit(_toDouble, surface.rmin) / dd4hep::mm * Acts::UnitConstants::mm;
0100 const double rmax =
0101 std::visit(_toDouble, surface.rmax) / dd4hep::mm * Acts::UnitConstants::mm;
0102 const uint32_t system_id = detector->constant<uint32_t>(surface.id);
0103 auto bounds = std::make_shared<Acts::RadialBounds>(rmin, rmax);
0104 auto t = Acts::Translation3(Acts::Vector3(0, 0, zmin));
0105 auto tf = Acts::Transform3(t);
0106 auto acts_surface = Acts::Surface::makeShared<Acts::DiscSurface>(tf, bounds);
0107 #if Acts_VERSION_MAJOR >= 40
0108 acts_surface->assignGeometryId(
0109 Acts::GeometryIdentifier().withExtra(system_id).withLayer(++system_id_layers[system_id]));
0110 #else
0111 acts_surface->assignGeometryId(
0112 Acts::GeometryIdentifier().setExtra(system_id).setLayer(++system_id_layers[system_id]));
0113 #endif
0114 return acts_surface;
0115 }
0116 throw std::domain_error("Unknown surface type");
0117 };
0118 m_target_surfaces.resize(m_cfg.target_surfaces.size());
0119 std::transform(m_cfg.target_surfaces.cbegin(), m_cfg.target_surfaces.cend(),
0120 m_target_surfaces.begin(), _toActsSurface);
0121 m_filter_surfaces.resize(m_cfg.filter_surfaces.size());
0122 std::transform(m_cfg.filter_surfaces.cbegin(), m_cfg.filter_surfaces.cend(),
0123 m_filter_surfaces.begin(), _toActsSurface);
0124
0125 m_log->trace("Initialized");
0126 }
0127
0128 void TrackPropagation::propagateToSurfaceList(
0129 const std::tuple<const edm4eic::TrackCollection&,
0130 const std::vector<const ActsExamples::Trajectories*>,
0131 const std::vector<const ActsExamples::ConstTrackContainer*>>
0132 input,
0133 const std::tuple<edm4eic::TrackSegmentCollection*> output) const {
0134 const auto [tracks, acts_trajectories, acts_tracks] = input;
0135 auto [track_segments] = output;
0136
0137
0138 m_log->trace("Propagate trajectories: --------------------");
0139 m_log->trace("number of tracks: {}", tracks.size());
0140 m_log->trace("number of acts_trajectories: {}", acts_trajectories.size());
0141 m_log->trace("number of acts_tracks: {}", acts_tracks.size());
0142
0143
0144 for (std::size_t i = 0; const auto& traj : acts_trajectories) {
0145
0146
0147 bool trajectory_reaches_filter_surface{false};
0148 for (const auto& filter_surface : m_filter_surfaces) {
0149 auto point = propagate(edm4eic::Track{}, traj, filter_surface);
0150 if (point) {
0151 trajectory_reaches_filter_surface = true;
0152 break;
0153 }
0154 }
0155 if (!trajectory_reaches_filter_surface) {
0156 ++i;
0157 continue;
0158 }
0159
0160
0161 auto track_segment = track_segments->create();
0162
0163
0164 if (tracks.size() == acts_trajectories.size()) {
0165 m_log->trace("track segment connected to track {}", i);
0166 track_segment.setTrack(tracks[i]);
0167 ++i;
0168 }
0169
0170
0171 decltype(edm4eic::TrackSegmentData::length) length = 0;
0172 decltype(edm4eic::TrackSegmentData::lengthError) length_error = 0;
0173
0174
0175 for (const auto& target_surface : m_target_surfaces) {
0176
0177
0178 auto point = propagate(edm4eic::Track{}, traj, target_surface);
0179 if (!point) {
0180 m_log->trace("<> Failed to propagate trajectory to this plane");
0181 continue;
0182 }
0183
0184
0185 m_log->trace("<> trajectory: x=( {:>10.2f} {:>10.2f} {:>10.2f} )", point->position.x,
0186 point->position.y, point->position.z);
0187 m_log->trace(" p=( {:>10.2f} {:>10.2f} {:>10.2f} )", point->momentum.x,
0188 point->momentum.y, point->momentum.z);
0189
0190
0191 if (!m_cfg.track_point_cut(*point)) {
0192 m_log->trace(" => REJECTED by trackPointCut");
0193 if (m_cfg.skip_track_on_track_point_cut_failure) {
0194 break;
0195 }
0196 continue;
0197 }
0198
0199
0200
0201 if (track_segment.points_size() > 0) {
0202 auto pos0 = point->position;
0203 auto pos1 = std::prev(track_segment.points_end())->position;
0204 auto dist = edm4hep::utils::magnitude(pos0 - pos1);
0205 length += dist;
0206 m_log->trace(" dist to previous point: {}", dist);
0207 }
0208
0209
0210 track_segment.addToPoints(*point);
0211
0212 }
0213
0214
0215 track_segment.setLength(length);
0216 track_segment.setLengthError(length_error);
0217
0218 }
0219 }
0220
0221 std::unique_ptr<edm4eic::TrackPoint>
0222 TrackPropagation::propagate(const edm4eic::Track& ,
0223 const ActsExamples::Trajectories* acts_trajectory,
0224 const std::shared_ptr<const Acts::Surface>& targetSurf) const {
0225
0226
0227
0228 const auto& mj = acts_trajectory->multiTrajectory();
0229 const auto& trackTips = acts_trajectory->tips();
0230
0231 m_log->trace(" Number of elements in trackTips {}", trackTips.size());
0232
0233
0234 if (trackTips.empty()) {
0235 m_log->trace(" Empty multiTrajectory.");
0236 return nullptr;
0237 }
0238 const auto& trackTip = trackTips.front();
0239
0240
0241 auto trajState = Acts::MultiTrajectoryHelpers::trajectoryState(mj, trackTip);
0242 int m_nMeasurements = trajState.nMeasurements;
0243 int m_nStates = trajState.nStates;
0244
0245 m_log->trace(" Num measurement in trajectory: {}", m_nMeasurements);
0246 m_log->trace(" Num states in trajectory : {}", m_nStates);
0247
0248
0249
0250 auto trackState = mj.getTrackState(trackTip);
0251 auto initSurface = trackState.referenceSurface().getSharedPtr();
0252 const auto& initParams = trackState.filtered();
0253 const auto& initCov = trackState.filteredCovariance();
0254
0255 Acts::BoundTrackParameters initBoundParams(initSurface, initParams, initCov,
0256 Acts::ParticleHypothesis::pion());
0257
0258
0259 const auto initPathLength = trackState.pathLength();
0260
0261 m_log->trace(" TrackPropagation. Propagating to surface # {}",
0262 typeid(targetSurf->type()).name());
0263
0264 std::shared_ptr<const Acts::TrackingGeometry> trackingGeometry = m_geoSvc->trackingGeometry();
0265 std::shared_ptr<const Acts::MagneticFieldProvider> magneticField = m_geoSvc->getFieldProvider();
0266 using Stepper = Acts::EigenStepper<>;
0267 using Propagator = Acts::Propagator<Stepper>;
0268 Stepper stepper(magneticField);
0269 Propagator propagator(stepper);
0270
0271 ACTS_LOCAL_LOGGER(eicrecon::getSpdlogLogger("PROP", m_log));
0272
0273 #if Acts_VERSION_MAJOR >= 36
0274 Propagator::template Options<> options(m_geoContext, m_fieldContext);
0275 #else
0276 Acts::PropagatorOptions<> options(m_geoContext, m_fieldContext);
0277 #endif
0278
0279 auto result = propagator.propagate(initBoundParams, *targetSurf, options);
0280
0281
0282 if (!result.ok()) {
0283 m_log->trace(" propagation failed (!result.ok())");
0284 return nullptr;
0285 }
0286 m_log->trace(" propagation result is OK");
0287
0288
0289 auto trackStateParams = *((*result).endParameters);
0290 const auto& parameter = trackStateParams.parameters();
0291 const auto& covariance = *trackStateParams.covariance();
0292
0293
0294 const float pathLength = initPathLength + (*result).pathLength;
0295 const float pathLengthError = 0;
0296 m_log->trace(" path len = {}", pathLength);
0297
0298
0299 auto projectionPos = trackStateParams.position(m_geoContext);
0300 const decltype(edm4eic::TrackPoint::position) position{static_cast<float>(projectionPos(0)),
0301 static_cast<float>(projectionPos(1)),
0302 static_cast<float>(projectionPos(2))};
0303 const decltype(edm4eic::TrackPoint::positionError) positionError{0, 0, 0};
0304 m_log->trace(" pos x = {}", position.x);
0305 m_log->trace(" pos y = {}", position.y);
0306 m_log->trace(" pos z = {}", position.z);
0307
0308
0309 const decltype(edm4eic::TrackPoint::momentum) momentum = edm4hep::utils::sphericalToVector(
0310 static_cast<float>(1.0 / std::abs(parameter[Acts::eBoundQOverP])),
0311 static_cast<float>(parameter[Acts::eBoundTheta]),
0312 static_cast<float>(parameter[Acts::eBoundPhi]));
0313 const decltype(edm4eic::TrackPoint::momentumError) momentumError{
0314 static_cast<float>(covariance(Acts::eBoundTheta, Acts::eBoundTheta)),
0315 static_cast<float>(covariance(Acts::eBoundPhi, Acts::eBoundPhi)),
0316 static_cast<float>(covariance(Acts::eBoundQOverP, Acts::eBoundQOverP)),
0317 static_cast<float>(covariance(Acts::eBoundTheta, Acts::eBoundPhi)),
0318 static_cast<float>(covariance(Acts::eBoundTheta, Acts::eBoundQOverP)),
0319 static_cast<float>(covariance(Acts::eBoundPhi, Acts::eBoundQOverP))};
0320
0321
0322 const float time{static_cast<float>(parameter(Acts::eBoundTime))};
0323 const float timeError{static_cast<float>(sqrt(covariance(Acts::eBoundTime, Acts::eBoundTime)))};
0324
0325
0326 const float theta(parameter[Acts::eBoundTheta]);
0327 const float phi(parameter[Acts::eBoundPhi]);
0328 const decltype(edm4eic::TrackPoint::directionError) directionError{
0329 static_cast<float>(covariance(Acts::eBoundTheta, Acts::eBoundTheta)),
0330 static_cast<float>(covariance(Acts::eBoundPhi, Acts::eBoundPhi)),
0331 static_cast<float>(covariance(Acts::eBoundTheta, Acts::eBoundPhi))};
0332
0333
0334 m_log->trace(" loc 0 = {:.4f}", parameter[Acts::eBoundLoc0]);
0335 m_log->trace(" loc 1 = {:.4f}", parameter[Acts::eBoundLoc1]);
0336 m_log->trace(" phi = {:.4f}", parameter[Acts::eBoundPhi]);
0337 m_log->trace(" theta = {:.4f}", parameter[Acts::eBoundTheta]);
0338 m_log->trace(" q/p = {:.4f}", parameter[Acts::eBoundQOverP]);
0339 m_log->trace(" p = {:.4f}", 1.0 / parameter[Acts::eBoundQOverP]);
0340 m_log->trace(" err phi = {:.4f}", sqrt(covariance(Acts::eBoundPhi, Acts::eBoundPhi)));
0341 m_log->trace(" err th = {:.4f}", sqrt(covariance(Acts::eBoundTheta, Acts::eBoundTheta)));
0342 m_log->trace(" err q/p = {:.4f}", sqrt(covariance(Acts::eBoundQOverP, Acts::eBoundQOverP)));
0343 m_log->trace(" chi2 = {:.4f}", trajState.chi2Sum);
0344 m_log->trace(" loc err = {:.4f}",
0345 static_cast<float>(covariance(Acts::eBoundLoc0, Acts::eBoundLoc0)));
0346 m_log->trace(" loc err = {:.4f}",
0347 static_cast<float>(covariance(Acts::eBoundLoc1, Acts::eBoundLoc1)));
0348 m_log->trace(" loc err = {:.4f}",
0349 static_cast<float>(covariance(Acts::eBoundLoc0, Acts::eBoundLoc1)));
0350
0351 uint64_t surface = targetSurf->geometryId().value();
0352 uint32_t system = 0;
0353
0354 return std::make_unique<edm4eic::TrackPoint>(
0355 edm4eic::TrackPoint{surface, system, position, positionError, momentum, momentumError, time,
0356 timeError, theta, phi, directionError, pathLength, pathLengthError});
0357 }
0358
0359 }