Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:12:12

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 #pragma once
0010 
0011 #include "Acts/Definitions/TrackParametrization.hpp"
0012 #include "Acts/EventData/TransformationHelpers.hpp"
0013 #include "Acts/Geometry/DetectorElementBase.hpp"
0014 #include "Acts/Surfaces/Surface.hpp"
0015 #include "Acts/Utilities/Result.hpp"
0016 #include "ActsFatras/EventData/Hit.hpp"
0017 
0018 #include <array>
0019 #include <functional>
0020 #include <utility>
0021 
0022 namespace ActsFatras {
0023 
0024 /// Smearing function definition for single track parameters.
0025 ///
0026 /// The function takes the unsmeared parameter and returns the smeared value and
0027 /// a standard deviation.
0028 ///
0029 /// @tparam generator_t The type of the random generator.
0030 template <typename generator_t>
0031 using SingleParameterSmearFunction =
0032     std::function<Acts::Result<std::pair<double, double>>(double,
0033                                                           generator_t&)>;
0034 
0035 /// Uncorrelated smearing algorithm for fast digitisation of bound parameters.
0036 ///
0037 /// @tparam generator_t Random number generator type
0038 /// @tparam kSize Number of smeared parameters
0039 ///
0040 /// The smearer takes a single simulated `Hit` and generates a smeared parameter
0041 /// vector and associated covariance matrix.
0042 template <typename generator_t, std::size_t kSize>
0043 struct BoundParametersSmearer {
0044   using ParametersVector = Acts::ActsVector<kSize>;
0045   using CovarianceMatrix = Acts::ActsSquareMatrix<kSize>;
0046   using Result = Acts::Result<std::pair<ParametersVector, CovarianceMatrix>>;
0047 
0048   /// Parameter indices that will be used to create the smeared measurements.
0049   std::array<Acts::BoundIndices, kSize> indices{};
0050   std::array<SingleParameterSmearFunction<generator_t>, kSize> smearFunctions{};
0051   std::array<bool, kSize> forcePositive = {};
0052 
0053   static constexpr std::size_t size() { return kSize; }
0054 
0055   /// Generate smeared measured for configured parameters.
0056   ///
0057   /// @param rng Random number generator
0058   /// @param hit Simulated hit
0059   /// @param surface Local surface on which the hit is smeared
0060   /// @param geoCtx Geometry context
0061   /// @retval Smeared parameters vector and associated covariance on success
0062   /// @retval Error code for failure
0063   Result operator()(generator_t& rng, const Hit& hit,
0064                     const Acts::Surface& surface,
0065                     const Acts::GeometryContext& geoCtx) const {
0066     // We use the thickness of the detector element as tolerance, because Geant4
0067     // treats the Surfaces as volumes and thus it is not ensured, that each hit
0068     // lies exactly on the Acts::Surface
0069     const auto tolerance =
0070         surface.associatedDetectorElement() != nullptr
0071             ? surface.associatedDetectorElement()->thickness()
0072             : Acts::s_onSurfaceTolerance;
0073 
0074     // construct full bound parameters. they are probably not all needed, but it
0075     // is easier to just create them all and then select the requested ones.
0076     Acts::Result<Acts::BoundVector> boundParamsRes =
0077         Acts::transformFreeToBoundParameters(hit.position(), hit.time(),
0078                                              hit.direction(), 0, surface,
0079                                              geoCtx, tolerance);
0080 
0081     if (!boundParamsRes.ok()) {
0082       return boundParamsRes.error();
0083     }
0084 
0085     const auto& boundParams = *boundParamsRes;
0086 
0087     ParametersVector par = ParametersVector::Zero();
0088     CovarianceMatrix cov = CovarianceMatrix::Zero();
0089     for (std::size_t i = 0; i < kSize; ++i) {
0090       auto res = smearFunctions[i](boundParams[indices[i]], rng);
0091       if (!res.ok()) {
0092         return Result::failure(res.error());
0093       }
0094       auto [value, stddev] = res.value();
0095       par[i] = value;
0096       if (forcePositive[i]) {
0097         par[i] = std::abs(value);
0098       }
0099       cov(i, i) = stddev * stddev;
0100     }
0101 
0102     return Result::success(std::make_pair(par, cov));
0103   }
0104 };
0105 
0106 /// Uncorrelated smearing algorithm for fast digitisation of free parameters.
0107 ///
0108 /// @tparam generator_t Random number generator type
0109 /// @tparam kSize Number of smeared parameters
0110 ///
0111 /// The smearer takes a single simulated `Hit` and generates a smeared parameter
0112 /// vector and associated covariance matrix.
0113 ///
0114 /// @note Uncorrelated smearing of the direction using each components
0115 ///   individually is not recommended
0116 template <typename generator_t, std::size_t kSize>
0117 struct FreeParametersSmearer {
0118   using ParametersVector = Acts::ActsVector<kSize>;
0119   using CovarianceMatrix = Acts::ActsSquareMatrix<kSize>;
0120   using Result = Acts::Result<std::pair<ParametersVector, CovarianceMatrix>>;
0121 
0122   /// Parameter indices that will be used to create the smeared measurements.
0123   std::array<Acts::FreeIndices, kSize> indices{};
0124   std::array<SingleParameterSmearFunction<generator_t>, kSize> smearFunctions;
0125 
0126   static constexpr std::size_t size() { return kSize; }
0127 
0128   /// Generate smeared measured for configured parameters.
0129   ///
0130   /// @param rng Random number generator
0131   /// @param hit Simulated hit
0132   /// @return Smeared free parameter set wrapped in a Result<...> object
0133   /// @retval Smeared parameters vector and associated covariance on success
0134   /// @retval Error code for failure
0135   Result operator()(generator_t& rng, const Hit& hit) const {
0136     // construct full free parameters. they are probably not all needed, but it
0137     // is easier to just create them all and then select the requested ones.
0138     Acts::FreeVector freeParams;
0139     freeParams.segment<3>(Acts::eFreePos0) = hit.position();
0140     freeParams[Acts::eFreeTime] = hit.time();
0141     freeParams.segment<3>(Acts::eFreeDir0) = hit.direction();
0142     freeParams[Acts::eFreeQOverP] = 0;
0143 
0144     ParametersVector par = ParametersVector::Zero();
0145     CovarianceMatrix cov = CovarianceMatrix::Zero();
0146     for (std::size_t i = 0; i < kSize; ++i) {
0147       auto res = smearFunctions[i](freeParams[indices[i]], rng);
0148       if (!res.ok()) {
0149         return Result::failure(res.error());
0150       }
0151       auto [value, stddev] = res.value();
0152       par[i] = value;
0153       cov(i, i) = stddev * stddev;
0154     }
0155 
0156     return Result::success(std::make_pair(par, cov));
0157   }
0158 };
0159 
0160 }  // namespace ActsFatras