Analysis Software
Documentation for sPHENIX simulation software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
EventDataView3DBase.hpp
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file EventDataView3DBase.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 
40 
41 #include <cmath>
42 #include <fstream>
43 #include <optional>
44 #include <random>
45 #include <sstream>
46 #include <string>
47 
49 
50 namespace Acts {
51 namespace EventDataView3DTest {
52 
54 
55 std::normal_distribution<double> gauss(0., 1.);
56 std::default_random_engine generator(42);
57 
68  std::vector<const Surface*>& surfaces,
69  std::shared_ptr<const TrackingGeometry>& detector,
70  const size_t nSurfaces = 7) {
71  using namespace UnitLiterals;
72 
73  if (nSurfaces < 1) {
74  throw std::invalid_argument("At least 1 surfaces needs to be created.");
75  }
76 
77  // Construct the rotation
78  RotationMatrix3 rotation = RotationMatrix3::Identity();
79  double rotationAngle = 90_degree;
80  Vector3 xPos(cos(rotationAngle), 0., sin(rotationAngle));
81  Vector3 yPos(0., 1., 0.);
82  Vector3 zPos(-sin(rotationAngle), 0., cos(rotationAngle));
83  rotation.col(0) = xPos;
84  rotation.col(1) = yPos;
85  rotation.col(2) = zPos;
86 
87  // Boundaries of the surfaces
88  const auto rBounds =
89  std::make_shared<const RectangleBounds>(RectangleBounds(50_mm, 50_mm));
90 
91  // Material of the surfaces
92  MaterialSlab matProp(Acts::Test::makeSilicon(), 0.5_mm);
93  const auto surfaceMaterial =
94  std::make_shared<HomogeneousSurfaceMaterial>(matProp);
95 
96  // Set translation vectors
97  std::vector<Vector3> translations;
98  translations.reserve(nSurfaces);
99  for (unsigned int i = 0; i < nSurfaces; i++) {
100  translations.push_back({i * 100_mm - 300_mm, 0., 0.});
101  }
102 
103  // Construct layer configs
104  std::vector<CuboidVolumeBuilder::LayerConfig> lConfs;
105  lConfs.reserve(nSurfaces);
106  for (unsigned int i = 0; i < translations.size(); i++) {
108  sConf.position = translations[i];
109  sConf.rotation = rotation;
110  sConf.rBounds = rBounds;
111  sConf.surMat = surfaceMaterial;
112  // The thickness to construct the associated detector element
113  sConf.thickness = 1._um;
114  sConf.detElementConstructor =
115  [](const Transform3& trans,
116  const std::shared_ptr<const RectangleBounds>& bounds,
117  double thickness) {
118  return new Test::DetectorElementStub(trans, bounds, thickness);
119  };
121  lConf.surfaceCfg = {sConf};
122  lConfs.push_back(lConf);
123  }
124 
125  // Construct volume config
127  vConf.position = {0., 0., 0.};
128  vConf.length = {1.2_m, 1._m, 1._m};
129  vConf.layerCfg = lConfs;
130  vConf.name = "Tracker";
131 
132  // Construct volume builder config
134  conf.position = {0., 0., 0.};
135  conf.length = {1.2_m, 1._m, 1._m};
136  conf.volumeCfg = {vConf}; // one volume
137 
138  // Build detector
139  std::cout << "Build the detector" << std::endl;
141  cvb.setConfig(conf);
143  tgbCfg.trackingVolumeBuilders.push_back(
144  [=](const auto& context, const auto& inner, const auto& vb) {
145  return cvb.trackingVolume(context, inner, vb);
146  });
147  TrackingGeometryBuilder tgb(tgbCfg);
148  detector = tgb.trackingGeometry(tgContext);
149 
150  // Get the surfaces;
151  surfaces.reserve(nSurfaces);
152  detector->visitSurfaces([&](const Surface* surface) {
153  if (surface != nullptr && surface->associatedDetectorElement() != nullptr) {
154  std::cout << "surface " << surface->geometryId() << " placed at: ("
155  << surface->center(tgContext).transpose() << " )" << std::endl;
156  surfaces.push_back(surface);
157  }
158  });
159  std::cout << "There are " << surfaces.size() << " surfaces" << std::endl;
160 }
161 
168  std::stringstream ss;
169 
170  ViewConfig pcolor({20, 120, 20});
171  ViewConfig scolor({235, 198, 52});
172 
173  auto gctx = GeometryContext();
174  auto identity = Transform3::Identity();
175 
176  // rectangle and plane
177  auto rectangle = std::make_shared<RectangleBounds>(15., 15.);
178  auto plane = Surface::makeShared<PlaneSurface>(identity, rectangle);
179 
180  double momentumScale = 0.005;
181  double localErrorScale = 10.;
182  double directionErrorScale = 1000.;
183 
184  // now create parameters on this surface
185  // l_x, l_y, phi, theta, q/p (1/p), t
186  std::array<double, 6> pars_array = {
187  {-0.1234, 4.8765, 0.45, 0.128, 0.001, 21.}};
188 
190  BoundTrackParameters::ParametersVector::Zero();
191  pars << pars_array[0], pars_array[1], pars_array[2], pars_array[3],
192  pars_array[4], pars_array[5];
193 
194  Covariance cov = Covariance::Zero();
195  cov << 0.25, 0.0042, -0.00076, 6.156e-06, -2.11e-07, 0, 0.0042, 0.859,
196  -0.000173, 0.000916, -4.017e-08, 0, -0.00076, -0.000173, 2.36e-04,
197  -2.76e-07, 1.12e-08, 0, 6.15e-06, 0.000916, -2.76e-07, 8.84e-04,
198  -2.85e-11, 0, -2.11 - 07, -4.017e-08, 1.123e-08, -2.85 - 11, 1.26e-10, 0,
199  0, 0, 0, 0, 0, 1;
200 
202  helper,
205  gctx, momentumScale, localErrorScale, directionErrorScale, pcolor,
206  scolor);
207 
208  helper.write("EventData_BoundAtPlaneParameters");
209  helper.write(ss);
210 
211  return ss.str();
212 }
213 
220  using namespace UnitLiterals;
221  std::stringstream ss;
222 
223  // Create a test context
225 
226  // Create a detector
227  const size_t nSurfaces = 7;
228  std::vector<const Surface*> surfaces;
229  std::shared_ptr<const TrackingGeometry> detector;
230  createDetector(tgContext, surfaces, detector, nSurfaces);
231 
232  // Create measurements (assuming they are for a linear track parallel to
233  // global x-axis)
234  std::cout << "Creating measurements:" << std::endl;
235  std::vector<Test::TestSourceLink> sourcelinks;
236  sourcelinks.reserve(nSurfaces);
237  Vector2 lPosCenter{5_mm, 5_mm};
238  Vector2 resolution{200_um, 150_um};
239  SquareMatrix2 cov2D = resolution.cwiseProduct(resolution).asDiagonal();
240  for (const auto& surface : surfaces) {
241  // 2D measurements
242  Vector2 loc = lPosCenter;
243  loc[0] += resolution[0] * gauss(generator);
244  loc[1] += resolution[1] * gauss(generator);
245  sourcelinks.emplace_back(Test::TestSourceLink{
246  eBoundLoc0, eBoundLoc1, loc, cov2D, surface->geometryId()});
247  }
248 
249  double localErrorScale = 100.;
250  ViewConfig mcolor({255, 145, 48});
251  mcolor.offset = 0.01;
252 
253  // Draw the measurements
254  std::cout << "Draw the measurements" << std::endl;
255  // auto singleMeasurement = sourcelinks[0];
256  for (auto& singleMeasurement : sourcelinks) {
257  auto cov = singleMeasurement.covariance;
258  auto lposition = singleMeasurement.parameters;
259 
260  auto surf = detector->findSurface(singleMeasurement.m_geometryId);
261  auto transf = surf->transform(tgContext);
262 
263  EventDataView3D::drawMeasurement(helper, lposition, cov, transf,
264  localErrorScale, mcolor);
265  }
266 
267  helper.write("EventData_Measurement");
268  helper.write(ss);
269 
270  return ss.str();
271 }
272 
279  using namespace UnitLiterals;
280  std::stringstream ss;
281 
282  // Create a test context
285  CalibrationContext calContext = CalibrationContext();
286 
287  // Create a detector
288  const size_t nSurfaces = 7;
289  std::vector<const Surface*> surfaces;
290  std::shared_ptr<const TrackingGeometry> detector;
291  createDetector(tgContext, surfaces, detector, nSurfaces);
292 
293  // Create measurements (assuming they are for a linear track parallel to
294  // global x-axis)
295  std::cout << "Creating measurements:" << std::endl;
296  std::vector<Acts::SourceLink> sourcelinks;
297  sourcelinks.reserve(nSurfaces);
298  Vector2 lPosCenter{5_mm, 5_mm};
299  Vector2 resolution{200_um, 150_um};
300  SquareMatrix2 cov2D = resolution.cwiseProduct(resolution).asDiagonal();
301  for (const auto& surface : surfaces) {
302  // 2D measurements
303  Vector2 loc = lPosCenter;
304  loc[0] += resolution[0] * gauss(generator);
305  loc[1] += resolution[1] * gauss(generator);
306  sourcelinks.emplace_back(Test::TestSourceLink{
307  eBoundLoc0, eBoundLoc1, loc, cov2D, surface->geometryId()});
308  }
309 
310  // The KalmanFitter - we use the eigen stepper for covariance transport
311  std::cout << "Construct KalmanFitter and perform fit" << std::endl;
313  cfg.resolvePassive = false;
314  cfg.resolveMaterial = true;
315  cfg.resolveSensitive = true;
316  Navigator rNavigator(cfg);
317 
318  // Configure propagation with deactivated B-field
319  auto bField = std::make_shared<ConstantBField>(Vector3(0., 0., 0.));
320  using RecoStepper = EigenStepper<>;
321  RecoStepper rStepper(bField);
322  using RecoPropagator = Propagator<RecoStepper, Navigator>;
323  RecoPropagator rPropagator(rStepper, rNavigator);
324 
325  // Set initial parameters for the particle track
326  Covariance cov;
327  cov << std::pow(100_um, 2), 0., 0., 0., 0., 0., 0., std::pow(100_um, 2), 0.,
328  0., 0., 0., 0., 0., 0.0025, 0., 0., 0., 0., 0., 0., 0.0025, 0., 0., 0.,
329  0., 0., 0., 0.01, 0., 0., 0., 0., 0., 0., 1.;
330  Vector3 rPos(-350._mm, 100_um * gauss(generator), 100_um * gauss(generator));
331  Vector3 rDir(1, 0.025 * gauss(generator), 0.025 * gauss(generator));
332  CurvilinearTrackParameters rStart(makeVector4(rPos, 42_ns), rDir, 1_e / 1_GeV,
334 
335  const Surface* rSurface = &rStart.referenceSurface();
336 
338 
339  KalmanFitter kFitter(rPropagator);
340 
341  auto logger = getDefaultLogger("KalmanFilter", Logging::WARNING);
342 
343  Acts::GainMatrixUpdater kfUpdater;
344  Acts::GainMatrixSmoother kfSmoother;
345 
347  extensions.calibrator
348  .connect<&Test::testSourceLinkCalibrator<VectorMultiTrajectory>>();
349  extensions.updater
350  .connect<&Acts::GainMatrixUpdater::operator()<VectorMultiTrajectory>>(
351  &kfUpdater);
352  extensions.smoother
353  .connect<&Acts::GainMatrixSmoother::operator()<VectorMultiTrajectory>>(
354  &kfSmoother);
355 
357  extensions.surfaceAccessor
358  .connect<&Test::TestSourceLink::SurfaceAccessor::operator()>(
359  &surfaceAccessor);
360 
361  KalmanFitterOptions kfOptions(tgContext, mfContext, calContext, extensions,
362  PropagatorPlainOptions(), rSurface);
363 
366 
367  // Fit the track
368  auto fitRes = kFitter.fit(sourcelinks.begin(), sourcelinks.end(), rStart,
369  kfOptions, tracks);
370  if (not fitRes.ok()) {
371  std::cout << "Fit failed" << std::endl;
372  return ss.str();
373  }
374  auto& track = *fitRes;
375 
376  // Draw the track
377  std::cout << "Draw the fitted track" << std::endl;
378  double momentumScale = 10;
379  double localErrorScale = 100.;
380  double directionErrorScale = 100000;
381 
382  ViewConfig scolor({214, 214, 214});
383  ViewConfig mcolor({255, 145, 48});
384  mcolor.offset = -0.01;
385  ViewConfig ppcolor({51, 204, 51});
386  ppcolor.offset = -0.02;
387  ViewConfig fpcolor({255, 255, 0});
388  fpcolor.offset = -0.03;
389  ViewConfig spcolor({0, 125, 255});
390  spcolor.offset = -0.04;
391 
393  helper, tracks.trackStateContainer(), track.tipIndex(), tgContext,
394  momentumScale, localErrorScale, directionErrorScale, scolor, mcolor,
395  ppcolor, fpcolor, spcolor);
396 
397  helper.write("EventData_MultiTrajectory");
398  helper.write(ss);
399 
400  return ss.str();
401 }
402 
403 } // namespace EventDataView3DTest
404 } // namespace Acts