docs: align SPC with code; document pip extras and API

- README: remove claim that SPC is not in-tree; add spc/flows install lines
- install.md: bring-up table mentions optional [flows] and [spc]
- docs/spc.md: match Hotelling keyword-only alpha, mean_/covariance_, MR span
- spc package docstring: lazy NumPy/SciPy loading clarified

Made-with: Cursor
This commit is contained in:
Robert McMahon 2026-04-10 19:41:48 -07:00
parent 6bf0535aa5
commit 1bcefa93c8
4 changed files with 83 additions and 8 deletions

View File

@ -16,7 +16,7 @@ This repository ships that distribution (**`fiwicontrol`** on PyPI / `pip`) with
A **first concrete goal** for this stack is to support **PCIe hot-swap (hot-plug) testing** in the lab: controlled **remove / restore** of the link, predictable **enumeration** and driver behavior, and **repeatable** runs across builds and rigs.
That work fails if the bench is informal—wrong port, wrong power path, or no shared picture of what was connected when. FiWiControl targets that gap by combining **documented inventory** (INI + **`--verify-inventory`**), **remote automation** (**`ssh_node`**, **`python3 -m fiwicontrol.commands`** to bring up rigs), and **programmable power / USB paths** (**`fiwicontrol.power`**) so sequences are **scripted and checkable** before the PCIe harness runs. Longer term, **SPC** (below) is meant for **many hot-plug cycles**—spotting drift in failure rates or side metrics—not only general FiWi bring-up.
That work fails if the bench is informal—wrong port, wrong power path, or no shared picture of what was connected when. FiWiControl targets that gap by combining **documented inventory** (INI + **`--verify-inventory`**), **remote automation** (**`ssh_node`**, **`python3 -m fiwicontrol.commands`** to bring up rigs), and **programmable power / USB paths** (**`fiwicontrol.power`**) so sequences are **scripted and checkable** before the PCIe harness runs. **`fiwicontrol.spc`** is aimed at **many hot-plug cycles**—spotting drift in failure rates or side metrics—not only general FiWi bring-up (see **`docs/spc.md`**).
## Lab fleet: Raspberry Pi 5 and iperf 2 (planned)
@ -32,11 +32,13 @@ Expanded **ush** orchestration alongside OpenSSH—not only the **`ush`** transp
## Product differentiation
We expect **advanced telemetry** (including **802.11-centric**, e.g. **ESP32**, data) and **advanced use of iperf 2 on Raspberry Pi 5** hosts—patterns **tied to rig state, inventory, and (eventually) SPC**, not ad hoc throughput screenshots—to help **differentiate** Umber FiWi products in the market.
We expect **advanced telemetry** (including **802.11-centric**, e.g. **ESP32**, data) and **advanced use of iperf 2 on Raspberry Pi 5** hosts—patterns **tied to rig state, inventory, and SPC** (**`fiwicontrol.spc`**), not ad hoc throughput screenshots—to help **differentiate** Umber FiWi products in the market.
## Statistical process control (planned)
## Statistical process control
The project is intended to grow **statistical process control (SPC)** support—for example **Hotelling**-style multivariate monitoring and **Shewhart** control charts—for lab and field metrics tied to FiWi rigs (including **high-volume PCIe hot-swap** campaigns where you need to know if the **process** is still in control). That code is **not** in the tree yet; todays packages focus on automation, inventory, and power/USB control as described above.
**In tree:** **`fiwicontrol.spc`** — **`ShewhartControlChart`** and **`HotellingT2`** (Phase I fit, *T*², Phase II UCL). Optional **`pip install -e ".[spc]"`**; overview **`docs/spc.md`**.
**Planned:** tighter coupling with inventory / harness automation, campaign-scale reporting, and richer charting beyond these primitives.
**Layout**
@ -49,7 +51,8 @@ FiWiControl/
│ ├── install.md
│ ├── node-control-asyncio-design.md
│ ├── power-control-and-inventory.md
│ └── flows.md
│ ├── flows.md
│ └── spc.md
├── src/
│ └── fiwicontrol/
│ ├── commands/
@ -96,6 +99,9 @@ cd ~/Code/FiWiControl
python3 -m pip install -e ".[dev]"
# optional: power / USB discovery (Acroname, Monsoon)
python3 -m pip install -e ".[power]"
# optional: async iperf flows / SPC (see docs/flows.md, docs/spc.md)
python3 -m pip install -e ".[flows]"
python3 -m pip install -e ".[spc]"
```
Imports:

View File

@ -14,7 +14,7 @@ Use this order the first time you (or someone else) joins the project or replace
| Step | Where | What to do |
|------|--------|------------|
| 1 | Workstation | **Clone** this repo and **`cd`** into it. |
| 2 | Workstation | **Python 3.11+** and an **editable install**: **`python3 -m pip install -e ".[dev]"`**, then **`python3 -m pip install -e ".[power]"`** if you use Acroname/Monsoon or remote power tests (see **Workstation** below). |
| 2 | Workstation | **Python 3.11+** and an **editable install**: **`python3 -m pip install -e ".[dev]"`**, then **`python3 -m pip install -e ".[power]"`** if you use Acroname/Monsoon or remote power tests. Add **`".[flows]"`** / **`".[spc]"`** when you use **`fiwicontrol.flows`** or **`fiwicontrol.spc`** (see **Workstation** below and **`docs/flows.md`** / **`docs/spc.md`**). |
| 3 | Workstation → rig | **Passwordless SSH as root:** **`ssh -o BatchMode=yes root@192.168.1.39 true`** must exit **0** with no password prompt. On the rig, install your workstations **public key** in **`/root/.ssh/authorized_keys`** and ensure **`sshd`** allows **`root`** with pubkey auth. |
| 4 | Rig (e.g. Pi) | **`git clone`** the same repo where you will run power/discovery (often **`/root/Code/FiWiControl`**). Your **`--remote-repo`** path must match. |
| 5 | Workstation | From your clone, run **`python3 -m fiwicontrol.commands`** with the Pi IP and **`--remote-repo`** (PEP 668 / Raspberry Pi OS needs **`--break-system-packages`** or **`FIWI_REMOTE_PIP_FLAGS`**). See **Remote host setup** below (numbered subsections **3** and **4**: install **`fiwicontrol[power]`** on the rig, then align **`python3`** with **`pip`**). |
@ -48,6 +48,19 @@ Or in one line:
python3 -m pip install -e ".[dev,power]"
```
**Flows** (async **iperf** over SSH, SciPy / Matplotlib stack) and **SPC** (**Shewhart** / **Hotelling** *T*² helpers) are separate optional extras:
```bash
python3 -m pip install -e ".[flows]" # NumPy, SciPy, Matplotlib — see docs/flows.md
python3 -m pip install -e ".[spc]" # NumPy, SciPy — see docs/spc.md
```
Or combined with dev and power:
```bash
python3 -m pip install -e ".[dev,power,flows,spc]"
```
**Why this is the default:** you avoid remembering **`PYTHONPATH=src`**, IDEs and **`python -m`** behave predictably, and it matches how **`pyproject.toml`** / **`pytest`** are meant to be used.
### Without a local install (one-off)

55
docs/spc.md Normal file
View File

@ -0,0 +1,55 @@
# FiWiControl SPC — Shewhart and Hotelling *T*²
**Package:** **`fiwicontrol.spc`**
**Implementation:** **`src/fiwicontrol/spc/`** (`shewhart.py`, `hotelling.py`; lazy exports from **`fiwicontrol/spc/__init__.py`**)
Small **statistical process control (SPC)** building blocks for lab metrics: a univariate **Shewhart**-style individuals chart (moving-range dispersion) and a multivariate **Hotelling *T*²** object with a Phase II upper control limit.
---
## Install
SPC uses **NumPy** and **SciPy** (not bundled in the base **`fiwicontrol`** install):
```bash
cd ~/Code/FiWiControl
python3 -m pip install -e ".[spc]"
```
**`import fiwicontrol.spc`** does not load **NumPy** / **SciPy** until you access **`ShewhartControlChart`** (NumPy only) or **`HotellingT2`** (both).
---
## Classes
### `ShewhartControlChart`
- **`ShewhartControlChart(k=3.0)`** — chart width in multiples of estimated sigma.
- **`fit_individuals(x, moving_range_span=2)`** — Phase I fit from a 1-D **`numpy`** array; only **`moving_range_span=2`** is supported (average moving range of consecutive pairs, **`d₂ = 1.128`**).
- **`limits()`** → **`(LCL, center, UCL)`** with width **`k`** sigma (default **`k=3.0`**).
- **`is_out_of_control(value)`** — boolean vs those limits.
### `HotellingT2`
- **`fit(X)`** — **`X`** shape **`(m, p)`** with **`m > p + 1`**; unbiased sample covariance, inverse for *T*².
- **`mean_`**, **`covariance_`** — fitted Phase I mean vector and covariance (after **`fit`**).
- **`t2(x)`** — Hotelling statistic for one observation **`x`** of length **`p`** vs the fitted mean.
- **`ucl(alpha=0.05)`** — Phase II UCL using the **`F_{p, m-p}`** distribution (**SciPy**).
- **`is_out_of_control(x, *, alpha=0.05)`** — **`True`** if **`t2(x) > ucl(alpha=alpha)`** (**`alpha`** is keyword-only).
---
## Tests
With **`[spc]`** installed:
```bash
python3 -m pytest tests/test_spc.py -q
```
---
## See also
- **`README.md`** (package list)
- **`docs/install.md`** (optional **`[spc]`** alongside **`[flows]`**, **`[power]`**, …)

View File

@ -8,8 +8,9 @@ Install optional dependencies before importing the classes::
pip install -e ".[spc]"
Symbols load lazily so ``import fiwicontrol.spc`` does not import **NumPy** until
you access a class.
Symbols load lazily so ``import fiwicontrol.spc`` does not import **NumPy** or
**SciPy** until you access a class (``ShewhartControlChart`` uses NumPy;
``HotellingT2`` uses both).
"""
from __future__ import annotations