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.1.tar.gz (264.2 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.1-py3-none-any.whl (81.1 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: qmrpy-0.6.1.tar.gz
  • Upload date:
  • Size: 264.2 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.1.tar.gz
Algorithm Hash digest
SHA256 39390fe652e1e9f5149ee4bc31f60fa3f46bf245f5c1c46e03ba4563ccb160ef
MD5 7215ad1ba3397e7d76af491a319dfe80
BLAKE2b-256 49d66b07774238c966b34a5b24b3bab48fe70ac0bf3e82ab4f9c56fca18eaf03

See more details on using hashes here.

File details

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

File metadata

  • Download URL: qmrpy-0.6.1-py3-none-any.whl
  • Upload date:
  • Size: 81.1 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.1-py3-none-any.whl
Algorithm Hash digest
SHA256 3589072a0de243a4ecb810173d8125c60a87f6e5cd1df71c9012d7a87d33eb36
MD5 6bbd353ff70ecadd993986a48a2844ae
BLAKE2b-256 caf47d3a0c13a6080eeb3b776b5830cd623e0f7c21754966bbdd4434a4543d77

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