35.8. Record Simulation Data
Table of Contents
Organizing What You Want to Record
Before writing any code, decide which results are essential for the final project. You already defined your goal, geometry, materials, source, physics, and sensitive detectors. Now you must translate that physics goal into specific recorded quantities.
For a typical detector simulation you usually need, per event or per hit, some combination of:
- Energy deposition, such as total energy in a detector element or per event.
- Position, such as where the interaction or hit occurred.
- Time, such as global time or time of flight.
- Particle information, such as particle type, track ID, parent ID.
You do not need to record everything. Recording too many details will slow the simulation and produce huge files. Start from the plots or numbers you want at the end, then work backwards. If you plan to plot an energy spectrum per detector, then you need at least energy per detector element per event, and an identifier for each detector.
Always define only the variables that you will really use in analysis. Too many unnecessary variables increase file size and reduce performance without improving physics results.
Once you know what to keep, map each quantity to a stage of the simulation where it is naturally available. For example, hit position is available in the sensitive detector, total event energy is easiest to accumulate in the event action, and run averages belong in the run action.
Using G4AnalysisManager
Geant4 provides the G4AnalysisManager class to manage all analysis output in a uniform way. You normally create and configure it in your RunAction so that it is ready before events start and properly closed afterward.
In your final project, you will use G4AnalysisManager to:
- Define histograms for quick spectra, such as energy spectra.
- Define ntuples for detailed event-by-event information.
- Write everything into a single output file per run.
A typical pattern in your RunAction constructor is:
- Get the singleton instance of
G4AnalysisManager. - Set the output file name.
- Create histograms.
- Create ntuples and their columns.
You will then open the file at the beginning of the run and close it at the end.
Use a single G4AnalysisManager instance (the singleton) for your whole application. Do not create your own instances in different user action classes.
In the final project, keep all analysis configuration in one place, usually RunAction, so that it is easy to modify binning, variable names, and file names without touching stepping or sensitive detector code.
Defining What to Save: Histograms and Ntuples
Histograms are useful for quick, binned distributions such as energy spectra or depth dose, while ntuples provide unbinned event records that you will later analyze in ROOT or another tool. For a realistic final project, use both.
A typical setup for a detector simulation includes at least:
- One 1D histogram of deposited energy in the main detector.
- An ntuple with columns such as event ID, detector ID, total deposited energy, and possibly interaction time or position.
You define these objects once, usually in the RunAction constructor. For example, conceptually you might define:
- Histogram 0: total deposited energy per event in units of keV.
- Histogram 1: depth dose, energy as a function of position coordinate.
- Ntuple 0: one row per event with columns for event ID, sum energy, and number of hits.
- Ntuple 1: one row per hit with columns for event ID, detector ID, hit energy, and hit time.
You must also choose binning parameters for histograms. Define the number of bins, and the minimum and maximum values according to the expected physics range. It is common to choose the maximum energy somewhat above the source energy to allow for energy resolution effects.
A simple energy histogram configuration might look like this in conceptual form:
| Quantity | Symbol | Range | Bins |
|---|---|---|---|
| Deposited energy | $E$ | $0$ to $E_{\text{max}}$ | 100 |
Choose histogram ranges that cover all physically possible values. If a value falls outside the range, it will not be counted in the histogram, and your spectrum will be distorted.
Ntuples are more flexible because you do not specify a range or binning. You just define columns and write one row per event or per hit. This is the main structure that you will later inspect and plot in ROOT during the final analysis steps of the project.
Connecting Analysis to User Actions
To fill your histograms and ntuples, your user action classes must communicate with G4AnalysisManager. The usual pattern is:
- Configure histograms and ntuples in
RunAction. - Accumulate event-level quantities in
EventAction. - Possibly compute derived quantities in
SteppingAction,TrackingAction, orStackingActionand pass them toEventAction. - Fill the analysis objects at well defined points, commonly at the end of each event.
In your EventAction, keep simple C++ member variables such as:
fEdepEventfor total deposited energy in the detector for the current event.- Possibly
fEdepPerDetector, for example a vector of energies indexed by detector ID.
Reset these variables at the start of each event, and fill them during stepping or hit processing.
At the end of the event you:
- Access
G4AnalysisManager. - Fill histograms with the accumulated values.
- Fill an ntuple row and add it.
For runtime clarity, keep all filling of event-level ntuples in EventAction::EndOfEventAction. Let the sensitive detectors or stepping action only pass numbers into the event action, instead of writing into the analysis manager directly. This separation helps you avoid confusion and makes it easier to change the output structure later.
Do not write into the analysis manager in many scattered places unless necessary. Prefer to accumulate values in user actions, then fill in a single, well defined method such as EndOfEventAction.
Recording Event-Level Quantities
Event-level quantities summarize what happened in a single event across all tracks and hits. Typical event-level results include:
- Total energy deposition in a volume or a detector module.
- The number of hits in a detector.
- Energy-weighted position of interaction.
- Event time characteristics, such as the time of the first hit.
In a detector simulation for the final project, one key event-level quantity is usually the total detected energy for that event. You can implement this as follows:
- In your sensitive detector or stepping action, whenever there is an energy deposition in your sensitive volume, add it to
fEdepEvent. - Also, update per element or per detector energy if your detector has many elements.
Then, in EndOfEventAction, you fill your histogram and ntuple. Conceptually, you might do:
- Fill a histogram with
fEdepEvent / keVto represent the energy spectrum. - Fill an ntuple row with the event ID and
fEdepEvent.
This gives you an energy spectrum directly in the output file, and also an unbinned record of energies by event for later analysis.
If your final project requires multiple detector components, maintain distinct accumulators such as fEdepDetectorA and fEdepDetectorB or a container indexed by detector ID. Then define separate histograms or columns for each.
Event-level recording is also where you can compute derived quantities for later analysis, such as:
- Ratios of energy in two detectors.
- Coincidence flags for multi detector setups.
- Event classification codes, such as “full energy peak,” “Compton” or “escape” if you implement such logic.
Even if you do not classify events in the simulation, it is useful to record enough event-level data so that you can perform classification later in ROOT.
Recording Hit-Level Information
Hits represent localized detector responses, such as an energy deposition in a crystal or a step in a sensitive volume. They are the natural place to record detailed information about each interaction.
In your final project, you already created one or more sensitive detector classes that inherit from G4VSensitiveDetector. Each time ProcessHits is called, you can:
- Read information from the
G4Step, such as energy deposited, position, time, and particle type. - Fill or update a hit object.
- Insert the hit into a hit collection.
To record hit-level data in your final project output file, you have two main strategies:
- Use Geant4 hits and hit collections only for internal bookkeeping, and then, at the end of the event, loop over the hit collections in
EventActionand copy selected information into ntuple rows. - Directly fill the analysis ntuple from within your sensitive detector whenever a new hit is created.
The first strategy gives you a clean separation and makes it easier to compute event-level quantities using the hits. The second strategy is more direct but ties your sensitive detector strongly to the analysis format.
The hit-level ntuple might include columns such as:
- Event ID.
- Detector or crystal ID.
- Hit energy deposition.
- Global or local position components.
- Global time of the hit.
- Particle PDG code.
This structure allows you to perform very flexible offline analysis in ROOT, including reconstruction algorithms, detector response modeling, or track-by-track studies.
If you record every single hit with many variables for many events, files can become very large. Balance the level of detail you record with your available disk space and analysis needs.
When your detector has many repeated elements, be sure to record a unique detector ID with each hit. This ID is usually derived from the copy number of the volume, or from an index that you assign in the geometry or stepping code.
Managing Output Files
Your final project will produce at least one output file per run, possibly with many histograms and ntuples. A clear file management strategy is important so that your results are reproducible and easy to compare.
The typical workflow in RunAction is:
- In the beginning of the run, open a file through
G4AnalysisManagerusing an appropriate file name. - At the end of the run, write all data and close the file.
Choose file names that encode important information such as:
- The configuration or geometry variant.
- The particle type and energy.
- The date or version of the simulation.
For example, instead of writing to a generic name, you might use a macro command or a configuration parameter to set the output file name. This is especially useful if you run parameter scans or multiple runs with different settings in the final project.
In a multithreaded run, Geant4 can merge analysis output from worker threads into a single file. The exact behavior depends on the analysis backend and configuration, but conceptually:
- Each thread fills its own histograms and ntuples.
- At the end of the run, the analysis manager merges the results and writes a single file.
This lets you use multiple CPU cores without changing the structure of your analysis code.
Always close the analysis file at the end of the run. If you stop the program abruptly or forget to close the file, the data may not be fully written and the file may be corrupted or incomplete.
When planning the final project, think about the size of the output. Consider:
- Reducing the number of stored variables to only what is necessary.
- Writing only hit-level ntuples for a subset of events if you mainly need event-level sums.
- Running shorter tests with full detail and longer production runs with summarized information.
Keeping Data Consistent with the Project Goals
Recording simulation data is not just a technical step. It is directly tied to your project goals and validation plan. Every quantity that you plan to compare with analytical results or experimental data must be:
- Clearly defined and documented.
- Stored with appropriate units.
- Reproducible by re running the simulation.
To ensure consistency:
- Use Geant4 units everywhere when filling histograms and ntuples, and document which units you use.
- Keep a record of the main simulation parameters in the output file or in a separate log. For instance, number of events, particle type, and energy.
- Make sure the mapping between detector geometry and recorded IDs is stable so that analysis scripts do not break when you change the geometry.
You can also store simple configuration information inside your output file, for example as metadata in a separate ntuple or as specially named histograms. This helps you remember which simulation settings produced a given file, which is crucial when you compare different runs in the final stages of the project.
Never analyze results without knowing the units, detector IDs, and configuration used to generate the file. Misinterpreting units or IDs is a common source of incorrect physics conclusions.
By designing your recording strategy carefully at this stage, you prepare for the later steps of the final project, where you will run the simulation, analyze the data with ROOT, validate the physics results, and create publication quality figures.
Views: 8
KAHIBARO