Analysis Software
Documentation for sPHENIX simulation software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
EventDataView3D.hpp
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file EventDataView3D.hpp
1 // This file is part of the Acts project.
2 //
3 // Copyright (C) 2020-2023 CERN for the benefit of the Acts project
4 //
5 // This Source Code Form is subject to the terms of the Mozilla Public
6 // License, v. 2.0. If a copy of the MPL was not distributed with this
7 // file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 
9 #pragma once
10 
25 
26 #include <array>
27 #include <cmath>
28 #include <cstddef>
29 #include <optional>
30 #include <vector>
31 
32 namespace Acts {
33 class IVisualization3D;
34 
35 static ViewConfig s_viewParameter = ViewConfig({0, 0, 255});
36 static ViewConfig s_viewMeasurement = ViewConfig({255, 102, 0});
37 static ViewConfig s_viewPredicted = ViewConfig({51, 204, 51});
38 static ViewConfig s_viewFiltered = ViewConfig({255, 255, 0});
39 static ViewConfig s_viewSmoothed = ViewConfig({0, 102, 255});
40 
45  static inline std::array<double, 3> decomposeCovariance(
47  double c00 = covariance(eBoundLoc0, eBoundLoc0);
48  double c01 = covariance(eBoundLoc0, eBoundLoc1);
49  double c11 = covariance(eBoundLoc1, eBoundLoc1);
50 
51  double cdsq = std::pow((c00 - c11), 2) / 4.;
52  double cosq = c01 * c01;
53 
54  // Calculate the eigen values w.r.t reference frame
55  double lambda0 = (c00 + c11) / 2. + std::sqrt(cdsq + cosq);
56  double lambda1 = (c00 + c11) / 2. - std::sqrt(cdsq + cosq);
57  double theta = atan2(lambda0 - c00, c01);
58 
59  return {lambda0, lambda1, theta};
60  }
61 
71  static inline std::vector<Vector3> createEllipse(
72  double lambda0, double lambda1, double theta, size_t lseg, double offset,
73  const Vector2& lposition = Vector2(0., 0.),
74  const Transform3& transform = Transform3::Identity()) {
75  double ctheta = std::cos(theta);
76  double stheta = std::sin(theta);
77 
78  double l1sq = std::sqrt(lambda0);
79  double l2sq = std::sqrt(lambda1);
80 
81  // Now generate the ellipse points
82  std::vector<Vector3> ellipse;
83  ellipse.reserve(lseg);
84  double thetaStep = 2 * M_PI / lseg;
85  for (size_t it = 0; it < lseg; ++it) {
86  double phi = -M_PI + it * thetaStep;
87  double cphi = std::cos(phi);
88  double sphi = std::sin(phi);
89  double x = lposition.x() + (l1sq * ctheta * cphi - l2sq * stheta * sphi);
90  double y = lposition.y() + (l1sq * stheta * cphi + l2sq * ctheta * sphi);
91  ellipse.push_back(transform * Vector3(x, y, offset));
92  }
93  return ellipse;
94  }
95 
104  static void drawCovarianceCartesian(
105  IVisualization3D& helper, const Vector2& lposition,
107  double locErrorScale = 1, const ViewConfig& viewConfig = s_viewParameter);
108 
118  static void drawCovarianceAngular(
119  IVisualization3D& helper, const Vector3& position,
120  const Vector3& direction, const ActsSquareMatrix<2>& covariance,
121  double directionScale = 1, double angularErrorScale = 1,
122  const ViewConfig& viewConfig = s_viewParameter);
123 
135  template <typename parameters_t>
136  static inline void drawBoundTrackParameters(
137  IVisualization3D& helper, const parameters_t& parameters,
139  double momentumScale = 1., double locErrorScale = 1.,
140  double angularErrorScale = 1.,
141  const ViewConfig& parConfig = s_viewParameter,
142  const ViewConfig& covConfig = s_viewParameter,
143  const ViewConfig& surfConfig = s_viewSensitive) {
144  if (surfConfig.visible) {
145  GeometryView3D::drawSurface(helper, parameters.referenceSurface(), gctx,
146  Transform3::Identity(), surfConfig);
147  }
148 
149  // Draw the parameter shaft and cone
150  auto position = parameters.position(gctx);
151  auto direction = parameters.direction();
152  double p = parameters.absoluteMomentum();
153 
154  ViewConfig lparConfig = parConfig;
155  lparConfig.lineThickness = 0.05;
156  Vector3 parLength = p * momentumScale * direction;
157 
159  helper, position, position + 0.5 * parLength, 100., 1.0, lparConfig);
160 
161  GeometryView3D::drawArrowForward(helper, position + 0.5 * parLength,
162  position + parLength, 4., 2.5, lparConfig);
163 
164  if (parameters.covariance().has_value()) {
165  auto paramVec = parameters.parameters();
166  auto lposition = paramVec.template block<2, 1>(0, 0);
167 
168  // Draw the local covariance
169  const auto& covariance = *parameters.covariance();
170  drawCovarianceCartesian(helper, lposition,
171  covariance.template block<2, 2>(0, 0),
172  parameters.referenceSurface().transform(gctx),
173  locErrorScale, covConfig);
174 
176  helper, position, direction, covariance.template block<2, 2>(2, 2),
177  0.9 * p * momentumScale, angularErrorScale, covConfig);
178  }
179  }
180 
191  static void drawMeasurement(
192  IVisualization3D& helper, const Vector2& lposition,
194  const double locErrorScale = 1.,
195  const ViewConfig& measurementConfig = s_viewMeasurement) {
196  if (locErrorScale <= 0) {
197  throw std::invalid_argument("locErrorScale must be > 0");
198  }
199  if (measurementConfig.visible) {
200  drawCovarianceCartesian(helper, lposition, covariance, transform,
201  locErrorScale, measurementConfig);
202  }
203  }
204 
222  template <typename traj_t>
223  static void drawMultiTrajectory(
224  IVisualization3D& helper, const traj_t& multiTraj,
225  const size_t& entryIndex, const GeometryContext& gctx = GeometryContext(),
226  double momentumScale = 1., double locErrorScale = 1.,
227  double angularErrorScale = 1.,
228  const ViewConfig& surfaceConfig = s_viewSensitive,
229  const ViewConfig& measurementConfig = s_viewMeasurement,
230  const ViewConfig& predictedConfig = s_viewPredicted,
231  const ViewConfig& filteredConfig = s_viewFiltered,
232  const ViewConfig& smoothedConfig = s_viewSmoothed) {
233  // @TODO: Refactor based on Track class
234 
235  // TODO get particle hypothesis from track
237 
238  // Visit the track states on the trajectory
239  multiTraj.visitBackwards(entryIndex, [&](const auto& state) {
240  // Only draw the measurement states
241  if (not state.typeFlags().test(Acts::TrackStateFlag::MeasurementFlag)) {
242  return true;
243  }
244 
245  // Use smaller scaling factors for the first state
246  // @Todo: add parameter for the first state error scaling
247  if (state.index() == 0) {
248  locErrorScale = locErrorScale * 0.1;
249  angularErrorScale = angularErrorScale * 0.1;
250  }
251 
252  // First, if necessary, draw the surface
253  if (surfaceConfig.visible) {
254  GeometryView3D::drawSurface(helper, state.referenceSurface(), gctx,
255  Transform3::Identity(), surfaceConfig);
256  }
257 
258  // Second, if necessary and present, draw the calibrated measurement (only
259  // draw 2D measurement here)
260  // @Todo: how to draw 1D measurement?
261  if (state.hasCalibrated() and state.calibratedSize() == 2) {
262  const Vector2& lposition = state.template calibrated<2>();
263  const SquareMatrix2 covariance =
264  state.template calibratedCovariance<2>();
265  drawMeasurement(helper, lposition, covariance,
266  state.referenceSurface().transform(gctx), locErrorScale,
267  measurementConfig);
268  }
269 
270  // Last, if necessary and present, draw the track parameters
271  // (a) predicted track parameters
272  if (predictedConfig.visible and state.hasPredicted()) {
274  helper,
275  BoundTrackParameters(state.referenceSurface().getSharedPtr(),
276  state.predicted(), state.predictedCovariance(),
278  gctx, momentumScale, locErrorScale, angularErrorScale,
279  predictedConfig, predictedConfig, ViewConfig(false));
280  }
281  // (b) filtered track parameters
282  if (filteredConfig.visible and state.hasFiltered()) {
284  helper,
285  BoundTrackParameters(state.referenceSurface().getSharedPtr(),
286  state.filtered(), state.filteredCovariance(),
288  gctx, momentumScale, locErrorScale, angularErrorScale,
289  filteredConfig, filteredConfig, ViewConfig(false));
290  }
291  // (c) smoothed track parameters
292  if (smoothedConfig.visible and state.hasSmoothed()) {
294  helper,
295  BoundTrackParameters(state.referenceSurface().getSharedPtr(),
296  state.smoothed(), state.smoothedCovariance(),
298  gctx, momentumScale, locErrorScale, angularErrorScale,
299  smoothedConfig, smoothedConfig, ViewConfig(false));
300  }
301  return true;
302  });
303  }
304 };
305 
306 } // namespace Acts