File indexing completed on 2025-08-05 08:09:41
0001
0002
0003
0004
0005
0006
0007
0008
0009 #include "Acts/Surfaces/Surface.hpp"
0010
0011 #include "Acts/Definitions/Common.hpp"
0012 #include "Acts/Surfaces/SurfaceBounds.hpp"
0013 #include "Acts/Surfaces/detail/AlignmentHelper.hpp"
0014 #include "Acts/Utilities/JacobianHelpers.hpp"
0015 #include "Acts/Utilities/VectorHelpers.hpp"
0016
0017 #include <iomanip>
0018 #include <utility>
0019
0020 std::array<std::string, Acts::Surface::SurfaceType::Other>
0021 Acts::Surface::s_surfaceTypeNames = {
0022 "Cone", "Cylinder", "Disc", "Perigee", "Plane", "Straw", "Curvilinear"};
0023
0024 Acts::Surface::Surface(const Transform3& transform)
0025 : GeometryObject(), m_transform(transform) {}
0026
0027 Acts::Surface::Surface(const DetectorElementBase& detelement)
0028 : GeometryObject(), m_associatedDetElement(&detelement) {}
0029
0030 Acts::Surface::Surface(const Surface& other)
0031 : GeometryObject(other),
0032 std::enable_shared_from_this<Surface>(),
0033 m_transform(other.m_transform),
0034 m_surfaceMaterial(other.m_surfaceMaterial) {}
0035
0036 Acts::Surface::Surface(const GeometryContext& gctx, const Surface& other,
0037 const Transform3& shift)
0038 : GeometryObject(),
0039 m_transform(shift * other.transform(gctx)),
0040 m_surfaceMaterial(other.m_surfaceMaterial) {}
0041
0042 Acts::Surface::~Surface() = default;
0043
0044 bool Acts::Surface::isOnSurface(const GeometryContext& gctx,
0045 const Vector3& position,
0046 const Vector3& direction,
0047 const BoundaryCheck& bcheck) const {
0048
0049 auto lpResult = globalToLocal(gctx, position, direction);
0050 if (lpResult.ok()) {
0051 return bcheck.isEnabled() ? bounds().inside(lpResult.value(), bcheck)
0052 : true;
0053 }
0054 return false;
0055 }
0056
0057 Acts::AlignmentToBoundMatrix Acts::Surface::alignmentToBoundDerivative(
0058 const GeometryContext& gctx, const Vector3& position,
0059 const Vector3& direction, const FreeVector& pathDerivative) const {
0060 assert(isOnSurface(gctx, position, direction, BoundaryCheck(false)));
0061
0062
0063
0064 const auto alignToBoundWithoutCorrection =
0065 alignmentToBoundDerivativeWithoutCorrection(gctx, position, direction);
0066
0067 const auto alignToPath = alignmentToPathDerivative(gctx, position, direction);
0068
0069 FreeToBoundMatrix jacToLocal = freeToBoundJacobian(gctx, position, direction);
0070
0071
0072
0073 AlignmentToBoundMatrix alignToBound =
0074 alignToBoundWithoutCorrection + jacToLocal * pathDerivative * alignToPath;
0075
0076 return alignToBound;
0077 }
0078
0079 Acts::AlignmentToBoundMatrix
0080 Acts::Surface::alignmentToBoundDerivativeWithoutCorrection(
0081 const GeometryContext& gctx, const Vector3& position,
0082 const Vector3& direction) const {
0083 (void)direction;
0084 assert(isOnSurface(gctx, position, direction, BoundaryCheck(false)));
0085
0086
0087 const auto pcRowVec = (position - center(gctx)).transpose().eval();
0088
0089 const auto& rotation = transform(gctx).rotation();
0090
0091 const auto& localXAxis = rotation.col(0);
0092 const auto& localYAxis = rotation.col(1);
0093 const auto& localZAxis = rotation.col(2);
0094
0095 const auto [rotToLocalXAxis, rotToLocalYAxis, rotToLocalZAxis] =
0096 detail::rotationToLocalAxesDerivative(rotation);
0097
0098
0099 AlignmentToPositionMatrix alignToLoc3D = AlignmentToPositionMatrix::Zero();
0100 alignToLoc3D.block<1, 3>(eX, eAlignmentCenter0) = -localXAxis.transpose();
0101 alignToLoc3D.block<1, 3>(eY, eAlignmentCenter0) = -localYAxis.transpose();
0102 alignToLoc3D.block<1, 3>(eZ, eAlignmentCenter0) = -localZAxis.transpose();
0103 alignToLoc3D.block<1, 3>(eX, eAlignmentRotation0) =
0104 pcRowVec * rotToLocalXAxis;
0105 alignToLoc3D.block<1, 3>(eY, eAlignmentRotation0) =
0106 pcRowVec * rotToLocalYAxis;
0107 alignToLoc3D.block<1, 3>(eZ, eAlignmentRotation0) =
0108 pcRowVec * rotToLocalZAxis;
0109
0110 ActsMatrix<2, 3> loc3DToBoundLoc =
0111 localCartesianToBoundLocalDerivative(gctx, position);
0112
0113
0114 AlignmentToBoundMatrix alignToBound = AlignmentToBoundMatrix::Zero();
0115
0116 alignToBound.block<2, eAlignmentSize>(eBoundLoc0, eAlignmentCenter0) =
0117 loc3DToBoundLoc * alignToLoc3D;
0118 return alignToBound;
0119 }
0120
0121 Acts::AlignmentToPathMatrix Acts::Surface::alignmentToPathDerivative(
0122 const GeometryContext& gctx, const Vector3& position,
0123 const Vector3& direction) const {
0124 assert(isOnSurface(gctx, position, direction, BoundaryCheck(false)));
0125
0126
0127 const auto pcRowVec = (position - center(gctx)).transpose().eval();
0128
0129 const auto& rotation = transform(gctx).rotation();
0130
0131 const auto& localZAxis = rotation.col(2);
0132
0133 const auto dz = localZAxis.dot(direction);
0134
0135 const auto [rotToLocalXAxis, rotToLocalYAxis, rotToLocalZAxis] =
0136 detail::rotationToLocalAxesDerivative(rotation);
0137
0138
0139 AlignmentToPathMatrix alignToPath = AlignmentToPathMatrix::Zero();
0140 alignToPath.segment<3>(eAlignmentCenter0) = localZAxis.transpose() / dz;
0141 alignToPath.segment<3>(eAlignmentRotation0) =
0142 -pcRowVec * rotToLocalZAxis / dz;
0143
0144 return alignToPath;
0145 }
0146
0147 std::shared_ptr<Acts::Surface> Acts::Surface::getSharedPtr() {
0148 return shared_from_this();
0149 }
0150
0151 std::shared_ptr<const Acts::Surface> Acts::Surface::getSharedPtr() const {
0152 return shared_from_this();
0153 }
0154
0155 Acts::Surface& Acts::Surface::operator=(const Surface& other) {
0156 if (&other != this) {
0157 GeometryObject::operator=(other);
0158
0159 m_transform = other.m_transform;
0160 m_associatedLayer = other.m_associatedLayer;
0161 m_surfaceMaterial = other.m_surfaceMaterial;
0162 m_associatedDetElement = other.m_associatedDetElement;
0163 }
0164 return *this;
0165 }
0166
0167 bool Acts::Surface::operator==(const Surface& other) const {
0168
0169 if (&other == this) {
0170 return true;
0171 }
0172
0173 if (other.type() != type()) {
0174 return false;
0175 }
0176
0177 if (other.bounds() != bounds()) {
0178 return false;
0179 }
0180
0181 if (m_associatedDetElement != other.m_associatedDetElement) {
0182 return false;
0183 }
0184
0185 if (!m_transform.isApprox(other.m_transform, 1e-9)) {
0186 return false;
0187 }
0188
0189 if (m_surfaceMaterial != other.m_surfaceMaterial) {
0190 return false;
0191 }
0192
0193
0194 return true;
0195 }
0196
0197
0198 std::ostream& Acts::Surface::toStream(const GeometryContext& gctx,
0199 std::ostream& sl) const {
0200 sl << std::setiosflags(std::ios::fixed);
0201 sl << std::setprecision(4);
0202 sl << name() << std::endl;
0203 const Vector3& sfcenter = center(gctx);
0204 sl << " Center position (x, y, z) = (" << sfcenter.x() << ", "
0205 << sfcenter.y() << ", " << sfcenter.z() << ")" << std::endl;
0206 Acts::RotationMatrix3 rot(transform(gctx).matrix().block<3, 3>(0, 0));
0207 Acts::Vector3 rotX(rot.col(0));
0208 Acts::Vector3 rotY(rot.col(1));
0209 Acts::Vector3 rotZ(rot.col(2));
0210 sl << std::setprecision(6);
0211 sl << " Rotation: colX = (" << rotX(0) << ", " << rotX(1)
0212 << ", " << rotX(2) << ")" << std::endl;
0213 sl << " colY = (" << rotY(0) << ", " << rotY(1)
0214 << ", " << rotY(2) << ")" << std::endl;
0215 sl << " colZ = (" << rotZ(0) << ", " << rotZ(1)
0216 << ", " << rotZ(2) << ")" << std::endl;
0217 sl << " Bounds : " << bounds();
0218 sl << std::setprecision(-1);
0219 return sl;
0220 }
0221
0222 std::string Acts::Surface::toString(const GeometryContext& gctx) const {
0223 std::stringstream ss;
0224 toStream(gctx, ss);
0225 return ss.str();
0226 }
0227
0228 bool Acts::Surface::operator!=(const Acts::Surface& sf) const {
0229 return !(operator==(sf));
0230 }
0231
0232 Acts::Vector3 Acts::Surface::center(const GeometryContext& gctx) const {
0233
0234 auto tMatrix = transform(gctx).matrix();
0235 return Vector3(tMatrix(0, 3), tMatrix(1, 3), tMatrix(2, 3));
0236 }
0237
0238 const Acts::Transform3& Acts::Surface::transform(
0239 const GeometryContext& gctx) const {
0240 if (m_associatedDetElement != nullptr) {
0241 return m_associatedDetElement->transform(gctx);
0242 }
0243 return m_transform;
0244 }
0245
0246 bool Acts::Surface::insideBounds(const Vector2& lposition,
0247 const BoundaryCheck& bcheck) const {
0248 return bounds().inside(lposition, bcheck);
0249 }
0250
0251 Acts::RotationMatrix3 Acts::Surface::referenceFrame(
0252 const GeometryContext& gctx, const Vector3& ,
0253 const Vector3& ) const {
0254 return transform(gctx).matrix().block<3, 3>(0, 0);
0255 }
0256
0257 Acts::BoundToFreeMatrix Acts::Surface::boundToFreeJacobian(
0258 const GeometryContext& gctx, const Vector3& position,
0259 const Vector3& direction) const {
0260 assert(isOnSurface(gctx, position, direction, BoundaryCheck(false)));
0261
0262
0263 const auto rframe = referenceFrame(gctx, position, direction);
0264
0265
0266 BoundToFreeMatrix jacToGlobal = BoundToFreeMatrix::Zero();
0267
0268 jacToGlobal.topLeftCorner<3, 2>() = rframe.topLeftCorner<3, 2>();
0269
0270 jacToGlobal(eFreeTime, eBoundTime) = 1;
0271
0272 jacToGlobal.block<3, 2>(eFreeDir0, eBoundPhi) =
0273 sphericalToFreeDirectionJacobian(direction);
0274 jacToGlobal(eFreeQOverP, eBoundQOverP) = 1;
0275 return jacToGlobal;
0276 }
0277
0278 Acts::FreeToBoundMatrix Acts::Surface::freeToBoundJacobian(
0279 const GeometryContext& gctx, const Vector3& position,
0280 const Vector3& direction) const {
0281 assert(isOnSurface(gctx, position, direction, BoundaryCheck(false)));
0282
0283
0284 RotationMatrix3 rframeT =
0285 referenceFrame(gctx, position, direction).transpose();
0286
0287
0288 FreeToBoundMatrix jacToLocal = FreeToBoundMatrix::Zero();
0289
0290 jacToLocal.block<2, 3>(eBoundLoc0, eFreePos0) = rframeT.block<2, 3>(0, 0);
0291
0292 jacToLocal(eBoundTime, eFreeTime) = 1;
0293
0294 jacToLocal.block<2, 3>(eBoundPhi, eFreeDir0) =
0295 freeToSphericalDirectionJacobian(direction);
0296 jacToLocal(eBoundQOverP, eFreeQOverP) = 1;
0297 return jacToLocal;
0298 }
0299
0300 Acts::FreeToPathMatrix Acts::Surface::freeToPathDerivative(
0301 const GeometryContext& gctx, const Vector3& position,
0302 const Vector3& direction) const {
0303 assert(isOnSurface(gctx, position, direction, BoundaryCheck(false)));
0304
0305
0306 const RotationMatrix3 rframe = referenceFrame(gctx, position, direction);
0307
0308 const Vector3 refZAxis = rframe.col(2);
0309
0310 const ActsScalar dz = refZAxis.dot(direction);
0311
0312 FreeToPathMatrix freeToPath = FreeToPathMatrix::Zero();
0313 freeToPath.segment<3>(eFreePos0) = -1.0 * refZAxis.transpose() / dz;
0314 return freeToPath;
0315 }
0316
0317 const Acts::DetectorElementBase* Acts::Surface::associatedDetectorElement()
0318 const {
0319 return m_associatedDetElement;
0320 }
0321
0322 const Acts::Layer* Acts::Surface::associatedLayer() const {
0323 return m_associatedLayer;
0324 }
0325
0326 const Acts::ISurfaceMaterial* Acts::Surface::surfaceMaterial() const {
0327 return m_surfaceMaterial.get();
0328 }
0329
0330 const std::shared_ptr<const Acts::ISurfaceMaterial>&
0331 Acts::Surface::surfaceMaterialSharedPtr() const {
0332 return m_surfaceMaterial;
0333 }
0334
0335 void Acts::Surface::assignDetectorElement(
0336 const DetectorElementBase& detelement) {
0337 m_associatedDetElement = &detelement;
0338
0339
0340 m_transform = Transform3::Identity();
0341 }
0342
0343 void Acts::Surface::assignSurfaceMaterial(
0344 std::shared_ptr<const Acts::ISurfaceMaterial> material) {
0345 m_surfaceMaterial = std::move(material);
0346 }
0347
0348 void Acts::Surface::associateLayer(const Acts::Layer& lay) {
0349 m_associatedLayer = (&lay);
0350 }