|
|
|||
File indexing completed on 2026-09-19 09:18:10
0001 //========================================================================== 0002 // AIDA Detector description implementation 0003 //-------------------------------------------------------------------------- 0004 // Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN) 0005 // All rights reserved. 0006 // 0007 // For the licensing terms see $DD4hepINSTALL/LICENSE. 0008 // For the list of contributors see $DD4hepINSTALL/doc/CREDITS. 0009 // 0010 // Author : M.Frank 0011 // 0012 //========================================================================== 0013 0014 #ifndef DDG4_GEANT4ISOTROPEGENERATOR_H 0015 #define DDG4_GEANT4ISOTROPEGENERATOR_H 0016 0017 // Framework include files 0018 #include <DDG4/Geant4ParticleGenerator.h> 0019 0020 // C/C++ include files 0021 #include <array> 0022 #include <cstdint> 0023 #include <functional> 0024 #include <mutex> 0025 0026 /// Namespace for the AIDA detector description toolkit 0027 namespace dd4hep { 0028 0029 /// Namespace for the Geant4 based simulation part of the AIDA detector description toolkit 0030 namespace sim { 0031 0032 // Forward declarations 0033 class Geant4Random; 0034 0035 /// Generate particles isotrop in space around origine (0,0,0) 0036 /** 0037 * Supports both standard PRNG-based sampling and Randomized Quasi-Monte Carlo 0038 * sampling via scrambled Halton sequences (Cranley-Patterson rotation). 0039 * 0040 * When Halton mode is enabled (property "Halton" = true), the three sampling 0041 * dimensions use low-discrepancy Halton sequences in bases 2 (phi), 3 (theta), 0042 * and 5 (momentum), each additively scrambled by a per-dimension shift derived 0043 * from the Geant4Random seed. This provides superior phase-space coverage 0044 * relative to a PRNG while remaining reproducible and independent across jobs 0045 * (using different seeds or "HaltonOffset" values). 0046 * 0047 * Note: the "ffbar" distribution is incompatible with Halton mode because its 0048 * acceptance-rejection loop cannot be driven by a fixed per-particle Halton point. 0049 * 0050 * \author M.Frank 0051 * \version 1.0 0052 * \ingroup DD4HEP_SIMULATION 0053 */ 0054 class Geant4IsotropeGenerator: public Geant4ParticleGenerator { 0055 protected: 0056 /// Property: Distribution name. Default: "uniform". Allowed: "uniform", "cos(theta)", "ffbar", "eta" 0057 std::string m_distribution; 0058 /// Property: Minimal phi angular value 0059 double m_phiMin; 0060 /// Property: Maximal phi angular value 0061 double m_phiMax; 0062 /// Property: Minimal theta angular value 0063 double m_thetaMin; 0064 /// Property: Maximal theta angular value 0065 double m_thetaMax; 0066 /// Property: Enable scrambled Halton sequence sampling (RQMC mode) 0067 bool m_halton; 0068 /// Property: Starting index in the Halton sequence (use for parallel-job partitioning) 0069 uint64_t m_haltonOffset; 0070 /// Current Halton sequence index (incremented per generated particle) 0071 mutable uint64_t m_haltonIndex; 0072 /// Per-dimension additive scramble shifts in [0,1), sampled from Geant4Random on first use 0073 mutable std::array<double,3> m_haltonShift; 0074 /// Ensures initHalton() runs exactly once across all events 0075 mutable std::once_flag m_haltonOnce; 0076 0077 /// Initialize Cranley-Patterson shifts using @a rnd; set m_haltonIndex = m_haltonOffset 0078 void initHalton(Geant4Random& rnd) const; 0079 /// Compute the radical inverse of @a index in the given @a base (standard Halton value) 0080 static double haltonValue(uint64_t index, int base); 0081 /// Return the scrambled Halton sample for dimension @a dim (0=phi,1=theta,2=momentum) 0082 double haltonScrambled(uint64_t index, unsigned int dim) const; 0083 /// Build and return a per-particle sampler: either PRNG or Halton, depending on m_halton. 0084 /// For Halton mode, advances m_haltonIndex by one. 0085 std::function<double(unsigned int)> makeSampler(Geant4Random& rnd) const; 0086 /// Sample momentum from [m_momentumMin, m_momentumMax] using a pre-computed [0,1) value @a h 0087 void sampleMomentum(double h, double& momentum) const; 0088 0089 /// Particle modification. Caller presets defaults to: ( direction = m_direction, momentum = [m_momentumMin, m_momentumMax]) 0090 /** Use this function to implement isotrop guns, multiple guns etc. 0091 User must return a UNIT vector, which gets scaled with momentum. 0092 */ 0093 virtual void getParticleDirection(int num, ROOT::Math::XYZVector& direction, double& momentum) const override; 0094 /// e+e- --> ffbar particle distribution ~ 1 + cos^2(theta) (PRNG only; incompatible with Halton) 0095 void getParticleDirectionFFbar(int num, ROOT::Math::XYZVector& direction, double& momentum) const; 0096 /// Flat pseudorapidity (eta) distribution 0097 void getParticleDirectionEta(int num, const std::function<double(unsigned int)>& sample, ROOT::Math::XYZVector& direction, double& momentum) const; 0098 /// Particle distribution ~ cos(theta) 0099 void getParticleDirectionCosTheta(int num, const std::function<double(unsigned int)>& sample, ROOT::Math::XYZVector& direction, double& momentum) const; 0100 /// Uniform particle distribution 0101 void getParticleDirectionUniform(int num, const std::function<double(unsigned int)>& sample, ROOT::Math::XYZVector& direction, double& momentum) const; 0102 0103 public: 0104 /// Inhibit default constructor 0105 Geant4IsotropeGenerator() = delete; 0106 /// Inhibit copy constructor 0107 Geant4IsotropeGenerator(const Geant4IsotropeGenerator& copy) = delete; 0108 /// Standard constructor 0109 Geant4IsotropeGenerator(Geant4Context* context, const std::string& name); 0110 /// Default destructor 0111 virtual ~Geant4IsotropeGenerator(); 0112 }; 0113 } // End namespace sim 0114 } // End namespace dd4hep 0115 #endif // DDG4_GEANT4ISOTROPEGENERATOR_H
| [ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
|
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |
|