In [1]:
import pandas as pd
import numpy as np
import scipy.stats as stats
import seaborn as sns
import matplotlib as mpl
import matplotlib.pyplot as plt
from pyabc import History
from pyabc.weighted_statistics import weighted_mean, weighted_median
from ionchannelABC.visualization import plot_variables
from ionchannelABC.utils import weighted_cv
In [2]:
h_nyg_r_original = History('sqlite:///results/nygren/isus/original/nygren_isus_rgate_original.db')
h_nyg_s_original = History('sqlite:///results/nygren/isus/original/nygren_isus_sgate_original.db')
In [3]:
h_nyg_r_unified = History('sqlite:///results/nygren/isus/unified/nygren_isus_rgate_unified.db')
In [4]:
df_nyg_r_original, w_nyg_r_original = h_nyg_r_original.get_distribution(m=0)
df_nyg_s_original, w_nyg_s_original = h_nyg_s_original.get_distribution(m=0)
In [5]:
df_nyg_r_unified, w_nyg_r_unified = h_nyg_r_unified.get_distribution(m=0)
In [6]:
h_cou_a_original = History('sqlite:///results/courtemanche/isus/original/courtemanche_isus_agate_original.db')
h_cou_i_original = History('sqlite:///results/courtemanche/isus/original/courtemanche_isus_igate_original.db')
In [7]:
h_cou_i_unified = History('sqlite:///results/courtemanche/isus/unified/courtemanche_isus_igate_unified.db')
In [8]:
df_cou_a_original, w_cou_a_original = h_cou_a_original.get_distribution(m=0)
df_cou_i_original, w_cou_i_original = h_cou_i_original.get_distribution(m=0)
In [9]:
df_cou_i_unified, w_cou_i_unified = h_cou_i_unified.get_distribution(m=0)
In [10]:
h_sta = History('sqlite:///results/standardised/isus/standardised_isus.db')
In [11]:
df_sta, w_sta = h_sta.get_distribution(m=0)
In [12]:
data = [['N',6,7],['C',13,7],['S',4,4]]
In [13]:
df = pd.DataFrame(data, columns = ['model', 'act', 'inact'])
In [14]:
df.inact = df.act+df.inact
In [15]:
sns.set(style="ticks")
sns.set_context('talk')
sns.set_color_codes("pastel")
mpl.rcParams['font.size'] = 14
mpl.rcParams['legend.fontsize'] = 14
f, ax = plt.subplots(figsize=(6,3))
sns.barplot(x="inact", y="model", hue="model", data=df,
palette="pastel", dodge=False)
#label="inact", color="b")
sns.set_color_codes("muted")
sns.barplot(x="act", y="model", hue="model", data=df,
palette="muted", dodge=False)
#label="act", color="r")
handles, labels = ax.get_legend_handles_labels()
order = []
ax.legend([handles[idx] for idx in order],[labels[idx] for idx in order],
ncol=2, loc="lower right", frameon=False)
ax.set(xlabel="number of gating parameters")
ax.xaxis.grid(True)
ax.set(ylabel="")
sns.despine(trim=True, left=True)
In [16]:
#f.savefig('figures/isus/param_num_compare.pdf')
Plot relative standard deviation (RSD) of parameter posteriors and gating functions for Nygren and Courtemanche using the original dataset and unified datasets.
Note: we use the term RSD instead of CV (coefficient of variation) to avoid confusion with conduction velocity.
In [17]:
rsd_nyg_r_original = weighted_cv(df_nyg_r_original, w_nyg_r_original, sample_size=len(df_nyg_r_original))
rsd_nyg_s_original = weighted_cv(df_nyg_s_original, w_nyg_s_original, sample_size=len(df_nyg_s_original))
rsd_nyg_original = pd.concat([rsd_nyg_r_original, rsd_nyg_s_original])
model = ['N',]*len(rsd_nyg_original)
data = ['ORIGINAL',]*len(rsd_nyg_original)
frame = {'model': model, 'data': data, 'RSD': rsd_nyg_original}
nyg_original = pd.DataFrame(frame)
In [18]:
rsd_nyg_r_unified = weighted_cv(df_nyg_r_unified, w_nyg_r_unified, sample_size=len(df_nyg_r_unified))
rsd_nyg_unified = pd.concat([rsd_nyg_r_unified, rsd_nyg_s_original])
model = ['N',]*len(rsd_nyg_unified)
data = ['UNIFIED',]*len(rsd_nyg_unified)
frame = {'model': model, 'data': data, 'RSD': rsd_nyg_unified}
nyg_unified = pd.DataFrame(frame)
In [19]:
rsd_cou_a_original = weighted_cv(df_cou_a_original, w_cou_a_original, sample_size=len(df_cou_a_original))
rsd_cou_i_original = weighted_cv(df_cou_i_original, w_cou_i_original, sample_size=len(df_cou_i_original))
rsd_cou_original = pd.concat([rsd_cou_a_original, rsd_cou_i_original])
model = ['C',]*len(rsd_cou_original)
data = ['ORIGINAL',]*len(rsd_cou_original)
frame = {'model': model, 'data': data, 'RSD': rsd_cou_original}
cou_original = pd.DataFrame(frame)
In [20]:
rsd_cou_i_unified = weighted_cv(df_cou_i_unified, w_cou_i_unified, sample_size=len(df_cou_i_unified))
rsd_cou_unified = pd.concat([rsd_cou_a_original, rsd_cou_i_unified])
model = ['C',]*len(rsd_cou_unified)
data = ['UNIFIED',]*len(rsd_cou_unified)
frame = {'model': model, 'data': data, 'RSD': rsd_cou_unified}
cou_unified = pd.DataFrame(frame)
In [21]:
rsd_compare = pd.concat([nyg_original, nyg_unified, cou_original, cou_unified], sort=False)
In [22]:
sns.set(style="ticks")
sns.set_context("poster")
# Initialize the figure
f, ax = plt.subplots(figsize=(4, 6))
# Plot the boxplot summary of RSD
sns.boxplot(x="model", y="RSD", hue="data", data=rsd_compare,
palette="pastel", whis="range")
# Add in points to show each observation
sns.swarmplot(x="model", y="RSD", hue="data", data=rsd_compare,
linewidth=0.5, size=8, dodge=True)
# Tweak the visual presentation
ax.yaxis.grid(True)
ax.set(ylabel="RSD")
ax.set_yscale('log')
ax.set(xlabel="")
sns.despine(trim=True, bottom=True)
ax.get_legend().remove()
In [23]:
#f.savefig('figures/isus/rsd_compare.pdf')
In [24]:
N = 100
In [25]:
nyg_par_samples_r_original = df_nyg_r_original.sample(n=N, weights=w_nyg_r_original, replace=True)
nyg_par_samples_r_original = nyg_par_samples_r_original.set_index([pd.Index(range(N))])
nyg_par_samples_s_original = df_nyg_s_original.sample(n=N, weights=w_nyg_s_original, replace=True)
nyg_par_samples_s_original = nyg_par_samples_s_original.set_index([pd.Index(range(N))])
nyg_par_samples_original = (pd.concat([nyg_par_samples_r_original,
nyg_par_samples_s_original],axis=1)
.to_dict(orient='records'))
In [26]:
nyg_par_samples_r_unified = df_nyg_r_unified.sample(n=N, weights=w_nyg_r_unified, replace=True)
nyg_par_samples_r_unified = nyg_par_samples_r_unified.set_index([pd.Index(range(N))])
nyg_par_samples_unified = (pd.concat([nyg_par_samples_r_unified,
nyg_par_samples_s_original],axis=1)
.to_dict(orient='records'))
In [27]:
v = np.arange(-100, 50, 0.5)
nyg_par_map = {'ri': 'isus.r_inf',
'rt': 'isus.tau_r',
'si': 'isus.s_inf',
'st': 'isus.tau_s'}
In [28]:
from ionchannelABC.visualization import plot_variables
sns.set_context('poster')
sns.set_palette('deep')
mpl.rcParams['font.size'] = 14
mpl.rcParams['legend.fontsize'] = 14
f, ax = plot_variables(v, [nyg_par_map, nyg_par_map],
['models/nygren_isus.mmt', 'models/nygren_isus_.mmt'],
[nyg_par_samples_original, nyg_par_samples_unified],
original=[True,False],
figshape=(2,2))
ax[0][0].set_ylabel(r'$a$')
ax[1][0].set_ylabel(r'$i$')
ax[0][0].set_title(r'$\bar{x}$')
ax[0][1].set_title(r'$\tau_x$ (ms)')
for a in ax[:,1].flatten():
a.set_ylabel('')
for a in ax[1][:]:
a.set_xlabel('voltage (mV)')
for a in ax[:,0]:
a.set_ylim((-0.05, 1.05))
plt.tight_layout()
In [29]:
#f.savefig('figures/isus/nyg_gating_functions.pdf')
In [30]:
cou_par_samples_a_original = df_cou_a_original.sample(n=N, weights=w_cou_a_original, replace=True)
cou_par_samples_a_original = cou_par_samples_a_original.set_index([pd.Index(range(N))])
cou_par_samples_i_original = df_cou_i_original.sample(n=N, weights=w_cou_i_original, replace=True)
cou_par_samples_i_original = cou_par_samples_i_original.set_index([pd.Index(range(N))])
cou_par_samples_original = pd.concat([cou_par_samples_a_original, cou_par_samples_i_original],axis=1).to_dict(orient='records')
In [31]:
cou_par_samples_i = df_cou_i_unified.sample(n=N, weights=w_cou_i_unified, replace=True)
cou_par_samples_i = cou_par_samples_i.set_index([pd.Index(range(N))])
cou_par_samples_unified = pd.concat([cou_par_samples_a_original, cou_par_samples_i],axis=1).to_dict(orient='records')
In [32]:
cou_par_map = {'ri': 'isus.a_inf',
'rt': 'isus.tau_a',
'si': 'isus.i_inf',
'st': 'isus.tau_i'}
In [33]:
from ionchannelABC.visualization import plot_variables
sns.set_context('poster')
sns.set_palette('deep')
mpl.rcParams['font.size'] = 14
mpl.rcParams['legend.fontsize'] = 14
f, ax = plot_variables(v, [cou_par_map, cou_par_map],
['models/courtemanche_isus.mmt', 'models/courtemanche_isus_.mmt'],
[cou_par_samples_original, cou_par_samples_unified],
original=[True,False],
figshape=(2,2))
ax[0][0].set_ylabel(r'$a$')
ax[1][0].set_ylabel(r'$i$')
ax[0][0].set_title(r'$\bar{x}$')
ax[0][1].set_title(r'$\tau_x$ (ms)')
for a in ax[:,1].flatten():
a.set_ylabel('')
for a in ax[1][:]:
a.set_xlabel('voltage (mV)')
for a in ax[:,0]:
a.set_ylim((-0.05, 1.05))
ax[1,1].set_ylim((-0.05*25000, 1.05*25000))
plt.tight_layout()
In [34]:
#f.savefig('figures/isus/cou_gating_functions.pdf')
In [35]:
rsd_sta = weighted_cv(df_sta, w_sta, sample_size=len(df_sta))
model = ['S',]*len(rsd_sta)
frame = {'model': model, 'RSD': rsd_sta}
sta = pd.DataFrame(frame)
In [36]:
rsd_unified = pd.concat([nyg_unified, cou_unified, sta], sort=False)
In [37]:
sns.set(style="ticks")
sns.set_context('talk')
# Initialize the figure
f, ax = plt.subplots(figsize=(6, 3))
sns.boxplot(x="RSD", y="model", data=rsd_unified,
palette="pastel", whis="range")
# Add in points to show each observation
sns.swarmplot(x="RSD", y="model", data=rsd_unified,
linewidth=0.5, size=8, dodge=True)
# Tweak the visual presentation
ax.xaxis.grid(True)
ax.set(xlabel="RSD")
ax.set_xscale("log")
ax.set(ylabel="")
sns.despine(trim=True, left=True)
In [38]:
#f.savefig('figures/isus/rsd_compare_unified.pdf')
In [39]:
stats.mannwhitneyu(rsd_unified[rsd_unified.model=='N'].RSD,
rsd_unified[rsd_unified.model=='S'].RSD)
Out[39]:
In [40]:
stats.mannwhitneyu(rsd_unified[rsd_unified.model=='C'].RSD,
rsd_unified[rsd_unified.model=='S'].RSD)
Out[40]:
In [41]:
stats.mannwhitneyu(rsd_unified[rsd_unified.model=='N'].RSD,
rsd_unified[rsd_unified.model=='C'].RSD)
Out[41]:
In [42]:
N = 100
In [43]:
eps_nyg_r = h_nyg_r_unified.get_weighted_distances()
eps_nyg_s = h_nyg_s_original.get_weighted_distances()
In [44]:
eps_nyg = np.array([])
eps_nyg = (np.array(eps_nyg_r.sample(n=100,axis=0,weights=eps_nyg_r.w,replace=True).distance) +
np.array(eps_nyg_s.sample(n=100,axis=0,weights=eps_nyg_s.w,replace=True).distance))
eps_nyg = pd.DataFrame({'model': 'N', 'eps': eps_nyg, 'exp': 'all'})
In [45]:
eps_cou_a = h_cou_a_original.get_weighted_distances()
eps_cou_i = h_cou_i_unified.get_weighted_distances()
eps_cou = np.array([])
eps_cou = (np.array(eps_cou_a.sample(n=100,axis=0,weights=eps_cou_a.w,replace=True).distance) +
np.array(eps_cou_i.sample(n=100,axis=0,weights=eps_cou_i.w,replace=True).distance))
eps_cou = pd.DataFrame({'model': 'C', 'eps': eps_cou, 'exp': 'all'})
In [46]:
eps_sta = h_sta.get_weighted_distances()
eps_sta = eps_sta.sample(n=100,axis=0,weights=eps_sta.w,replace=True).distance
eps_sta = pd.DataFrame({'model': 'S', 'eps': eps_sta, 'exp': 'all'})
In [47]:
eps = pd.concat([eps_nyg,eps_cou,eps_sta])
In [48]:
eps['normalised'] = (eps['eps']-eps['eps'].min())/(eps['eps'].max()-eps['eps'].min())
In [49]:
sns.set_context("talk")
sns.set_style("whitegrid")
mpl.rcParams["font.size"] = 14
mpl.rcParams["legend.fontsize"] = 14
f, ax = plt.subplots(figsize=(2, 3))
sns.despine(bottom=True, left=True)
sns.stripplot(x='exp', y='normalised', hue='model', data=eps,
dodge=True, jitter=True, alpha=.25, zorder=1,
palette='deep', ax=ax)
sns.pointplot(x="exp", y="normalised", hue="model",
data=eps,
estimator=np.median,
dodge=.532, join=False, palette="dark",
markers="d", scale=.75, ci=None)
ax.get_legend().remove()
ax.set_xlabel('experiment number')
ax.set_ylabel('normalised residual')
Out[49]:
In [50]:
#f.savefig('figures/isus/eps_all_stripplot.pdf')
In [51]:
sns.set_context('talk')
sns.set_style("ticks")
mpl.rcParams['font.size'] = 14
mpl.rcParams['legend.fontsize'] = 14
f, ax = plt.subplots(figsize=(6,3))
sns.barplot(x="eps", y="model", data=eps, palette='pastel')
ax.xaxis.grid(True)
ax.set(ylabel="")
ax.set(xlabel="converged residual")
sns.despine(trim=True, left=True)
In [52]:
#f.savefig('figures/isus/eps_all_barplot.pdf')
Below we sample from the posterior particle populations and run the calibration experiments to be able to calculate a per-experiment epsilon value.
In [53]:
N = 100
nyg_par_samples_r = df_nyg_r_unified.sample(n=N, weights=w_nyg_r_unified, replace=True)
nyg_par_samples_r = nyg_par_samples_r.set_index([pd.Index(range(N))])
nyg_par_samples_r = nyg_par_samples_r.to_dict(orient='records')
nyg_par_samples_s = df_nyg_s_original.sample(n=N, weights=w_nyg_s_original, replace=True)
nyg_par_samples_s = nyg_par_samples_s.set_index([pd.Index(range(N))])
nyg_par_samples_s = nyg_par_samples_s.to_dict(orient='records')
cou_par_samples_a = df_cou_a_original.sample(n=N, weights=w_cou_a_original, replace=True)
cou_par_samples_a = cou_par_samples_a.set_index([pd.Index(range(N))])
cou_par_samples_a = cou_par_samples_a.to_dict(orient='records')
cou_par_samples_i = df_cou_i_unified.sample(n=N, weights=w_cou_i_unified, replace=True)
cou_par_samples_i = cou_par_samples_i.set_index([pd.Index(range(N))])
cou_par_samples_i = cou_par_samples_i.to_dict(orient='records')
std_par_samples = df_sta.sample(n=N, weights=w_sta, replace=True)
std_par_samples = std_par_samples.set_index([pd.Index(range(N))])
std_par_samples = std_par_samples.to_dict(orient='records')
In [54]:
from ionchannelABC.experiment import setup
from ionchannelABC.distance import IonChannelDistance
In [58]:
from experiments.isus_wang import (wang_act,
wang_act_kin,
wang_inact)
from experiments.isus_courtemanche import (courtemanche_inact_kin,
courtemanche_deact)
from experiments.isus_firek import (firek_inact)
from experiments.isus_nygren import (nygren_inact_kin,
nygren_rec)
experiments = [wang_act,
wang_act_kin,
courtemanche_deact,
firek_inact,
nygren_inact_kin,
nygren_rec]
models = ['models/nygren_isus_temp_adj.mmt',
'models/courtemanche_isus_temp_adj.mmt',
'models/standardised_isus.mmt']
par_samples = [[nyg_par_samples_r,nyg_par_samples_s], [cou_par_samples_a,cou_par_samples_i], std_par_samples]
names = ['N','C','S']
In [59]:
def experiment_dist(par_samples, modelfile, experiment):
eps = []
observ, model, sum_stats = setup(modelfile,
experiment)
obs = observ.to_dict()['y']
obs = {str(k): v for k, v in obs.items()}
dist = IonChannelDistance(exp_id=list(observ.exp_id),
variance=list(observ.variance),
delta=0.05)
for sample in par_samples:
eps.append(dist(sum_stats(model(sample)), obs, None))
return eps
The below cell calculates the per-experiment distance and may take some time to run depending on number of samples.
In [60]:
df = pd.DataFrame({})
mask = [[0, 0, 0, 1, 1, 1], [0, 0, 0, 1, 1, 1], None]
for j, exp in enumerate(experiments):
df_ = pd.DataFrame({})
for i, m in enumerate(models):
if mask[i] is not None:
eps = np.array(
experiment_dist(par_samples[i][mask[i][j]],
m,
exp)
)
else:
eps = np.array(
experiment_dist(par_samples[i],
m,
exp)
)
df_ = df_.append(pd.DataFrame({'model': names[i],
'exp': str(j),
'eps': eps[~np.isinf(eps)]}))
eps_max = df_['eps'].max()
eps_min = df_['eps'].min()
df_['eps'] = (df_['eps'] - eps_min)/(eps_max-eps_min)
df = df.append(df_)
In [61]:
sns.set_context('talk')
sns.set_style('whitegrid')
mpl.rcParams['font.size'] = 14
mpl.rcParams['legend.fontsize'] = 14
fig, ax = plt.subplots(figsize=(12, 3))
sns.despine(bottom=True, left=True)
sns.stripplot(x='exp', y='eps', hue='model', data=df,
dodge=True, jitter=True, alpha=.25, zorder=1,
palette='deep', ax=ax)
sns.pointplot(x="exp", y="eps", hue="model",
data=df,
estimator=np.median,
dodge=.532, join=False, palette="dark",
markers="d", scale=.75, ci=None)
handles, labels = ax.get_legend_handles_labels()
ax.legend(handles[3:], labels[3:], title="model",
handletextpad=0, columnspacing=1,
loc="best", ncol=3, frameon=True)
ax.set_xlabel('experiment number')
ax.set_ylabel('normalised residual')
Out[61]:
In [62]:
#fig.savefig('figures/isus/eps_per_exp_stripplot.pdf')
In [63]:
from ionchannelABC.visualization import plot_sim_results
In [64]:
from experiments.isus_wang import (wang_act_and_kin,
wang_inact)
from experiments.isus_courtemanche import (courtemanche_inact_kin,
courtemanche_deact)
from experiments.isus_firek import (firek_inact)
from experiments.isus_nygren import (nygren_inact_kin,
nygren_rec)
In [67]:
sns.set(style="ticks")
sns.set_context('talk')
mpl.rcParams['font.size'] = 14
mpl.rcParams['legend.fontsize'] = 14
g = plot_sim_results(['models/nygren_isus.mmt',
'models/nygren_isus.mmt',
'models/courtemanche_isus.mmt',
'models/courtemanche_isus.mmt',
'models/standardised_isus.mmt'],
wang_act_and_kin,
courtemanche_deact,
firek_inact,
nygren_inact_kin,
nygren_rec,
temp_match_model = 4,
masks=[[(0,1),2]+[None,]*3,
[None,]*2+[3,4,5],
[(0,1),2]+[None,]*3,
[None,]*2+[3,4,5],
None],
df=[df_nyg_r_unified,
df_nyg_s_original,
df_cou_a_original,
df_cou_i_unified,
df_sta],
w=[w_nyg_r_unified,
w_nyg_s_original,
w_cou_a_original,
w_cou_i_unified,
w_sta])
ylabels = ["steady-state activation", "activation τ (ms)", "deactivation τ (ms)", "steady-state inactivation",
"inactivation τ (ms)", "recovery τ (ms)"]
for ax in g.axes.flatten():
ax.set_xlabel("voltage (mV)")
for ax, yl in zip(g.axes.flatten(), ylabels):
ax.set_ylabel(yl)
for ax in g.axes.flatten():
ax.set_title("")
plt.tight_layout()
In [72]:
#g.savefig('figures/isus/compare_summary_statistics.pdf')
In [73]:
nyg = 'models/nygren_isus_temp_adj.mmt'
cou ='models/courtemanche_isus_temp_adj.mmt'
std = 'models/standardised_isus.mmt'
In [74]:
v = np.arange(-80, 50, 0.5)
In [75]:
std_par_map = {'ri': 'isus.r_ss',
'si': 'isus.s_ss',
'rt': 'isus.tau_r',
'st': 'isus.tau_s'}
In [76]:
N = 100
nyg_par_samples_r = df_nyg_r_unified.sample(n=N, weights=w_nyg_r_unified, replace=True)
nyg_par_samples_r = nyg_par_samples_r.set_index([pd.Index(range(N))])
nyg_par_samples_s = df_nyg_s_original.sample(n=N, weights=w_nyg_s_original, replace=True)
nyg_par_samples_s = nyg_par_samples_s.set_index([pd.Index(range(N))])
nyg_par_samples = (pd.concat([nyg_par_samples_r,
nyg_par_samples_s],axis=1).to_dict(orient='records'))
cou_par_samples_a = df_cou_a_original.sample(n=N, weights=w_cou_a_original, replace=True)
cou_par_samples_a = cou_par_samples_a.set_index([pd.Index(range(N))])
cou_par_samples_i = df_cou_i_unified.sample(n=N, weights=w_cou_i_unified, replace=True)
cou_par_samples_i = cou_par_samples_i.set_index([pd.Index(range(N))])
cou_par_samples = pd.concat([cou_par_samples_a,cou_par_samples_i],axis=1).to_dict(orient='records')
std_par_samples = df_sta.sample(n=N, weights=w_sta, replace=True)
std_par_samples = std_par_samples.set_index([pd.Index(range(N))])
std_par_samples = std_par_samples.to_dict(orient='records')
In [78]:
sns.set(style='ticks')
sns.set_context('poster')
mpl.rcParams['font.size'] = 14
mpl.rcParams['legend.fontsize'] = 14
f, ax = plot_variables(v, [nyg_par_map, cou_par_map, std_par_map],
[nyg, cou, std],
[nyg_par_samples, cou_par_samples, std_par_samples],
original=[True, True, False],
figshape=(2,2))
ax[0][0].set_title('steady state')
ax[0][1].set_title('time constant (ms)')
ax[0][0].set_ylabel('Activation')
ax[1][0].set_ylabel('Inactivation')
for a in ax[:,0]:
a.set_ylim((-0.05, 1.05))
for a in ax[:,1]:
a.set_ylabel('')
for a in ax[1,:]:
a.set_xlabel('voltage (mV)')
ax[1][1].set_ylim([-0.05*100+200, 1.05*100+200])
for a in ax.flatten():
x0,x1 = a.get_xlim()
y0,y1 = a.get_ylim()
a.set_aspect(abs(x1-x0)/abs(y1-y0))
plt.tight_layout()
In [79]:
#f.savefig('figures/isus/compare_gating_functions.pdf')
In [80]:
import myokit
In [81]:
nsteps = 100
period = 10000
tstep = 1000
vhold = -50
vstep = -10
pulsetrain = myokit.pacing.steptrain([vstep,]*nsteps,
vhold,
period-tstep,
tstep)
In [82]:
# nygren_ina_full has had tau values adjusted for temperature to 310K
models = [myokit.load_model(modelfile) for modelfile in ['models/nygren_isus_temp_adj.mmt',
'models/courtemanche_isus_temp_adj.mmt',
'models/standardised_isus.mmt']]
for m in models:
pace = m.get('membrane.V')
if pace.binding() != 'pace':
if pace.is_state():
pace.demote()
pace.set_rhs(0)
pace.set_binding('pace')
In [83]:
sims = [myokit.Simulation(m, pulsetrain) for m in models]
In [84]:
par_samples = [nyg_par_samples, cou_par_samples, std_par_samples]
In [85]:
import time
all_samples = pd.DataFrame({})
for i, s in enumerate(sims):
s.reset()
# store original
if models[i].name() != 'STA':
datalog = s.run(pulsetrain.characteristic_time(),
log=['isus.g','engine.time','membrane.V'],
log_interval=1)
datalog = datalog.trim((nsteps)*period-tstep-20, (nsteps)*period, adjust=True)
df = {'time': datalog['engine.time'],
'gate': datalog.npview()['isus.g']/max(datalog['isus.g']),
'sample': 0,
'model': models[i].name(),
'type': 'original'}
df = pd.DataFrame(df)
all_samples = all_samples.append(df, ignore_index=True)
# re-calibrated
for j, par_sample in enumerate(par_samples[i]):
s.reset()
for p, v in par_sample.items():
name = p
value = v
if p.startswith("log"):
name = p[4:]
value = 10**v
s.set_constant(name, value)
# Log run time for comparisons
t0 = time.time()
datalog = s.run(pulsetrain.characteristic_time(),
log=['isus.g','engine.time','membrane.V'],
log_interval=1)
t1 = time.time()
dt = t1-t0
datalog = datalog.trim((nsteps)*period-tstep-20, (nsteps)*period, adjust=True)
df = {'time': datalog['engine.time'],
'gate': datalog.npview()['isus.g']/max(datalog['isus.g']),
'sample': j,
'model': models[i].name(),
'type': 'recalibrated',
'runtime': dt}
df = pd.DataFrame(df)
all_samples = all_samples.append(df, ignore_index=True)
In [87]:
recalibrated_df = all_samples[all_samples['type']=='recalibrated']
In [88]:
sns.set(style="ticks")
sns.set_context('talk')
# Initialize the figure
f, ax = plt.subplots(figsize=(6, 3))
sns.boxplot(x='runtime', y='model', data=recalibrated_df,
palette="pastel", whis="range")
# Tweak the visual presentation
ax.xaxis.grid(True)
ax.set(ylabel="")
ax.set(xlabel="time (ms)")
sns.despine(left=True)
In [89]:
#f.savefig('figures/isus/runtime_compare.pdf')
In [90]:
all_samples_detail = all_samples[(all_samples['time']>=19) & (all_samples['time'] < 50)]
In [91]:
sns.set_context('talk')
mpl.rcParams['font.size'] = 14
mpl.rcParams['legend.fontsize'] = 14
f, ax = plt.subplots(figsize=(8,4))
g = sns.lineplot(x='time', y='gate', hue='model', style='type',
dashes = [(1,1),''],
data=all_samples, ax=ax,
legend=False)
ax2 = plt.axes([.6, .4, .2, .4])
sns.lineplot(x='time',y='gate',hue='model',style='type',
dashes=[(1,1),''],
data=all_samples_detail, ax=ax2,
legend=False)
ax2.set_xlabel('')
ax2.set_ylabel('')
ax.set_ylabel('normalised gate')
ax.set_title('')
Out[91]:
In [92]:
#f.savefig('figures/isus/trace_compare.pdf')
In [ ]: