Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
peremato committed Apr 9, 2024
1 parent 865d3b4 commit 4bf7f5c
Show file tree
Hide file tree
Showing 16 changed files with 1,663 additions and 123 deletions.
51 changes: 51 additions & 0 deletions .github/workflows/jupyterbook.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
name: deploy-book
on:
pull_request:
branches:
- main
push:
branches:
- main

# This job installs dependencies, builds the book, and pushes it to `gh-pages`
jobs:
deploy-book:
runs-on: ubuntu-latest
defaults:
run:
working-directory: ./julia-intro
shell: bash -l {0}

steps:
- uses: actions/checkout@v4
# Install dependencies
- name: Set up MiniConda
uses: mamba-org/setup-micromamba@v1
with:
environment-file: ./julia-intro/environment.yml
init-shell: bash powershell
cache-environment: true

- name: Set up Julia
uses: julia-actions/setup-julia@v1

- uses: julia-actions/cache@v1
- uses: julia-actions/julia-buildpkg@v1


- name: Build the book
run: |
jupyter-book build ./docs
# Push the book's HTML to github-pages
- name: GitHub Pages action
uses: peaceiris/actions-gh-pages@v3
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: ./geant4.jl/docs/_build/html
if: github.event_name != 'pull_request'
- name: Deploy preview
uses: rossjrw/pr-preview-action@v1
with:
source-dir: ./julia-intro/docs/_build/html
if: github.event_name == 'pull_request'
516 changes: 395 additions & 121 deletions LICENSE

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions Project.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[deps]
Geant4 = "559df036-b7a0-42fd-85df-7d5dd9d70f44"
IJulia = "7073ff75-c697-5162-941a-fcdaad2a7d2a"
16 changes: 14 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,14 @@
# Geant4-tutorial
Tutorial for Geant4.jl
# Geant4.jl-tutorial
Materials for the Geant4.jl Tutorial.

Read the rendered Jupyter book: https://juliahep.github.io/JuliaHEP-2023/

