Skip to main content

Python toolkit for quantitative MRI modeling, fitting, and simulation.

Project description

qmrpy

PyPI

Python toolkit for quantitative MRI (qMRI) modeling, fitting, and simulation.

Statement of need

qMRLab (MATLAB) and DECAES (Julia) provide widely used qMRI reference implementations, but integration into Python workflows can be frictional. qmrpy reimplements key models in Python with a unified API, explicit parameter naming, and reproducible tests so researchers can run model fitting and comparisons inside a single Python environment.

Scope

  • Models: T1, T2, B1, QSM, noise, and simulation utilities.
  • Interfaces: object-oriented models plus functional wrappers.
  • Verification: parity checks for DECAES components and a broad test suite.

Installation

pip install qmrpy

If you use uv:

uv add qmrpy

Quickstart

import numpy as np
from qmrpy.models.t1.vfa_t1 import VfaT1

model = VfaT1(tr_ms=15.0, flip_angle_deg=np.array([2, 5, 10, 15]))

signal = model.forward(m0=1.0, t1_ms=1200.0)
fit = model.fit(signal)
print(fit["t1_ms"], fit["m0"])

Functional API (no object):

import numpy as np
from qmrpy import vfa_t1_fit

signal = np.array([0.02, 0.06, 0.12, 0.18], dtype=float)
fit = vfa_t1_fit(signal, flip_angle_deg=np.array([2, 5, 10, 15]), tr_ms=15.0)
print(fit["t1_ms"], fit["m0"])

EPG-corrected T2 (multi-echo spin-echo):

import numpy as np
from qmrpy.models.t2 import EpgT2

model = EpgT2(n_te=32, te_ms=10.0, t1_ms=1000.0, alpha_deg=180.0)
signal = model.forward(m0=1.0, t2_ms=80.0)
fit = model.fit(signal)
print(fit["t2_ms"], fit["m0"])

Optional B1 correction: forward(..., b1=0.9), fit(..., b1=0.9), or fit_image(..., b1_map=...).

Functional API (EPG-corrected T2):

import numpy as np
from qmrpy import epg_t2_fit, epg_t2_forward

signal = epg_t2_forward(
    m0=1.0, t2_ms=80.0, n_te=32, te_ms=10.0, t1_ms=1000.0, alpha_deg=180.0
)
fit = epg_t2_fit(signal, n_te=32, te_ms=10.0, t1_ms=1000.0, alpha_deg=180.0)
print(fit["t2_ms"], fit["m0"])

B1 mapping integration (example):

import numpy as np
from qmrpy.models.b1 import B1Dam
from qmrpy.models.t2 import EpgT2

b1_model = B1Dam(alpha_deg=60.0)
sig_b1 = b1_model.forward(m0=1.0, b1=0.9)
b1_fit = b1_model.fit(sig_b1)

t2_model = EpgT2(n_te=16, te_ms=10.0, t1_ms=1000.0, alpha_deg=180.0)
sig_t2 = t2_model.forward(m0=1.0, t2_ms=80.0, b1=b1_fit["b1_raw"])
t2_fit = t2_model.fit(sig_t2, b1=b1_fit["b1_raw"])
print(t2_fit["t2_ms"])

Use b1_map for voxel-wise correction: t2_model.fit_image(data, b1_map=..., mask=...).

API overview

  • Names use physical quantity + unit (e.g., t1_ms, t2_ms, flip_angle_deg).
  • forward(**params) returns simulated signal(s).
  • fit(signal, **kwargs) returns a dict for a single voxel.
  • fit_image(data, mask=None, **kwargs) returns a dict for images/volumes.
    • data shape is (..., n_obs) and mask matches spatial shape.
  • Primary estimates use fixed keys (e.g., t1_ms, t2_ms, m0); auxiliaries use snake_case.

Model modules:

  • qmrpy.models.t1
  • qmrpy.models.t2
  • qmrpy.models.b1
  • qmrpy.models.qsm
  • qmrpy.models.noise
  • qmrpy.sim

Verification highlights

DECAES parity (reference CSV)

Errors against reference CSV in tests/data (regenerate with uv run scripts/summarize_parity.py --no-qmrlab).

reg abs(alpha-alpha_ref) [deg] abs(mu-mu_ref) abs(chi2factor-chi2_ref) max abs(dist-dist_ref)
none 0 N/A N/A 2.22045e-15
gcv 1.99e-10 4.79026e-08 N/A 1.12119e-06
lcurve 1.99e-10 0 1.04894e-11 3.29564e-12
chi2 1.99e-10 5.67276e-14 1.28786e-14 4.82459e-12
mdp 1.99e-10 5.66938e-14 1.69642e-13 4.91318e-12

qMRLab parity (optional)

Requires Octave and a qMRLab checkout. The script compares qMRLab-generated signals against qmrpy fits.

QMRLAB_PATH=/path/to/qMRLab uv run scripts/verify_parity.py --model inversion_recovery
QMRLAB_PATH=/path/to/qMRLab uv run scripts/verify_qmrlab_mwf.py
QMRLAB_PATH=/path/to/qMRLab uv run scripts/sweep_qmrlab_mwf.py

Inversion Recovery (Barral, rdNLS):

metric abs diff
T1 (ms) 0

MWF example:

metric abs diff
MWF (%) 0.105
T2MW (ms) 0.127
T2IEW (ms) 0.045

Tests

Run the test suite:

uv run --locked -m pytest

Generate a test matrix table (output under output/, not tracked):

uv run scripts/summarize_tests.py

Development

uv sync --extra viz
uv sync --extra viz --extra dev

Citation

For JOSS submission, see paper.md and paper.bib. A Zenodo archive DOI will be added before release.

License

  • qmrpy core: MIT (LICENSE)
  • Third-party notices: THIRD_PARTY_NOTICES.md

Project details


Download files

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

Source Distribution

qmrpy-0.6.0.tar.gz (263.5 kB view details)

Uploaded Source

Built Distribution

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

qmrpy-0.6.0-py3-none-any.whl (81.2 kB view details)

Uploaded Python 3

File details

Details for the file qmrpy-0.6.0.tar.gz.

File metadata

  • Download URL: qmrpy-0.6.0.tar.gz
  • Upload date:
  • Size: 263.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.14

File hashes

Hashes for qmrpy-0.6.0.tar.gz
Algorithm Hash digest
SHA256 5c76d4bb2b03bc6142b6aa3316ad9d594bf35bc13e69ac42df21ab9b85285c21
MD5 a600c57911312e739c75860b5db7822e
BLAKE2b-256 d655f0478ed740c2d340397fc36be749bb0e27da3bf96e9b13df1ac88e1cfacf

See more details on using hashes here.

File details

Details for the file qmrpy-0.6.0-py3-none-any.whl.

File metadata

  • Download URL: qmrpy-0.6.0-py3-none-any.whl
  • Upload date:
  • Size: 81.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.14

File hashes

Hashes for qmrpy-0.6.0-py3-none-any.whl
Algorithm Hash digest
SHA256 b72cf2f9075526fe05581f5dcaa43217fedf96682e0b61a48607519c3b9bea16
MD5 bb54572bfadced08e13fe8b532ba9fe9
BLAKE2b-256 9864a04399785564af9221141d00df95c67161d851aa7c40a1846a1763894c32

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page