JuliaHEP / Geant4.jl

Apache License 2.0
25 stars 5 forks source link

Implementing a Plane Source #9

Closed tobiascremer closed 8 months ago

tobiascremer commented 8 months ago

Hello, I'm new to Julia and Geant4 in general and I have a question on using Geant4 in Julia. I want to simulate a plane source shooting gammas on a fairly simple structure. I have used your examples to create the necessary geometry and scorers and so on but I couldn't really find a way to implement a working plane source. Basicly, I want to recreate a Geant4 simulation which was in C++ before. There, the plane source is set as a General Particle Source as:

UserDefinedPrimaryGeneratorAction::UserDefinedPrimaryGeneratorAction()
  : G4VUserPrimaryGeneratorAction(),
    gps(new G4GeneralParticleSource())
{}

and the source configurations are passed in a .mac file as:

/gps/particle gamma
/gps/pos/centre 0 0 -14.9 cm
/gps/direction 0 0 1
/gps/energy 0.07 MeV
/gps/pos/type Plane
/gps/pos/shape Rectangle
/gps/pos/halfx 7 cm
/gps/pos/halfy 7 cm

It would be great if you could tell me how I would define a particle source with the same configurations using Geant4.jl.

Also is there a way to easily look up predefined classes and the corresponding parameters?

peremato commented 8 months ago

Hi, I have not wrapped the class G4GeneralParticleSource in the current version. I can do it in the next version, which I will try to release it in the next days. Meanwhile, you can, with a bit of effort, to implement the same functionality in a ad-hoc manner. Have a look at the WaterPhantom primary particle generator example. Something like this would probably work (I have not tested):

# define the data structure with the generator parameters
mutable struct PlaneSourceData <: G4JLGeneratorData
  particleName::String
  particlePtr::CxxPtr{G4ParticleDefinition}
  energy::Float64 
  halfx::Float64
  halfy::Float64
  position::G4ThreeVector
  direction::G4ThreeVector
end

# define the constructor with the default parameters (as you have them in the .mac file) but can be changed as calling time
function PlaneSource(;particle="gamma", energy=0.07MeV, halfx=7cm, halfy=7cm, 
                                      position=G4ThreeVector(0,0,-14.9cm), direction=G4ThreeVector(0,0,1))
  data = PlaneSourceData(particle, CxxPtr{G4ParticleDefinition}(C_NULL), energy, halfx, halfy, position, direction)
  function init(data:: PlaneSourceData, app::G4JLApplication)
    data.particlePtr = FindParticle(data.particleName)
  end
  function generate( evt::G4Event, data:: PlaneSourceData)::Nothing
    mass = data.particlePtr |> GetPDGMass
    momentum = √((mass + data.energy)^2 - mass^2)
    pvec = momentum * data.direction
    pos = data.position + G4ThreeVector( data.halfx * (rand() - 0.5),  data.halfy * (rand() - 0.5), 0)
    primary = G4PrimaryParticle(data.particlePtr, pvec |> x, pvec |> y, pvec |> z )
    vertex = G4PrimaryVertex(pos, 0ns)
    SetPrimary(vertex, move!(primary))    # note that we give up ownership of the objects just created
    AddPrimaryVertex(evt, move!(vertex))  # note that we give up ownership of the objects just created
  end
  G4JLPrimaryGenerator("PlaneSource", data; init_method=init, generate_method=generate)
end

and then instantiate PlaneSource() as the generator in the G4JLApplication.

tobiascremer commented 8 months ago

Thank you very much for the quick answer. Your solution works exactly how i hoped it would :)

peremato commented 8 months ago

@tobiascremer just to let you know that the latest release 0.1.11 has the wrapper for G4GeneralParticleSource class and you can configure a Plane source easily. Please have a look at the example You can also use the UI commands after initialisation with

ui`/gps/particle gamma`
ui`/gps/pos/centre 0 0 -14.9 cm`
ui`/gps/direction 0 0 1`
ui`/gps/energy 0.07 MeV`
ui`/gps/pos/type Plane`
ui`/gps/pos/shape Rectangle`
ui`/gps/pos/halfx 7 cm`
ui`/gps/pos/halfy 7 cm`