21.5. Detector Maps
Table of Contents
Crystal occupancy
In PET or SPECT simulations, a detector is usually made of many repeated elements such as crystals or pixels. Each detected event is assigned to one of these elements, for example a specific crystal in a PET ring or a pixel in a gamma camera. A detector map summarizes how many events are recorded in each element. When you visualize this as an image, you obtain an occupancy map of the detector.
In GATE with ROOT output, crystal identity is encoded in integer identifiers. Common branch names in singles or hits trees include fields like crystalID, moduleID, ringID, or a more general detID. The exact naming depends on how the detector hierarchy was defined in your simulation, but the principle is always the same. Every event corresponds to one detector element, and you can count how many events fell into each element.
To build a crystal occupancy map you typically follow these steps using ROOT:
First, open the ROOT file written by GATE and get the tree corresponding to the data of interest. For imaging detectors, the Singles or Hits tree is often used because it contains detector-level information and high statistics. Second, inspect the branches to find which integer field encodes crystal identity and which encodes additional levels such as module or ring indices. ROOT tools like TTree::Print() or the ROOT browser help you to discover the branch structure.
Third, for each event in the tree, fill a histogram that bins in the detector ID. For a simple linear indexing, you can create a one dimensional histogram where the x axis index corresponds to crystalID. For more structured geometries, you may instead define a two dimensional histogram, for instance with ringID along one axis and crystalID within the ring on the other axis. This allows you to view occupancy in a form that resembles the physical layout of the scanner.
In practice, a typical ROOT macro would create something like TH1I hOccupancy("hOccupancy", "Crystal occupancy;Crystal ID;Counts", nCrystals, -0.5, nCrystals - 0.5) and fill it with hOccupancy.Fill(crystalID) inside an event loop. Alternatively, ROOT’s Draw command can be used interactively, for example Singles->Draw("crystalID>>hOccupancy"). For two dimensional maps, a command like Singles->Draw("crystalID:ringID>>h2( nCrystalBins, -0.5, ..., nRingBins, -0.5, ... )") will fill a TH2 histogram automatically.
Once filled, the occupancy histogram reveals how uniformly your detector is used. Ideally, in a symmetric configuration with a centered source, the occupancy pattern should be symmetric. For a PET ring with a central point source, all crystals at the same radius should show similar counts, resulting in a periodic pattern with the same peak height across the ring. Any crystal with significantly fewer or zero counts may indicate a problem in the geometry, detector IDs, or digitizer configuration.
Occupancy maps are particularly useful to catch configuration mistakes. If entire modules or rings have zero occupancy, it may mean that their placement is wrong, that they are outside the field of view, or that the digitizer chain does not assign IDs correctly for those elements. If occupancy is highly uneven in a geometry that should be uniform, this can signal misaligned sources, incorrect material assignments causing unexpected attenuation, or errors in the rotation or translation of detector components.
You can also compare crystal occupancy between simulations. For example, by simulating the same setup with different physics options or source sizes, you can create normalized occupancy maps and see how scatter or attenuation redistributes counts among crystals. This is especially important when evaluating the performance of different collimators or shielding designs, where occupancy at the edges or behind shielding parts may change.
Occupancy maps are not limited to PET crystals. For SPECT gamma cameras, you can treat detector pixels as elements in a two dimensional array. In ROOT, you produce a 2D histogram with pixel indices on each axis and fill it with hits or singles coming from the scintillation crystal. The resulting image is a raw flood field, similar to what one measures in detector quality tests. After normalization, such maps can be used to derive correction factors for non uniform detector response.
To visualize occupancy histograms in ROOT you typically use Draw("COLZ") for two dimensional maps, which color codes the intensity of counts. For one dimensional histograms you inspect shapes, peaks, and gaps. You should also pay attention to statistical fluctuations; crystals with few counts will show larger relative fluctuations, so it is helpful to run enough events so that the occupancy pattern is dominated by systematic effects rather than random noise.
Occupancy maps are also a first step toward building more advanced detector response models. Once you understand which crystals receive which fraction of events in a reference configuration, you can study how mechanical misalignments, dead channels, or energy thresholds affect the occupancy distribution. Comparing an ideal map from simulation with measured detector flood fields helps validate your geometry and detector modeling.
Finally, it is helpful to summarize the key idea: a crystal occupancy map is simply the count of events per detector element, organized according to the detector’s indexing scheme. When interpreted correctly, it is a powerful diagnostic tool to verify detector geometry, check for dead or missing elements, and understand how the detector responds to different source positions and configurations.
A detector occupancy map is built by counting events per detector element (for example per crystal or pixel) using integer detector IDs from the ROOT tree. Large differences or zeros in occupancy for elements that should be equivalent usually indicate geometry or configuration errors.
Detector counts
Detector counts are the basic quantitative measure produced by imaging simulations and experiments. Every time a particle interaction in the detector satisfies your detection and digitization criteria, it contributes one count. By analyzing how these counts accumulate across time, energy, and detector elements you can understand the performance of your system.
In GATE with ROOT output, counts are not stored explicitly; instead, each row in a ROOT tree represents a detection or interaction event. For example, in a Singles tree every entry is a detected single photon, and in a Coincidences tree every entry is a paired event. To obtain total counts you simply count the number of entries that pass a given selection. ROOT provides this through the number of entries in the tree or by applying selection criteria in Draw or TTree::GetEntries("cut expression").
A simple global count is the total number of singles or coincidences recorded during a simulation. If your simulation is time based, this can be converted to a count rate, usually expressed in counts per second. For example, if the Singles tree has $N$ entries and the acquisition time simulated is $T$, the mean singles rate is $R = N / T$. Similarly, the coincidence rate is obtained from the size of the Coincidences tree.
More detailed information comes from counting events by energy. With ROOT, you create a histogram of the measured or simulated energy using a command such as Singles->Draw("energy>>hE( nbins, Emin, Emax )"). The area under the histogram represents the total counts, and the shape of the spectrum shows features such as photopeaks and Compton continua. By integrating counts inside a chosen energy window you quantify how many events fall into the useful range for your imaging task versus those that are likely scatter or noise.
Detector counts can also be studied as a function of time when time stamps are available. In ROOT, you may have a time branch that records the detection time relative to the start of acquisition. By filling a histogram of time, you obtain a time activity curve of detected counts. This is useful in dynamic imaging studies or when simulating radioactive decay across longer time intervals. It also helps verify that your simulation of time dependent activity or motion is behaving as expected.
Spatial distributions of counts can be examined in combination with detector IDs, as described in the occupancy section. Here, the focus is not on which element was hit but on how many counts each element received. By summing counts over different angles, modules, or rings, you can build projection data, sinograms, or flood fields depending on the imaging modality. For PET, counts can be binned into lines of response according to the positions of the two detectors in each coincidence, producing sinograms that are the input to reconstruction algorithms. For SPECT, 2D count maps as a function of detector pixel and angle form projection images.
In ROOT, constructing these more complex count distributions often involves using two or more variables together, for example Coincidences->Draw("detectorID2:detectorID1>>hLOR( ... )") to build a simple LOR map, or including angular coordinates to sort counts by projection angle. The bins of such histograms then give you the number of counts per geometrical or physical bin.
Detector counts are directly related to key performance metrics. Sensitivity is defined as the number of detected events per unit activity and per unit time. In simulation you can calculate sensitivity by dividing the number of counts in your accepted energy and timing windows by the product of the source activity and simulation duration. Noise properties depend on the statistics of counts in each bin. For large numbers of counts, statistical fluctuations are described by Poisson statistics, where the standard deviation in a bin with $N$ counts is approximately $\sqrt{N}$.
This connection means that achieving low statistical uncertainty requires enough counts in each bin of interest. In practice, you can estimate the relative statistical uncertainty as $\sqrt{N}/N = 1/\sqrt{N}$. If, for instance, you want a relative uncertainty of 1% in a particular detector element or energy bin, you need at least $N \approx 10^4$ counts in that bin. When the counts are too low, detector maps and spectra become noisy and it is hard to distinguish real patterns from random variations.
Detector counts also provide a way to verify that your simulation configuration is consistent when you change parameters. For example, if you double the simulated activity while keeping geometry and acquisition time fixed, you should expect approximately double the counts in each bin, within statistical uncertainty. If instead counts do not scale as expected, this might reveal hidden bottlenecks such as saturated detectors, too strict energy thresholds, or incorrect time windows.
In ROOT based analysis, cuts and filters let you refine detector counts to specific subsets of interest. For example, you can count only primary photons by applying a filter on a primaryID or process branch, or count only events in a central region of the detector by imposing conditions on detector coordinates. This is essential when separating true, scattered, and random events in PET, or when assessing counts in specific regions of SPECT or CT detectors.
Finally, when you document or report your simulation results, always relate detector counts to simulation conditions. Counts without context can be misleading because they depend strongly on source strength, acquisition time, geometry, and energy windows. By stating the number of counts together with activity, time, detector configuration, and selection criteria, you make your results reproducible and comparable across simulations.
Detector counts in ROOT based GATE analysis are obtained by counting tree entries that pass a given selection. The statistical uncertainty in a bin with $N$ counts is approximately $\sqrt{N}$, so the relative uncertainty is $1 / \sqrt{N}$. High precision therefore requires large enough counts per bin.
Views: 12
KAHIBARO