celeritas
celeritas copied to clipboard
Implement on-device general tally/histogram
For #1751 , #809, #261 we will want some multi-dimensional (potentially ragged) data structures for binning tracks, scoring them and their moments, reducing and normalizing in parallel (threads + MPI processes), and efficiently transferring between CPU and GPU. We might be able to use some other software (ADIOS?) as a backend for reducing and I/O.
Indexers
Continuous:
- One-dimensional nonuniform grid (for x, y, z, E, or t)
- One-dimensional uniform grid (optimization of 1D nonuniform, but common)
- One-dimensional uniform log space (optimization of 1D nonuniform)
- Particle attributes (charged vs neutral, em vs hadron, see https://github.com/celeritas-project/celeritas/issues/1594)
Discrete:
- Particle type
- Volume or region
Multi-dimensional:
- Multi-D regular grid (x * y * z)
- Multi-D ragged (particle type * energy per particle)
- Concatenated grid (e.g. LZ time grid, just an optimization for 1D nonuniform grid)
Index quantity
Continuous:
- Track position
- Track kinetic energy
- Source position (aka primary vertex)
- Angle (either dot product with surface normal or absolute direction?)
- Custom, e.g.
(primary position, detector id) -> hypot(detector center - primary position)for LZ (#1751)
Discrete:
- Particle type
- Track's pre-step volume
- (For surface detectors) post-step volume?
- Particle charge
Tallying quantities and estimators:
- Weighted path length (#809)
- Reaction rate (path length estimator)
- Reaction rate (collision estimator)
- Energy deposition
- Change in angle (?)
- Step count (for steps-per-track diagnostic)
- Number of secondaries
- Interacting process (post-step action)
- Loss in energy
Accumulation event:
- Lifetime (for steps-per-track diagnostic, observables)
- Surface crossing (optical detectors, or cell based detectors)
- Virtual surface crossing (mesh tally)
- Every step
- Every interaction
Accumulation type:
- Mean
- Mean + variance
- If we ever do variance reduction schemes, a bin structure that could resolve low-variance but accurately tally high-variance events
Combining dimensions:
- N-dimensional binning: arbitrary number of axes but optimize for a few?
- Ragged binning, e.g. different energy bins for different particle types; perhaps as sub-dimensions (i.e. two concatenated uniform grids would have sub-indices (0, 0..4) and (1, 0..9); the particles could have different sub-dimensions).
- Interface for tallying from Celeritas kernel or using Geant4 tracking+stepping action
- Future work: MSOD (?)
Caching:
- Some indexers (particle type, primary position) will not change over track's lifetime
- Some (energy, volume) will have multiple consecutive accumulation
- Some quantities (change in angle) require both pre- and post-step quantities
- Quantifier: given particle view (and sometimes params data), return a scalar (or vector? or tuple?)
- Volume ID: GeoParams -> VolumeId
- Detector ID: VolumeId -> DetectorId
- Distance to detector: DetectorId -> real
- Spatial location: GeoParams -> {real, real, real}
- Particle type+energy: ParticleParams -> {pid, real}
- Indexer: essentially like Grid, maps value to a bin, has size, composable (can use other indexers)
- Uniform grid: real -> size
- Concatenated grids: ? -> size
- Regular multi-D grids: {size, ...} -> size
- Irregular grids: {...} -> size
- Estimator: get the quantity to be tallied (maybe same as quantifier?)
- Unity: increment every time a score happens
- Weight: increment by a weighted value
Final indexing scheme:
- [permanent index][temporary index]
- permanent index: calculated at track start (source location, particle ID[?], ...)
- temporary index: merged from all indexers
To start:
- Focus on the specific LZ application: two specific tallies
- To start, don't make the indexing fully user configurable/extensible
- Use hard-coded composition to combine indexers into one permanent, one temporary
- Score into double precision, use a single batch