ECCE @ EIC Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
EventDataVisualization.hpp
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file EventDataVisualization.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 
21 
22 #include <optional>
23 
24 namespace Acts {
25 namespace Visualization {
26 
30 static inline std::array<double, 3> decomposeCovariance(
31  const ActsSymMatrixD<2>& covariance) {
32  double c00 = covariance(eLOC_0, eLOC_0);
33  double c01 = covariance(eLOC_0, eLOC_1);
34  double c11 = covariance(eLOC_1, eLOC_1);
35 
36  double cdsq = std::pow((c00 - c11), 2) / 4.;
37  double cosq = c01 * c01;
38 
39  // Calculate the eigen values w.r.t reference frame
40  double lambda0 = (c00 + c11) / 2. + std::sqrt(cdsq + cosq);
41  double lambda1 = (c00 + c11) / 2. - std::sqrt(cdsq + cosq);
42  double theta = atan2(lambda0 - c00, c01);
43 
44  return {lambda0, lambda1, theta};
45 }
46 
56 static inline std::vector<Vector3D> createEllipse(
57  double lambda0, double lambda1, double theta, size_t lseg,
58  double outOfPlane, const Vector2D& lposition = Vector2D(0., 0.),
59  const Transform3D& transform = Transform3D::Identity()) {
60  double ctheta = std::cos(theta);
61  double stheta = std::sin(theta);
62 
63  double l1sq = std::sqrt(lambda0);
64  double l2sq = std::sqrt(lambda1);
65 
66  // Now generate the ellipse points
67  std::vector<Vector3D> ellipse;
68  ellipse.reserve(lseg);
69  double thetaStep = 2 * M_PI / lseg;
70  for (size_t it = 0; it < lseg; ++it) {
71  double phi = -M_PI + it * thetaStep;
72  double cphi = std::cos(phi);
73  double sphi = std::sin(phi);
74  double x = lposition.x() + (l1sq * ctheta * cphi - l2sq * stheta * sphi);
75  double y = lposition.y() + (l1sq * stheta * cphi + l2sq * ctheta * sphi);
76  ellipse.push_back(transform * Vector3D(x, y, outOfPlane));
77  }
78  return ellipse;
79 }
80 
91 static inline void drawCovarianceCartesian(
92  IVisualization& helper, const Vector2D& lposition,
93  const ActsSymMatrixD<2>& covariance, const Transform3D& transform,
94  std::vector<int> nsigma = {3}, double locErrorScale = 1, size_t lseg = 72,
95  const IVisualization::ColorType& color = {20, 120, 20},
96  double outOfPlane = 0.1) {
97  auto [lambda0, lambda1, theta] = decomposeCovariance(covariance);
98 
99  // Now generate the ellipse points
100  std::vector<Vector3D> ellipse = createEllipse(
101  lambda0, lambda1, theta, lseg, outOfPlane, lposition, transform);
102 
103  ellipse.push_back(transform *
104  Vector3D(lposition.x(), lposition.y(), outOfPlane));
105  auto faces = detail::FacesHelper::convexFaceMesh(ellipse, true);
106  Polyhedron ellipseHedron(ellipse, faces.first, faces.second);
107  ellipseHedron.draw(helper, false, color);
108 }
109 
121 static inline void drawCovarianceAngular(
122  IVisualization& helper, const Vector3D& position, const Vector3D& direction,
123  const ActsSymMatrixD<2>& covariance, std::vector<int> nsigma = {3},
124  double directionScale = 1, double angularErrorScale = 1, size_t lseg = 72,
125  const IVisualization::ColorType& color = {20, 120, 20}) {
126  auto [lambda0, lambda1, theta] = decomposeCovariance(covariance);
127 
128  // Anker point
129  Vector3D anker = position + directionScale * direction;
130 
131  double dphi = VectorHelpers::phi(direction);
132  double dtheta = VectorHelpers::theta(direction);
133 
134  Transform3D eplane(Translation3D(anker) *
135  AngleAxis3D(dtheta, Vector3D(1., 0., 0.)) *
136  AngleAxis3D(dphi, Vector3D(0., 0., 1.)));
137 
138  // Now generate the ellipse points
139  std::vector<Vector3D> ellipse =
140  createEllipse(angularErrorScale * directionScale * tan(lambda0),
141  angularErrorScale * directionScale * tan(lambda1), theta,
142  lseg, 0., {0., 0.}, eplane);
143 
144  std::vector<Vector3D> coneTop = ellipse;
145  coneTop.push_back(anker);
146  auto coneTopFaces = detail::FacesHelper::convexFaceMesh(coneTop, true);
147  Polyhedron coneTopHedron(coneTop, coneTopFaces.first, coneTopFaces.second);
148  coneTopHedron.draw(helper, false, color);
149 
150  std::vector<Vector3D> cone = ellipse;
151  cone.push_back(position);
152  auto coneFaces = detail::FacesHelper::convexFaceMesh(cone, true);
153  Polyhedron coneHedron(cone, coneFaces.first, coneFaces.second);
154  coneHedron.draw(helper, true, color);
155 }
156 
169 template <typename parameters_t>
170 static inline void drawBoundParameters(
171  IVisualization& helper, const parameters_t& parameters,
172  const GeometryContext& gctx = GeometryContext(), double momentumScale = 1.,
173  double locErrorScale = 1., double angularErrorScale = 1.,
174  bool drawParameterSurface = true, size_t lseg = 72,
175  const IVisualization::ColorType& pcolor = {20, 120, 20},
176  const IVisualization::ColorType& scolor = {235, 198, 52}) {
177  // First, if necessary, draw the surface
178  if (drawParameterSurface) {
179  drawSurface(helper, parameters.referenceSurface(), gctx,
180  Transform3D::Identity(), lseg, false, scolor);
181  }
182 
183  // Draw the parameter shaft and cone
184  auto position = parameters.position();
185  auto direction = parameters.momentum().normalized();
186  double p = parameters.momentum().norm();
187 
188  Vector3D startmod = parameters.covariance().has_value()
189  ? 0.25 * p * momentumScale * direction
190  : Vector3D(0., 0., 0.);
191 
192  drawArrowForward(helper, position, position + p * momentumScale * direction,
193  0.025, 0.05, 2., 72, pcolor);
194 
195  if (parameters.covariance().has_value()) {
196  auto lposition =
197  parameters.getParameterSet().getParameters().template block<2, 1>(0, 0);
198 
199  // Draw the local covariance
200  const auto& covariance = *parameters.covariance();
201  drawCovarianceCartesian(helper, lposition,
202  covariance.template block<2, 2>(0, 0),
203  parameters.referenceSurface().transform(gctx), {3},
204  locErrorScale, 72, pcolor, 0.01);
205 
207  helper, parameters.position(), parameters.momentum().normalized(),
208  covariance.template block<2, 2>(2, 2), {3}, 0.9 * p * momentumScale,
209  angularErrorScale, 72, pcolor);
210  }
211 }
212 
213 } // namespace Visualization
214 } // namespace Acts