File indexing completed on 2026-05-27 07:24:51
0001
0002
0003
0004
0005
0006
0007
0008
0009 #include "ActsFatras/Digitization/SurfaceDrift.hpp"
0010
0011 #include "Acts/Definitions/Tolerance.hpp"
0012 #include "Acts/Utilities/Helpers.hpp"
0013 #include "ActsFatras/Digitization/DigitizationError.hpp"
0014
0015 #include <cmath>
0016
0017 namespace ActsFatras {
0018
0019 namespace {
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031 bool toLocalFrame(const Acts::GeometryContext& gctx,
0032 const Acts::Surface& surface, const Acts::Vector3& pos,
0033 const Acts::Vector3& dir, Acts::Vector3& pos3Local,
0034 Acts::Vector3& dir3Local) {
0035 const auto invTransform = surface.localToGlobalTransform(gctx).inverse();
0036
0037 if (surface.type() == Acts::Surface::SurfaceType::Cylinder) {
0038
0039 const Acts::Vector3 posCyl = invTransform * pos;
0040 const Acts::Vector3 dirCyl = invTransform.linear() * dir.normalized();
0041
0042 const double phi = std::atan2(posCyl.y(), posCyl.x());
0043 const double R = std::hypot(posCyl.x(), posCyl.y());
0044 const double cphi = std::cos(phi);
0045 const double sphi = std::sin(phi);
0046
0047
0048
0049
0050 const double dsRPhi = -sphi * dirCyl.x() + cphi * dirCyl.y();
0051 const double dsZ = dirCyl.z();
0052 const double dsR = cphi * dirCyl.x() + sphi * dirCyl.y();
0053
0054
0055 pos3Local = Acts::Vector3(R * phi, posCyl.z(), 0.);
0056
0057 dir3Local = Acts::Vector3(dsRPhi, dsZ, dsR);
0058 return true;
0059 }
0060
0061
0062 pos3Local = invTransform * pos;
0063 dir3Local = invTransform.linear() * dir.normalized();
0064 return true;
0065 }
0066
0067 }
0068
0069 Acts::Result<std::tuple<SurfaceDrift::Segment2D, SurfaceDrift::Segment3D>>
0070 SurfaceDrift::toReadout(const Acts::GeometryContext& gctx,
0071 const Acts::Surface& surface, double thickness,
0072 const Acts::Vector3& pos, const Acts::Vector3& dir,
0073 const Acts::Vector3& driftDir) const {
0074 Acts::Vector3 pos3Local = Acts::Vector3::Zero();
0075 Acts::Vector3 seg3Local = Acts::Vector3::Zero();
0076 if (!toLocalFrame(gctx, surface, pos, dir, pos3Local, seg3Local)) {
0077 return DigitizationError::DriftError;
0078 }
0079
0080
0081
0082
0083 if (std::abs(seg3Local.z()) < Acts::s_epsilon) {
0084 return DigitizationError::DriftError;
0085 }
0086
0087
0088 const double scale = thickness / seg3Local.z();
0089 seg3Local *= scale;
0090
0091 const Acts::Vector3 entry = pos3Local - 0.5 * seg3Local;
0092 const Acts::Vector3 exit = pos3Local + 0.5 * seg3Local;
0093 Acts::Vector3 driftedEntry = entry;
0094 Acts::Vector3 driftedExit = exit;
0095
0096
0097
0098 if (Acts::VectorHelpers::perp(driftDir) > Acts::s_epsilon &&
0099 std::abs(driftDir.z()) > Acts::s_epsilon) {
0100
0101 const double driftScale = 0.5 * thickness / driftDir.z();
0102 driftedEntry += driftScale * driftDir;
0103 driftedExit -= driftScale * driftDir;
0104 }
0105
0106
0107
0108
0109 return std::tuple{
0110 Segment2D{driftedEntry.segment<2>(0), driftedExit.segment<2>(0)},
0111 Segment3D{entry, exit}};
0112 }
0113
0114 }