Skip to content

Commit a28411a

Browse files
committed
Fix bug in source emission in Geant4 extension
1 parent 6f7a3ad commit a28411a

File tree

1 file changed

+55
-37
lines changed

1 file changed

+55
-37
lines changed

ext/Geant4/g4jl_application.jl

Lines changed: 55 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -13,17 +13,17 @@ struct SSDPhysics <: G4VUserPhysicsList
1313
end
1414

1515
struct 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")}[])))
1818
end
1919

2020
function _initialize(::G4HCofThisEvent, data::SDData)::Nothing
21-
empty!(data.detectorHits)
22-
return
21+
empty!(data.detectorHits)
22+
return
2323
end
2424

2525
function _endOfEvent(::G4HCofThisEvent, data::SDData)::Nothing
26-
return
26+
return
2727
end
2828

2929
function _processHits(step::G4Step, ::G4TouchableHistory, data::SDData{T})::Bool where {T}
@@ -48,6 +48,10 @@ function _processHits(step::G4Step, ::G4TouchableHistory, data::SDData{T})::Bool
4848
end
4949

5050
function 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
5256
end
5357

@@ -66,31 +70,39 @@ function SSDGenerator(source::SolidStateDetectors.MonoenergeticSource; kwargs..
6670
data = GeneratorData(;kwargs...)
6771

6872
function _init(data::GeneratorData, ::Any)
69-
gun = data.gun = move!(G4ParticleGun())
73+
data.gun = move!(G4SingleParticleSource())
7074
particle = data.particle = FindParticle(source.particle_type)
71-
data.position = G4ThreeVector(
75+
SetParticleDefinition(data.gun, particle)
76+
77+
# Place the SingleParticleSource as point source
78+
data.position = G4ThreeVector(
7279
source.position.x * Geant4.SystemOfUnits.meter,
7380
source.position.y * Geant4.SystemOfUnits.meter,
7481
source.position.z * Geant4.SystemOfUnits.meter
7582
)
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)
83+
posdist = GetPosDist(data.gun)
84+
SetPosDisType(posdist, "Point")
85+
SetCentreCoords(posdist, data.position)
86+
87+
# Define the source emission
88+
d::CartesianVector = normalize(source.direction)
89+
a::CartesianVector = normalize(d × (abs(d.x) == 1 ? CartesianVector(0,1,0) : CartesianVector(1,0,0)))
90+
b::CartesianVector = normalize(a × d)
91+
data.direction = G4ThreeVector(d.x, d.y, d.z)
92+
93+
angdist = GetAngDist(data.gun)
94+
SetAngDistType(angdist, "iso")
95+
DefineAngRefAxes(angdist, "angref1", G4ThreeVector(a...))
96+
DefineAngRefAxes(angdist, "angref2", G4ThreeVector(b...))
97+
SetMinTheta(angdist, 0.0)
98+
SetMaxTheta(angdist, ustrip(NoUnits, source.opening_angle)) # convert to radians
99+
# SetParticleMomentumDirection(angdist, data.direction)
100+
101+
# set energy
102+
SetMonoEnergy(GetEneDist(data.gun), ustrip(u"MeV", source.energy))
81103
end
82104

83105
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
94106
GeneratePrimaryVertex(data.gun, CxxPtr(evt))
95107
end
96108

@@ -103,16 +115,32 @@ function SSDGenerator(source::SolidStateDetectors.IsotopeSource; kwargs...)
103115

104116
data = GeneratorData(;kwargs...)
105117
function _init(data::GeneratorData, ::Any)
106-
gun = data.gun = move!(G4SingleParticleSource())
118+
data.gun = move!(G4SingleParticleSource())
119+
120+
# Place the SingleParticleSource as point source
107121
data.position = G4ThreeVector(
108122
source.position.x * Geant4.SystemOfUnits.meter,
109123
source.position.y * Geant4.SystemOfUnits.meter,
110124
source.position.z * Geant4.SystemOfUnits.meter
111125
)
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)
126+
posdist = GetPosDist(data.gun)
127+
SetPosDisType(posdist, "Point")
128+
SetCentreCoords(posdist, data.position)
129+
130+
# Define the source emission
131+
d::CartesianVector = normalize(source.direction)
132+
a::CartesianVector = normalize(d × (abs(d.x) == 1 ? CartesianVector(0,1,0) : CartesianVector(1,0,0)))
133+
b::CartesianVector = normalize(a × d)
134+
data.direction = G4ThreeVector(d.x, d.y, d.z)
135+
136+
angdist = GetAngDist(data.gun)
137+
SetAngDistType(angdist, "iso")
138+
DefineAngRefAxes(angdist, "angref1", G4ThreeVector(a...))
139+
DefineAngRefAxes(angdist, "angref2", G4ThreeVector(b...))
140+
SetMinTheta(angdist, 0.0)
141+
SetMaxTheta(angdist, ustrip(NoUnits, source.opening_angle)) # convert to radians
142+
143+
# SetMonoEnergy(GetEneDist(data.gun), 0.0 * Geant4.SystemOfUnits.MeV)
116144
end
117145

118146
function _gen(evt::G4Event, data::GeneratorData)::Nothing
@@ -121,16 +149,6 @@ function SSDGenerator(source::SolidStateDetectors.IsotopeSource; kwargs...)
121149
SetParticleDefinition(data.gun, data.particle)
122150
SetParticleCharge(data.gun, source.ionCharge)
123151
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
134152
GeneratePrimaryVertex(data.gun, CxxPtr(evt))
135153
end
136154

0 commit comments

Comments
 (0)