Accumulator is a digital twin (emulator) of a charged particle accelerator based on the Elegant physics engine and the EPICS Channel Access protocol.
The project is developed as part of the scaut ecosystem and allows debugging control systems, optimization algorithms, and user interfaces without access to real hardware.
- Automatic PV Generation: PVs (Process Variables) are generated automatically based on the accelerator lattice file (
*.lte). - Real Physics: Every parameter change (via EPICS) triggers a simulation in Elegant, calculating the real beam response.
- Scalability: Ability to run multiple independent accelerator instances (e.g., for testing interaction between multiple rings).
- Value Mapping: Built-in support for unit scaling (e.g., converting orbit from meters to millimeters or magnet current to K1).
- Docker-native: Easy execution in an isolated container.
- Docker
- Docker Compose
docker compose -f docker-compose.accumulator.yml up --buildThis will start the base accelerator emulator ACC1: on ports 5064 (RPC), 5065 (stream), 8501 (UI).
docker compose -f docker-compose.jupyter.yml up --buildThis starts Jupyter Notebook on port 8888 with installed dependencies from requirements.txt.
To run multiple accelerator instances, generate all services:
python scripts/generate_compose.py --count 10This creates docker-compose.accumulator.yml with 10 accelerators (ACC1: through ACC10:) on UI ports 8501-8510.
docker compose -f docker-compose.accumulator.yml -f docker-compose.jupyter.yml up --buildYou can use caget/caput (from the pyepics package or command line) to interact.
Example (for ACC1):
# Read beam position
caget ACC1:BI-LA1:PK3:Cx
# Change magnet strength
caput ACC1:MG-LA1:QLF1:K1 -9.5All configuration is centralized in the elegant/ folder:
config.py: Element handlers, energy settings, PV/device mappings, and scale factors.config.lte: Magnetic structure description.config.ele: Simulation commands.
Element handlers are defined as dictionaries in elegant/config.py:
ELEMENT_HANDLERS = {
'QUAD': {
'K1': {'pv_suffix': 'K1', 'param_name': 'K1', ...},
'DX': {'pv_suffix': 'DX', 'param_name': 'DX', 'scale': PK_MONITOR_SCALE_FACTOR},
...
},
...
}Each element type maps to a dictionary of parameters with properties like:
pv_suffix: Suffix for PV name generationparam_name: Elegant parameter nameis_read_only: Whether the parameter is read-onlyscale: Value scaling factorprecision: Number of decimal placesdefault_val: Default value
PV_MAPPING: Maps elegant element names to EPICS PV namesSCALE_MAPPING: Defines scaling factors for specific parametersDEVICE_MAPPING: Maps element names to device prefixes
Beam energies are defined for each linac section:
ENERGY_LA1 = 38e-3 # [GeV/c]
ENERGY_LA2 = 76e-3
...See .env_example for a complete list of configuration options.
ACCUMULATOR_PREFIX: Prefix for all PVs (defaultACC1:for base service).LOG_LEVEL: Logging level (defaultINFO).LOG_DIR: Directory for log files (defaultlogs).ELEGANT_SIMULATION_DIR: Path to elegant configuration directoryELEGANT_SIMULATION_CONFIG_FILE: Path to elegant config fileELEGANT_SIMULATION_LATTICES_FILE: Path to elegant lattice file
accumulator/: Python package source code.core/: Core configuration and utilities.config.py: Application configuration.logger.py: Logging configuration.
elegant/: Elegant simulation integration.lattice.py: Lattice parser and PV configuration.mapping.py: PV name and simulation name resolution.ioc.py: EPICS request handling and Elegant simulation logic.
main.py: Entry point.
elegant/: Physics engine and accelerator configuration.config.py: Element handlers, energy settings, PV mappings, and scale factors.config.lte: Magnetic structure description.config.ele: Elegant simulation commands.
scripts/: Utility scripts (e.g.,generate_compose.pyfor Docker Compose generation).notebooks/: Jupyter notebooks for analysis and experimentation.