Skip to main content

leds

GitHub tag (latest by date) GitHub Workflow Status pre-commit Code style: black Codecov GitHub issues GitHub pull requests License Read the Docs

An event viewer for the LEGEND experiment: a Panel dashboard with event display, waveforms, spectra, dataset-metadata and validation views over a legend-dataflow production cycle.

Running

pip install legend-leds   # or: uv pip install .

leds app /path/to/production_cycle          # local single-user browser tab
leds app --desktop /path/to/cycle           # native window (needs leds[desktop])
leds serve /path/to/cycle --port 5006       # hosted multi-user server

The production-cycle path (a directory containing dataflow-config.yaml, or a directory of such cycles) can also come from $LEDS_BASE_PATH; several paths may be listed separated by :.

Deployment (NERSC Spin)

The Dockerfile builds a slim two-stage image by cloning this repository:

docker build -t registry.nersc.gov/<project>/leds:latest \
  --build-arg LEDS_REPO=https://github.com/legend-exp/leds.git \
  --build-arg LEDS_REF=main .
docker push registry.nersc.gov/<project>/leds:latest

(Point LEDS_REPO at a fork while changes are not upstream yet.) The container listens on port 5006 and runs under an arbitrary non-root UID, as Spin requires.

Service environment

Variable Required Meaning
LEDS_BASE_PATH yes production cycle(s) on the mounted filesystem (e.g. CFS)
BOKEH_ALLOW_WS_ORIGIN yes public hostname (host[:port]) allowed to open the websocket, i.e. the Spin ingress name
NUM_PROCS no (default 2) Panel worker processes; sessions in one process share its caches (and its HDF5 lock, see Threads)
NUM_THREADS no (default 4) thread pool per worker that callbacks run on, so one session's slow read does not freeze the others; 0 disables it (see Threads)
LEDS_PREWARM no (default on) scan cycles and build the newest channelmap before forking workers, so the first session of each is warm; delays the listening socket; 0 disables
LEDS_CACHE_TTL no (default 3600) seconds a metadata-derived entry (channelmaps, statuses, calibration pars) is reused before being re-read
LEDS_SCAN_TTL no (default 300) seconds a directory scan is reused; bounds how long a newly-written run stays invisible
LEDS_MAX_CACHED_RUN_SPECTRA no (default 4) whole runs of per-hit energies held per worker; the dominant memory line
LEDS_MAX_CACHED_CAL_PARS no (default 4) parsed par_hit calibration files held per worker; MB-scale each

Sessions in one worker share the read-only data they have in common — channelmaps, detector statuses, directory scans, per-run reductions — so a second user on the same cycle starts nearly instantly and does not duplicate that memory. All the bounds above are per worker process, so multiply by NUM_PROCS when sizing the Spin memory limit.

Because that sharing includes the parsed metadata, an updated metadata checkout is picked up within LEDS_CACHE_TTL rather than immediately. Lower it if the deployment updates metadata often; restarting the service always picks it up at once.

Threads

NUM_THREADS (passed by the image to leds serve --num-threads, like NUM_PROCS to --num-procs) runs callbacks on a thread pool instead of the worker's single event loop. Without it, one session's slow operation — a first visit to the Validation tab, a raw read stalling on CFS — freezes the UI of every other session in that worker until it finishes. With it those sessions keep responding, and work that is not HDF5 (parsing a channelmap, evaluating cuts, building Bokeh models) runs in parallel.

What it does not buy: h5py serialises every HDF5 call behind one process-wide lock, so two sessions' raw reads still take turns within a worker. NUM_PROCS is the lever for that; the two combine.

Per-session state — the viewer's caches and open HDF5 handles, the spectrum accumulator, the tab bookkeeping — is guarded by one lock per session, so a session's own callbacks never overlap even though they run on the pool. Open HDF5 handles are per session and never shared across sessions or forked workers. A playback tick that arrives while the previous frame is still rendering is dropped rather than queued.

Login (Spin secrets)

