Skip to content
This repository was archived by the owner on Feb 26, 2025. It is now read-only.

Commit 227015c

Browse files
authored
Add simulated values to IV and FI plots for comparison with experimental data (#177)
* update IV and FI plots to include simulated values alongside experimental data for comparison * fix FI plot title * add a warning when trying to plot using absolute amplitudes
1 parent 609b136 commit 227015c

File tree

4 files changed

+306
-76
lines changed

4 files changed

+306
-76
lines changed

bluepyemodel/emodel_pipeline/emodel_settings.py

+8
Original file line numberDiff line numberDiff line change
@@ -456,6 +456,14 @@ def __init__(
456456
self.plot_IV_curves = plot_IV_curves
457457
self.plot_FI_curve_comparison = plot_FI_curve_comparison
458458
self.plot_traces_comparison = plot_traces_comparison
459+
if extract_absolute_amplitudes is True:
460+
if any((plot_IV_curves, plot_FI_curve_comparison)):
461+
logger.warning(
462+
"The 'plot_IV_curves' and 'plot_FI_curve_comparison' features do not "
463+
"support absolute current amplitude. These plots have been disabled."
464+
)
465+
self.plot_IV_curves = False
466+
self.plot_FI_curve_comparison = False
459467
if pickle_cells_extraction is False:
460468
if any((plot_IV_curves, plot_FI_curve_comparison, plot_traces_comparison)):
461469
logger.warning(

bluepyemodel/emodel_pipeline/plotting.py

+76-64
Original file line numberDiff line numberDiff line change
@@ -43,14 +43,18 @@
4343
from bluepyemodel.emodel_pipeline.plotting_utils import get_experimental_FI_curve_for_plotting
4444
from bluepyemodel.emodel_pipeline.plotting_utils import get_impedance
4545
from bluepyemodel.emodel_pipeline.plotting_utils import get_ordered_currentscape_keys
46+
from bluepyemodel.emodel_pipeline.plotting_utils import get_original_protocol_name
4647
from bluepyemodel.emodel_pipeline.plotting_utils import get_recording_names
4748
from bluepyemodel.emodel_pipeline.plotting_utils import get_simulated_FI_curve_for_plotting
4849
from bluepyemodel.emodel_pipeline.plotting_utils import get_sinespec_evaluator
4950
from bluepyemodel.emodel_pipeline.plotting_utils import get_title
5051
from bluepyemodel.emodel_pipeline.plotting_utils import get_traces_names_and_float_responses
5152
from bluepyemodel.emodel_pipeline.plotting_utils import get_traces_ylabel
5253
from bluepyemodel.emodel_pipeline.plotting_utils import get_voltage_currents_from_files
54+
from bluepyemodel.emodel_pipeline.plotting_utils import plot_fi_curves
5355
from bluepyemodel.emodel_pipeline.plotting_utils import rel_to_abs_amplitude
56+
from bluepyemodel.emodel_pipeline.plotting_utils import save_fig
57+
from bluepyemodel.emodel_pipeline.plotting_utils import update_evaluator
5458
from bluepyemodel.evaluation.evaluation import compute_responses
5559
from bluepyemodel.evaluation.evaluation import get_evaluator_from_access_point
5660
from bluepyemodel.evaluation.evaluator import PRE_PROTOCOLS
@@ -85,14 +89,6 @@
8589
}
8690

8791

88-
def save_fig(figures_dir, figure_name, dpi=100):
89-
"""Save a matplotlib figure"""
90-
p = Path(figures_dir) / figure_name
91-
plt.savefig(str(p), dpi=dpi, bbox_inches="tight")
92-
plt.close("all")
93-
plt.clf()
94-
95-
9692
def optimisation(
9793
optimiser,
9894
emodel,
@@ -1205,8 +1201,11 @@ def run_and_plot_EPSP(
12051201
def plot_IV_curves(
12061202
evaluator,
12071203
emodels,
1204+
access_point,
12081205
figures_dir,
12091206
efel_settings,
1207+
mapper,
1208+
seeds,
12101209
prot_name="iv",
12111210
custom_bluepyefe_cells_pklpath=None,
12121211
write_fig=True,
@@ -1218,23 +1217,40 @@ def plot_IV_curves(
12181217
Args:
12191218
evaluator (CellEvaluator): cell evaluator
12201219
emodels (list): list of EModels
1220+
access_point (DataAccessPoint): data access point
12211221
figures_dir (str or Path): output directory for the figure to be saved on
12221222
efel_settings (dict): eFEL settings in the form {setting_name: setting_value}.
1223+
mapper (map): used to parallelize the evaluation of the individual in the population.
1224+
seeds (list): if not None, filter emodels to keep only the ones with these seeds.
12231225
prot_name (str): Only recordings from this protocol will be used.
12241226
custom_bluepyefe_cells_pklpath (str): file path to the cells.pkl output of BluePyEfe.
12251227
If None, will use usual file path used in BluePyEfe,
12261228
so this is to be set only to use a file at an unexpected path.
12271229
write_fig (bool): whether to save the figure
12281230
n_bin (int): number of bins to use
12291231
"""
1230-
# pylint: disable=too-many-nested-blocks, possibly-used-before-assignment
1232+
# pylint: disable=too-many-nested-blocks, possibly-used-before-assignment, disable=too-many-locals, disable=too-many-statements
12311233
# note: should maybe also check location and recorded variable
12321234
make_dir(figures_dir)
12331235
if efel_settings is None:
12341236
efel_settings = bluepyefe.tools.DEFAULT_EFEL_SETTINGS.copy()
12351237

1238+
lower_bound = -100
1239+
upper_bound = 100
1240+
1241+
# Generate amplitude points
1242+
sim_amp_points = list(map(int, numpy.linspace(lower_bound, upper_bound, n_bin + 1)))
12361243
# add missing features (if any) to evaluator
1237-
updated_evaluator = fill_in_IV_curve_evaluator(evaluator, efel_settings, prot_name)
1244+
updated_evaluator = fill_in_IV_curve_evaluator(
1245+
evaluator, efel_settings, prot_name, sim_amp_points
1246+
)
1247+
1248+
emodels = compute_responses(
1249+
access_point,
1250+
updated_evaluator,
1251+
map_function=mapper,
1252+
seeds=seeds,
1253+
)
12381254

12391255
emodel_name = None
12401256
cells = None
@@ -1349,6 +1365,9 @@ def plot_IV_curves(
13491365
def plot_FI_curves_comparison(
13501366
evaluator,
13511367
emodels,
1368+
access_point,
1369+
seeds,
1370+
mapper,
13521371
figures_dir,
13531372
prot_name,
13541373
custom_bluepyefe_cells_pklpath=None,
@@ -1362,6 +1381,9 @@ def plot_FI_curves_comparison(
13621381
Args:
13631382
evaluator (CellEvaluator): cell evaluator
13641383
emodels (list): list of EModels
1384+
access_point (DataAccessPoint): data access point
1385+
seeds (list): if not None, filter emodels to keep only the ones with these seeds.
1386+
mapper (map): used to parallelize the evaluation of the individual in the population.
13651387
figures_dir (str or Path): output directory for the figure to be saved on
13661388
prot_name (str): name of the protocol to use for the FI curve
13671389
custom_bluepyefe_cells_pklpath (str): file path to the cells.pkl output of BluePyEfe.
@@ -1373,24 +1395,18 @@ def plot_FI_curves_comparison(
13731395
# pylint: disable=too-many-nested-blocks, possibly-used-before-assignment
13741396
make_dir(figures_dir)
13751397

1376-
emodel_name = None
1377-
cells = None
1398+
emodel_name, cells = None, None
1399+
updated_evaluator = copy.deepcopy(evaluator)
13781400
for emodel in emodels:
13791401
# do not re-extract data if the emodel is the same as previously
13801402
if custom_bluepyefe_cells_pklpath is not None:
13811403
if cells is None:
13821404
cells = read_extraction_output(custom_bluepyefe_cells_pklpath)
13831405
if cells is None:
13841406
continue
1407+
13851408
# experimental FI curve
1386-
(
1387-
expt_amp_rel,
1388-
expt_freq_rel,
1389-
expt_freq_rel_err,
1390-
expt_amp,
1391-
expt_freq_abs,
1392-
expt_freq_abs_err,
1393-
) = get_experimental_FI_curve_for_plotting(cells, prot_name, n_bin=n_bin)
1409+
expt_data = get_experimental_FI_curve_for_plotting(cells, prot_name, n_bin=n_bin)
13941410
elif emodel_name != emodel.emodel_metadata.emodel or cells is None:
13951411
# take extraction data from pickle file and rearange it for plotting
13961412
cells = read_extraction_output_cells(emodel.emodel_metadata.emodel)
@@ -1399,57 +1415,47 @@ def plot_FI_curves_comparison(
13991415
continue
14001416

14011417
# experimental FI curve
1402-
(
1403-
expt_amp_rel,
1404-
expt_freq_rel,
1405-
expt_freq_rel_err,
1406-
expt_amp,
1407-
expt_freq_abs,
1408-
expt_freq_abs_err,
1409-
) = get_experimental_FI_curve_for_plotting(cells, prot_name, n_bin=n_bin)
1418+
expt_data = get_experimental_FI_curve_for_plotting(cells, prot_name, n_bin=n_bin)
14101419

14111420
emodel_name = emodel.emodel_metadata.emodel
14121421

1413-
# simulated FI curve
1414-
simulated_amp_rel, simulated_amp, simulated_freq = get_simulated_FI_curve_for_plotting(
1415-
evaluator, emodel.responses, prot_name
1422+
expt_data_amp_rel = expt_data[0]
1423+
prot_name_original = get_original_protocol_name(prot_name, evaluator)
1424+
updated_evaluator = update_evaluator(
1425+
expt_data_amp_rel, prot_name_original, updated_evaluator
14161426
)
14171427

1418-
# plotting
1419-
_, ax = plt.subplots(nrows=1, ncols=2, figsize=(10, 3))
1420-
ax[0].errorbar(
1421-
expt_amp_rel,
1422-
expt_freq_rel,
1423-
yerr=expt_freq_rel_err,
1424-
marker="o",
1425-
color="grey",
1426-
label="experiment",
1427-
)
1428-
ax[0].set_xlabel("Amplitude (% of rheobase)")
1429-
ax[0].set_ylabel("Mean Frequency (Hz)")
1430-
ax[0].set_title("FI curve (relative amplitude)")
1431-
ax[0].plot(simulated_amp_rel, simulated_freq, "o", color="blue", label="model")
1428+
updated_evaluator.fitness_protocols["main_protocol"].execution_order = (
1429+
updated_evaluator.fitness_protocols["main_protocol"].compute_execution_order()
1430+
)
14321431

1433-
ax[1].errorbar(
1434-
expt_amp,
1435-
expt_freq_abs,
1436-
yerr=expt_freq_abs_err,
1437-
marker="o",
1438-
color="grey",
1439-
label="experiment",
1440-
)
1441-
ax[1].set_xlabel("Amplitude (nA)")
1442-
ax[1].set_ylabel("Voltage (mV)")
1443-
ax[1].set_title("IV curve (absolute amplitude)")
1444-
ax[1].plot(simulated_amp, simulated_freq, "o", color="blue", label="model")
1432+
emodels = compute_responses(access_point, updated_evaluator, mapper, seeds)
1433+
for emodel in emodels:
1434+
# do not re-extract data if the emodel is the same as previously
1435+
if custom_bluepyefe_cells_pklpath is not None:
1436+
if cells is None:
1437+
cells = read_extraction_output(custom_bluepyefe_cells_pklpath)
1438+
if cells is None:
1439+
continue
14451440

1446-
ax[0].legend()
1447-
ax[1].legend()
1448-
if write_fig:
1449-
save_fig(
1450-
figures_dir,
1451-
emodel.emodel_metadata.as_string(emodel.seed) + "__FI_curve_comparison.pdf",
1452-
)
1441+
# experimental FI curve
1442+
expt_data = get_experimental_FI_curve_for_plotting(cells, prot_name, n_bin=n_bin)
1443+
elif emodel_name != emodel.emodel_metadata.emodel or cells is None:
1444+
# take extraction data from pickle file and rearange it for plotting
1445+
cells = read_extraction_output_cells(emodel.emodel_metadata.emodel)
1446+
emodel_name = emodel.emodel_metadata.emodel
1447+
if cells is None:
1448+
continue
1449+
1450+
# experimental FI curve
1451+
expt_data = get_experimental_FI_curve_for_plotting(cells, prot_name, n_bin=n_bin)
1452+
1453+
emodel_name = emodel.emodel_metadata.emodel
1454+
1455+
sim_data = get_simulated_FI_curve_for_plotting(
1456+
updated_evaluator, emodel.responses, prot_name
1457+
)
1458+
plot_fi_curves(expt_data, sim_data, figures_dir, emodel, write_fig)
14531459

14541460

14551461
def phase_plot(
@@ -2046,10 +2052,13 @@ def plot_models(
20462052
plot_IV_curves(
20472053
cell_evaluator,
20482054
emodels,
2055+
access_point,
20492056
figures_dir_IV_curves,
20502057
# maybe we should give efel_settings as an argument of plot_models,
20512058
# like the other pipeline_settings
20522059
access_point.pipeline_settings.efel_settings,
2060+
mapper,
2061+
seeds,
20532062
IV_curve_prot_name,
20542063
custom_bluepyefe_cells_pklpath=custom_bluepyefe_cells_pklpath,
20552064
)
@@ -2059,6 +2068,9 @@ def plot_models(
20592068
plot_FI_curves_comparison(
20602069
cell_evaluator,
20612070
emodels,
2071+
access_point,
2072+
seeds,
2073+
mapper,
20622074
figures_dir_FI_curves,
20632075
FI_curve_prot_name,
20642076
custom_bluepyefe_cells_pklpath=custom_bluepyefe_cells_pklpath,

0 commit comments

Comments
 (0)