T1
, MTR
and MTsat
in-vivo¶
3 healthy participants were scanned with the following MTsat
protocol:
Click here to reveal the MTsat protocol.
Parameter (PDw/MTw/T1w) |
G1NATIVE |
S1NATIVE |
S2NATIVE |
VENUS |
---|---|---|---|---|
Sequence Name |
SPGR |
FLASH |
FLASH |
mt_sat v1.0 |
Flip Angle (°) |
6/6/20 |
6/6/20 |
6/6/20 |
6/6/20 |
TR (ms) |
32/32/18 |
32/32/18 |
32/32/18 |
32/32/18 |
TE (ms) |
4 |
4 |
4 |
4 |
FOV (cm) |
25.6 |
25.6 |
25.6 |
25.6 |
Acquisition Matrix |
256x256 |
256x256 |
256x256 |
256x256 |
Receiver BW (kHz) |
62.5 |
62.5 |
62.5 |
62.5 |
RF Phase Increment (°) |
115.4 |
50 |
50 |
117 |
MT Pulse |
off/on/off |
off/on/off |
off/on/off |
off/on/off |
MT Pulse Duration (ms) |
8 |
10 |
10 |
12 |
MT Pulse Shape |
Fermi |
Gaussian |
Gaussian |
Fermi |
MT Pulse Offset (Hz) |
1200 |
1200 |
1200 |
1200 |
The following code cell loads all the necessary Python packages, defines common functions and downloads the data to /tmp/VENUS
directory. If data already exists, the download will be skipped.
The number of data points per kernel-density estimations (KDE) were limited to 10k for faster visualization. Lower and upper limits of the distributions are set according to the original publication.
Tip
You can use the legend on the right to display a selection of KDEs. For example, double click on G1VENUS to single out vendor-neutral distributions acquired on the GE scanner.
At the top right corner of the plot background, you can switch the hover mode to
compare data on hover
to compare KDEs point by point.
import plotly.graph_objs as go
import plotly.express as px
from plotly import tools, subplots
import numpy as np
import pandas as pd
import ipywidgets as widgets
import math
from plotly.offline import download_plotlyjs, init_notebook_mode, plot, iplot
from ipywidgets import interact, interactive, fixed, interact_manual
from IPython.core.display import display, HTML
init_notebook_mode(connected=True)
import scipy.io as sio
import random
random.seed(123)
from plotly.subplots import make_subplots
from repo2data.repo2data import Repo2Data
import os
data_req_path = os.path.join("..", "binder", "data_requirement.json")
repo2data = Repo2Data(data_req_path)
data_path = repo2data.install()[0]
derivativesDir = os.path.join(data_path,"qMRFlow")
sessions = ['vendor750rev','vendorPRIrev','vendorSKYrev',
'rth750rev','rthPRIrev','rthSKYrev']
sides = ["negative","negative","negative","positive","positive","positive"]
pointpos = [0,0,-0.14,0.14,0,0]
convert_tag = {'rth750':'G1<sub>VENUS</sub>','rthPRI':'S1<sub>VENUS</sub>','rthSKY':'S2<sub>VENUS</sub>',
'vendor750':'G1<sub>NATIVE</sub>','vendorPRI':'S1<sub>NATIVE</sub>','vendorSKY':'S2<sub>NATIVE</sub>'}
colors = {'rth750':'rgba(255,8,30,1)','rthPRI':'rgba(255,117,0,1)','rthSKY':'rgba(255,220,0,1)',
'vendor750':'rgba(0,75,255,1)','vendorPRI':'rgba(24,231,234,1)','vendorSKY':'rgba(24,234,141,1)'}
colors_line = {'rth750':'rgba(255,8,30,0.35)','rthPRI':'rgba(255,117,0,0.35)','rthSKY':'rgba(255,220,0,0.35)',
'vendor750':'rgba(0,75,255,0.35)','vendorPRI':'rgba(24,231,234,0.35)','vendorSKY':'rgba(24,234,141,0.35)'}
def plot_ridgelines(subject,sessions,metric,region,colors,sides,sampN,leg,lowlim,uplim):
df = pd.DataFrame()
traces = []
for jj in range(0,len(sessions),1):
avg_array = []
std_array = []
cur_region = derivativesDir + '/sub-' + subject + '/ses-' + sessions[jj] + '/stat/sub-' + subject + '_ses-' + sessions[jj] + '_desc-' + region + '_metrics.mat'
cur_contents = sio.loadmat(cur_region)
cur_contents = cur_contents[metric]
cur_contents = np.delete(cur_contents, np.where(cur_contents < lowlim))
cur_contents = np.delete(cur_contents, np.where(cur_contents > uplim))
cur_tag = sessions[jj][0:-3]
cur_contents = random.sample(list(cur_contents),sampN)
traces.append(go.Violin(
x=cur_contents,
name = convert_tag[cur_tag],
marker=dict(
opacity = 0.7,
outliercolor='rgba(255, 255, 255, 0.6)',
line=dict(
outliercolor='rgba(219, 64, 82, 0.6)',
outlierwidth=2)),
line_color= colors[cur_tag],
legendgroup= convert_tag[cur_tag],
showlegend=leg,
side=sides[jj],
pointpos = pointpos[jj]))
return traces
def plot_mosaic(metric,axis_title,lowlim,uplim):
nSamp = 10000
traces1 = plot_ridgelines('invivo1',sessions,metric,'wm',colors,sides,nSamp,True,lowlim,uplim)
traces2 = plot_ridgelines('invivo1',sessions,metric,'gm',colors,sides,nSamp,False,lowlim,uplim)
traces3 = plot_ridgelines('invivo2',sessions,metric,'wm',colors,sides,nSamp,False,lowlim,uplim)
traces4 = plot_ridgelines('invivo2',sessions,metric,'gm',colors,sides,nSamp,False,lowlim,uplim)
traces5 = plot_ridgelines('invivo3',sessions,metric,'wm',colors,sides,nSamp,False,lowlim,uplim)
traces6 = plot_ridgelines('invivo3',sessions,metric,'gm',colors,sides,nSamp,False,lowlim,uplim)
fig = make_subplots(rows=3, cols=2,
subplot_titles=("P1 White Matter", "P1 Gray Matter", "P2 White Matter", "P2 Gray Matter", "P3 White Matter", "P3 Gray Matter"),
vertical_spacing = 0.08,
shared_xaxes=True)
for trace in traces1:
fig.add_trace(trace,row=1, col=1)
for trace in traces2:
fig.add_trace(trace,row=1, col=2)
for trace in traces3:
fig.add_trace(trace,row=2, col=1)
for trace in traces4:
fig.add_trace(trace,row=2, col=2)
for trace in traces5:
fig.add_trace(trace,row=3, col=1)
for trace in traces6:
fig.add_trace(trace,row=3, col=2)
axis_template = dict(linecolor = 'white',
showticklabels = True,
tickfont=dict(color="white",size=12),
gridcolor = 'rgba(255,255,255,0.2)')
fig.update_yaxes(axis_template,showgrid=False)
fig.update_traces(orientation='h')
fig.update_layout(paper_bgcolor = '#1c2a3d',plot_bgcolor = '#1c2a3d')
fig.update_traces(meanline=dict(visible=True,color="white",width=3),
points= 'outliers', # show all points
jitter=0.1,
width=3) # add some jitter on points for better visibility
#scalemode='count')
fig.update_xaxes(axis_template)
fig.update_layout(width=800,height=950,title=f"VENUS vs NATIVE in-vivo {metric} distributions for each participant (P)", title_font_color="white")
fig.update_annotations(font=dict(color="white", family = "Courier"))
for i in range(1,7):
fig['layout']['xaxis{}'.format(i)]['title']= axis_title
fig.for_each_xaxis(lambda axis: axis.title.update(font=dict(color = 'white', size=12,family="Courier"),standoff=0))
fig.update_layout(
legend=dict(
y = 0.5,
font=dict(
family="Courier",
size=16,
color="white")))
return fig
import warnings
warnings.filterwarnings('ignore')
---- repo2data starting ----
/Users/agah/opt/anaconda3/envs/jbnew/lib/python3.6/site-packages/repo2data
Config from file :
../binder/data_requirement.json
Destination:
/tmp/VENUS
Info : /tmp/VENUS already downloaded
VENUS vs NATIVE T1
distributions¶
Note
Reproduces Figure 5d-g from the article for the Participant-3.
The following KDEs agree well with the qualitative observations from the Fig. 1 above: Inter-vendor agreement (G1-vs-S1 and G1-vs-S2) of VENUS is superior to that of vendor-native T1 maps, both in the GM and WM.
fig = plot_mosaic('T1','T1 (s)',0.5,3)
fig.show()