diff --git a/DDG4/include/DDG4/Geant4IsotropeGenerator.h b/DDG4/include/DDG4/Geant4IsotropeGenerator.h index 084ba36a8834711b3613001dfe652ea3b89f9f86..a16388de7a77f4dfae585daf150841b0ab667ef0 100644 --- a/DDG4/include/DDG4/Geant4IsotropeGenerator.h +++ b/DDG4/include/DDG4/Geant4IsotropeGenerator.h @@ -40,12 +40,8 @@ namespace dd4hep { double m_thetaMin; /// Property: Maximal theta angular value double m_thetaMax; - /// Property: Minimal momentum value - double m_momentumMin; - /// Property: Maximal momentum value - double m_momentumMax; - /// Particle modification. Caller presets defaults to: ( direction = m_direction, momentum = m_energy) + /// Particle modification. Caller presets defaults to: ( direction = m_direction, momentum = [m_momentumMin, m_momentumMax]) /** Use this function to implement isotrop guns, multiple guns etc. User must return a UNIT vector, which gets scaled with momentum. */ @@ -58,8 +54,6 @@ namespace dd4hep { void getParticleDirectionCosTheta(int num, ROOT::Math::XYZVector& direction, double& momentum) const; /// Uniform particle distribution void getParticleDirectionUniform(int num, ROOT::Math::XYZVector& direction, double& momentum) const; - /// Uniform particle momentum - void getParticleMomentumUniform(double& momentum) const; public: /// Inhibit default constructor diff --git a/DDG4/include/DDG4/Geant4ParticleGenerator.h b/DDG4/include/DDG4/Geant4ParticleGenerator.h index 44aa717080b077248b8c69146a22636f001d392d..7810f8d2b722b0ca0c89c266920c98a525b2c4ad 100644 --- a/DDG4/include/DDG4/Geant4ParticleGenerator.h +++ b/DDG4/include/DDG4/Geant4ParticleGenerator.h @@ -46,8 +46,12 @@ namespace dd4hep { std::string m_particleName; /// Pointer to geant4 particle definition G4ParticleDefinition* m_particle; - /// Property: Particle energy + /// Property: Fixed momentum value, overwrites momentumMin and momentumMax if set double m_energy; + /// Property: Minimal momentum value + double m_momentumMin; + /// Property: Maximal momentum value + double m_momentumMax; /// Property: Desired multiplicity of the particles to be shot int m_multiplicity; /// Property: User mask passed to all particles in the generated interaction @@ -64,6 +68,8 @@ namespace dd4hep { User must return a UNIT vector, which gets scaled with momentum. */ virtual void getParticleDirection(int num, ROOT::Math::XYZVector& direction, double& momentum) const; + /// Uniform particle momentum + void getParticleMomentumUniform(double& momentum) const; /// Print single particle interaction identified by its mask virtual void printInteraction(int mask) const; diff --git a/DDG4/include/DDG4/Geant4ParticleGun.h b/DDG4/include/DDG4/Geant4ParticleGun.h index f1c46625f149b37787859c281df76361e7415343..db33baf6388e46344955bd4b54aab7485a299c14 100644 --- a/DDG4/include/DDG4/Geant4ParticleGun.h +++ b/DDG4/include/DDG4/Geant4ParticleGun.h @@ -63,7 +63,7 @@ namespace dd4hep { bool m_print; /// Shot number in sequence int m_shotNo; - /// Particle modification. Caller presets defaults to: ( direction = m_direction, momentum = m_energy) + /// Particle modification. Caller presets defaults to: ( direction = m_direction, momentum = [m_momentumMin, m_momentumMax]) virtual void getParticleDirection(int, ROOT::Math::XYZVector& direction, double& momentum) const; public: /// Standard constructor diff --git a/DDG4/python/DDG4.py b/DDG4/python/DDG4.py index 38bb05a66fb3efc7a340dc30f46713a2b1a6ffd3..eefe6b9c6351706183182f61b3666d4970ec4d3c 100644 --- a/DDG4/python/DDG4.py +++ b/DDG4/python/DDG4.py @@ -763,7 +763,7 @@ class Geant4: gun = GeneratorAction(self.kernel(), typ + "/" + name, True) for i in args.items(): setattr(gun, i[0], i[1]) - gun.energy = energy + gun.Energy = energy gun.particle = particle gun.multiplicity = multiplicity gun.position = position diff --git a/DDG4/python/DDSim/Helper/Gun.py b/DDG4/python/DDSim/Helper/Gun.py index c33a5c1f5653fec4a698adf6331b9b604680df65..97b35cdfd14bd268fb32d161b28e292a3996a053 100644 --- a/DDG4/python/DDSim/Helper/Gun.py +++ b/DDG4/python/DDSim/Helper/Gun.py @@ -27,7 +27,11 @@ class Gun(ConfigHelper): self.thetaMax = None self._momentumMin_EXTRA = {'help': "Minimal momentum when using distribution (default = 0.0)"} self.momentumMin = None + self._momentumMax_EXTRA = {'help': "Maximal momentum when using distribution (default = 0.0)"} self.momentumMax = 10 * GeV + self._energy_EXTRA = {'help': "The kinetic energy for the particle gun.\n\n" + "If not None, it will overwrite the setting of momentumMin and momentumMax"} + self.energy = None self._distribution_EXTRA = {'choices': ['uniform', 'cos(theta)', 'eta', 'pseudorapidity', @@ -113,6 +117,8 @@ class Gun(ConfigHelper): def setOptions(self, ddg4Gun): """set the starting properties of the DDG4 particle gun""" try: + if self.energy: + ddg4Gun.Energy = self.energy ddg4Gun.particle = self.particle ddg4Gun.multiplicity = self.multiplicity ddg4Gun.position = self.position diff --git a/DDG4/src/Geant4IsotropeGenerator.cpp b/DDG4/src/Geant4IsotropeGenerator.cpp index aed96621b26a883d752422bf74e959ae0ff25d88..f7d132c6c29a70548a88325b6b0ba3a946044285 100644 --- a/DDG4/src/Geant4IsotropeGenerator.cpp +++ b/DDG4/src/Geant4IsotropeGenerator.cpp @@ -29,8 +29,6 @@ Geant4IsotropeGenerator::Geant4IsotropeGenerator(Geant4Context* ctxt, const stri declareProperty("PhiMax", m_phiMax = 2.0*M_PI); declareProperty("ThetaMin", m_thetaMin = 0.0); declareProperty("ThetaMax", m_thetaMax = M_PI); - declareProperty("MomentumMin", m_momentumMin = 0.0); - declareProperty("MomentumMax", m_momentumMax = -1.0); declareProperty("Distribution", m_distribution = "uniform" ); } @@ -39,16 +37,6 @@ Geant4IsotropeGenerator::~Geant4IsotropeGenerator() { InstanceCount::decrement(this); } -/// Uniform momentum distribution -void Geant4IsotropeGenerator::getParticleMomentumUniform(double& momentum) const { - Geant4Event& evt = context()->event(); - Geant4Random& rnd = evt.random(); - if (m_momentumMax < m_momentumMin) - momentum = m_momentumMin+(momentum-m_momentumMin)*rnd.rndm(); - else - momentum = m_momentumMin+(m_momentumMax-m_momentumMin)*rnd.rndm(); -} - /// Uniform particle distribution void Geant4IsotropeGenerator::getParticleDirectionUniform(int, ROOT::Math::XYZVector& direction, double& momentum) const { Geant4Event& evt = context()->event(); @@ -128,7 +116,7 @@ void Geant4IsotropeGenerator::getParticleDirectionFFbar(int, ROOT::Math::XYZVect } } -/// Particle modification. Caller presets defaults to: ( direction = m_direction, momentum = m_energy) +/// Particle modification. Caller presets defaults to: ( direction = m_direction, momentum = [mMin, mMax]) void Geant4IsotropeGenerator::getParticleDirection(int num, ROOT::Math::XYZVector& direction, double& momentum) const { switch(::toupper(m_distribution[0])) { case 'C': // cos(theta) diff --git a/DDG4/src/Geant4ParticleGenerator.cpp b/DDG4/src/Geant4ParticleGenerator.cpp index 76361b7d388361c95b3feaf6caeb0bd2db930697..0be46c42b969fb8a0fccd3efdfa699a7052463b9 100644 --- a/DDG4/src/Geant4ParticleGenerator.cpp +++ b/DDG4/src/Geant4ParticleGenerator.cpp @@ -17,6 +17,7 @@ #include "DDG4/Geant4Context.h" #include "DDG4/Geant4Primary.h" #include "DDG4/Geant4ParticleGenerator.h" +#include "DDG4/Geant4Random.h" #include "CLHEP/Units/SystemOfUnits.h" // Geant4 include files @@ -37,7 +38,10 @@ Geant4ParticleGenerator::Geant4ParticleGenerator(Geant4Context* ctxt, const stri InstanceCount::increment(this); m_needsControl = true; declareProperty("Particle", m_particleName = "e-"); - declareProperty("Energy", m_energy = 50 * CLHEP::MeV); + declareProperty("Energy", m_energy = -1); + declareProperty("energy", m_energy = -1); + declareProperty("MomentumMin", m_momentumMin = 0.0); + declareProperty("MomentumMax", m_momentumMax = 50 * CLHEP::MeV); declareProperty("Multiplicity", m_multiplicity = 1); declareProperty("Mask", m_mask = 0); declareProperty("Position", m_position = ROOT::Math::XYZVector(0.,0.,0.)); @@ -49,8 +53,24 @@ Geant4ParticleGenerator::~Geant4ParticleGenerator() { InstanceCount::decrement(this); } -/// Particle modification. Caller presets defaults to: ( direction = m_direction, momentum = m_energy) -void Geant4ParticleGenerator::getParticleDirection(int , ROOT::Math::XYZVector& , double& ) const { +/// Particle modification. Caller presets defaults to: ( direction = m_direction, momentum = [mMin, mMax]) +void Geant4ParticleGenerator::getParticleDirection(int , ROOT::Math::XYZVector& , double& momentum) const { + getParticleMomentumUniform(momentum); +} + +/// Uniform momentum distribution +void Geant4ParticleGenerator::getParticleMomentumUniform(double& momentum) const { + if (m_energy != -1) { + momentum = m_energy; + return; + } + Geant4Event& evt = context()->event(); + Geant4Random& rnd = evt.random(); + if (m_momentumMax < m_momentumMin) + // We no longer set m_momentumMax to -1 so, not entirely sure a) this will still happen, b) actually work + momentum = m_momentumMin+(momentum-m_momentumMin)*rnd.rndm(); + else + momentum = m_momentumMin+(m_momentumMax-m_momentumMin)*rnd.rndm(); } /// Particle modification. Caller presets defaults to: (multiplicity=m_multiplicity) @@ -85,8 +105,8 @@ void Geant4ParticleGenerator::printInteraction(Geant4PrimaryInteraction* inter) } for(const auto& iv : inter->vertices ) { for( Geant4Vertex* v : iv.second ){ - print("+-> Interaction [%d] %.3f GeV %s pos:(%.3f %.3f %.3f)[mm]", - count, m_energy/CLHEP::GeV, m_particleName.c_str(), + print("+-> Interaction [%d] [%.3f , %.3f] GeV %s pos:(%.3f %.3f %.3f)[mm]", + count, m_momentumMin/CLHEP::GeV, m_momentumMax/CLHEP::GeV, m_particleName.c_str(), v->x/CLHEP::mm, v->y/CLHEP::mm, v->z/CLHEP::mm); ++count; for ( int i : v->out ) { @@ -124,7 +144,7 @@ void Geant4ParticleGenerator::operator()(G4Event*) { vtx->z = position.Z(); inter->vertices[m_mask].emplace_back( vtx ); for(int i=0; i<m_multiplicity; ++i) { - double momentum = m_energy; + double momentum = 0.0; ROOT::Math::XYZVector direction = m_direction; Particle* p = new Particle(); getParticleDirection(i, direction, momentum); diff --git a/DDG4/src/Geant4ParticleGun.cpp b/DDG4/src/Geant4ParticleGun.cpp index b4bdea57790aca280bea41d20b728020fe282c32..2718dd950e4beb89284a90c3b86290d3a637ba31 100644 --- a/DDG4/src/Geant4ParticleGun.cpp +++ b/DDG4/src/Geant4ParticleGun.cpp @@ -40,7 +40,6 @@ Geant4ParticleGun::Geant4ParticleGun(Geant4Context* ctxt, const string& nam) declareProperty("position", m_position); declareProperty("distribution", m_distribution); declareProperty("direction", m_direction); - declareProperty("energy", m_energy); declareProperty("particle", m_particleName); declareProperty("multiplicity", m_multiplicity); declareProperty("print", m_print = true); @@ -51,7 +50,7 @@ Geant4ParticleGun::~Geant4ParticleGun() { InstanceCount::decrement(this); } -/// Particle modification. Caller presets defaults to: ( direction = m_direction, momentum = m_energy) +/// Particle modification. Caller presets defaults to: ( direction = m_direction, momentum = [mMin, mMax]) void Geant4ParticleGun::getParticleDirection(int num, ROOT::Math::XYZVector& direction, double& momentum) const { ( m_isotrop ) ? this->Geant4IsotropeGenerator::getParticleDirection(num, direction, momentum) @@ -68,11 +67,18 @@ void Geant4ParticleGun::operator()(G4Event* event) { if ( m_standalone ) { generationInitialization(this,context()); } - this->Geant4ParticleGenerator::operator()(event); - print("Shoot [%d] %.3f GeV %s pos:(%.3f %.3f %.3f)[mm] dir:(%6.3f %6.3f %6.3f)", - m_shotNo, m_energy/CLHEP::GeV, m_particleName.c_str(), + + //bit wasteful to always set this :( + if( m_energy != -1 ){ + m_momentumMin = m_energy; + m_momentumMax = m_energy; + } + + print("Shoot [%d] [%.3f , %.3f] GeV %s pos:(%.3f %.3f %.3f)[mm] dir:(%6.3f %6.3f %6.3f)", + m_shotNo, m_momentumMin/CLHEP::GeV, m_momentumMax/CLHEP::GeV, m_particleName.c_str(), m_position.X()/CLHEP::mm, m_position.Y()/CLHEP::mm, m_position.Z()/CLHEP::mm, - m_direction.X(),m_direction.Y(), m_direction.Z()); + m_direction.X(), m_direction.Y(), m_direction.Z()); + this->Geant4ParticleGenerator::operator()(event); if ( m_print ) { this->Geant4ParticleGenerator::printInteraction(m_mask); } diff --git a/doc/usermanuals/DDG4/sections/Setup.tex b/doc/usermanuals/DDG4/sections/Setup.tex index b4ec99e5af08f2c5c2dd4d309329a7c83055d20b..78821a69bf77b15f08bd09ac6a9fba1653866568 100644 --- a/doc/usermanuals/DDG4/sections/Setup.tex +++ b/doc/usermanuals/DDG4/sections/Setup.tex @@ -597,7 +597,7 @@ def run(): # Setup particle gun gun = DDG4.GeneratorAction(kernel,"Geant4ParticleGun/Gun") - gun.energy = 0.5*GeV + gun.Energy = 0.5*GeV gun.particle = 'e-' gun.multiplicity = 1 gun.enableUI() diff --git a/examples/ClientTests/scripts/NestedBoxReflection.py b/examples/ClientTests/scripts/NestedBoxReflection.py index ad1fd6bfc13dcc09c871f75cc8369bc06114fd9b..d4fd12a381aff3072c995a67aa33317be28fc5dc 100644 --- a/examples/ClientTests/scripts/NestedBoxReflection.py +++ b/examples/ClientTests/scripts/NestedBoxReflection.py @@ -112,7 +112,7 @@ def run(): gen.mask = 4 gen.isotrop = True gen.particle = 'e+' - gen.energy = 100 * GeV + gen.Energy = 100 * GeV gen.multiplicity = 200 gen.position = (0 * m, 0 * m, 0 * m) gen.direction = (0, 0, 1.)