lemke_handClaude Sonnet 5 e876c1af4f FS-based status_server settings, per-channel size projection, required-filter for monitors
Three follow-ups to the status_server namespace component and
recording feature:

1. StatusServer's recording settings are now AdjustableFS, not
   AdjustableMemory - each a small JSON file under the same shared
   eco_cnf_bernina/configuration tree channels_JF/config_JFs already
   use. The point: a setting changed in one process is visible to any
   other process reading the same filesystem (another session, or the
   status server itself) with no REST call or other new communication
   - confirmed with a test constructing two independent StatusServer
   instances against the same config_dir.

2. RecordingSession.size_report(): per-channel projected bandwidth -
   rate (this channel's own point count over elapsed time) times a
   sample value's size (element count * dtype itemsize, "frequency *
   data shape * bitdepth") - to judge storage/bandwidth cost from a
   short trial recording before committing to a long one. Works on a
   still-running recording. Exposed via GET /recording/<id>?size=1
   (optional &size_top_n=N) and StatusServerClient.recording(...,
   size=True).

3. failed_required for recordings: a channel that fails to attach and
   belongs to a required namespace component (namespace.required_names())
   is now reported separately in a recording's report() - the same
   "everyone else failing is expected, this failing is not" distinction
   /health's failed_required already makes for init failures. New
   client-side warn_recording_failed_required (red, but does not
   suggest reinit() the way the health one does - a demoted/
   disconnected channel isn't fixed by rebuilding the namespace),
   wired into Daq.start_scan_monitoring.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-10 17:34:49 +02:00
2026-09-09 15:58:41 +02:00
2026-08-18 21:56:17 +02:00
2026-08-28 18:20:00 +02:00
2026-09-07 16:54:05 +02:00
2026-09-09 17:14:38 +02:00
2026-08-18 21:56:17 +02:00
2018-07-06 12:38:44 +02:00
2026-08-18 21:56:17 +02:00
2026-08-18 21:56:17 +02:00
2026-08-18 21:56:17 +02:00
2026-09-07 17:11:28 +02:00
2021-01-13 13:11:22 +01:00
2026-08-18 21:56:17 +02:00
2026-08-21 15:10:25 +02:00
2026-08-21 15:10:25 +02:00
2025-06-24 15:33:02 +02:00

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.

S
Description
Experimental control package
Readme GPL-3.0
7.5 MiB
Languages
Python 86%
HTML 11%
Jupyter Notebook 2.1%
Shell 0.9%