extend Steps ntuple and switch Docker to Geant4 submodule source

Add 15 new columns to the Steps ntuple: edep, step_length, parent_id,
process name, layer_id, material, pre-step momentum direction, and
B/E field components (in T and V/m) at the pre-step point.

Replace wget Geant4 tarball download in all three Dockerfiles with
ADD of the lib/geant4 submodule source; narrow submodule init to
lib/pybind11 only so builds no longer require network access for Geant4.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-06-08 16:07:17 +02:00
parent f9a7f2d1f1
commit 4ffb2f78b8
5 changed files with 124 additions and 45 deletions
+16 -14
View File
@@ -50,22 +50,24 @@ RUN mkdir dawn-source \
&& make clean && make guiclean && make && make install \
&& cd - && rm -rf "dawn-source"
## main package
## main package — build Geant4 from submodule source
ADD minicalosim/lib/geant4 /tmp/geant4-src
RUN cd && wget -q https://gitlab.cern.ch/geant4/geant4/-/archive/v11.1.2/geant4-v11.1.2.tar.gz && \
tar -xzf geant4-v11.1.2.tar.gz -C /tmp && \
mkdir /tmp/geant4-v11.1.2-build && \
cd /tmp/geant4-v11.1.2-build && \
cmake -DCMAKE_INSTALL_PREFIX=/opt/geant4-v11.1.2 -DCMAKE_RULE_MESSAGES=OFF -DGEANT4_INSTALL_DATA=ON \
-DGEANT4_USE_GDML=ON -DGEANT4_USE_OPENGL_X11=ON \
RUN cmake \
-S /tmp/geant4-src \
-B /tmp/geant4-build \
-DCMAKE_INSTALL_PREFIX=/opt/geant4-v11.1.2 \
-DCMAKE_RULE_MESSAGES=OFF \
-DGEANT4_INSTALL_DATA=ON \
-DGEANT4_USE_GDML=ON \
-DGEANT4_USE_OPENGL_X11=ON \
-DGEANT4_BUILD_MULTITHREADED=OFF \
-DGEANT4_BUILD_TLS_MODEL=global-dynamic \
-DGEANT4_USE_RAYTRACER_X11=ON /tmp/geant4-v11.1.2 >/dev/null && \
make -j24 >/dev/null && \
make install >/dev/null
RUN rm -rf /tmp/geant4-v11.1.2 && \
rm -rf /tmp/geant4-v11.1.2-build
-DGEANT4_USE_RAYTRACER_X11=ON \
>/dev/null && \
cmake --build /tmp/geant4-build --parallel $(nproc) >/dev/null && \
cmake --install /tmp/geant4-build >/dev/null && \
rm -rf /tmp/geant4-src /tmp/geant4-build
RUN python3 -m pip install geant4-pybind
@@ -94,7 +96,7 @@ ARG USER
ADD minicalosim /root/minicalosim
RUN cd /root/minicalosim && git checkout $COMMIT && \
git submodule update --init && \
git submodule update --init lib/pybind11 && \
mkdir -p build && cd build && rm -rf * && cmake ../ && make -j4
+17 -14
View File
@@ -50,22 +50,24 @@ RUN mkdir dawn-source \
&& make clean && make guiclean && make && make install \
&& cd - && rm -rf "dawn-source"
## main package
## main package — build Geant4 from submodule source
ADD minicalosim/lib/geant4 /tmp/geant4-src
RUN cd && wget -q https://gitlab.cern.ch/geant4/geant4/-/archive/v11.1.2/geant4-v11.1.2.tar.gz && \
tar -xzf geant4-v11.1.2.tar.gz -C /tmp && \
mkdir /tmp/geant4-v11.1.2-build && \
cd /tmp/geant4-v11.1.2-build && \
cmake -DCMAKE_INSTALL_PREFIX=/opt/geant4-v11.1.2 -DCMAKE_RULE_MESSAGES=OFF -DGEANT4_INSTALL_DATA=ON \
-DGEANT4_USE_GDML=ON -DGEANT4_USE_OPENGL_X11=ON \
RUN cmake \
-S /tmp/geant4-src \
-B /tmp/geant4-build \
-DCMAKE_INSTALL_PREFIX=/opt/geant4-v11.1.2 \
-DCMAKE_RULE_MESSAGES=OFF \
-DGEANT4_INSTALL_DATA=ON \
-DGEANT4_USE_GDML=ON \
-DGEANT4_USE_OPENGL_X11=ON \
-DGEANT4_BUILD_MULTITHREADED=ON \
-DGEANT4_BUILD_TLS_MODEL=global-dynamic \
-DGEANT4_USE_RAYTRACER_X11=ON /tmp/geant4-v11.1.2 >/dev/null && \
make -j4 >/dev/null && \
make install >/dev/null
RUN rm -rf /tmp/geant4-v11.1.2 && \
rm -rf /tmp/geant4-v11.1.2-build
-DGEANT4_USE_RAYTRACER_X11=ON \
>/dev/null && \
cmake --build /tmp/geant4-build --parallel $(nproc) >/dev/null && \
cmake --install /tmp/geant4-build >/dev/null && \
rm -rf /tmp/geant4-src /tmp/geant4-build
RUN python3 -m pip install geant4-pybind
@@ -94,7 +96,8 @@ ARG USER
ADD minicalosim /root/minicalosim
RUN cd /root/minicalosim && git checkout $COMMIT && \
mkdir -p build && cd build && rm -rf * && cmake ../ && make -j4 &&\
git submodule update --init lib/pybind11 && \
mkdir -p build && cd build && rm -rf * && cmake ../ && make -j$(nproc) &&\
cp minicalo* ../bind/G4Calo.py /usr/local/lib/python3.8/dist-packages/
+10 -12
View File
@@ -16,23 +16,21 @@ RUN python3 -m pip install --upgrade pip && \
python3 -m pip install numpy pandas uproot awkward plotly ipython && \
ln -sf /usr/bin/python3 /usr/bin/python
# Geant4 v11.1.2 — batch mode only (no visualization, no multithreading)
RUN wget -q https://gitlab.cern.ch/geant4/geant4/-/archive/v11.1.2/geant4-v11.1.2.tar.gz && \
tar -xzf geant4-v11.1.2.tar.gz -C /tmp && \
rm geant4-v11.1.2.tar.gz && \
mkdir /tmp/geant4-v11.1.2-build && \
cmake \
-S /tmp/geant4-v11.1.2 \
-B /tmp/geant4-v11.1.2-build \
# Geant4 — build from submodule source (batch mode only, no visualization, no multithreading)
ADD minicalosim/lib/geant4 /tmp/geant4-src
RUN cmake \
-S /tmp/geant4-src \
-B /tmp/geant4-build \
-DCMAKE_INSTALL_PREFIX=/opt/geant4-v11.1.2 \
-DCMAKE_RULE_MESSAGES=OFF \
-DGEANT4_INSTALL_DATA=ON \
-DGEANT4_BUILD_MULTITHREADED=OFF \
-DGEANT4_BUILD_TLS_MODEL=global-dynamic \
> /dev/null && \
cmake --build /tmp/geant4-v11.1.2-build --parallel $(nproc) > /dev/null && \
cmake --install /tmp/geant4-v11.1.2-build > /dev/null && \
rm -rf /tmp/geant4-v11.1.2 /tmp/geant4-v11.1.2-build
cmake --build /tmp/geant4-build --parallel $(nproc) > /dev/null && \
cmake --install /tmp/geant4-build > /dev/null && \
rm -rf /tmp/geant4-src /tmp/geant4-build
ENV LD_LIBRARY_PATH="/opt/geant4-v11.1.2/lib"
@@ -45,7 +43,7 @@ LABEL org.label-schema.build-date=$BUILD_DATE
ADD minicalosim /root/minicalosim
RUN cd /root/minicalosim && git checkout $COMMIT && \
git submodule update --init && \
git submodule update --init lib/pybind11 && \
cmake \
-S . -B build \
-DWITH_GEANT4_UIVIS=OFF \
+15
View File
@@ -96,6 +96,21 @@ RunAction::RunAction()
analysisManager->CreateNtupleDColumn("post_y"); // col 9
analysisManager->CreateNtupleDColumn("post_z"); // col 10
analysisManager->CreateNtupleDColumn("post_E"); // col 11
analysisManager->CreateNtupleDColumn("edep"); // col 12 [MeV]
analysisManager->CreateNtupleDColumn("step_length"); // col 13 [mm]
analysisManager->CreateNtupleIColumn("parent_id"); // col 14
analysisManager->CreateNtupleSColumn("process"); // col 15
analysisManager->CreateNtupleIColumn("layer_id"); // col 16 (-1 = outside all layers)
analysisManager->CreateNtupleSColumn("material"); // col 17
analysisManager->CreateNtupleDColumn("pre_dx"); // col 18
analysisManager->CreateNtupleDColumn("pre_dy"); // col 19
analysisManager->CreateNtupleDColumn("pre_dz"); // col 20
analysisManager->CreateNtupleDColumn("Bx"); // col 21 [T]
analysisManager->CreateNtupleDColumn("By"); // col 22 [T]
analysisManager->CreateNtupleDColumn("Bz"); // col 23 [T]
analysisManager->CreateNtupleDColumn("Ex"); // col 24 [V/m]
analysisManager->CreateNtupleDColumn("Ey"); // col 25 [V/m]
analysisManager->CreateNtupleDColumn("Ez"); // col 26 [V/m]
analysisManager->FinishNtuple();
}
+61
View File
@@ -36,6 +36,10 @@
#include "G4AnalysisManager.hh"
#include "G4Track.hh"
#include "G4ParticleDefinition.hh"
#include "G4TransportationManager.hh"
#include "G4FieldManager.hh"
#include "G4Field.hh"
#include "G4SystemOfUnits.hh"
using namespace B4;
@@ -95,6 +99,63 @@ void SteppingAction::UserSteppingAction(const G4Step* step)
analysisManager->FillNtupleDColumn(1, 9, post->GetPosition().y());
analysisManager->FillNtupleDColumn(1, 10, post->GetPosition().z());
analysisManager->FillNtupleDColumn(1, 11, post->GetKineticEnergy());
// A: energy deposited in medium at this step (≠ pre_E - post_E when secondaries are created)
analysisManager->FillNtupleDColumn(1, 12, edep);
// B: geometric step length
analysisManager->FillNtupleDColumn(1, 13, step->GetStepLength());
// C: parent track ID (0 for primary)
analysisManager->FillNtupleIColumn(1, 14, track->GetParentID());
// D: process that ended this step
G4String processName = "";
const auto* postProc = post->GetProcessDefinedStep();
if (postProc) processName = postProc->GetProcessName();
analysisManager->FillNtupleSColumn(1, 15, processName);
// E: layer index (-1 if outside all layers) and material name at pre-step point
int layerId = -1;
const auto& layers = cw->getLayers();
for (int i = 0; i < (int)layers.size(); i++) {
if (layers[i].physicalVolume == volume) { layerId = i; break; }
}
G4String materialName = pre->GetMaterial() ? pre->GetMaterial()->GetName() : "";
analysisManager->FillNtupleIColumn(1, 16, layerId);
analysisManager->FillNtupleSColumn(1, 17, materialName);
// F: pre-step momentum direction (unit vector)
const auto dir = pre->GetMomentumDirection();
analysisManager->FillNtupleDColumn(1, 18, dir.x());
analysisManager->FillNtupleDColumn(1, 19, dir.y());
analysisManager->FillNtupleDColumn(1, 20, dir.z());
// Field: B [T] and E [V/m] at pre-step position; zero if no field is registered
G4double Bx=0, By=0, Bz=0, Ex=0, Ey=0, Ez=0;
const auto* fm = G4TransportationManager::GetTransportationManager()->GetFieldManager();
if (fm && fm->DoesFieldExist()) {
const G4Field* field = fm->GetDetectorField();
if (field) {
const G4double point[4] = {pre->GetPosition().x(), pre->GetPosition().y(),
pre->GetPosition().z(), pre->GetGlobalTime()};
G4double fieldVal[6] = {0,0,0,0,0,0};
field->GetFieldValue(point, fieldVal);
Bx = fieldVal[0] / tesla;
By = fieldVal[1] / tesla;
Bz = fieldVal[2] / tesla;
Ex = fieldVal[3] / (volt/m);
Ey = fieldVal[4] / (volt/m);
Ez = fieldVal[5] / (volt/m);
}
}
analysisManager->FillNtupleDColumn(1, 21, Bx);
analysisManager->FillNtupleDColumn(1, 22, By);
analysisManager->FillNtupleDColumn(1, 23, Bz);
analysisManager->FillNtupleDColumn(1, 24, Ex);
analysisManager->FillNtupleDColumn(1, 25, Ey);
analysisManager->FillNtupleDColumn(1, 26, Ez);
analysisManager->AddNtupleRow(1);
}