Introduction to the DD4hep simulation
Last updated on 2026-07-10 | Edit this page
Estimated time: 40 minutes
Overview
Questions
- Understand the inputs and outputs of the DD4hep simulation
Objectives
- Event generation
- Detector description
- MCParticles and detector hits
- Simulation campaign files
DD4hep simulation
This Geant4-based simulation package propagates particles through magnetic field and materials. Particles and detector hits for each event are saved in the output rootfiles.
Input 1: Event generation
The collision event at ePIC, including the beam particles, vertices, and outgoing particles, are typically generated with a dedicated event generator, e.g. PYTHIA8 for specific physics channels. The outputs are provided to the DD4hep simulation in HEPMC3 format.
One can also use the DD4hep’s particle gun to generate outgoing
particles with given vertex and distribution, see the Simulations
Using npsim and Geant4 tutorial on ddsim.
Input 2: Detector description
The ePIC detector description in DD4hep is maintained in the eic/epic repository on GitHub.
On the bottom of each sub-detector compact file under
epic/compact, the readout block specifies how
the detector hits are saved in the output rootfile.
Below is an example from
epic/compact/tracking/vertex_barrel.xml:
XML
<readouts>
<readout name="VertexBarrelHits">
<segmentation type="CartesianGridXY" grid_size_x="0.020*mm" grid_size_y="0.020*mm" />
<id>system:8,layer:4,module:12,sensor:2,x:32:-16,y:-16</id>
</readout>
</readouts>
All hits from this silicon vertex barrel detector, including their
position, energy deposit, time, will be stored under the branch
VertexBarrelHits in output. Each detector hit also comes
with an assigned 64-bit cell ID, with the last 32 bits from right to
left representing the hit location in a 0.020 x 0.020 mm mesh grid. This
segmentation often represents the detector granularity
(in this case, the silicon pixel sensor size) that will be used later
for hit digitization.
Output
The event tree in the simulation output contains
-
MCParticles: records the truth info of primary and secondary particles - Individual branches for signals from various sub-detector systems
e.g.
VertexBarrelHits
Exercise 1.1: access simulation campaign rootfiles
The simulation campaign dataset documentation documents the available datasets and version information.
-
Browse the directory
For the stand-alone
xrdfscommand, see the previous Analysis tutorial. Here we will proceed with the python interface:PYTHON
from XRootD import client # Create XRootD client eic_server = 'root://dtn-eic.jlab.org/' fs = client.FileSystem(eic_server) # List directory contents fpath = '/volatile/eic/EPIC/RECO/26.02.0/epic_craterlake/SINGLE/e-/10GeV/130to177deg/' status, files = fs.dirlist(fpath) # Print files if status.ok: print(files.size) for entry in files: print(entry.name) else: print(f"Error: {status.message}") -
Open a simulation campaign file
fs.dirlist returns the list of files available in the
campaign directory, and ur.open(...)[tree_name] opens the
events tree and reports the number of entries. If the
directory listing fails, check that the campaign version in
fpath still exists on the server (campaigns roll over and
older versions are removed).
tree.keys(...) lists the top-level branches
(e.g. MCParticles and the per-detector hit collections).
Reading MCParticles into an awkward array and converting to
a dataframe gives one row per particle, with columns such as
MCParticles.PDG, MCParticles.generatorStatus,
and the momentum components.
Exercise 1.3: extract momentum distribution of primary electrons
PYTHON
# select electrons
from particle import Particle
part = Particle.from_name("e-")
pdg_id = part.pdgid.abspid
condition1 = df["MCParticles.PDG"]==pdg_id
# select primary particles
condition2 = df["MCParticles.generatorStatus"]==1
# extract momentum and plot
# all electrons
df_new = df[condition1]
mom = np.sqrt(df_new["MCParticles.momentum.x"]**2+df_new["MCParticles.momentum.y"]**2+df_new["MCParticles.momentum.z"]**2)
bins = np.arange(0,20)
_ = plt.hist(mom,bins=bins,alpha=0.5)
# primary electrons
df_new = df[condition1&condition2]
mom = np.sqrt(df_new["MCParticles.momentum.x"]**2+df_new["MCParticles.momentum.y"]**2+df_new["MCParticles.momentum.z"]**2)
_ = plt.hist(mom,bins=bins,histtype="step", color='r')
The first histogram (filled) shows the momentum of all electrons,
including secondaries; the second (red outline), obtained by
additionally requiring generatorStatus==1, shows only the
primary electrons. The primary distribution is a subset of the
all-electron distribution, peaked near the generated
beam/scattered-electron momentum.
- event generator –
dd4hep–> simulated hits and particles