Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:11:25

0001 // This file is part of the ACTS project.
0002 //
0003 // Copyright (C) 2016 CERN for the benefit of the ACTS project
0004 //
0005 // This Source Code Form is subject to the terms of the Mozilla Public
0006 // License, v. 2.0. If a copy of the MPL was not distributed with this
0007 // file, You can obtain one at https://mozilla.org/MPL/2.0/.
0008 
0009 #include "Acts/MagneticField/MultiRangeBField.hpp"
0010 
0011 #include "Acts/MagneticField/MagneticFieldError.hpp"
0012 
0013 namespace Acts {
0014 
0015 MultiRangeBField::Cache::Cache(const MagneticFieldContext& /*unused*/) {}
0016 
0017 MultiRangeBField::MultiRangeBField(const std::vector<BFieldRange>& ranges)
0018     : fieldRanges(ranges) {}
0019 
0020 MultiRangeBField::MultiRangeBField(
0021     std::vector<MultiRangeBField::BFieldRange>&& ranges)
0022     : fieldRanges(std::move(ranges)) {}
0023 
0024 MagneticFieldProvider::Cache MultiRangeBField::makeCache(
0025     const MagneticFieldContext& mctx) const {
0026   return MagneticFieldProvider::Cache(std::in_place_type<Cache>, mctx);
0027 }
0028 
0029 Result<Vector3> MultiRangeBField::getField(
0030     const Vector3& position, MagneticFieldProvider::Cache& cache) const {
0031   // Because we assume that the regions are in increasing order of
0032   // precedence, we can iterate over the array, remembering the _last_
0033   // region that contained the given point. At the end of the loop, this
0034   // region will then be the one we query for its field vector.
0035   std::optional<std::size_t> foundRange = {};
0036 
0037   // The cache object for this type contains an optional integer; if the
0038   // integer is set, it indicates the index of the region in which the last
0039   // access succeeded. This acts as a cache because if the current access is
0040   // still within that region, it is guaranteed that none of the regions
0041   // with lower priority -- i.e. that are earlier in the region vector --
0042   // can be relevant to the current access. Thus, we request the cache index
0043   // if it exists and perform a membership check on it; if that succeeds, we
0044   // remember the corresponding region as a candidate.
0045   if (Cache& lCache = cache.as<Cache>();
0046       lCache.index.has_value() &&
0047       std::get<0>(fieldRanges[*lCache.index])
0048           .contains({position[0], position[1], position[2]})) {
0049     foundRange = *lCache.index;
0050   }
0051 
0052   // Now, we iterate over the ranges. If we already have a range candidate,
0053   // we start iteration just after the existing candidate; otherwise we
0054   // start from the beginning.
0055   for (std::size_t i = (foundRange.has_value() ? (*foundRange) + 1 : 0);
0056        i < fieldRanges.size(); ++i) {
0057     if (std::get<0>(fieldRanges[i])
0058             .contains({position[0], position[1], position[2]})) {
0059       foundRange = i;
0060     }
0061   }
0062 
0063   // Update the cache using the result of this access.
0064   cache.as<Cache>().index = foundRange;
0065 
0066   // If we found a valid range, return the corresponding vector; otherwise
0067   // return an out-of-bounds error.
0068   if (foundRange.has_value()) {
0069     return Result<Vector3>::success(std::get<1>(fieldRanges[*foundRange]));
0070   } else {
0071     return Result<Vector3>::failure(MagneticFieldError::OutOfBounds);
0072   }
0073 }
0074 
0075 }  // namespace Acts