Skip to content

Commit d2fac97

Browse files
committed
add simplified MPRAGE model
1 parent 18a30de commit d2fac97

17 files changed

+287
-35
lines changed

docs/api.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,7 @@ Iterative
124124
:nosignatures:
125125

126126
torchsim.models.FSEModel
127+
torchsim.models.MPRAGEModel
127128
torchsim.models.MP2RAGEModel
128129
torchsim.models.MPnRAGEModel
129130
torchsim.models.MRFModel
@@ -150,6 +151,7 @@ Iterative
150151
:nosignatures:
151152

152153
torchsim.fse_sim
154+
torchsim.mprage_sim
153155
torchsim.mp2rage_sim
154156
torchsim.mpnrage_sim
155157
torchsim.mrf_sim

docs/sg_execution_times.rst

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
Computation times
88
=================
9-
**01:07.135** total execution time for 4 files **from all galleries**:
9+
**00:28.558** total execution time for 4 files **from all galleries**:
1010

1111
.. container::
1212

@@ -33,10 +33,10 @@ Computation times
3333
- Time
3434
- Mem (MB)
3535
* - :ref:`sphx_glr_generated_autoexamples_02-synth-data.py` (``../examples/02-synth-data.py``)
36-
- 00:42.438
36+
- 00:22.610
3737
- 0.0
3838
* - :ref:`sphx_glr_generated_autoexamples_03-fitting.py` (``../examples/03-fitting.py``)
39-
- 00:24.697
39+
- 00:05.949
4040
- 0.0
4141
* - :ref:`sphx_glr_generated_autoexamples_01-simple-simulator.py` (``../examples/01-simple-simulator.py``)
4242
- 00:00.000

examples/02-synth-data.py

Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -28,20 +28,15 @@
2828

2929
warnings.filterwarnings("ignore")
3030

31+
import os
3132
import torchio as tio
3233

33-
try:
34-
ixi_dataset = tio.datasets.IXI(
35-
"/home/mcencini/ixi/",
36-
modalities=("PD", "T1", "T2"),
37-
download=False,
38-
)
39-
except:
40-
ixi_dataset = tio.datasets.IXI(
41-
"$HOME/.ixi/",
42-
modalities=("PD", "T1", "T2"),
43-
download=True,
44-
)
34+
path = os.path.realpath("data")
35+
ixi_dataset = tio.datasets.IXI(
36+
path,
37+
modalities=("PD", "T2"),
38+
download=False,
39+
)
4540

4641
# get subject 0
4742
sample_subject = ixi_dataset[0]

examples/03-fitting.py

Lines changed: 7 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -25,23 +25,17 @@
2525

2626
warnings.filterwarnings("ignore")
2727

28+
import os
2829
import numpy as np
2930
import torchio as tio
3031
import torchsim
3132

32-
33-
try:
34-
ixi_dataset = tio.datasets.IXI(
35-
"/home/mcencini/ixi/",
36-
modalities=("PD", "T1", "T2"),
37-
download=False,
38-
)
39-
except:
40-
ixi_dataset = tio.datasets.IXI(
41-
"$HOME/.ixi/",
42-
modalities=("PD", "T1", "T2"),
43-
download=True,
44-
)
33+
path = os.path.realpath("data")
34+
ixi_dataset = tio.datasets.IXI(
35+
path,
36+
modalities=("PD", "T2"),
37+
download=False,
38+
)
4539

4640
# get subject 0
4741
sample_subject = ixi_dataset[0]
6.05 MB
Binary file not shown.

examples/data/PD/IXI002-Guys-0828-PD.nii.gz:Zone.Identifier

Whitespace-only changes.
5.66 MB
Binary file not shown.

examples/data/T2/IXI002-Guys-0828-T2.nii.gz:Zone.Identifier

Whitespace-only changes.

src/torchsim/_functional/__init__.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,11 @@
1717
__all__.append("mp2rage_sim")
1818

1919

20+
from ._mprage import mprage_sim # noqa
21+
22+
__all__.append("mprage_sim")
23+
24+
2025
from ._fse import fse_sim # noqa
2126

2227
__all__.append("fse_sim")
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
"""MPRAGE simulator."""
2+
3+
__all__ = ["mprage_sim"]
4+
5+
import numpy.typing as npt
6+
import torch
7+
8+
from ..models.mprage import MPRAGEModel
9+
10+
11+
def mprage_sim(
12+
TI: float,
13+
flip: float,
14+
TRspgr: float,
15+
nshots: int | npt.ArrayLike,
16+
T1: float | npt.ArrayLike,
17+
diff: str | tuple[str] = None,
18+
inv_efficiency: float | npt.ArrayLike = 1.0,
19+
M0: float | npt.ArrayLike = 1.0,
20+
chunk_size: int = None,
21+
device: str | torch.device = None,
22+
):
23+
"""
24+
MPRAGE simulator wrapper.
25+
26+
Parameters
27+
----------
28+
TI : float
29+
Inversion time (s) in milliseconds.
30+
flip : float | npt.ArrayLike
31+
Flip angle train in degrees of shape ``(2,)``.
32+
If scalar, assume same angle for both blocks.
33+
TRspgr : float
34+
Repetition time in milliseconds for each SPGR readout.
35+
nshots : int | npt.ArrayLike
36+
Number of SPGR readout within the inversion block of shape ``(npre, npost)``
37+
If scalar, assume ``npre == npost == 0.5 * nshots``. Usually, this
38+
is the number of slice encoding lines ``(nshots = nz / Rz)``,
39+
i.e., the number of slices divided by the total acceleration factor along ``z``.
40+
T1 : float | npt.ArrayLike
41+
Longitudinal relaxation time in milliseconds.
42+
diff : str | tuple[str], optional
43+
Arguments to get the signal derivative with respect to.
44+
The default is ``None`` (no differentation).
45+
inv_efficiency : float | npt.ArrayLike, optional
46+
Inversion efficiency map, default is ``1.0``.
47+
M0 : float or array-like, optional
48+
Proton density scaling factor, default is ``1.0``.
49+
TI : float | npt.ArrayLike, optional
50+
Inversion time in milliseconds.
51+
The default is ``0.0``.
52+
chunk_size : int, optional
53+
Number of atoms to be simulated in parallel.
54+
The default is ``None``.
55+
device : str | torch.device, optional
56+
Computational device for simulation.
57+
The default is ``None`` (infer from input).
58+
59+
Returns
60+
-------
61+
sig : npt.ArrayLike
62+
Signal evolution of shape ``(...,)``.
63+
jac : npt.ArrayLike
64+
Derivatives of signal wrt ``diff`` parameters,
65+
of shape ``(..., len(diff))``.
66+
Not returned if ``diff`` is ``None``.
67+
68+
"""
69+
model = MPRAGEModel(diff, chunk_size, device)
70+
model.set_properties(T1, M0, inv_efficiency)
71+
model.set_sequence(TI, flip, TRspgr, nshots)
72+
return model()

0 commit comments

Comments
 (0)