DDALAB
ddalab is the unified Python package for DDALAB.
It ships:
- the command-line interface
- the Qt desktop application
- the shared local runtime and dataset readers
- the bundled
dda-rsbackend binary used for local DDA analysis
Entry Points
Installing this package provides:
ddalabddalab-cliddalab-gui
Use ddalab open to open the desktop application. Other ddalab commands use
the command-line interface. ddalab gui remains an alias for ddalab open,
and ddalab-gui launches the application directly.
Install
python -m pip install ddalab
ddalab open
For a source checkout:
cd packages/ddalab
python -m pip install .
Published wheels and desktop installers bundle the local dda-rs backend, so DDA works offline without a separate network service.
For editable or source installs, local DDA analysis also requires a working Rust toolchain with cargo so the bundled dda-rs binary can be built for your platform.
CLI Examples
ddalab health
ddalab dataset info --file data/MG100_Seizure1.edf
ddalab dda info --json
ddalab dda validate data/MG100_Seizure1.edf --json
ddalab dda run data/MG100_Seizure1.edf --channels 0 1 2 --variants ST SY --end 30
ddalab dda run data/MG100_Seizure1.edf --channels 0 1 2 --variants ST --device cuda
ddalab dda batch --bids-dir data/ds003029 --variants ST --continue-on-error
CPU execution is the default. The desktop DDA setup and CLI accept CUDA on
systems with an NVIDIA driver and cuBLAS runtime; cuda:N selects a specific
GPU. Analyses that use Rust-only CCD extensions continue those extension
computations on the CPU.
AI Agents (MCP)
ddalab mcp serves DDALAB over the Model Context Protocol on stdio, so an agent
such as Claude Code can open recordings, run DDA, and read results:
claude mcp add ddalab -- ddalab mcp
The tools are dataset_info, dda_info, dda_run, dda_result, and
dda_history. dda_run saves the full result as JSON and returns a summary;
dda_result returns time-binned values for chosen rows, so large matrices do not
fill the agent's context. dda_history lists the results saved by the desktop app,
and their IDs work in dda_result.
Python DDA Estimators
The bundled Python backend includes scalar estimators for derivative-form and
weak-form DDA. Derivative-form DDA builds delayed polynomial features
Phi(t) and regresses a numerical derivative of x(t) on those features.
Weak-form DDA uses the same delayed polynomial dictionary, but fits integrated
increments instead:
x(t + Delta) - x(t) ~= integral_t^{t+Delta} Phi(s) ds @ beta
This avoids pointwise derivative estimation and can be preferable when observation noise would be amplified by finite differences. Coefficients remain on the same differential-equation scale as derivative-form DDA because both the response and design matrix are integrated over the same window.
from ddalab_app.backend.dda import DerivativeDDA, WeakFormDDA
vanilla = DerivativeDDA(degree=3, delays=[0], derivative="finite_difference")
vanilla.fit(x, dt=0.01)
weak = WeakFormDDA(
degree=3,
delays=[0],
integration_window=9,
stride=1,
quadrature="trapezoid",
regression="ridge",
ridge_alpha=1e-6,
standardize_features=True,
)
weak.fit(x, dt=0.01)
print(weak.term_names_)
print(weak.coefficients_)
integration_window and stride are specified in samples. Use
integration_window_seconds or stride_seconds with dt/sample_rate when
time-based settings are more convenient. The default weak-form window is
conservative: half of the smallest positive delay, with a lower bound of three
samples, or five samples for nondelayed scalar systems. Too-small windows behave
more like derivative DDA; too-large windows can blur fast dynamics.
The available quadrature rules are trapezoid, left_rectangle,
right_rectangle, midpoint, and simpson when SciPy is available.
trapezoid is the default because it is the natural continuous-time weak-form
choice for sampled trajectories. left_rectangle can match an Euler-stepped
simulator more closely and is useful as a discretization diagnostic, but it is
not the recommended default for continuous-time estimation.
Weak-form DDA does not universally dominate derivative DDA. It trades derivative
noise sensitivity for integration-window bias. In practice, choose
integration_window on a held-out validation interval by minimizing weak-form
interval prediction error, then report the selected-window result. Oracle-best
windows, selected using known synthetic coefficients, are useful for experiments
but should be treated only as upper bounds.
For noisy or ill-conditioned windows, the recommended weak-form setting is
regression="ridge" with standardize_features=True. Feature standardization is
used only internally for numerical conditioning; exposed coefficients are
back-transformed to the original feature scale, so they remain comparable to
ordinary derivative-form DDA coefficients.
Weak-Form Sparse Additive DDA
The currently supported reliable Python estimator is polynomial WeakFormDDA.
SparseAdditiveWeakFormDDA is experimental infrastructure for nonlinear
main-effect delay discovery; use it for method development and diagnostics, not
as a replacement for polynomial weak-form DDA in production analyses.
Fixed polynomial dictionaries are interpretable but can be brittle when the
true delayed response is saturating, threshold-like, or otherwise smooth but not
well approximated by low-order monomials. SparseAdditiveWeakFormDDA replaces
polynomial terms with cubic B-spline response functions over candidate delays:
dx/dt = c + sum_tau f_tau(x(t - tau))
Each response function is fit in weak form by integrating spline basis functions over the same interval used for the observed increment. The first implementation is scalar and main-effect only; it does not yet fit pairwise delay surfaces. Delay selection is statistically meaningful only with group sparsity, because all spline basis functions for one delay must enter or leave the model together. Neighboring candidate delays can also be nearly duplicate predictors, so delay dictionary thinning and state-coverage diagnostics are part of the estimator.
from ddalab_app.backend.dda import (
SparseAdditiveWeakFormDDA,
stability_select_sparse_additive_weak_form,
)
model = SparseAdditiveWeakFormDDA(
candidate_delays=[0, 10, 11, 24, 25, 40],
n_knots=7,
spline_degree=3,
integration_window=9,
stride=1,
quadrature="trapezoid",
regression="group_lasso",
group_lasso_alpha=0.004,
ridge_alpha=1e-6,
standardize_features=True,
thin_delays=True,
max_delay_correlation=0.98,
)
model.fit([x_trial_1, x_trial_2, x_trial_3], dt=0.01)
print(model.selected_delays_)
print(model.group_strengths_)
print(model.delay_block_correlation_)
print(model.state_coverage_)
grid, effect = model.effect_curves_[10]
fit accepts either one scalar trajectory or a list of scalar trajectories. For
list input, spline bases are shared across trajectories and weak-form windows
are built within each trajectory only, never across trajectory boundaries.
Delay ranking is based on the L2 norm of each delay-specific spline coefficient
block. With regression="group_lasso", inactive delay blocks can be driven to
zero directly. For more conservative delay selection, use stability selection
with null calibration:
scores = stability_select_sparse_additive_weak_form(
[x_trial_1, x_trial_2, x_trial_3],
dt=0.01,
candidate_delays=model.candidate_delays_,
integration_window=9,
regression="group_lasso",
group_lasso_alpha=0.004,
n_repeats=20,
null_repeats=10,
calibrate=True,
)
print(scores.selection_frequency)
print(scores.null_selection_frequency)
print(scores.calibrated_selected_delays)
Prefer polynomial weak-form DDA when a low-order dictionary is scientifically meaningful and coefficient-level interpretation is the primary output. Prefer sparse additive weak-form DDA only when the main question is whether a small set of candidate delays has smooth nonlinear influence and the shape of that influence is itself informative. Current limitations are scalar input, main effects only, sensitivity to candidate-delay collinearity, dependence on broad state coverage, and validation-dependent choices of spline, group penalty, and stability thresholds.
Choosing Between WeakFormDDA and SparseAdditiveWeakFormDDA
Use WeakFormDDA as the default estimator when the goal is robust recovery of
polynomial DDA coefficients or when the analysis must be stable without
additional model-selection diagnostics. It is the reliable general-purpose
Python estimator.
Use SparseAdditiveWeakFormDDA only as an experimental nonlinear-delay
estimator. A defensible sparse-additive analysis should use group-lasso delay
blocks, candidate-delay thinning, stability selection, null calibration, and
state-coverage checks. Sparse-additive delay selections should not be trusted
when instantaneous null diagnostics select delayed terms, even if interval
prediction error is competitive. The current estimator also cannot represent
pairwise or interacting nonlinear delayed effects; those require a future
pairwise-surface model rather than the current main-effect spline model.
Desktop Development
cd packages/ddalab
./start.sh
The script provisions a local virtual environment, installs the unified package in editable mode, and launches the Qt application.
The desktop application uses a Qt Quick/QML workbench. Waveform and DDA-result plots use viewport-aware, cached Qt Quick scene-graph surfaces; there is no separate QWidget rendering mode.
See ARCHITECTURE.md for the desktop boundaries and data flow.
If you are working from source, ./start.sh expects cargo to be available so it can build or refresh the bundled dda-rs runtime.
Smoke Test
cd packages/ddalab
./start.sh --smoke-test
Metadata
Release files for ddalab 1.2.13
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Built distributions (wheels)
| File | Reset | |||
|---|---|---|---|---|
| ddalab-1.2.13-py3-none-win_amd64.whl | Python 3 | none | Windows x86-64 | Details |
| ddalab-1.2.13-py3-none-manylinux_2_35_x86_64.whl | Python 3 | none | Linux glibc 2.35+ x86-64 | Details |
| ddalab-1.2.13-py3-none-macosx_11_0_x86_64.whl | Python 3 | none | macOS 11.0+ x86-64 | Details |
| ddalab-1.2.13-py3-none-macosx_11_0_arm64.whl | Python 3 | none | macOS 11.0+ ARM64 | Details |
Total release size: 9.9 MB
Release files / ddalab-1.2.13-py3-none-win_amd64.whl
| Download URL | ddalab-1.2.13-py3-none-win_amd64.whl |
|---|---|
| Size | 2.3 MB |
| Tags | Python 3 Windows x86-64 |
|
SHA-256 checksum How to use checksums |
f86251078a9102558c8c8b7060f154488f69a1a29491831b6df42a0456c015c6
|
|
BLAKE2b-256 checksum How to use checksums |
0c1b3fcefead751bcdf9936f93080e8421d44f3c3e0dd6d27d253d45223a8452
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 29, 2026.
Transparency logRelease files / ddalab-1.2.13-py3-none-manylinux_2_35_x86_64.whl
| Download URL | ddalab-1.2.13-py3-none-manylinux_2_35_x86_64.whl |
|---|---|
| Size | 2.6 MB |
| Tags | Linux glibc 2.35+ x86-64 Python 3 |
|
SHA-256 checksum How to use checksums |
96cc75e10256dc9bea3f9729da64be7257818db3946896a52b7140f624cb9589
|
|
BLAKE2b-256 checksum How to use checksums |
57512164dcbce526b8ec713032bb9ff46eb5b9fe5f678c6e7bebf264b4626a7f
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 29, 2026.
Transparency logRelease files / ddalab-1.2.13-py3-none-macosx_11_0_x86_64.whl
| Download URL | ddalab-1.2.13-py3-none-macosx_11_0_x86_64.whl |
|---|---|
| Size | 2.5 MB |
| Tags | Python 3 macOS 11.0+ x86-64 |
|
SHA-256 checksum How to use checksums |
e33209618294473436922a1658fda7e885eb41966ad7255c79fb9999ff167b09
|
|
BLAKE2b-256 checksum How to use checksums |
7ab784f5afb35de229ca7163af5dd7e2f1920672f8b0644cbbcf45484df0bba1
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 29, 2026.
Transparency logRelease files / ddalab-1.2.13-py3-none-macosx_11_0_arm64.whl
| Download URL | ddalab-1.2.13-py3-none-macosx_11_0_arm64.whl |
|---|---|
| Size | 2.5 MB |
| Tags | Python 3 macOS 11.0+ ARM64 |
|
SHA-256 checksum How to use checksums |
90ad36c4e7feeafe3925bfc5736b9c8a82fda72c56e1df529c489034591a0bad
|
|
BLAKE2b-256 checksum How to use checksums |
3ff57187ec5d19bccfc11b7b90b82ae79b7ad34fc6883c81e4d90e7bb8a4dfc7
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 29, 2026.
Transparency log