Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-08-03 07:48:43

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/Algebra.hpp"
0012 #include "Acts/Utilities/AxisDefinitions.hpp"
0013 #include "ActsExamples/Framework/RandomNumbers.hpp"
0014 
0015 #include <functional>
0016 #include <random>
0017 
0018 namespace ActsExamples::AlignmentGenerator {
0019 
0020 /// @note Non-contextual random number generators
0021 ///
0022 /// Random numbers in the alignment generators can be context-free
0023 /// as their call sequence is controlled  by the IOV and not altered
0024 /// by eventually changing random number seeds.
0025 
0026 struct UniformRandom {
0027   /// The random number generator to be used for normal distribution
0028   /// @param seed The random seed to be used
0029   /// @param min The minimum value of the uniform distribution
0030   /// @param max The maximum value of the uniform distribution
0031   UniformRandom(RandomSeed seed, double min, double max)
0032       : randomEngine(seed), randomNumbers(min, max) {}
0033 
0034   /// @brief The call operation generating a random number
0035   double operator()() { return randomNumbers(randomEngine); }
0036 
0037   RandomEngine randomEngine;  ///< The random number generator
0038   std::uniform_real_distribution<double> randomNumbers;  ///< The distribution
0039 };
0040 
0041 struct GaussRandom {
0042   /// The random number generator to be used for Gaussian distribution
0043   /// @param seed The random seed to be used
0044   /// @param mean The mean value of the Gaussian distribution
0045   /// @param sigma The standard deviation of the Gaussian distribution
0046   GaussRandom(RandomSeed seed, double mean, double sigma)
0047       : randomEngine(seed), randomNumbers(mean, sigma) {}
0048 
0049   /// @brief The call operation generating a random number
0050   double operator()() { return randomNumbers(randomEngine); }
0051 
0052   RandomEngine randomEngine;  ///< The random number generator
0053   std::normal_distribution<double> randomNumbers;  ///< The distribution
0054 };
0055 
0056 struct ClippedGaussRandom {
0057   /// The random number generator to be usedfor gaussian with clipping
0058   /// @param seed The random seed to be used
0059   /// @param mean The mean value of the Gaussian distribution
0060   /// @param sigma The standard deviation of the Gaussian distribution
0061   /// @param minv The minimum value of the truncated Gaussian distribution
0062   /// @param maxv The maximum value of the truncated Gaussian distribution
0063   ClippedGaussRandom(RandomSeed seed, double mean, double sigma, double minv,
0064                      double maxv)
0065       : randomEngine(seed), randomNumbers(mean, sigma), min(minv), max(maxv) {}
0066 
0067   /// @brief The call operation generating a random number
0068   double operator()() {
0069     auto value = randomNumbers(randomEngine);
0070     return std::max(min, std::min(max, value));
0071   }
0072 
0073   RandomEngine randomEngine;  ///< The random number generator
0074   std::normal_distribution<double> randomNumbers;  ///< The distribution
0075   double min;  ///< The minimum value of the truncated Gaussian distribution
0076   double max;  ///< The maximum value of the truncated Gaussian distribution
0077 };
0078 
0079 /// This generator does nothing
0080 struct Nominal {
0081   /// @brief The call operation for the nominal alignment
0082   void operator()(Acts::Transform3* /*transform*/) const {
0083     // No operation, this is a nominal alignment generator}
0084   }
0085 };
0086 
0087 /// This generator applies a constant global shift to the transform
0088 struct GlobalShift {
0089   // The shift to be applied
0090   Acts::Vector3 shift = Acts::Vector3::UnitZ();
0091 
0092   std::function<double()> randomize = nullptr;  ///< Optional scale factor
0093 
0094   /// @brief The call operation applying the global shift
0095   void operator()(Acts::Transform3* transform) const {
0096     double scale =
0097         randomize != nullptr ? randomize() : 1.0;  ///< Default scale is 1.0
0098     transform->translation() += scale * shift;
0099   }
0100 };
0101 
0102 /// This generator applies a constant global rotation (i.e. around 0.,0.,0)
0103 /// of value `angle` around the `axis`
0104 struct GlobalRotation {
0105   /// The axis around which the rotation is applied
0106   Acts::Vector3 axis =
0107       Acts::Vector3::UnitZ();  ///< The rotation axis, default is Z-axis
0108   double angle = 0.0;          ///< The rotation angle in radians
0109 
0110   std::function<double()> randomize = nullptr;  ///< Optional scale factor
0111 
0112   /// @brief The call operation applying the global rotation
0113   /// @param transform The transform to be rotated
0114   void operator()(Acts::Transform3* transform) const {
0115     double angleS = randomize != nullptr ? randomize() * angle : angle;
0116     (*transform) = Acts::AngleAxis3(angleS, axis) * (*transform);
0117   }
0118 };
0119 
0120 /// This generator applies a rotation in the local frame around a given
0121 /// local axis. I.e. if the z-axis is chosen, the module will be rotated
0122 /// by the angle around this axis.
0123 struct LocalRotation {
0124   /// The axis around which the rotation is applied
0125   Acts::Vector3 axis =
0126       Acts::Vector3::UnitZ();  ///< The rotation axis, default is Z-axis
0127   double angle = 0.0;          ///< The rotation angle in radians
0128 
0129   std::function<double()> randomize = nullptr;  ///< Optional scale factor
0130 
0131   /// @brief The call operation applying the global rotation
0132   /// @param transform The transform to be rotated
0133   void operator()(Acts::Transform3* transform) const {
0134     double angleS = randomize != nullptr ? randomize() * angle : angle;
0135     (*transform) *= Acts::AngleAxis3(angleS, axis);
0136   }
0137 };
0138 
0139 /// This generator applies a local shift
0140 struct LocalShift {
0141   /// The axis direction
0142   Acts::AxisDirection axisDirection = Acts::AxisDirection::AxisX;
0143   /// The shift to be applied
0144   double shift = 0.0;
0145   /// Optional randomization function
0146   std::function<double()> randomize = nullptr;
0147 
0148   /// @brief The call operation applying the local shift
0149   /// @param transform The transform to be shifted
0150   void operator()(Acts::Transform3* transform) const {
0151     double shiftS = randomize != nullptr ? randomize() * shift : shift;
0152 
0153     const auto rotation = transform->rotation();
0154 
0155     switch (axisDirection) {
0156       case Acts::AxisDirection::AxisX: {
0157         Acts::Translation3 translation(shiftS * rotation.col(0));
0158         (*transform) = translation * (*transform);
0159         break;
0160       }
0161       case Acts::AxisDirection::AxisY: {
0162         Acts::Translation3 translation(shiftS * rotation.col(1));
0163         (*transform) = translation * (*transform);
0164         break;
0165       }
0166       case Acts::AxisDirection::AxisZ: {
0167         Acts::Translation3 translation(shiftS * rotation.col(2));
0168         (*transform) = translation * (*transform);
0169         break;
0170       }
0171       default:
0172         throw std::runtime_error("LocalShift: Invalid axis direction");
0173     }
0174   }
0175 };
0176 
0177 }  // namespace ActsExamples::AlignmentGenerator