Follow the tutorial with Binder:
[![Binder](https://binderhub.ssl-hep.org/badge_logo.svg)](https://binderhub.ssl-hep.org/v2/gh/JuliaHEP/JuliaHEP-2023/HEAD?labpath=julia-intro%2Fdocs%2Fjulia-intro-intro.ipynb)

- - -
When not taken from other sources (with its own Copyright and License), this material is:

Copyright © 2023 CERN and the authors / contributors.

Licensed under [CC-BY-4.0](./LICENSE).
9 changes: 9 additions & 0 deletions tutorial/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# An set of tutorials for Geant4.jl

This is a collection of Jupyter notebooks quickly covering various aspects of the Julia bindings for Geant4. It is assumed some familiarity of Geant4 itself.

The set of notebooks can also be processed by [Jupyter Book](https://jupyterbook.org/en/stable/intro.html) into a set of web pages.

- The `environment.yaml` file can be used by conda/mamba to setup the appropriate set of Python packages to do this.

Licenced CC-BY-4.0, Copyright © 2023 Pere Mato, CERN and other contributors
94 changes: 94 additions & 0 deletions tutorial/docs/DetectorB1.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
#---Example B1Detector constructor function--------------------------------------------------------
# It should return a pointer to G4VPhysicalVolume (aka CxxPtr{G4VPhysicalVolume})
#--------------------------------------------------------------------------------------------------
function constructB1Detector(::Nothing)::CxxPtr{G4VPhysicalVolume}

nist = G4NistManager!Instance()

# Envelope parameters
env_sizeXY = 20cm
env_sizeZ = 30cm
env_mat = FindOrBuildMaterial(nist, "G4_WATER")

# Option to switch on/off checking of volumes overlaps
checkOverlaps = true

# World
world_sizeXY = 1.2*env_sizeXY
world_sizeZ = 1.2*env_sizeZ
world_mat = FindOrBuildMaterial(nist, "G4_AIR")

solidworld = G4Box("World", 0.5 * world_sizeXY, 0.5 * world_sizeXY, 0.5 * world_sizeZ)
logicworld = G4LogicalVolume(solidworld, world_mat, "World")

physWorld = G4PVPlacement(nothing, # no rotation
G4ThreeVector(), # at (0,0,0)
logicworld, #q its logical volume
"World", # its name
nothing, # its mother volume
false, # no boolean operation
0, # copy number
checkOverlaps) # overlaps checking

# Envelope
solidEnv = G4Box("Envelope", 0.5 * env_sizeXY, 0.5 * env_sizeXY, 0.5 * env_sizeZ)
logicEnv = G4LogicalVolume(solidEnv, env_mat, "Envelope")

G4PVPlacement(nothing, # no rotation
G4ThreeVector(), # at (0,0,0)
logicEnv, # its logical volume
"Envelope", # its name
logicworld, # its mother volume
false, # no boolean operation
0, # copy number
checkOverlaps) # overlaps checking
# shape 1
shape1_mat = FindOrBuildMaterial(nist, "G4_A-150_TISSUE")
pos1 = G4ThreeVector(0, 2cm, -7cm)

# Conical section shape
shape1_rmina = 0cm; shape1_rmaxa = 2cm
shape1_rminb = 0cm; shape1_rmaxb = 4cm
shape1_hz = 3cm
shape1_phimin = 0deg; shape1_phimax = 360deg

solidShape1 = G4Cons("Shape1", shape1_rmina, shape1_rmaxa, shape1_rminb, shape1_rmaxb,
shape1_hz, shape1_phimin, shape1_phimax)

logicShape1 = G4LogicalVolume(solidShape1, shape1_mat, "Shape1")
G4PVPlacement(nothing, # no rotation
pos1, # at position
logicShape1, # its logical volume
"Shape1", # its name
logicEnv, # its mother volume
false, # no boolean operation
0, # copy number
checkOverlaps)# overlaps checking
# Shape 2
shape2_mat = FindOrBuildMaterial(nist, "G4_BONE_COMPACT_ICRU")
pos2 = G4ThreeVector(0, -1cm, 7cm)

# Trapezoid shape
shape2_dxa = 12cm; shape2_dxb = 12cm
shape2_dya = 10cm; shape2_dyb = 16cm
shape2_dz = 6cm
solidShape2 = G4Trd("Shape2", 0.5 * shape2_dxa, 0.5 * shape2_dxb, 0.5 * shape2_dya, 0.5 * shape2_dyb, 0.5 * shape2_dz)
logicShape2 = G4LogicalVolume(solidShape2, shape2_mat, "Shape2")
G4PVPlacement(nothing, # no rotation
pos2, # at position
logicShape2, # its logical volume
"Shape2", # its name
logicEnv, # its mother volume
false, # no boolean operation
0, # copy number
checkOverlaps) # overlaps checking

# Visualization attributes
SetVisAttributes(logicworld, G4VisAttributes!GetInvisible())
SetVisAttributes(logicEnv, G4VisAttributes!GetInvisible())
SetVisAttributes(logicShape1, G4VisAttributes(G4Colour(1.0, 1.0, 0.0)))
SetVisAttributes(logicShape2, G4VisAttributes(G4Colour(0.0, 0.0, 1.0)))

return physWorld # return a pointer to the G4PhysicalVolume
end

41 changes: 41 additions & 0 deletions tutorial/docs/_config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# Book settings
# Learn more at https://jupyterbook.org/customize/config.html

title: Geant4.jl Tutorials
author: Pere Mato
copyright: "CERN, The Contributors 2023"
logo: images/juliaheplogo.png

# Force re-execution of notebooks on each build.
# See https://jupyterbook.org/content/execute.html
execute:
execute_notebooks: force

# Define the name of the latex output file for PDF builds
latex:
latex_documents:
targetname: Geant4-tutorial.tex

# Add a bibtex file so that we can create citations
bibtex_bibfiles:
- references.bib

# Information about where the book exists on the web
repository:
url: https://github.com/peremato/Geant4.jl-tutorial # Online location of your book
path_to_book: tutorial/docs # Optional path to your book, relative to the repository root
branch: main # Which branch of the repository should be used when creating links (optional)

# Add GitHub buttons to your book
# See https://jupyterbook.org/customize/config.html#add-a-link-to-your-repository
html:
use_issues_button: true
use_repository_button: true

# Files in the `assets` subdirectory will be copied into the output directory
# This is used for, e.g.. images that will be inserted through HTML tags in order
# to have finer control over size/placement
sphinx:
config:
html_extra_path: ["assets"]
html_js_files: [ ['https://views.scientific-python.org/js/script.js', {'defer': 'defer', 'data-domain': 'hepsoftwarefoundation.org'}] ]
16 changes: 16 additions & 0 deletions tutorial/docs/_toc.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# Table of contents
# Learn more at https://jupyterbook.org/customize/toc.html

format: jb-book
root: intro
parts:
- caption: Introduction to Geant4.jl
chapters:
- file: geant4-jl-intro
- caption: Building simulation applications
chapters:
- file: geant4-jl-applications
- caption: Complete examples
chapters:
- file: examples/HBC30

Binary file added tutorial/docs/assets/hsf_logo_angled.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added tutorial/docs/examples/30_cm_bubble_chamber.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
70 changes: 70 additions & 0 deletions tutorial/docs/examples/DetectorHBC30.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@

mutable struct HBC30 <: G4JLDetector
# main input parameters
const chamberDiameter::Float64 # chamber diameter
const targetLength::Float64 # length of target
const checkOverlaps::Bool # do check overlaps when creating the geometry
# mutable data
worldZHalfLength::Float64
# constructor with defaults values for parameters
function HBC30(; chamberDiameter=30cm,
targetLength=5cm,
checkOverlaps=false)
self = new(chamberDiameter, targetLength, checkOverlaps)
# derived parameters
self.worldZHalfLength = 1.1 * (targetLength + chamberDiameter)/2
return self
end
end

import Geant4.SystemOfUnits:mole,cm3

function HBC30Construct(det::HBC30)::CxxPtr{G4VPhysicalVolume}
(; chamberDiameter, targetLength, checkOverlaps) = det

#---Materials----------------------------------------------------------------------------------
G4Material("LH₂", z=1., a=1.008*g/mole, density= 70.8*mg/cm3)
nist = G4NistManager!Instance()
m_air = FindOrBuildMaterial(nist, "G4_AIR")
m_lh2 = FindOrBuildMaterial(nist, "LH₂")
m_glass = FindOrBuildMaterial(nist, "G4_GLASS_PLATE")
m_target = FindOrBuildMaterial(nist, "G4_W")
m_lAr = FindOrBuildMaterial(nist, "G4_lAr")

#---Volumes------------------------------------------------------------------------------------
worldS = G4Box("world", det.worldZHalfLength, det.worldZHalfLength, det.worldZHalfLength)
worldLV = G4LogicalVolume(worldS, m_air, "World")
worldPV = G4PVPlacement(nothing, G4ThreeVector(), worldLV, "World", nothing, false, 0, checkOverlaps)

chamberS = G4Tubs("chamber", 0, chamberDiameter/2, 7.5cm, 0, 2π)
chamberLV = G4LogicalVolume(chamberS, m_lh2, "chamber")
G4PVPlacement(nothing, G4ThreeVector(), chamberLV, "chamber", worldLV, false, 0, checkOverlaps)
SetUserLimits(chamberLV, G4UserLimits(5mm))

windowS = G4Tubs("window", 0, chamberDiameter/2, 1.5cm, 0, 2π)
windowLV = G4LogicalVolume(windowS, m_glass, "window")
G4PVPlacement(nothing, G4ThreeVector(0, 0, 7.5cm+1.5cm), windowLV, "window1", worldLV, false, 0, checkOverlaps)
G4PVPlacement(nothing, G4ThreeVector(0, 0, -7.5cm-1.5cm), windowLV, "window2", worldLV, false, 0, checkOverlaps)

targetS = G4Tubs("target", 0, 1cm, targetLength/2, 0, 2π)
targetLV = G4LogicalVolume(targetS, m_air, "target")
rot = G4RotationMatrix()
rotateX(rot, π/2)
trans = G4Transform3D(rot,G4ThreeVector(0, chamberDiameter/2+targetLength/2, 0))
G4PVPlacement(trans, targetLV, "target", worldLV, false, 0, checkOverlaps)

# Visualization attributes
boxVisAtt = G4VisAttributes(G4Colour(1.0, 1.0, 1.0, 0.0))
targetVisAtt = G4VisAttributes(G4Colour(1.0, 1.0, 1.0, 0.9))
chamberVisAtt = G4VisAttributes(G4Colour(1.0, 1.0, 0.0, 0.1))
windowVisAtt = G4VisAttributes(G4Colour(0.0, 0.0, 1.0, 0.05))
SetVisAttributes(worldLV, boxVisAtt)
SetVisAttributes(targetLV, targetVisAtt)
SetVisAttributes(chamberLV, chamberVisAtt)
SetVisAttributes(windowLV, windowVisAtt)

# Always return the physical world-------------------------------------------------------------
return worldPV
end

Geant4.getConstructor(::HBC30)::Function = HBC30Construct
Loading

0 comments on commit 4bf7f5c

Please sign in to comment.