Warning, /tutorial-simulations-using-ddsim-and-geant4/episodes/01-single-particle-simulations.md is written in an unsupported language. File is not indexed.
0001 ---
0002 title: "Single Particle Simulations with `ddsim`"
0003 teaching: 30
0004 exercises: 20
0005 ---
0006
0007 ::::::::::::::::::::::::::::::::::::::::::::: questions
0008
0009 - How can I simulate single particles for detector studies?
0010
0011 :::::::::::::::::::::::::::::::::::::::::::::
0012
0013 ::::::::::::::::::::::::::::::::::::::::::::: objectives
0014
0015 - Know where to find the available options for `ddsim`.
0016 - Understand the differences between steering files and command line options.
0017 - Know what the key output file collections are.
0018
0019 :::::::::::::::::::::::::::::::::::::::::::::
0020
0021 In this first episode we will go through the running of single particle events with `ddsim`, using the built-in event generator of `ddsim`. This is the quickest way so run some straightforward tests of the geometry and produce output hits in the detectors for further analysis.
0022
0023 ::::::::::::::::::::::::::::::::::::::::::::: callout
0024
0025 You may also see reference to using `npsim` in some tutorials. We will discuss the difference between `ddsim` and `npsim`, along with cases where one should be used over the other, in the next episode of this tutorial. As a brief overview, `npsim` is `ddsim` under the hood which is itself, predominantly Geant4 under the hood. We will start with `ddsim` simply to demonstrate usage.
0026
0027 :::::::::::::::::::::::::::::::::::::::::::::
0028
0029 ## Passing options to `ddsim`
0030
0031 The program `ddsim` is part of the DD4hep installation when it is compiled with Geant4 support. In the EIC standard environment `eic-shell` it is available and used for many simulations in the suite of continuous integration and benchmarking checks for the geometry. Simply entering `ddsim --help` will show the large wealth of options that can be passed to `ddsim` on the command line.
0032
0033 It is also possible to use a python steering file to control the simulations. This is often a more convenient approach for sharing settings with others or archiving them for later reference or to iteratively add functionality. However, it should be noted that this can also lead to divergence in 'default' running conditions when these are not propagated to other environments.
0034
0035 ::::::::::::::::::::::::::::::::::::::::::::: challenge
0036
0037 ## Exercise: explore the `ddsim` options
0038
0039 - Consult the available options of `ddsim` by passing it the `--help` flag.
0040 - Find the appropriate option to specify the output file when using `ddsim`.
0041 - Use the `--dumpSteeringFile` flag to print out a default steering file, and redirect it into a file `steering.py`.
0042
0043 ::::::::::::::: solution
0044
0045 The output file is set with `--outputFile`. A default steering file can be written with:
0046
0047 ```bash
0048 ddsim --dumpSteeringFile > steering.py
0049 ```
0050
0051 :::::::::::::::
0052
0053 :::::::::::::::::::::::::::::::::::::::::::::
0054
0055 ## Available options in `ddsim`
0056
0057 There are several option blocks that can be used with `ddsim`. Those are best looked at in the `steering.py` file, where additional documentation is added.
0058
0059 - `SIM.action.*` or `--action.*` options can be used to tune sensitive detector actions,
0060 - `SIM.field.*` or `--field.*` options affect the magnetic field steppers,
0061 - `SIM.filter.*` or `--filter.*` options can add filters to sensitive detectors,
0062 - `SIM.gun.*` or `--gun.*` options can set single particle gun settings,
0063 - `SIM.physics.*` or `--physics.*` options allow setting the physics list,
0064 - `SIM.random.*` or `--random.*` options can be used to fix the random seed.
0065
0066 Some options, such as `SIM.physics.setupUserPhysics`, take as argument a python function, so they can only be used inside the python steering files. We will come back to this later.
0067
0068 When using the steering file approach, it is often useful to remove all options which you will not change (this allows you to take advantage of updates to the `ddsim` command itself without being stuck on old default settings). In this case, you would simply start from a steering file that only contains:
0069
0070 ```python
0071 from DDSim.DD4hepSimulation import DD4hepSimulation
0072 from g4units import mm, GeV, MeV
0073 SIM = DD4hepSimulation()
0074 ```
0075
0076 and which can be passed to `ddsim` with the `--steeringFile` flag:
0077
0078 ```bash
0079 ddsim --steeringFile steering.py
0080 ```
0081
0082 This steering file merely sets up the simulation object that can then be configured with settings that deviate from the default.
0083
0084 ::::::::::::::::::::::::::::::::::::::::::::: challenge
0085
0086 ## Exercise: a minimal steering file
0087
0088 - Compose a 'minimal' steering file that only contains the required header line.
0089 - Attempt to run this steering file and note what `ddsim` claims is missing (we will specify this on the command line next).
0090
0091 ::::::::::::::: solution
0092
0093 A minimal steering file contains only the three lines shown above (the `DD4hepSimulation` import and
0094 `SIM = DD4hepSimulation()`). Running it with `ddsim --steeringFile steering.py` reports that no
0095 geometry compact file was given, and that the number of events and the source of the events (an
0096 input file or the particle gun) are not specified.
0097
0098 :::::::::::::::
0099
0100 :::::::::::::::::::::::::::::::::::::::::::::
0101
0102 ## Running a first single-particle simulation
0103
0104 When we used the minimal steering file, `ddsim` pointed out that we did not specify the 'geometry compact file', nor the number of events and source of those events. In this sections we'll specify the geometry and tell `ddsim` to use a particle gun.
0105
0106 The compact file is the entry point of our geometry, for which we must load the geometry environment first
0107
0108 ```bash
0109 source /opt/detector/epic-main/bin/thisepic.sh
0110 ddsim --steeringFile steering.py --compactFile $DETECTOR_PATH/$DETECTOR_CONFIG.xml
0111 ```
0112
0113 Next, we will specify that we want `ddsim` to use the DD4hep particle gun, with `--enableGun` (or `-G`), and that we want 10 events, with `--numberOfEvents 10` (or `-N 10`):
0114
0115 ```bash
0116 ddsim --steeringFile steering.py --compactFile $DETECTOR_PATH/$DETECTOR_CONFIG.xml -G -N 10
0117 ```
0118
0119 ::::::::::::::::::::::::::::::::::::::::::::: callout
0120
0121 If you are running `eic-shell` directly on cvmfs, this may take a little while the first time. All large Geant4 data files are accessed for the first time and need to be retrieved.
0122
0123 :::::::::::::::::::::::::::::::::::::::::::::
0124
0125 When we run `ddsim`, by default it prints out some information for each generated event:
0126
0127 ```text
0128 GenerationInit INFO +++ Initializing event 1. Within run:0 event 1.
0129 Gun INFO Particle [0] mu- Mom:10.000 GeV vertex:( 0.000 0.000 0.000)[mm] direction:( 0.000 0.000 1.000)
0130 Gun INFO Shoot [0] 10.000 GeV mu- pos:(0.000 0.000 0.000)[mm] dir:( 0.000 0.000 1.000)
0131 Gun INFO +-> Interaction [0] 10.000 GeV mu- pos:(0.000 0.000 0.000)[mm]
0132 Gun INFO +++ +-> ID: 0 mu- status:00000002 PDG: 13 Vtx:(+0.00e+00,+0.00e+00,+0.00e+00)[mm] time: +0.00e+00 [ns] #Dau: 0 #Par:0
0133 PrimaryHandler INFO +++++ G4PrimaryVertex at (+0.00e+00,+0.00e+00,+0.00e+00) [mm] +0.00e+00 [ns]
0134 ParticleHandler INFO +++ Event 0 Begin event action. Access event related information.
0135 ```
0136
0137 You will notice that the particle gun has reverted to a default particle in a default direction: a 10 GeV muon in the positive z direction. That is, of course, not going to result in many hits in our ePIC detector... We will now take a closer look at some of the particle gun options.
0138
0139 ```text
0140 --gun.energy GUN.ENERGY
0141 --gun.particle GUN.PARTICLE
0142 --gun.multiplicity GUN.MULTIPLICITY
0143 --gun.phiMin GUN.PHIMIN
0144 Minimal azimuthal angle for random distribution
0145 --gun.phiMax GUN.PHIMAX
0146 --gun.thetaMin GUN.THETAMIN
0147 --gun.thetaMax GUN.THETAMAX
0148 --gun.momentumMin GUN.MOMENTUMMIN
0149 Minimal momentum when using distribution (default = 0.0)
0150 --gun.momentumMax GUN.MOMENTUMMAX
0151 --gun.direction GUN.DIRECTION
0152 direction of the particle gun, 3 vector
0153 --gun.distribution {uniform,cos(theta),eta,pseudorapidity,ffbar}
0154 choose the distribution of the random direction for theta
0155
0156 Options for random distributions:
0157
0158 'uniform' is the default distribution, flat in theta
0159 'cos(theta)' is flat in cos(theta)
0160 'eta', or 'pseudorapidity' is flat in pseudorapity
0161 'ffbar' is distributed according to 1+cos^2(theta)
0162
0163 Setting a distribution will set isotrop = True
0164
0165 --gun.isotrop GUN.ISOTROP
0166 isotropic distribution for the particle gun
0167
0168 use the options phiMin, phiMax, thetaMin, and thetaMax to limit the range of randomly distributed directions
0169 if one of these options is not None the random distribution will be set to True and cannot be turned off!
0170
0171 --gun.position GUN.POSITION
0172 position of the particle gun, 3 vector
0173 ```
0174
0175 While many of the options have straighforward names, others may be more confusing. The `gun.distribution` option is particularly relevant when we want to distribute single particle events over a range of angles. Depending on your needs, you may prefer one over the other, but in this tutorial we will simply use `cos(theta)` to throw uniformly on the unit sphere in the forward direction:
0176
0177 ```bash
0178 ddsim --steeringFile steering.py --compactFile $DETECTOR_PATH/$DETECTOR_CONFIG.xml -G -N 10 --gun.thetaMin "3*deg" --gun.thetaMax "45*deg" --gun.distribution "cos(theta)" --gun.momentumMin "1*GeV" --gun.momentumMax "10*GeV" --gun.particle "pi+"
0179 ```
0180
0181 ::::::::::::::::::::::::::::::::::::::::::::: callout
0182
0183 Avoid the use of the `gun.energy` option, since it is inherently more ambiguous than `gun.momentum` for massive particles (in the context of EIC).
0184
0185 :::::::::::::::::::::::::::::::::::::::::::::
0186
0187 Note how we pass arguments with units in this example. The double quotes are in many cases necessary on the command line to avoid having the `*` be expanded by your shell. In the python steering file they can be ommitted and one can simply write, e.g., `SIM.gun.thetaMin = 3*deg`.
0188
0189 When running this simulation above, note the output on the command line
0190
0191 ```text
0192 GenerationInit INFO +++ Initializing event 1. Within run:0 event 1.
0193 Gun INFO Particle [0] pi+ Mom:4.924 GeV vertex:( 0.000 0.000 0.000)[mm] direction:( 0.017 0.403 0.915)
0194 Gun INFO Shoot [0] 10.000 GeV pi+ pos:(0.000 0.000 0.000)[mm] dir:( 0.000 0.000 1.000)
0195 Gun INFO +-> Interaction [0] 10.000 GeV pi+ pos:(0.000 0.000 0.000)[mm]
0196 Gun INFO +++ +-> ID: 0 pi+ status:00000002 PDG: 211 Vtx:(+0.00e+00,+0.00e+00,+0.00e+00)[mm] time: +0.00e+00 [ns] #Dau: 0 #Par:0
0197 PrimaryHandler INFO +++++ G4PrimaryVertex at (+0.00e+00,+0.00e+00,+0.00e+00) [mm] +0.00e+00 [ns]
0198 ParticleHandler INFO +++ Event 0 Begin event action. Access event related information.
0199 ```
0200
0201 For historical reasons (which are being addressed), the relevant line is the one with `Particle [0]`.
0202
0203 ::::::::::::::::::::::::::::::::::::::::::::: challenge
0204
0205 ## Exercise: shoot into the negative endcap
0206
0207 - Simulate 10 events in the negative endcap, using an angle distribution that is uniform in `cos(theta)`, and with an electron multiplicity of 2.
0208 - Add all gun options (but not the number of events) to the minimal steering file you constructed earlier and rename the steering file to `ee_1GeV_10GeV_EndcapN.py` and run the simulation again.
0209 - Verify that the momentum ranges and angular ranges are correct in the output.
0210
0211 ::::::::::::::: solution
0212
0213 The negative endcap corresponds to large polar angles, so set `--gun.thetaMin "135*deg"` and
0214 `--gun.thetaMax "177*deg"` (or use a negative-`z` direction), with `--gun.particle "e-"`,
0215 `--gun.multiplicity 2`, and `--gun.distribution "cos(theta)"`. Moving these into the steering file as
0216 `SIM.gun.*` assignments and saving it as `ee_1GeV_10GeV_EndcapN.py` reproduces the same run. The
0217 `Particle [0]` lines in the output should show electrons with momenta between 1 and 10 GeV pointing
0218 into the negative endcap.
0219
0220 :::::::::::::::
0221
0222 :::::::::::::::::::::::::::::::::::::::::::::
0223
0224 ## Output files
0225
0226 Until now we have not bothered to check the output files (in case you were wondering and went exploring, you may have noticed that output went into `dummyOutput.slcio`). In this section we'll explore how to write output files.
0227
0228 The command line option to use to specify the output file is the `--outputFile` option (or `SIM.outputFile` in the steering file). Depending on the extension of the output file, a specific output file format is chosen. The default output is in the slcio format, but we have standardized on the EDM4hep data model inside ROOT files. To choose this output file format, use a file extension `.edm4hep.root`. We could, for example, run the following command:
0229
0230 ```bash
0231 ddsim --steeringFile ee_1GeV_10GeV_EndcapN.py --compactFile $DETECTOR_PATH/$DETECTOR_CONFIG.xml --numberOfEvents 10 --outputFile ee_1GeV_10GeV_EndcapN_1e1.edm4hep.root
0232 ```
0233
0234 ::::::::::::::::::::::::::::::::::::::::::::: callout
0235
0236 The extension `.edm4hep.root` of the output file is important since `ddsim` infers the output file type from the extension.
0237
0238 :::::::::::::::::::::::::::::::::::::::::::::
0239
0240 Let's take a look at the output file in ROOT (you can do this inside or outside the container, depending on your system and facility with opening ROOT browsers).
0241
0242 ```bash
0243 root -l ee_1GeV_10GeV_EndcapN_1e1.edm4hep.root
0244 root [1] .ls
0245 TFile** ee_1GeV_10GeV_EndcapN_1e1.edm4hep.root data file
0246 TFile* ee_1GeV_10GeV_EndcapN_1e1.edm4hep.root data file
0247 KEY: TTree events;1 Events tree
0248 KEY: TTree metadata;1 Metadata tree
0249 KEY: TTree run_metadata;1 Run metadata tree
0250 KEY: TTree evt_metadata;1 Event metadata tree
0251 KEY: TTree col_metadata;1 Collection metadata tree
0252 ```
0253
0254 All EDM4hep files will have the same structure. We focus here on the `events` tree (if you see `EVENT`, in capital letters, you will need to ensure that you are indeed using the `.edm4hep.root` extension).
0255
0256 ::::::::::::::::::::::::::::::::::::::::::::: callout
0257
0258 In a future version of `ddsim` the output file format will change slightly, and the various `metatadata` trees will not be there anymore.
0259
0260 :::::::::::::::::::::::::::::::::::::::::::::
0261
0262 ### `MCParticles`
0263
0264 Let's first focus on the `MCParticles` branch. This contains 'truth' information and exact Geant4 step output for selected tracks. It is filled independent of sensitive detectors defined in the geometry. It is most useful to analyze the initial state of the simulation (i.e. the final state of the event generator). In our case, the number of generated particles from the particle gun is always 2, which is what we expect to recover by looking at the `@MCParticles.size()` in the `events` tree:
0265
0266 ```c++
0267 root [2] events->Draw("@MCParticles.size()")
0268 ```
0269
0270 Wait a minute. What happened here? The `MCParticles` branch contains more than just the generated events. To include only the generated particles that were 'thrown' into the detector, we can select those with `generatorStatus` equal to 1.
0271
0272 ```c++
0273 root [3] events->Draw("MCParticles.PDG","MCParticles.generatorStatus==1")
0274 ```
0275
0276 Another approach which is sometimes useful to reduce the number of 'other' particles that are written is to pass the option `--part.minimalKineticEnergy "1*TeV"`. This restricts the particles that are written to those that have an energy higher than 1 TeV. Initial state event generator particles are exempt from this requirement and are always written.
0277
0278 ### `*Hits`
0279
0280 The second set of branches that are important, and that are used as input to the event reconstruction framework, are the `*Hits` branches. These branches include the hits in sensitive detectors: either tracker hits or calorimeter hits. You will notice that these two different types of hits contain slightly different information.
0281
0282 ::::::::::::::::::::::::::::::::::::::::::::: challenge
0283
0284 ## Exercise: inspect the output file
0285
0286 - Open the file `ee_1GeV_10GeV_EndcapN_1e1.edm4hep.root` which you just created in a local ROOT installation or online at [the JSROOT web viewer](https://root.cern/js/latest).
0287 - Plot the z component of the momentum for generated particles only and verify that this is indeed negative for particles going towards the negative endcap.
0288 - Verify that the total number of entries is consistent with the multiplicity and number of events you have simulated.
0289 - Plot the deposited energy of the hits in the endcap Ecal and compare the number of hits in the positive and negative endcaps.
0290
0291 ::::::::::::::: solution
0292
0293 Plotting `MCParticles.momentum.z` with the selection `MCParticles.generatorStatus==1` shows negative
0294 values, confirming the particles head into the negative endcap. With a multiplicity of 2 over 10
0295 events you expect 20 generated entries. The endcap Ecal `*Hits` branches (e.g.
0296 `EcalEndcapNHits.energy`) should show energy deposits concentrated in the negative endcap and few or
0297 none in the positive endcap.
0298
0299 :::::::::::::::
0300
0301 :::::::::::::::::::::::::::::::::::::::::::::
0302
0303 ::::::::::::::::::::::::::::::::::::::::::::: keypoints
0304
0305 - `ddsim` can be used with a particle gun to generate single particle simulations.
0306
0307 :::::::::::::::::::::::::::::::::::::::::::::