Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-07-05 08:15:18

0001 // SPDX-License-Identifier: LGPL-3.0-or-later
0002 // Copyright (C) 2022 - 2025 Whitney Armstrong, Wouter Deconinck, Dmitry Kalinkin
0003 
0004 #include "DD4hepBField.h"
0005 
0006 #include <Acts/Definitions/Algebra.hpp>
0007 #include <Acts/Definitions/Units.hpp>
0008 #include <DD4hep/Fields.h>
0009 #include <DD4hep/Objects.h>
0010 #include <Evaluator/DD4hepUnits.h>
0011 #include <Math/GenVector/Cartesian3D.h>
0012 #include <Math/GenVector/DisplacementVector3D.h>
0013 #include <Eigen/Core>
0014 #include <cmath>
0015 #include <limits>
0016 
0017 namespace eicrecon::BField {
0018 
0019 Acts::Result<Acts::Vector3>
0020 DD4hepBField::getField(const Acts::Vector3& position,
0021                        Acts::MagneticFieldProvider::Cache& /*cache*/) const {
0022   dd4hep::Position pos(position[0] * (dd4hep::mm / Acts::UnitConstants::mm),
0023                        position[1] * (dd4hep::mm / Acts::UnitConstants::mm),
0024                        position[2] * (dd4hep::mm / Acts::UnitConstants::mm));
0025 
0026   // Avoid crash during lookup.
0027   // Infinite values are possible due to https://github.com/acts-project/acts/issues/4166.
0028   if ((!std::isfinite(position[0])) && (!std::isfinite(position[1])) &&
0029       (!std::isfinite(position[2]))) {
0030     return Acts::Result<Acts::Vector3>::success({0., 0., 0.});
0031   }
0032 
0033   auto fieldObj = m_det->field();
0034   auto field    = fieldObj.magneticField(pos) * (Acts::UnitConstants::T / dd4hep::tesla);
0035 
0036   // FIXME Acts doesn't seem to like exact zero components
0037   if (field.x() * field.y() * field.z() == 0) {
0038     static dd4hep::Direction epsilon{std::numeric_limits<double>::epsilon(),
0039                                      std::numeric_limits<double>::epsilon(),
0040                                      std::numeric_limits<double>::epsilon()};
0041     field += epsilon;
0042   }
0043 
0044   return Acts::Result<Acts::Vector3>::success({field.x(), field.y(), field.z()});
0045 }
0046 
0047 #if Acts_VERSION_MAJOR < 39
0048 Acts::Result<Acts::Vector3>
0049 DD4hepBField::getFieldGradient(const Acts::Vector3& position,
0050                                Acts::ActsMatrix<3, 3>& /*derivative*/,
0051                                Acts::MagneticFieldProvider::Cache& cache) const {
0052   return this->getField(position, cache);
0053 }
0054 #endif
0055 
0056 } // namespace eicrecon::BField