ML pipeline¶
Pipeline ¶
ML lifecycle + state for an App.
Constructor registers the predict thread + cleanup on the App's hook
lists; they fire on app.run() start/exit. Decorators set the
callbacks. Transition methods flip app.ctx.state.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
app
|
App
|
The myogestic App. |
required |
predict_hz
|
float
|
Maximum predict-loop tick rate. Set to 0 or negative to remove the cap (run at full speed). |
50.0
|
Source code in myogestic/ml/__init__.py
extract ¶
Decorator: register the feature-extraction callback.
The wrapped function receives windows: dict[str, np.ndarray]
keyed by stream name — each array is channels-first
(n_channels, n_samples). Return whatever shape your model
wants to consume. The same function is invoked from inside
train() (over recorded windows) and on the predict thread
(over live windows), so keep its return type stable.
Source code in myogestic/ml/__init__.py
train ¶
Decorator: register the training callback.
The wrapped function receives one :class:TrainingData and
must return any object — it's stored on pipeline.model and
forwarded to every subsequent predict() call. If
pipeline.save_model is set, the Save Model button calls
it as save_model(pipeline.model, path).
Source code in myogestic/ml/__init__.py
predict ¶
Decorator: register the predict callback.
The wrapped function is called every 1/predict_hz seconds
with (model, features) where features is the return
value of the extract callback. Must return a
dict[str, Any] — non-dict returns are silently dropped
(the previous prediction stays in pipeline.predictions).
Source code in myogestic/ml/__init__.py
PipelineState ¶
Bases: StrEnum
ML-side extension of :class:~myogestic.AppState.
The core app only knows about "idle" and "recording";
attaching a :class:Pipeline (via Pipeline(app)) adds two more
states for the ML lifecycle. Mutually exclusive with each other and
with the core states: a Pipeline cannot be predicting and training
at the same time, by design (the train pause exists so the GPU
isn't fought over).
The enum is a StrEnum so it compares cleanly against the raw
string written to app.ctx.state by the transition methods.
Members
TRAINING: train() is running on a background thread.
Predict ticks short-circuit so they don't fight for GPU.
PREDICTING: The predict thread is calling extract +
predict each tick at predict_hz and writing the
result to pipeline.predictions.
save_pickle ¶
Pickle model to path. Creates parent directories if needed.
Source code in myogestic/ml/persistence.py
load_pickle ¶
Widgets¶
train_button ¶
predict_button ¶
Source code in myogestic/ml/widgets.py
training_log ¶
Read-only view of pipeline.train_log with smart autoscroll.
Uses the same scrollable-child + tail-follow renderer as
process_launcher. The autoscroll/popout toggles aren't drawn
here — they're rendered as part of pipeline_panel's control row
so they sit next to Train/Predict.
Source code in myogestic/ml/widgets.py
save_model_button ¶
Source code in myogestic/ml/widgets.py
load_model_button ¶
Source code in myogestic/ml/widgets.py
pipeline_panel ¶
Train + Predict + log as a single titled panel — matches the visual
style of recording_controls, session_manager, and FilterControl.
The log inherits the same autoscroll + popout UX as the process launcher's log: a double-chevron-down icon toggles auto-tail-follow, a box-out icon detaches the log into a floating ImGui window that survives across selection / frame churn.
Source code in myogestic/ml/widgets.py
