end_scan_monitoring() now writes to aux/namespace_monitor.h5 (instead
of the general-purpose recording API's default monitors.esc.h5) and
registers it via scan.set_scan_parameter("monitors",
"aux/namespace_monitor.h5") right after dispatching the capture job -
the same "register the path now, the async job finishes later"
pattern copy_aliases_to_scan/append_start_status_to_scan already use
for "aliases"/"status", so copy_scan_info_to_raw's scan_info_rel.json
carries it the same way.
Added eco/status_server/NAMESPACE_MONITOR_FORMAT.md: a handoff spec
for escape_fel describing the file format (one escape.ArrayTimestamps
per channel, keyed by the same dotted alias space as status.json/
aliases.json), how to load it (escape.DataSet(results_file=...)
already dict2structure()s it correctly for free - found by reading
escape_fel 0.2.7's actual source, not guessed), how it relates to and
should replace the existing pickle-based "monitor data hack" in
escape/swissfel/parse.py, and the merge-order needed for a co-loaded
bs/detector dataset to supersede the CA-monitor one for the same
component. Not yet exercised against a real load - flagged as such.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
eco — Experiment Control
___ _______
/ -_) __/ _ \
Experiment Control \__/\__/\___/
eco is a Python-based control environment for experiments, developed and used at SwissFEL, PSI. It is used both as:
- a library of experimental devices for higher-level Python applications or GUIs, and
- an interactive command-line interface, e.g. from an IPython/Jupyter shell or notebook.
eco follows an object-oriented approach: every device is represented as a Python object with a small, predictable interface, so devices can be freely combined in generic control/acquisition routines and analysed with the scientific Python ecosystem. For a general introduction to object-oriented Python, see e.g. this short introduction.
Documentation
The full documentation — installation, core concepts, and worked examples (listening monitors, archiver data and strip charts, pipeline offload, motor configuration) — lives in docs/ and is built with Sphinx, configured to build on Read the Docs via .readthedocs.yaml.
Build it locally:
pip install -r docs/requirements.txt
sphinx-build -b html docs docs/_build/html
Installation
conda install -c paulscherrerinstitute eco
or, for development, in editable mode from a checkout:
git clone https://github.com/paulscherrerinstitute/eco.git
cd eco
pip install -e .
See Installation for beamline-specific setup (the
eco launcher, .ecorc defaults) and the full dependency picture.
Creating a new device
New devices are implemented as a subclass of Assembly, which provides
naming, aliasing, and shell representation:
from eco.elements.assembly import Assembly
class MyDevice(Assembly):
def __init__(self, name=None):
super().__init__(name=name)
self._append(MySubObject, name="my_sub_object", is_setting=True, is_status=True)
is_setting=True marks the child as a setting of the assembly (shown by
.settings() and captured when settings are saved); is_status=True marks it
as contributing to the assembly's .status(). See
Representing real devices — the Assembly in the full docs
for the rest of the model (Adjustable, Detector, Namespace) and a
from-scratch, runnable example of each.