Without any of the variables below the server is open. In all authenticated setups set a fixed LEDS_COOKIE_SECRET — with an ephemeral one, logins break on every restart and across the NUM_PROCS workers.

Option A — shared password / user list: set LEDS_BASIC_AUTH to either a single shared password or a path to a mounted JSON file of {"username": "password"}.

Option B — LDAP (takes precedence over LEDS_BASIC_AUTH): users sign in with their directory credentials. Fill the values in from the LEGEND LDAP administrators:

Variable Required Meaning
LEDS_LDAP_SERVER yes (enables LDAP) e.g. ldaps://ldap.legend.example:636
LEDS_LDAP_USER_DN_TEMPLATE direct-bind mode e.g. uid={username},ou=people,dc=legend,dc=example
LEDS_LDAP_BIND_DN / LEDS_LDAP_BIND_PASSWORD search-bind mode read-only service account (as a Spin secret)
LEDS_LDAP_SEARCH_BASE search-bind mode subtree searched for the user entry
LEDS_LDAP_USER_FILTER no (default (uid={username})) search filter template
LEDS_LDAP_GROUP_DN no if set, only members (member/uniqueMember/memberUid) of this group may log in
LEDS_LDAP_STARTTLS no 1 upgrades an ldap:// connection via StartTLS
LEDS_LDAP_CA_FILE no CA bundle path (mount as a secret); defaults to certifi's bundle

Configure either LEDS_LDAP_USER_DN_TEMPLATE (direct bind) or the three search-bind variables; if both are present, direct bind wins. Server certificates are always verified. Bad credentials, unknown users and non-members all get the same generic login error; infrastructure failures are reported as "authentication service unavailable" with details in the container log only.

To try the LDAP flow locally against a throwaway directory:

docker run --rm -d -p 1389:1389 -e LDAP_ADMIN_PASSWORD=adminpw \
  -e LDAP_USERS=alice -e LDAP_PASSWORDS=alicepw bitnamilegacy/openldap

LEDS_LDAP_SERVER=ldap://localhost:1389 \
LEDS_LDAP_USER_DN_TEMPLATE="cn={username},ou=users,dc=example,dc=org" \
LEDS_COOKIE_SECRET=devsecret leds serve /path/to/cycle

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

legend_leds-0.0.3.tar.gz (135.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

legend_leds-0.0.3-py3-none-any.whl (124.0 kB view details)

Uploaded Python 3

File details

Details for the file legend_leds-0.0.3.tar.gz.

File metadata

  • Download URL: legend_leds-0.0.3.tar.gz
  • Upload date:
  • Size: 135.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for legend_leds-0.0.3.tar.gz
Algorithm Hash digest
SHA256 b657a8178887e5271aca9bc32bd5c79a526e0e4e8cd4dd35e1200079a6083ad4
MD5 2db21f330cf8b8ec93c88937cb811dd2
BLAKE2b-256 cded14d43372b6c630bf53914a4c7502b0073c1cccaa0df271c7a0638dbe6dd3

See more details on using hashes here.

Provenance

The following attestation bundles were made for legend_leds-0.0.3.tar.gz:

Publisher: distribution.yml on legend-exp/leds

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file legend_leds-0.0.3-py3-none-any.whl.

File metadata

  • Download URL: legend_leds-0.0.3-py3-none-any.whl
  • Upload date:
  • Size: 124.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for legend_leds-0.0.3-py3-none-any.whl
Algorithm Hash digest
SHA256 4e0a69e5463eeb7f03fc78d12f1129e3ff77be31dc15eeb3d94f473d666547fa
MD5 43150c3ed94b631c4695e8a93e9dd2c0
BLAKE2b-256 f2be0dd86b9b0f7cf7933caca9d899d914329d983f8f9498ba82c786393eb208

See more details on using hashes here.

Provenance

The following attestation bundles were made for legend_leds-0.0.3-py3-none-any.whl:

Publisher: distribution.yml on legend-exp/leds

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

This release

0.0.3 This release

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page