File indexing completed on 2026-08-04 08:39:33
0001
0002
0003
0004
0005
0006
0007
0008
0009 #pragma once
0010
0011 #include "Acts/Definitions/Algebra.hpp"
0012 #include "Acts/Definitions/TrackParametrization.hpp"
0013 #include "Acts/EventData/TrackParameters.hpp"
0014 #include "Acts/Geometry/GeometryContext.hpp"
0015 #include "Acts/Geometry/Polyhedron.hpp"
0016 #include "Acts/Surfaces/Surface.hpp"
0017 #include "Acts/Visualization/GeometryView3D.hpp"
0018 #include "Acts/Visualization/IVisualization3D.hpp"
0019 #include "Acts/Visualization/ViewConfig.hpp"
0020
0021 #include <array>
0022 #include <cmath>
0023 #include <cstddef>
0024 #include <numbers>
0025 #include <vector>
0026
0027 namespace Acts {
0028 class IVisualization3D;
0029
0030
0031 static ViewConfig s_viewParameter = {.color = {0, 0, 255}};
0032
0033 static ViewConfig s_viewMeasurement = {.color = {255, 102, 0}};
0034
0035 static ViewConfig s_viewPredicted = {.color = {51, 204, 51}};
0036
0037 static ViewConfig s_viewFiltered = {.color = {255, 255, 0}};
0038
0039 static ViewConfig s_viewSmoothed = {.color = {0, 102, 25}};
0040
0041
0042 struct EventDataView3D {
0043
0044
0045
0046
0047 static inline std::array<double, 3> decomposeCovariance(
0048 const SquareMatrix<2>& covariance) {
0049 double c00 = covariance(eBoundLoc0, eBoundLoc0);
0050 double c01 = covariance(eBoundLoc0, eBoundLoc1);
0051 double c11 = covariance(eBoundLoc1, eBoundLoc1);
0052
0053 double cdsq = std::pow((c00 - c11), 2) / 4.;
0054 double cosq = c01 * c01;
0055
0056
0057 double lambda0 = (c00 + c11) / 2. + std::sqrt(cdsq + cosq);
0058 double lambda1 = (c00 + c11) / 2. - std::sqrt(cdsq + cosq);
0059 double theta = std::atan2(lambda0 - c00, c01);
0060
0061 return {lambda0, lambda1, theta};
0062 }
0063
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074 static inline std::vector<Vector3> createEllipse(
0075 double lambda0, double lambda1, double theta, std::size_t lseg,
0076 double offset, const Vector2& lposition = Vector2(0., 0.),
0077 const Transform3& transform = Transform3::Identity()) {
0078 double ctheta = std::cos(theta);
0079 double stheta = std::sin(theta);
0080
0081 double l1sq = std::sqrt(lambda0);
0082 double l2sq = std::sqrt(lambda1);
0083
0084
0085 std::vector<Vector3> ellipse;
0086 ellipse.reserve(lseg);
0087 double thetaStep = 2 * std::numbers::pi / lseg;
0088 for (std::size_t it = 0; it < lseg; ++it) {
0089 double phi = -std::numbers::pi + it * thetaStep;
0090 double cphi = std::cos(phi);
0091 double sphi = std::sin(phi);
0092 double x = lposition.x() + (l1sq * ctheta * cphi - l2sq * stheta * sphi);
0093 double y = lposition.y() + (l1sq * stheta * cphi + l2sq * ctheta * sphi);
0094 ellipse.push_back(transform * Vector3(x, y, offset));
0095 }
0096 return ellipse;
0097 }
0098
0099
0100
0101
0102
0103
0104
0105
0106
0107 static void drawCovarianceCartesian(
0108 IVisualization3D& helper, const Vector2& lposition,
0109 const SquareMatrix2& covariance, const Transform3& transform,
0110 double locErrorScale = 1, const ViewConfig& viewConfig = s_viewParameter);
0111
0112
0113
0114
0115
0116
0117
0118
0119
0120
0121 static void drawCovarianceAngular(
0122 IVisualization3D& helper, const Vector3& position,
0123 const Vector3& direction, const SquareMatrix<2>& covariance,
0124 double directionScale = 1, double angularErrorScale = 1,
0125 const ViewConfig& viewConfig = s_viewParameter);
0126
0127
0128
0129
0130
0131
0132
0133
0134
0135
0136
0137
0138 template <typename parameters_t>
0139 static inline void drawBoundTrackParameters(
0140 IVisualization3D& helper, const parameters_t& parameters,
0141 const GeometryContext& gctx =
0142 GeometryContext::dangerouslyDefaultConstruct(),
0143 double momentumScale = 1., double locErrorScale = 1.,
0144 double angularErrorScale = 1.,
0145 const ViewConfig& parConfig = s_viewParameter,
0146 const ViewConfig& covConfig = s_viewParameter,
0147 const ViewConfig& surfConfig = s_viewSensitive) {
0148 if (surfConfig.visible) {
0149 GeometryView3D::drawSurface(helper, parameters.referenceSurface(), gctx,
0150 Transform3::Identity(), surfConfig);
0151 }
0152
0153
0154 auto position = parameters.position(gctx);
0155 auto direction = parameters.direction();
0156 double p = parameters.absoluteMomentum();
0157
0158 ViewConfig lparConfig = parConfig;
0159 lparConfig.lineThickness = 0.05;
0160 Vector3 parLength = p * momentumScale * direction;
0161
0162 GeometryView3D::drawArrowBackward(
0163 helper, position, position + 0.5 * parLength, 100., 1.0, lparConfig);
0164
0165 GeometryView3D::drawArrowForward(helper, position + 0.5 * parLength,
0166 position + parLength, 4., 2.5, lparConfig);
0167
0168 if (parameters.covariance().has_value()) {
0169 auto paramVec = parameters.parameters();
0170 auto lposition = paramVec.template block<2, 1>(0, 0);
0171
0172
0173 const auto& covariance = *parameters.covariance();
0174 drawCovarianceCartesian(
0175 helper, lposition, covariance.template block<2, 2>(0, 0),
0176 parameters.referenceSurface().localToGlobalTransform(gctx),
0177 locErrorScale, covConfig);
0178
0179 drawCovarianceAngular(
0180 helper, position, direction, covariance.template block<2, 2>(2, 2),
0181 0.9 * p * momentumScale, angularErrorScale, covConfig);
0182 }
0183 }
0184
0185
0186
0187
0188
0189
0190
0191
0192
0193
0194
0195 static void drawMeasurement(
0196 IVisualization3D& helper, const Vector2& lposition,
0197 const SquareMatrix2& covariance, const Transform3& transform,
0198 const double locErrorScale = 1.,
0199 const ViewConfig& measurementConfig = s_viewMeasurement) {
0200 if (locErrorScale <= 0) {
0201 throw std::invalid_argument("locErrorScale must be > 0");
0202 }
0203 if (measurementConfig.visible) {
0204 drawCovarianceCartesian(helper, lposition, covariance, transform,
0205 locErrorScale, measurementConfig);
0206 }
0207 }
0208
0209
0210
0211
0212
0213
0214
0215
0216
0217
0218
0219
0220
0221
0222
0223
0224
0225
0226 template <typename traj_t>
0227 static void drawMultiTrajectory(
0228 IVisualization3D& helper, const traj_t& multiTraj,
0229 const std::size_t& entryIndex,
0230 const GeometryContext& gctx =
0231 GeometryContext::dangerouslyDefaultConstruct(),
0232 double momentumScale = 1., double locErrorScale = 1.,
0233 double angularErrorScale = 1.,
0234 const ViewConfig& surfaceConfig = s_viewSensitive,
0235 const ViewConfig& measurementConfig = s_viewMeasurement,
0236 const ViewConfig& predictedConfig = s_viewPredicted,
0237 const ViewConfig& filteredConfig = s_viewFiltered,
0238 const ViewConfig& smoothedConfig = s_viewSmoothed) {
0239
0240
0241
0242 ParticleHypothesis particleHypothesis = ParticleHypothesis::pion();
0243
0244
0245 multiTraj.visitBackwards(entryIndex, [&](const auto& state) {
0246
0247 if (!state.typeFlags().hasMeasurement()) {
0248 return true;
0249 }
0250
0251
0252
0253 if (state.index() == 0) {
0254 locErrorScale = locErrorScale * 0.1;
0255 angularErrorScale = angularErrorScale * 0.1;
0256 }
0257
0258
0259 if (surfaceConfig.visible) {
0260 GeometryView3D::drawSurface(helper, state.referenceSurface(), gctx,
0261 Transform3::Identity(), surfaceConfig);
0262 }
0263
0264
0265
0266
0267 if (state.hasCalibrated() && state.calibratedSize() == 2) {
0268 const Vector2& lposition = state.template calibrated<2>();
0269 const SquareMatrix2 covariance =
0270 state.template calibratedCovariance<2>();
0271 drawMeasurement(helper, lposition, covariance,
0272 state.referenceSurface().localToGlobalTransform(gctx),
0273 locErrorScale, measurementConfig);
0274 }
0275
0276
0277
0278 if (predictedConfig.visible && state.hasPredicted()) {
0279 drawBoundTrackParameters(
0280 helper,
0281 BoundTrackParameters(state.referenceSurface().getSharedPtr(),
0282 state.predicted(), state.predictedCovariance(),
0283 particleHypothesis),
0284 gctx, momentumScale, locErrorScale, angularErrorScale,
0285 predictedConfig, predictedConfig, {.visible = false});
0286 }
0287
0288 if (filteredConfig.visible && state.hasFiltered()) {
0289 drawBoundTrackParameters(
0290 helper,
0291 BoundTrackParameters(state.referenceSurface().getSharedPtr(),
0292 state.filtered(), state.filteredCovariance(),
0293 particleHypothesis),
0294 gctx, momentumScale, locErrorScale, angularErrorScale,
0295 filteredConfig, filteredConfig, {.visible = false});
0296 }
0297
0298 if (smoothedConfig.visible && state.hasSmoothed()) {
0299 drawBoundTrackParameters(
0300 helper,
0301 BoundTrackParameters(state.referenceSurface().getSharedPtr(),
0302 state.smoothed(), state.smoothedCovariance(),
0303 particleHypothesis),
0304 gctx, momentumScale, locErrorScale, angularErrorScale,
0305 smoothedConfig, smoothedConfig, {.visible = false});
0306 }
0307 return true;
0308 });
0309 }
0310 };
0311
0312 }