Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:28:03

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