@@ -13,17 +13,17 @@ struct SSDPhysics <: G4VUserPhysicsList
1313end
1414
1515struct SDData{T} <: G4JLSDData
16- detectorHits:: DetectorHits
17- SDData {T} () where {T} = new (DetectorHits ((evtno = Int32[], detno = Int32[], thit = typeof (zero (T)* u " s" )[], edep = typeof (zero (T)* u " keV" )[], pos = SVector{3 ,typeof (zero (T)* u " mm" )}[])))
16+ detectorHits:: DetectorHits
17+ SDData {T} () where {T} = new (DetectorHits ((evtno = Int32[], detno = Int32[], thit = typeof (zero (T)* u " s" )[], edep = typeof (zero (T)* u " keV" )[], pos = SVector{3 ,typeof (zero (T)* u " mm" )}[])))
1818end
1919
2020function _initialize (:: G4HCofThisEvent , data:: SDData ):: Nothing
21- empty! (data. detectorHits)
22- return
21+ empty! (data. detectorHits)
22+ return
2323end
2424
2525function _endOfEvent (:: G4HCofThisEvent , data:: SDData ):: Nothing
26- return
26+ return
2727end
2828
2929function _processHits (step:: G4Step , :: G4TouchableHistory , data:: SDData{T} ):: Bool where {T}
@@ -48,12 +48,19 @@ function _processHits(step::G4Step, ::G4TouchableHistory, data::SDData{T})::Bool
4848end
4949
5050function endeventaction (evt:: G4Event , app:: G4JLApplication )
51+ # direction = evt |> (evt -> GetPrimaryVertex(evt, 0)) |> (vertex -> GetPrimary(vertex, 0)) |> GetMomentumDirection
52+ # pos = evt |> (evt -> GetPrimaryVertex(evt, 0)) |> GetPosition
53+ # d = [x(direction), y(direction), z(direction)]
54+ # @info [x(pos), y(pos), z(pos)], normalize(d)
5155 return
5256end
5357
5458
59+ # We are using G4SingleParticleSource instead of G4ParticleGun for uniformity
60+ # across MonoenergeticSource and IsotopeSource, see discussion
61+ # https://github.com/JuliaPhysics/SolidStateDetectors.jl/pull/526
5562@with_kw mutable struct GeneratorData <: G4JLGeneratorData
56- gun:: Union{Nothing, CxxPtr{G4ParticleGun}, CxxPtr{ G4SingleParticleSource}} = nothing
63+ gun:: Union{Nothing, CxxPtr{G4SingleParticleSource}} = nothing
5764 particle:: Union{Nothing, CxxPtr{G4ParticleDefinition}} = nothing
5865 position:: G4ThreeVector = G4ThreeVector (0 , 0 , 0 )
5966 direction:: G4ThreeVector = G4ThreeVector (0 , 0 , 0 )
@@ -66,31 +73,39 @@ function SSDGenerator(source::SolidStateDetectors.MonoenergeticSource; kwargs..
6673 data = GeneratorData (;kwargs... )
6774
6875 function _init (data:: GeneratorData , :: Any )
69- gun = data. gun = move! (G4ParticleGun ())
76+ data. gun = move! (G4SingleParticleSource ())
7077 particle = data. particle = FindParticle (source. particle_type)
78+ SetParticleDefinition (data. gun, particle)
79+
80+ # Place the SingleParticleSource as point source
7181 data. position = G4ThreeVector (
7282 source. position. x * Geant4. SystemOfUnits. meter,
7383 source. position. y * Geant4. SystemOfUnits. meter,
7484 source. position. z * Geant4. SystemOfUnits. meter
7585 )
76- SetParticlePosition (gun, data. position)
77- data. direction = G4ThreeVector (source. direction. x, source. direction. y, source. direction. z)
78- SetParticleMomentumDirection (gun, data. direction)
79- SetParticleEnergy (gun, ustrip (u " MeV" , source. energy))
80- SetParticleDefinition (gun, particle)
86+ posdist = GetPosDist (data. gun)
87+ SetPosDisType (posdist, " Point" )
88+ SetCentreCoords (posdist, data. position)
89+
90+ # Define the source emission
91+ d:: CartesianVector = normalize (source. direction)
92+ a:: CartesianVector = normalize (d × (abs (d. x) == 1 ? CartesianVector (0 ,1 ,0 ) : CartesianVector (1 ,0 ,0 )))
93+ b:: CartesianVector = normalize (a × d)
94+ data. direction = G4ThreeVector (d. x, d. y, d. z)
95+
96+ angdist = GetAngDist (data. gun)
97+ SetAngDistType (angdist, " iso" )
98+ DefineAngRefAxes (angdist, " angref1" , G4ThreeVector (a... ))
99+ DefineAngRefAxes (angdist, " angref2" , G4ThreeVector (b... ))
100+ SetMinTheta (angdist, 0.0 )
101+ SetMaxTheta (angdist, ustrip (NoUnits, source. opening_angle)) # convert to radians
102+ # SetParticleMomentumDirection(angdist, data.direction)
103+
104+ # set energy
105+ SetMonoEnergy (GetEneDist (data. gun), ustrip (u " MeV" , source. energy))
81106 end
82107
83108 function _gen (evt:: G4Event , data:: GeneratorData ):: Nothing
84- if ! iszero (source. opening_angle)
85- d:: CartesianVector = normalize (source. direction)
86- a:: CartesianVector = normalize (d × (abs (d. x) == 1 ? CartesianVector (0 ,1 ,0 ) : CartesianVector (1 ,0 ,0 )))
87- b:: CartesianVector = normalize (a × d)
88- ϕ = rand ()* 2 π
89- θ = acos (1 - (1 - cos (source. opening_angle))* rand ())
90- v = (cos (θ) * d + sin (θ) * (cos (ϕ) * a + sin (ϕ) * b))
91- direction = G4ThreeVector (v. x, v. y, v. z)
92- SetParticleMomentumDirection (data. gun, direction)
93- end
94109 GeneratePrimaryVertex (data. gun, CxxPtr (evt))
95110 end
96111
@@ -103,16 +118,33 @@ function SSDGenerator(source::SolidStateDetectors.IsotopeSource; kwargs...)
103118
104119 data = GeneratorData (;kwargs... )
105120 function _init (data:: GeneratorData , :: Any )
106- gun = data. gun = move! (G4SingleParticleSource ())
121+ data. gun = move! (G4SingleParticleSource ())
122+
123+ # Place the SingleParticleSource as point source
107124 data. position = G4ThreeVector (
108125 source. position. x * Geant4. SystemOfUnits. meter,
109126 source. position. y * Geant4. SystemOfUnits. meter,
110127 source. position. z * Geant4. SystemOfUnits. meter
111128 )
112- SetParticlePosition (gun, data. position)
113- data. direction = G4ThreeVector (source. direction. x, source. direction. y, source. direction. z)
114- SetParticleMomentumDirection (GetAngDist (gun), data. direction)
115- SetMonoEnergy (gun |> GetEneDist, 0.0 * Geant4. SystemOfUnits. MeV)
129+ posdist = GetPosDist (data. gun)
130+ SetPosDisType (posdist, " Point" )
131+ SetCentreCoords (posdist, data. position)
132+
133+ # Define the source emission
134+ d:: CartesianVector = normalize (source. direction)
135+ a:: CartesianVector = normalize (d × (abs (d. x) == 1 ? CartesianVector (0 ,1 ,0 ) : CartesianVector (1 ,0 ,0 )))
136+ b:: CartesianVector = normalize (a × d)
137+ data. direction = G4ThreeVector (d. x, d. y, d. z)
138+
139+ angdist = GetAngDist (data. gun)
140+ SetAngDistType (angdist, " iso" )
141+ DefineAngRefAxes (angdist, " angref1" , G4ThreeVector (a... ))
142+ DefineAngRefAxes (angdist, " angref2" , G4ThreeVector (b... ))
143+ SetMinTheta (angdist, 0.0 )
144+ SetMaxTheta (angdist, ustrip (NoUnits, source. opening_angle)) # convert to radians
145+
146+ # Set kinetic energy of the decaying isotope to zero ("decay at rest")
147+ SetMonoEnergy (GetEneDist (data. gun), 0.0 * Geant4. SystemOfUnits. MeV)
116148 end
117149
118150 function _gen (evt:: G4Event , data:: GeneratorData ):: Nothing
@@ -121,16 +153,6 @@ function SSDGenerator(source::SolidStateDetectors.IsotopeSource; kwargs...)
121153 SetParticleDefinition (data. gun, data. particle)
122154 SetParticleCharge (data. gun, source. ionCharge)
123155 end
124- if ! iszero (source. opening_angle)
125- d:: CartesianVector = normalize (source. direction)
126- a:: CartesianVector = normalize (d × (abs (d. x) == 1 ? CartesianVector (0 ,1 ,0 ) : CartesianVector (1 ,0 ,0 )))
127- b:: CartesianVector = normalize (a × d)
128- ϕ = rand ()* 2 π
129- θ = acos (1 - (1 - cos (source. opening_angle))* rand ())
130- v = (cos (θ) * d + sin (θ) * (cos (ϕ) * a + sin (ϕ) * b))
131- direction = G4ThreeVector (v. x, v. y, v. z)
132- SetParticleMomentumDirection (GetAngDist (data. gun), direction)
133- end
134156 GeneratePrimaryVertex (data. gun, CxxPtr (evt))
135157 end
136158
0 commit comments