EIC 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 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 
23 
24 #include <optional>
25 
26 namespace Acts {
27 
28 static ViewConfig s_viewParameter = ViewConfig({0, 0, 255});
29 static ViewConfig s_viewMeasurement = ViewConfig({255, 102, 0});
30 static ViewConfig s_viewPredicted = ViewConfig({51, 204, 51});
31 static ViewConfig s_viewFiltered = ViewConfig({255, 255, 0});
32 static ViewConfig s_viewSmoothed = ViewConfig({0, 102, 255});
33 
38  static inline std::array<double, 3> decomposeCovariance(
39  const ActsSymMatrixD<2>& covariance) {
40  double c00 = covariance(eBoundLoc0, eBoundLoc0);
41  double c01 = covariance(eBoundLoc0, eBoundLoc1);
42  double c11 = covariance(eBoundLoc1, eBoundLoc1);
43 
44  double cdsq = std::pow((c00 - c11), 2) / 4.;
45  double cosq = c01 * c01;
46 
47  // Calculate the eigen values w.r.t reference frame
48  double lambda0 = (c00 + c11) / 2. + std::sqrt(cdsq + cosq);
49  double lambda1 = (c00 + c11) / 2. - std::sqrt(cdsq + cosq);
50  double theta = atan2(lambda0 - c00, c01);
51 
52  return {lambda0, lambda1, theta};
53  }
54 
64  static inline std::vector<Vector3D> createEllipse(
65  double lambda0, double lambda1, double theta, size_t lseg, double offset,
66  const Vector2D& lposition = Vector2D(0., 0.),
67  const Transform3D& transform = Transform3D::Identity()) {
68  double ctheta = std::cos(theta);
69  double stheta = std::sin(theta);
70 
71  double l1sq = std::sqrt(lambda0);
72  double l2sq = std::sqrt(lambda1);
73 
74  // Now generate the ellipse points
75  std::vector<Vector3D> ellipse;
76  ellipse.reserve(lseg);
77  double thetaStep = 2 * M_PI / lseg;
78  for (size_t it = 0; it < lseg; ++it) {
79  double phi = -M_PI + it * thetaStep;
80  double cphi = std::cos(phi);
81  double sphi = std::sin(phi);
82  double x = lposition.x() + (l1sq * ctheta * cphi - l2sq * stheta * sphi);
83  double y = lposition.y() + (l1sq * stheta * cphi + l2sq * ctheta * sphi);
84  ellipse.push_back(transform * Vector3D(x, y, offset));
85  }
86  return ellipse;
87  }
88 
97  static void drawCovarianceCartesian(
98  IVisualization3D& helper, const Vector2D& lposition,
99  const ActsSymMatrixD<2>& covariance, const Transform3D& transform,
100  double locErrorScale = 1, const ViewConfig& viewConfig = s_viewParameter);
101 
111  static void drawCovarianceAngular(
112  IVisualization3D& helper, const Vector3D& position,
113  const Vector3D& direction, const ActsSymMatrixD<2>& covariance,
114  double directionScale = 1, double angularErrorScale = 1,
115  const ViewConfig& viewConfig = s_viewParameter);
116 
128  template <typename parameters_t>
129  static inline void drawBoundTrackParameters(
130  IVisualization3D& helper, const parameters_t& parameters,
132  double momentumScale = 1., double locErrorScale = 1.,
133  double angularErrorScale = 1.,
134  const ViewConfig& parConfig = s_viewParameter,
135  const ViewConfig& covConfig = s_viewParameter,
136  const ViewConfig& surfConfig = s_viewSensitive) {
137  if (surfConfig.visible) {
138  GeometryView3D::drawSurface(helper, parameters.referenceSurface(), gctx,
139  Transform3D::Identity(), surfConfig);
140  }
141 
142  // Draw the parameter shaft and cone
143  auto position = parameters.position(gctx);
144  auto direction = parameters.unitDirection();
145  double p = parameters.absoluteMomentum();
146 
147  ViewConfig lparConfig = parConfig;
148  lparConfig.lineThickness = 0.05;
149  Vector3D parLength = p * momentumScale * direction;
150 
152  helper, position, position + 0.5 * parLength, 100., 1.0, lparConfig);
153 
154  GeometryView3D::drawArrowForward(helper, position + 0.5 * parLength,
155  position + parLength, 4., 2.5, lparConfig);
156 
157  if (parameters.covariance().has_value()) {
158  auto paramVec = parameters.parameters();
159  auto lposition = paramVec.template block<2, 1>(0, 0);
160 
161  // Draw the local covariance
162  const auto& covariance = *parameters.covariance();
163  drawCovarianceCartesian(helper, lposition,
164  covariance.template block<2, 2>(0, 0),
165  parameters.referenceSurface().transform(gctx),
166  locErrorScale, covConfig);
167 
169  helper, position, direction, covariance.template block<2, 2>(2, 2),
170  0.9 * p * momentumScale, angularErrorScale, covConfig);
171  }
172  }
173 
192  template <typename source_link_t>
193  static inline void drawMultiTrajectory(
194  IVisualization3D& helper,
195  const Acts::MultiTrajectory<source_link_t>& multiTraj,
196  const size_t& entryIndex, const GeometryContext& gctx = GeometryContext(),
197  double momentumScale = 1., double locErrorScale = 1.,
198  double angularErrorScale = 1.,
199  const ViewConfig& surfaceConfig = s_viewSensitive,
200  const ViewConfig& measurementConfig = s_viewMeasurement,
201  const ViewConfig& predictedConfig = s_viewPredicted,
202  const ViewConfig& filteredConfig = s_viewFiltered,
203  const ViewConfig& smoothedConfig = s_viewSmoothed) {
204  // Visit the track states on the trajectory
205  multiTraj.visitBackwards(entryIndex, [&](const auto& state) {
206  // Only draw the measurement states
207  if (not state.typeFlags().test(Acts::TrackStateFlag::MeasurementFlag)) {
208  return true;
209  }
210 
211  // Use unit scaling factors for the first state
212  // @Todo: add parameter for the first state error scaling
213  if (state.index() == 0) {
214  locErrorScale = 1;
215  angularErrorScale = 1;
216  }
217 
218  // First, if necessary, draw the surface
219  if (surfaceConfig.visible) {
220  GeometryView3D::drawSurface(helper, state.referenceSurface(), gctx,
221  Transform3D::Identity(), surfaceConfig);
222  }
223 
224  // Second, if necessary and present, draw the calibrated measurement (only
225  // draw 2D measurement here)
226  // @Todo: how to draw 1D measurement?
227  if (measurementConfig.visible and state.hasCalibrated() and
228  state.calibratedSize() == 2) {
229  const Vector2D& lposition = state.calibrated().template head<2>();
230  ActsSymMatrixD<2> covariance =
231  state.calibratedCovariance().template topLeftCorner<2, 2>();
232  drawCovarianceCartesian(helper, lposition, covariance,
233  state.referenceSurface().transform(gctx),
234  locErrorScale, measurementConfig);
235  }
236 
237  // Last, if necessary and present, draw the track parameters
238  // (a) predicted track parameters
239  if (predictedConfig.visible and state.hasPredicted()) {
241  helper,
242  BoundTrackParameters(state.referenceSurface().getSharedPtr(),
243  state.predicted(),
244  state.predictedCovariance()),
245  gctx, momentumScale, locErrorScale, angularErrorScale,
246  predictedConfig, predictedConfig, ViewConfig(false));
247  }
248  // (b) filtered track parameters
249  if (filteredConfig.visible and state.hasFiltered()) {
251  helper,
252  BoundTrackParameters(state.referenceSurface().getSharedPtr(),
253  state.filtered(), state.filteredCovariance()),
254  gctx, momentumScale, locErrorScale, angularErrorScale,
255  filteredConfig, filteredConfig, ViewConfig(false));
256  }
257  // (c) smoothed track parameters
258  if (smoothedConfig.visible and state.hasSmoothed()) {
260  helper,
261  BoundTrackParameters(state.referenceSurface().getSharedPtr(),
262  state.smoothed(), state.smoothedCovariance()),
263  gctx, momentumScale, locErrorScale, angularErrorScale,
264  smoothedConfig, smoothedConfig, ViewConfig(false));
265  }
266  return true;
267  });
268  }
269 };
270 
271 } // namespace Acts