CaltechExperimentalGravity / CaltechExperimentalGravity/system_ident

Stage C: CDSTransport seam + AWGNDSTransport (awg/cdsutils/gpstime)

Open
#11 1 comment 0 reactions 0 assignees View on GitHub
enhancement
Dominant language
Python
Stars
0
Forks
1
PR merge metrics
No merged PRs in 30d

Description

**Stage C (spec §4.1).** The pluggable transport
[the roadmap already asks for](https://github.com/CaltechExperimentalGravity/system_ident/blob/feat/cds-hardware-backend/notes/40m-sos-campaign-handoff-2026-07.md) ("behind a **pluggable
transport**"), and what makes the backend and safety work verifiable without hardware.

New `src/system_ident/backends/cds_transport.py`:

```python
class CDSTransport(Protocol):
def now_gps(self) -> float: ...
def probe_rate(self, channels) -> float: ... # getdata(chans, 1)
def start(self, channel, array, rate, start_gps, ramptime): ... # -> handle
def stop(self, handle, ramptime) -> None: ...
def fetch(self, channels, duration) -> dict[str, Capture]: ... # data, start_gps, rate
```

`AWGNDSTransport` ports the sibling project's `measurement/backend_rtcds.py` (branch `40m-sys-test`),
**comments included** — the comments are the hardware lessons:

1. **The `Thread.isAlive` shim.** python-awg 3.1.2 calls `Thread.isAlive()` at `awg.py:706`, removed in
Python 3.9, so `ArbitraryLoop.start()` dies on its first line and **every injection fails before it
begins**. The site CDS stack runs awg under Python 2.7, so this only appears in a pinned py3.9 conda
env. Patch the class at import, not site-packages — an env rebuild would discard the latter.
2. **The `started`-flag `finally` stop**, verbatim: always stop the excitation, but only if it actually
started (`ArbitraryLoop.stop()` joins its worker thread and raises "cannot join thread before it is
started" otherwise, **masking the real error**); print a loud warning on a failed stop; re-raise only
when nothing else is already propagating.
3. **Probe the rate, don't configure it** — a one-second read-back, and **print it with its source
channels**. A Foton-derived seed model assumes a front-end rate, and a mismatch silently invalidates
the whole run.
4. **Lazy import** of `awg`/`cdsutils`/`gpstime` inside `AWGNDSTransport.__init__`, never at module
scope, so `import system_ident` stays clean on a plain scientific stack — the contract
[`src/system_ident/backends/cds.py:3`](https://github.com/CaltechExperimentalGravity/system_ident/blob/feat/cds-hardware-backend/src/system_ident/backends/cds.py#L3) already states.
5. **Site environment precondition.** `cdsutils/nds.py` reads the site IFO variable at *import* time and
raises `NDSError: IFO environment variable not specified` otherwise — check it first and raise
actionably. Its **value is site configuration, not a constant** (it is `C1` at the 40m); that belongs
in the deferred site-profile layer, never hardcoded. Also document the trap: sourcing the site
workstation rc script prepends the Python 2.7 CDS stack to `PYTHONPATH`, after which `import
cdsutils` dies with `ModuleNotFoundError: No module named 'matrix'`; unsetting `PYTHONPATH` recovers.

### Acceptance

`tests/test_cds_lazy_import.py` — `import system_ident` must not import `awg`/`cdsutils`. Transport unit
tests on the Stage A fakes.

---
**Campaign:** CDS hardware backend · branch [`feat/cds-hardware-backend`](https://github.com/CaltechExperimentalGravity/system_ident/tree/feat/cds-hardware-backend)
· [spec](https://github.com/CaltechExperimentalGravity/system_ident/blob/feat/cds-hardware-backend/docs/superpowers/specs/2026-08-03-cds-hardware-backend-design.md) · [plan](https://github.com/CaltechExperimentalGravity/system_ident/blob/feat/cds-hardware-backend/docs/superpowers/plans/2026-08-03-cds-hardware-backend.md) · [handoff](https://github.com/CaltechExperimentalGravity/system_ident/blob/feat/cds-hardware-backend/notes/cds-hardware-bringup-2026-08.md)
*Code is deferred until the plan and issues have been reviewed.*

Contributor guide

No contributing guide indexed for this repository

Research direction

Read the transport contract in the issue, the import boundary at src/system_ident/backends/cds.py:3, and the referenced Stage A fakes and sibling measurement/backend_rtcds.py. Start with tests/test_cds_lazy_import.py and the plan/spec; done means lazy imports remain clean and transport unit tests cover the stated behavior without requiring hardware.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
backend, testing
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.