Skip to main content

openmodalpy banner

CI PyPI Python License

openmodalpy puts nine modal decomposition methods for spatiotemporal data behind one API. Extract coherent structures from simulation or experimental data — energy-ranked POD modes, frequency-resolved SPOD modes, DMD eigenvalues, nonlinear BSMD triads — without switching libraries or rewriting your loading code for each method.

Why this package

Most Python tools here specialise: PyDMD covers DMD variants in depth, PySPOD covers SPOD. That depth is real, and if you only need one method they are excellent choices.

OpenModalPy trades some of that depth for breadth. Nine methods share one analyzer interface, one data contract and one config file, so running POD, SPOD, DMD and BSMD over the same dataset — and comparing them directly — is a single command rather than four integrations. Bispectral mode decomposition (BSMD) in particular has little open-source coverage elsewhere.

It runs on the NumPy/SciPy stack. No compiled solver toolchain (PETSc, SLEPc) to install.

Installation

uv add openmodalpy                 # library
uv tool install openmodalpy        # standalone CLI

Optional extras:

Extra Adds
openmodalpy[viz3d] 3D slice and isosurface plotting (PyVista)
openmodalpy[mkl] Intel MKL FFT backend
openmodalpy[gpu] CuPy / PyTorch FFT backends

Quick Start

from openmodalpy import PODAnalyzer, SPODAnalyzer, DMDAnalyzer

pod = PODAnalyzer(file_path="data.mat", n_modes_save=10)
pod.run_analysis()

spod = SPODAnalyzer(file_path="data.mat", nfft=256, overlap=0.5)
spod.run_analysis()

# DMD is driven in two steps, so the fit method can be chosen after loading.
dmd = DMDAnalyzer(file_path="data.mat", n_modes_save=10)
dmd.load_and_preprocess()
dmd.perform_dmd(method="ls")

Configuration-Driven Workflow

One JSONC file runs several methods over the same dataset — the main reason to reach for this package over a single-method library:

{
  "case": {
    "name": "my_case",
    "data": { "kind": "file", "path": "data.mat" },
    "n_modes_save": 10, "nfft": 128, "overlap": 0.5
  },
  "runs": [
    { "id": "pod",   "method": "pod" },
    { "id": "spod",  "method": "spod" },
    { "id": "dmd",   "method": "dmd",   "params": { "method": "ls" } },
    { "id": "hodmd", "method": "hodmd", "params": { "delays": 4 } },
    { "id": "bsmd",  "method": "bsmd" }
  ]
}
openmodalpy run --config analysis.jsonc

CLI

openmodalpy analyze pod --config case.jsonc     # one method
openmodalpy run --config suite.jsonc            # full suite
openmodalpy run --config suite.jsonc --dry-run  # preview without computing
openmodalpy methods list                        # supported methods
openmodalpy examples list                       # bundled examples
openmodalpy results inspect output.hdf5         # inspect a result file

Three example cases ship with the package and need no external data — double_gyre, cylinder_wake and taylor_green generate their fields analytically. A fourth config, run_benchmarks, runs all three as a suite. So openmodalpy examples list gives you something runnable immediately, with nothing to download.

Methods

These are the names openmodalpy methods list reports and the values the method field takes in a config file.

method Class What it extracts Reference
pod variance-optimal energy-ranked spatial modes Lumley (1967); Sirovich (1987)
mpod variance-optimal scale-separated modes across non-overlapping bands Mendez et al. (2019)
psd-pod variance-optimal POD of blockwise Fourier realizations
spod variance-optimal frequency-local modes (Welch blocks) Towne, Schmidt & Colonius (2018)
stpod variance-optimal space-time structures via delay embedding
dmd evolution-fit modes with frequency and growth rate Schmid (2010); Tu et al. (2014)
hodmd evolution-fit delay-embedded (Hankel) DMD Le Clainche & Vega (2017)
tls-hodmd evolution-fit delay-embedded DMD, total-least-squares fit Hemati et al. (2017)
bsmd triadic interaction nonlinear triad structures Schmidt (2020)

dmd accepts method: "ls" (least squares) or method: "tls" (total least squares, de-biased for noisy data).

The BSMD implementation follows Schmidt (2020) and was inspired by the reference MATLAB implementation.

Data Format

.mat and .npz files are auto-detected and must provide:

{
    "q": np.ndarray,   # (Ns, Nspace) — snapshots × spatial points
    "dt": float,       # time step
    "Nx": int,         # grid points in x
    "Ny": int,         # grid points in y
    "x": np.ndarray,   # x-coordinates
    "y": np.ndarray,   # y-coordinates
}

Anything else can be read with a custom loader returning the same dictionary:

def my_loader(path):
    return {"q": data, "dt": 0.01, "Nx": 100, "Ny": 50, "x": x, "y": y}

pod = PODAnalyzer(file_path="ignored", data_loader=my_loader)

FFT Backend

FFT dispatch comes from fftkit, installed automatically. It probes the available backends, picks the fastest, and falls back to SciPy when nothing else is present — so this section is optional reading.

To pin a backend:

export FFTKIT_BACKEND=mkl      # or scipy, numpy, cupy, accelerate
from openmodalpy.core import FFT_BACKEND
print(FFT_BACKEND)   # the backend actually in use

The legacy PYMODAL_FFT_BACKEND variable still works as a fallback, but FFTKIT_BACKEND is the supported name.

Contributing

Contributions are welcome, and questions and bug reports count. See CONTRIBUTING.md for setup and the checks CI runs, and the openfluids Code of Conduct for how we work together.

License

Apache-2.0. Originally developed by Ricardo A S Frantz — see LICENSE and NOTICE for terms and attribution.

Download files

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

Source Distribution

openmodalpy-0.5.0.tar.gz (351.5 kB view details)

Uploaded Source

Built Distribution

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

openmodalpy-0.5.0-py3-none-any.whl (160.8 kB view details)

Uploaded Python 3

File details

Details for the file openmodalpy-0.5.0.tar.gz.

File metadata

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

File hashes

Hashes for openmodalpy-0.5.0.tar.gz
Algorithm Hash digest
SHA256 38e304a9588333aa3c3f3398692883e84c8ce908791947a392dffd34adb424ea
MD5 ae8a22cfbb8f87e095dbec75e7d43f1f
BLAKE2b-256 7df0955a1beb847962df2025dce0739d75e417f54ff4f2059a6bcd6ec2ab7488

See more details on using hashes here.

Provenance

The following attestation bundles were made for openmodalpy-0.5.0.tar.gz:

Publisher: release.yml on openfluids/openmodalpy

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

File details

Details for the file openmodalpy-0.5.0-py3-none-any.whl.

File metadata

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

File hashes

Hashes for openmodalpy-0.5.0-py3-none-any.whl
Algorithm Hash digest
SHA256 11c3650ba56b1bc0c420b5bb56dffaaecf924ef3b66eb9b0039ff7b3a56c4106
MD5 8627c3b1977c1611e0db13af4583adab
BLAKE2b-256 c5024b9218e877485f43efc38cb399e854a730eefb44c9c2aa11467e656146b0

See more details on using hashes here.

Provenance

The following attestation bundles were made for openmodalpy-0.5.0-py3-none-any.whl:

Publisher: release.yml on openfluids/openmodalpy

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.5.0 This release

2 files

0.4.0

2 files

0.3.0

2 files

0.2.0

2 files

0.1.0

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