Scintillating Detector Example#
Taken from the original at settwi/g4-basic-scintillation and adapted to the Geant4.jl interface
This is an example with optical photons and customized physics list, as well as with a couple of sensitive detectors (for the crystal and silicon) and some simple analysis of the results.
using Geant4
using Geant4.PhysicalConstants
using Geant4.SystemOfUnits
using FHist, Printf, Plots
#using CairoMakie, Rotations, IGLWrap_jll # to force loading G4Vis extension
Detector Geometry#
The detector construction and parameters are in separated files. You also visualize the detector at this moment.
include(joinpath(@__DIR__, "Parameters.jl"))
include(joinpath(@__DIR__, "Detector.jl"))
crysdet = ScintDetector()
#world = scintConstruct(crysdet)
#img = draw(world[])
#display("image/png", img)
ScintDetector(50.0, true, true, 20.0, 10.0, 2.0, 1.0, 1.0, 10.0, true, CxxPtr{G4Material}(Ptr{G4Material} @0x0000000000000000), CxxPtr{G4Material}(Ptr{G4Material} @0x0000000000000000), CxxPtr{G4Material}(Ptr{G4Material} @0x0000000000000000), CxxPtr{G4Material}(Ptr{G4Material} @0x0000000000000000), CxxPtr{G4Material}(Ptr{G4Material} @0x0000000000000000), CxxPtr{G4Material}(Ptr{G4Material} @0x0000000000000000), CxxPtr{G4Material}(Ptr{G4Material} @0x0000000000000000))
Physics#
We construct a physics list starting from the pre-defined FTFP_BERT
list, replacing the EM part with G4EmStandardPhysics_option4
, and registering the optical photon physics G4OpticalPhysics
. The constructor ScintPhysicsList()
will be called by the toolkit at the adequate moment in the initialization of the application.
struct ScintPhysicsList <: G4VUserPhysicsList
function ScintPhysicsList(verbose)
pl = FTFP_BERT(verbose)
ReplacePhysics(pl, move!(G4EmStandardPhysics_option4(verbose)))
RegisterPhysics(pl, move!(G4OpticalPhysics(verbose)))
# need to enable scintillation
optpar = G4OpticalParameters!Instance()
SetProcessActivation(optpar, "Scintillation", true);
# I have found Cherenkov radiation to be error-prone
SetProcessActivation(optpar, "Cerenkov", true);
return pl
end
end
Particle Gun#
The primary particle generator is a simple particle gun.
particlegun = G4JLGunGenerator(particle = "gamma",
energy = 30keV,
direction = G4ThreeVector(0, 0, -1),
position = G4ThreeVector(0, 0, 2cm))
G4JLGunGenerator("ParticleGun", Geant4.G4JLParticleGunData(nothing, "gamma", G4ThreeVector(0.0,0.0,-1.0), G4ThreeVector(0.0,0.0,20.0), 0.03), Geant4.var"#init#19"(), Geant4.var"#gen#20"(), G4JLGeneratorAction[])
Simulation Data#
It is normally filled by the user actions. We define a set of histograms using the FHist.jl package and set of counters. We need to provide a method add!
to be able to reduce the output in case we run in multi-threading mode.
We also provide a method to plot the results.
#---Simulation Data-------------(normally filled by actions)---------------------------------------
const Hist1D64 = Hist1D{Float64, Tuple{StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}, Int64}}}
mutable struct ScintSimData <: G4JLSimulationData
scintPhotonsPerEvent::Int64
scintPhotonsHisto::Hist1D64
siHitsHisto::Hist1D64
crysEdepHisto::Hist1D64
ScintSimData() = new()
end
#---Addd function-----------------------------------------------------------------------------------
function add!(x::ScintSimData, y::ScintSimData)
x.scintPhotonsHisto += y.scintPhotonsHisto
x.siHitsHisto += y.siHitsHisto
x.crysEdepHisto += y.crysEdepHisto
end
#---Plot Simulation data----------------------------------------------------------------------------
function do_plot(data::ScintSimData)
(;scintPhotonsHisto, siHitsHisto, crysEdepHisto) = data
lay = @layout [° °; °]
plot(layout=lay, show=true, size=(1000,700))
plot!(subplot=1, scintPhotonsHisto, title="# scintillating photons/event", xlabel="# photons", show=true)
plot!(subplot=2, siHitsHisto, title="# hits in Silicon/event", xlabel="# hits")
plot!(subplot=3, crysEdepHisto, title="energy deposited in crystal", xlabel="keV")
end
too many parameters for type Hist1D
Stacktrace:
[1] top-level scope
@ In[5]:2
User Actions and Application definition#
include(joinpath(@__DIR__, "UserActions.jl"))
#--------------------------------------------------------------------------------------------------
#---Create the Application-------------------------------------------------------------------------
#--------------------------------------------------------------------------------------------------
app = G4JLApplication(; detector = crysdet, # detector with parameters
simdata = ScintSimData(), # simulation data structure
generator = particlegun, # primary particle generator
nthreads = 0, # # of threads (0 = no MT)
physics_type = ScintPhysicsList, # what physics list to instantiate
stepaction_method = stepping, # step action method
begineventaction_method = beginevent, # begin-event action (initialize per-event data)
endeventaction_method = endevent, # end-event action (fill histograms per event)
beginrunaction_method = beginrun, # begin run action
endrunaction_method = endrun, # end run action
sdetectors = ["si_log" => silicon_SD,
"cebr3_log" => crystal_SD] # mapping of LVs to SDs (+ means multiple LVs with same name)
);
Configure, Initialize#
configure(app)
initialize(app)
Run and Plot results#
#ui`/tracking/verbose 1`
beamOn(app,1000)
do_plot(app.simdata[1])