Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
Mark Chiew
pytreat-practicals-2020
Commits
6e5f1b9a
Commit
6e5f1b9a
authored
Mar 22, 2020
by
Mark Chiew
Browse files
Fixed weird bug w.r.t. ipynbs created in VS Code, switched ode to odeint
parent
d74a8c2c
Changes
2
Hide whitespace changes
Inline
Side-by-side
talks/matlab_vs_python/bloch/bloch.ipynb
View file @
6e5f1b9a
%% Cell type:markdown id: tags:
%% Cell type:markdown id: tags:
Imports
Imports
%% Cell type:code id: tags:
%% Cell type:code id: tags:
```
python
```
python
import
numpy
as
np
import
numpy
as
np
from
scipy.integrate
import
ode
from
scipy.integrate
import
ode
,
solve_ivp
import
matplotlib.pyplot
as
plt
import
matplotlib.pyplot
as
plt
```
```
%% Cell type:markdown id: tags:
%% Cell type:markdown id: tags:
# Define the Bloch equation
# Define the Bloch equation
$$
\f
rac{d
\v
ec{M}}{dt} =
\v
ec{M}
\t
imes
\v
ec{B} -
\f
rac{M_x + M_y}{T2} -
\f
rac{M_z - M_0}{T1}$$
$$
\f
rac{d
\v
ec{M}}{dt} =
\v
ec{M}
\t
imes
\v
ec{B} -
\f
rac{M_x + M_y}{T2} -
\f
rac{M_z - M_0}{T1}$$
In this section:
In this section:
-
define a function
-
define a function
-
numpy functions like np.cross
-
numpy functions like np.cross
%% Cell type:code id: tags:
%% Cell type:code id: tags:
```
python
```
python
# define bloch equation
# define bloch equation
def
bloch
_ode
(
t
,
M
,
T1
,
T2
):
def
bloch
(
t
,
M
,
T1
,
T2
):
# get effective B-field at time t
# get effective B-field at time t
B
=
B_eff
(
t
)
B
=
B_eff
(
t
)
# cross product of M and B, add T1 and T2 relaxation terms
# cross product of M and B, add T1 and T2 relaxation terms
return
np
.
array
([
M
[
1
]
*
B
[
2
]
-
M
[
2
]
*
B
[
1
]
-
M
[
0
]
/
T2
,
return
np
.
array
([
M
[
1
]
*
B
[
2
]
-
M
[
2
]
*
B
[
1
]
-
M
[
0
]
/
T2
,
M
[
2
]
*
B
[
0
]
-
M
[
0
]
*
B
[
2
]
-
M
[
1
]
/
T2
,
M
[
2
]
*
B
[
0
]
-
M
[
0
]
*
B
[
2
]
-
M
[
1
]
/
T2
,
M
[
0
]
*
B
[
1
]
-
M
[
1
]
*
B
[
0
]
-
(
M
[
2
]
-
1
)
/
T1
])
M
[
0
]
*
B
[
1
]
-
M
[
1
]
*
B
[
0
]
-
(
M
[
2
]
-
1
)
/
T1
])
# alternatively
# alternatively
#return np.cross(M,B) - np.array([M[0]/T2, M[1]/T2, (M[2]-1)/T1])
#return np.cross(M,B) - np.array([M[0]/T2, M[1]/T2, (M[2]-1)/T1])
```
```
%% Cell type:markdown id: tags:
%% Cell type:markdown id: tags:
# Define the pulse sequence
# Define the pulse sequence
We work in the rotating frame, so we only need the amplitude envelope of the RF pulse
We work in the rotating frame, so we only need the amplitude envelope of the RF pulse
Typically, B1 excitation fields point in the x- and/or y-directions
Typically, B1 excitation fields point in the x- and/or y-directions
Gradient fields point in the z-direction
Gradient fields point in the z-direction
In this simple example, a simple sinc-pulse excitation pulse is applied for 1 ms along the x-axis
In this simple example, a simple sinc-pulse excitation pulse is applied for 1 ms along the x-axis
then a gradient is turned on for 1.5 ms after that.
then a gradient is turned on for 1.5 ms after that.
In this section:
In this section:
-
constants such as np.pi
-
constants such as np.pi
-
functions like np.sinc
-
functions like np.sinc
%% Cell type:code id: tags:
%% Cell type:code id: tags:
```
python
```
python
# define effective B-field
# define effective B-field
def
B_eff
(
t
):
def
B_eff
(
t
):
# Do nothing for 0.25 ms
# Do nothing for 0.25 ms
if
t
<
0.25
:
if
t
<
0.25
:
return
np
.
array
([
0
,
0
,
0
])
return
np
.
array
([
0
,
0
,
0
])
# Sinc RF along x-axis and slice-select gradient on for 1.00 ms
# Sinc RF along x-axis and slice-select gradient on for 1.00 ms
elif
t
<
1.25
:
elif
t
<
1.25
:
return
np
.
array
([
np
.
pi
*
np
.
sinc
((
t
-
0.75
)
*
4
),
0
,
np
.
pi
])
return
np
.
array
([
np
.
pi
*
np
.
sinc
((
t
-
0.75
)
*
4
),
0
,
np
.
pi
])
# Do nothing for 0.25 ms
# Do nothing for 0.25 ms
elif
t
<
1.50
:
elif
t
<
1.50
:
return
np
.
array
([
0
,
0
,
0
])
return
np
.
array
([
0
,
0
,
0
])
# Slice refocusing gradient on for 1.50 ms
# Slice refocusing gradient on for 1.50 ms
# Half the area of the slice-select gradient lobe
# Half the area of the slice-select gradient lobe
elif
t
<
3.00
:
elif
t
<
3.00
:
return
np
.
array
([
0
,
0
,
-
(
1
/
3
)
*
np
.
pi
])
return
np
.
array
([
0
,
0
,
-
(
1
/
3
)
*
np
.
pi
])
# Pulse sequence finished
# Pulse sequence finished
else
:
else
:
return
np
.
array
([
0
,
0
,
0
])
return
np
.
array
([
0
,
0
,
0
])
```
```
%% Cell type:markdown id: tags:
%% Cell type:markdown id: tags:
# Plot the pulse sequence
# Plot the pulse sequence
In this section:
In this section:
-
unpacking return values
-
unpacking return values
-
unwanted return values
-
unwanted return values
-
list comprehension
-
list comprehension
-
basic plotting
-
basic plotting
%% Cell type:code id: tags:
%% Cell type:code id: tags:
```
python
```
python
# Create 2 vertical subplots
# Create 2 vertical subplots
_
,
ax
=
plt
.
subplots
(
2
,
1
,
figsize
=
(
12
,
12
))
_
,
ax
=
plt
.
subplots
(
2
,
1
,
figsize
=
(
12
,
12
))
# Get pulse sequence B-fields from 0 - 5 ms
# Get pulse sequence B-fields from 0 - 5 ms
pulseq
=
[
B_eff
(
t
)
for
t
in
np
.
linspace
(
0
,
5
,
1000
)]
pulseq
=
[
B_eff
(
t
)
for
t
in
np
.
linspace
(
0
,
5
,
1000
)]
pulseq
=
np
.
array
(
pulseq
)
pulseq
=
np
.
array
(
pulseq
)
# Plot RF
# Plot RF
ax
[
0
].
plot
(
pulseq
[:,
0
])
ax
[
0
].
plot
(
pulseq
[:,
0
])
ax
[
0
].
set_ylabel
(
'B1'
)
ax
[
0
].
set_ylabel
(
'B1'
)
# Plot gradient
# Plot gradient
ax
[
1
].
plot
(
pulseq
[:,
2
])
ax
[
1
].
plot
(
pulseq
[:,
2
])
ax
[
1
].
set_ylabel
(
'Gradient'
)
ax
[
1
].
set_ylabel
(
'Gradient'
)
```
```
%% Cell type:markdown id: tags:
%% Cell type:markdown id: tags:
# Integrate ODE
# Integrate ODE
This uses a Runge-Kutta variant called the "Dormand-Prince method"
This uses a Runge-Kutta variant called the "Dormand-Prince method"
by default. Other ode integration methods are available.
In this section:
In this section:
-
list of arrays
-
ode solvers
-
ode solvers
-
l
ist appending
-
l
ambdas (anonymous functions)
%% Cell type:code id: tags:
%% Cell type:code id: tags:
```
python
```
python
# Set the initial conditions
# Set the initial conditions
# time (t) = 0
# equilibrium magnetization (M) = (0, 0, 1)
# equilibrium magnetization (M) = (0, 0, 1)
t
=
[
0
]
M
=
[
0
,
0
,
1
]
M
=
[
np
.
array
([
0
,
0
,
1
])]
# Set
integrator time-step
# Set
time interval for integration
dt
=
0.005
t
=
[
0
,
5
]
# Set up ODE integrator object
# Set max step size
r
=
ode
(
bloch_ode
)
dt
=
0.005
# Choose the integrator method
r
.
set_integrator
(
'dopri5'
)
# Pass in initial values
r
.
set_initial_value
(
M
[
0
],
t
[
0
])
# Set T1 and T2
# Set T1 and T2
T1
,
T2
=
1500
,
50
T1
,
T2
=
1500
,
50
r
.
set_f_params
(
T1
,
T2
)
# Integrate by looping over time, moving dt by step size each iteration
# Integrate ODE
# Append new time point and Magnetisation vector at every step to t and M
# In Scipy 1.2.0, the first argument to solve_ivp must be a function that takes exactly 2 arguments
while
r
.
successful
()
and
r
.
t
<
5
:
sol
=
solve_ivp
(
lambda
t
,
M
:
bloch
(
t
,
M
,
T1
,
T2
),
t
,
M
,
max_step
=
dt
)
t
.
append
(
r
.
t
+
dt
)
M
.
append
(
r
.
integrate
(
t
[
-
1
]))
# Convert M to 2-D numpy array from list of arrays
# Grab output
M
=
np
.
array
(
M
)
t
=
sol
.
t
M
=
sol
.
y
```
```
%% Cell type:markdown id: tags:
%% Cell type:markdown id: tags:
# Plot Results
# Plot Results
In this section:
In this section:
-
more plotting
-
more plotting
%% Cell type:code id: tags:
%% Cell type:code id: tags:
```
python
```
python
# Create single axis
# Create single axis
_
,
ax
=
plt
.
subplots
(
figsize
=
(
12
,
12
))
_
,
ax
=
plt
.
subplots
(
figsize
=
(
12
,
12
))
# Plot x, y and z components of Magnetisation
# Plot x, y and z components of Magnetisation
ax
.
plot
(
t
,
M
[
:,
0
],
label
=
'Mx'
)
ax
.
plot
(
t
,
M
[
0
,:
],
label
=
'Mx'
)
ax
.
plot
(
t
,
M
[
:,
1
],
label
=
'My'
)
ax
.
plot
(
t
,
M
[
1
,:
],
label
=
'My'
)
ax
.
plot
(
t
,
M
[
:,
2
],
label
=
'Mz'
)
ax
.
plot
(
t
,
M
[
2
,:
],
label
=
'Mz'
)
# Add legend and grid
# Add legend and grid
ax
.
legend
()
ax
.
legend
()
ax
.
grid
()
ax
.
grid
()
```
```
...
...
talks/matlab_vs_python/partial_fourier/partial_fourier.ipynb
View file @
6e5f1b9a
...
@@ -2,9 +2,7 @@
...
@@ -2,9 +2,7 @@
"cells": [
"cells": [
{
{
"cell_type": "markdown",
"cell_type": "markdown",
"execution_count": null,
"metadata": {},
"metadata": {},
"outputs": [],
"source": [
"source": [
"Imports"
"Imports"
]
]
...
@@ -22,9 +20,7 @@
...
@@ -22,9 +20,7 @@
},
},
{
{
"cell_type": "markdown",
"cell_type": "markdown",
"execution_count": null,
"metadata": {},
"metadata": {},
"outputs": [],
"source": [
"source": [
"# Load data\n",
"# Load data\n",
"\n",
"\n",
...
@@ -57,9 +53,7 @@
...
@@ -57,9 +53,7 @@
},
},
{
{
"cell_type": "markdown",
"cell_type": "markdown",
"execution_count": null,
"metadata": {},
"metadata": {},
"outputs": [],
"source": [
"source": [
"# 6/8 Partial Fourier sampling\n",
"# 6/8 Partial Fourier sampling\n",
"\n",
"\n",
...
@@ -91,9 +85,7 @@
...
@@ -91,9 +85,7 @@
},
},
{
{
"cell_type": "markdown",
"cell_type": "markdown",
"execution_count": null,
"metadata": {},
"metadata": {},
"outputs": [],
"source": [
"source": [
"# Estimate phase\n",
"# Estimate phase\n",
"\n",
"\n",
...
@@ -130,9 +122,7 @@
...
@@ -130,9 +122,7 @@
},
},
{
{
"cell_type": "markdown",
"cell_type": "markdown",
"execution_count": null,
"metadata": {},
"metadata": {},
"outputs": [],
"source": [
"source": [
"# POCS reconstruction\n",
"# POCS reconstruction\n",
"\n",
"\n",
...
@@ -192,9 +182,7 @@
...
@@ -192,9 +182,7 @@
},
},
{
{
"cell_type": "markdown",
"cell_type": "markdown",
"execution_count": null,
"metadata": {},
"metadata": {},
"outputs": [],
"source": [
"source": [
"# Display error and plot reconstruction\n",
"# Display error and plot reconstruction\n",
"\n",
"\n",
...
@@ -252,9 +240,9 @@
...
@@ -252,9 +240,9 @@
"name": "python",
"name": "python",
"nbconvert_exporter": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"pygments_lexer": "ipython3",
"version": "3.7.3
-final
"
"version": "3.7.3"
}
}
},
},
"nbformat": 4,
"nbformat": 4,
"nbformat_minor": 4
"nbformat_minor": 4
}
}
\ No newline at end of file
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment