File indexing completed on 2025-01-18 09:13:03
0001
0002
0003
0004
0005
0006
0007
0008
0009 #pragma once
0010
0011 #include "Acts/Definitions/Algebra.hpp"
0012 #include "Acts/EventData/MeasurementHelpers.hpp"
0013 #include "Acts/EventData/SourceLink.hpp"
0014 #include "Acts/EventData/TrackParameters.hpp"
0015 #include "Acts/EventData/VectorMultiTrajectory.hpp"
0016 #include "Acts/EventData/VectorTrackContainer.hpp"
0017 #include "Acts/EventData/detail/TestSourceLink.hpp"
0018 #include "Acts/Geometry/CuboidVolumeBuilder.hpp"
0019 #include "Acts/Geometry/GeometryContext.hpp"
0020 #include "Acts/Geometry/TrackingGeometry.hpp"
0021 #include "Acts/Geometry/TrackingGeometryBuilder.hpp"
0022 #include "Acts/MagneticField/ConstantBField.hpp"
0023 #include "Acts/MagneticField/MagneticFieldContext.hpp"
0024 #include "Acts/Material/HomogeneousSurfaceMaterial.hpp"
0025 #include "Acts/Material/ISurfaceMaterial.hpp"
0026 #include "Acts/Propagator/EigenStepper.hpp"
0027 #include "Acts/Propagator/Navigator.hpp"
0028 #include "Acts/Propagator/Propagator.hpp"
0029 #include "Acts/Surfaces/PlaneSurface.hpp"
0030 #include "Acts/Surfaces/RectangleBounds.hpp"
0031 #include "Acts/Tests/CommonHelpers/DetectorElementStub.hpp"
0032 #include "Acts/Tests/CommonHelpers/PredefinedMaterials.hpp"
0033 #include "Acts/TrackFitting/GainMatrixSmoother.hpp"
0034 #include "Acts/TrackFitting/GainMatrixUpdater.hpp"
0035 #include "Acts/TrackFitting/KalmanFitter.hpp"
0036 #include "Acts/Utilities/CalibrationContext.hpp"
0037 #include "Acts/Visualization/EventDataView3D.hpp"
0038 #include "Acts/Visualization/IVisualization3D.hpp"
0039
0040 #include <cmath>
0041 #include <fstream>
0042 #include <optional>
0043 #include <random>
0044 #include <sstream>
0045 #include <string>
0046
0047 using Acts::VectorHelpers::makeVector4;
0048
0049 namespace Acts::EventDataView3DTest {
0050
0051 using Covariance = BoundSquareMatrix;
0052
0053 std::normal_distribution<double> gauss(0., 1.);
0054 std::default_random_engine generator(42);
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065 void createDetector(GeometryContext& tgContext,
0066 std::vector<const Surface*>& surfaces,
0067 std::shared_ptr<const TrackingGeometry>& detector,
0068 const std::size_t nSurfaces = 7) {
0069 using namespace UnitLiterals;
0070
0071 if (nSurfaces < 1) {
0072 throw std::invalid_argument("At least 1 surfaces needs to be created.");
0073 }
0074
0075
0076 RotationMatrix3 rotation = RotationMatrix3::Identity();
0077 double rotationAngle = 90_degree;
0078 Vector3 xPos(cos(rotationAngle), 0., sin(rotationAngle));
0079 Vector3 yPos(0., 1., 0.);
0080 Vector3 zPos(-sin(rotationAngle), 0., cos(rotationAngle));
0081 rotation.col(0) = xPos;
0082 rotation.col(1) = yPos;
0083 rotation.col(2) = zPos;
0084
0085
0086 const auto rBounds =
0087 std::make_shared<const RectangleBounds>(RectangleBounds(50_mm, 50_mm));
0088
0089
0090 MaterialSlab matProp(Acts::Test::makeSilicon(), 0.5_mm);
0091 const auto surfaceMaterial =
0092 std::make_shared<HomogeneousSurfaceMaterial>(matProp);
0093
0094
0095 std::vector<Vector3> translations;
0096 translations.reserve(nSurfaces);
0097 for (unsigned int i = 0; i < nSurfaces; i++) {
0098 translations.push_back({i * 100_mm - 300_mm, 0., 0.});
0099 }
0100
0101
0102 std::vector<CuboidVolumeBuilder::LayerConfig> lConfs;
0103 lConfs.reserve(nSurfaces);
0104 for (unsigned int i = 0; i < translations.size(); i++) {
0105 CuboidVolumeBuilder::SurfaceConfig sConf;
0106 sConf.position = translations[i];
0107 sConf.rotation = rotation;
0108 sConf.rBounds = rBounds;
0109 sConf.surMat = surfaceMaterial;
0110
0111 sConf.thickness = 1._um;
0112 sConf.detElementConstructor =
0113 [](const Transform3& trans,
0114 const std::shared_ptr<const RectangleBounds>& bounds,
0115 double thickness) {
0116 return new Test::DetectorElementStub(trans, bounds, thickness);
0117 };
0118 CuboidVolumeBuilder::LayerConfig lConf;
0119 lConf.surfaceCfg = {sConf};
0120 lConfs.push_back(lConf);
0121 }
0122
0123
0124 CuboidVolumeBuilder::VolumeConfig vConf;
0125 vConf.position = {0., 0., 0.};
0126 vConf.length = {1.2_m, 1._m, 1._m};
0127 vConf.layerCfg = lConfs;
0128 vConf.name = "Tracker";
0129
0130
0131 CuboidVolumeBuilder::Config conf;
0132 conf.position = {0., 0., 0.};
0133 conf.length = {1.2_m, 1._m, 1._m};
0134 conf.volumeCfg = {vConf};
0135
0136
0137 std::cout << "Build the detector" << std::endl;
0138 CuboidVolumeBuilder cvb;
0139 cvb.setConfig(conf);
0140 TrackingGeometryBuilder::Config tgbCfg;
0141 tgbCfg.trackingVolumeBuilders.push_back(
0142 [=](const auto& context, const auto& inner, const auto& vb) {
0143 return cvb.trackingVolume(context, inner, vb);
0144 });
0145 TrackingGeometryBuilder tgb(tgbCfg);
0146 detector = tgb.trackingGeometry(tgContext);
0147
0148
0149 surfaces.reserve(nSurfaces);
0150 detector->visitSurfaces([&](const Surface* surface) {
0151 if (surface != nullptr && surface->associatedDetectorElement() != nullptr) {
0152 std::cout << "surface " << surface->geometryId() << " placed at: ("
0153 << surface->center(tgContext).transpose() << " )" << std::endl;
0154 surfaces.push_back(surface);
0155 }
0156 });
0157 std::cout << "There are " << surfaces.size() << " surfaces" << std::endl;
0158 }
0159
0160
0161
0162
0163
0164
0165 static inline std::string testBoundTrackParameters(IVisualization3D& helper) {
0166 std::stringstream ss;
0167
0168 ViewConfig pcolor{.color = {20, 120, 20}};
0169 ViewConfig scolor{.color = {235, 198, 52}};
0170
0171 auto gctx = GeometryContext();
0172 auto identity = Transform3::Identity();
0173
0174
0175 auto rectangle = std::make_shared<RectangleBounds>(15., 15.);
0176 auto plane = Surface::makeShared<PlaneSurface>(identity, rectangle);
0177
0178 double momentumScale = 0.005;
0179 double localErrorScale = 10.;
0180 double directionErrorScale = 1000.;
0181
0182
0183
0184 std::array<double, 6> pars_array = {
0185 {-0.1234, 4.8765, 0.45, 0.128, 0.001, 21.}};
0186
0187 BoundTrackParameters::ParametersVector pars =
0188 BoundTrackParameters::ParametersVector::Zero();
0189 pars << pars_array[0], pars_array[1], pars_array[2], pars_array[3],
0190 pars_array[4], pars_array[5];
0191
0192 Covariance cov = Covariance::Zero();
0193 cov << 0.25, 0.0042, -0.00076, 6.156e-06, -2.11e-07, 0, 0.0042, 0.859,
0194 -0.000173, 0.000916, -4.017e-08, 0, -0.00076, -0.000173, 2.36e-04,
0195 -2.76e-07, 1.12e-08, 0, 6.15e-06, 0.000916, -2.76e-07, 8.84e-04,
0196 -2.85e-11, 0, -2.11 - 07, -4.017e-08, 1.123e-08, -2.85 - 11, 1.26e-10, 0,
0197 0, 0, 0, 0, 0, 1;
0198
0199 EventDataView3D::drawBoundTrackParameters(
0200 helper,
0201 BoundTrackParameters(plane, pars, std::move(cov),
0202 ParticleHypothesis::pion()),
0203 gctx, momentumScale, localErrorScale, directionErrorScale, pcolor,
0204 scolor);
0205
0206 helper.write("EventData_BoundAtPlaneParameters");
0207 helper.write(ss);
0208
0209 return ss.str();
0210 }
0211
0212
0213
0214
0215
0216
0217 static inline std::string testMeasurement(IVisualization3D& helper,
0218 const double localErrorScale = 100.) {
0219 using namespace UnitLiterals;
0220 std::stringstream ss;
0221
0222
0223 GeometryContext tgContext = GeometryContext();
0224
0225
0226 const std::size_t nSurfaces = 7;
0227 std::vector<const Surface*> surfaces;
0228 std::shared_ptr<const TrackingGeometry> detector;
0229 createDetector(tgContext, surfaces, detector, nSurfaces);
0230
0231
0232
0233 std::cout << "Creating measurements:" << std::endl;
0234 std::vector<detail::Test::TestSourceLink> sourceLinks;
0235 sourceLinks.reserve(nSurfaces);
0236 Vector2 lPosCenter{5_mm, 5_mm};
0237 Vector2 resolution{200_um, 150_um};
0238 SquareMatrix2 cov2D = resolution.cwiseProduct(resolution).asDiagonal();
0239 for (const auto& surface : surfaces) {
0240
0241 Vector2 loc = lPosCenter;
0242 loc[0] += resolution[0] * gauss(generator);
0243 loc[1] += resolution[1] * gauss(generator);
0244 sourceLinks.emplace_back(detail::Test::TestSourceLink{
0245 eBoundLoc0, eBoundLoc1, loc, cov2D, surface->geometryId()});
0246 }
0247
0248 ViewConfig mcolor{.color = {255, 145, 48}};
0249 mcolor.offset = 0.01;
0250
0251
0252 std::cout << "Draw the measurements" << std::endl;
0253
0254 for (auto& singleMeasurement : sourceLinks) {
0255 auto cov = singleMeasurement.covariance;
0256 auto lposition = singleMeasurement.parameters;
0257
0258 auto surf = detector->findSurface(singleMeasurement.m_geometryId);
0259 auto transf = surf->transform(tgContext);
0260
0261 EventDataView3D::drawMeasurement(helper, lposition, cov, transf,
0262 localErrorScale, mcolor);
0263 }
0264
0265 helper.write("EventData_Measurement");
0266 helper.write(ss);
0267
0268 return ss.str();
0269 }
0270
0271
0272
0273
0274
0275
0276 static inline std::string testMultiTrajectory(IVisualization3D& helper) {
0277 using namespace UnitLiterals;
0278 std::stringstream ss;
0279
0280
0281 GeometryContext tgContext = GeometryContext();
0282 MagneticFieldContext mfContext = MagneticFieldContext();
0283 CalibrationContext calContext = CalibrationContext();
0284
0285
0286 const std::size_t nSurfaces = 7;
0287 std::vector<const Surface*> surfaces;
0288 std::shared_ptr<const TrackingGeometry> detector;
0289 createDetector(tgContext, surfaces, detector, nSurfaces);
0290
0291
0292
0293 std::cout << "Creating measurements:" << std::endl;
0294 std::vector<Acts::SourceLink> sourceLinks;
0295 sourceLinks.reserve(nSurfaces);
0296 Vector2 lPosCenter{5_mm, 5_mm};
0297 Vector2 resolution{200_um, 150_um};
0298 SquareMatrix2 cov2D = resolution.cwiseProduct(resolution).asDiagonal();
0299 for (const auto& surface : surfaces) {
0300
0301 Vector2 loc = lPosCenter;
0302 loc[0] += resolution[0] * gauss(generator);
0303 loc[1] += resolution[1] * gauss(generator);
0304 sourceLinks.emplace_back(detail::Test::TestSourceLink{
0305 eBoundLoc0, eBoundLoc1, loc, cov2D, surface->geometryId()});
0306 }
0307
0308
0309 std::cout << "Construct KalmanFitter and perform fit" << std::endl;
0310 Navigator::Config cfg{detector};
0311 cfg.resolvePassive = false;
0312 cfg.resolveMaterial = true;
0313 cfg.resolveSensitive = true;
0314 Navigator rNavigator(cfg);
0315
0316
0317 auto bField = std::make_shared<ConstantBField>(Vector3(0., 0., 0.));
0318 using RecoStepper = EigenStepper<>;
0319 RecoStepper rStepper(bField);
0320 using RecoPropagator = Propagator<RecoStepper, Navigator>;
0321 RecoPropagator rPropagator(rStepper, rNavigator);
0322
0323
0324 Covariance cov;
0325 cov << std::pow(100_um, 2), 0., 0., 0., 0., 0., 0., std::pow(100_um, 2), 0.,
0326 0., 0., 0., 0., 0., 0.0025, 0., 0., 0., 0., 0., 0., 0.0025, 0., 0., 0.,
0327 0., 0., 0., 0.01, 0., 0., 0., 0., 0., 0., 1.;
0328 Vector3 rPos(-350._mm, 100_um * gauss(generator), 100_um * gauss(generator));
0329 Vector3 rDir(1, 0.025 * gauss(generator), 0.025 * gauss(generator));
0330 CurvilinearTrackParameters rStart(makeVector4(rPos, 42_ns), rDir, 1_e / 1_GeV,
0331 cov, ParticleHypothesis::pion());
0332
0333 const Surface* rSurface = &rStart.referenceSurface();
0334
0335 using KalmanFitter = KalmanFitter<RecoPropagator, VectorMultiTrajectory>;
0336
0337 KalmanFitter kFitter(rPropagator);
0338
0339 auto logger = getDefaultLogger("KalmanFilter", Logging::WARNING);
0340
0341 Acts::GainMatrixUpdater kfUpdater;
0342 Acts::GainMatrixSmoother kfSmoother;
0343
0344 KalmanFitterExtensions<VectorMultiTrajectory> extensions;
0345 extensions.calibrator.connect<
0346 &detail::Test::testSourceLinkCalibrator<VectorMultiTrajectory>>();
0347 extensions.updater
0348 .connect<&Acts::GainMatrixUpdater::operator()<VectorMultiTrajectory>>(
0349 &kfUpdater);
0350 extensions.smoother
0351 .connect<&Acts::GainMatrixSmoother::operator()<VectorMultiTrajectory>>(
0352 &kfSmoother);
0353
0354 detail::Test::TestSourceLink::SurfaceAccessor surfaceAccessor{*detector};
0355 extensions.surfaceAccessor
0356 .connect<&detail::Test::TestSourceLink::SurfaceAccessor::operator()>(
0357 &surfaceAccessor);
0358
0359 KalmanFitterOptions kfOptions(tgContext, mfContext, calContext, extensions,
0360 PropagatorPlainOptions(tgContext, mfContext),
0361 rSurface);
0362
0363 Acts::TrackContainer tracks{Acts::VectorTrackContainer{},
0364 Acts::VectorMultiTrajectory{}};
0365
0366
0367 auto fitRes = kFitter.fit(sourceLinks.begin(), sourceLinks.end(), rStart,
0368 kfOptions, tracks);
0369 if (!fitRes.ok()) {
0370 std::cout << "Fit failed" << std::endl;
0371 return ss.str();
0372 }
0373 auto& track = *fitRes;
0374
0375
0376 std::cout << "Draw the fitted track" << std::endl;
0377 double momentumScale = 10;
0378 double localErrorScale = 100.;
0379 double directionErrorScale = 100000;
0380
0381 ViewConfig scolor{.color = {214, 214, 214}};
0382 ViewConfig mcolor{.color = {255, 145, 48}};
0383 mcolor.offset = -0.01;
0384 ViewConfig ppcolor{.color = {51, 204, 51}};
0385 ppcolor.offset = -0.02;
0386 ViewConfig fpcolor{.color = {255, 255, 0}};
0387 fpcolor.offset = -0.03;
0388 ViewConfig spcolor{.color = {0, 125, 255}};
0389 spcolor.offset = -0.04;
0390
0391 EventDataView3D::drawMultiTrajectory(
0392 helper, tracks.trackStateContainer(), track.tipIndex(), tgContext,
0393 momentumScale, localErrorScale, directionErrorScale, scolor, mcolor,
0394 ppcolor, fpcolor, spcolor);
0395
0396 helper.write("EventData_MultiTrajectory");
0397 helper.write(ss);
0398
0399 return ss.str();
0400 }
0401
0402 }