Skip to content

Commit

Permalink
Merge pull request #163 from BlueBrain/iv-curve-plot
Browse files Browse the repository at this point in the history
New plotting functions
  • Loading branch information
AurelienJaquier authored Aug 13, 2024
2 parents fd3dc5a + 9771ee2 commit 8387c4d
Show file tree
Hide file tree
Showing 22 changed files with 2,091 additions and 377 deletions.
49 changes: 48 additions & 1 deletion bluepyemodel/efeatures_extraction/efeatures_extraction.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

import logging
import pathlib
import pickle
from importlib.machinery import SourceFileLoader

import bluepyefe.extract
Expand All @@ -29,6 +30,52 @@
logger = logging.getLogger(__name__)


def get_extraction_output_directory(emodel):
"""Get output directory for extraction figures.
Args:
emodel (str): emodel name as in emodel_metadata.emodel
"""
return pathlib.Path(f"./figures/{emodel}/efeatures_extraction/")


def read_extraction_output(filepath):
"""Returns output of extraction if present. Can return cells or protocols file.
Args:
filename (str or Path): path to extraction pickle file
"""
filepath = pathlib.Path(filepath)
if not filepath.is_file():
logger.warning("Could not find experimental output file at %s.", filepath)
return None
with open(filepath, "rb") as f:
cells = pickle.load(f)
return cells


def read_extraction_output_cells(emodel):
"""Returns cells output of extraction if present.
Args:
emodel (str): emodel name as in emodel_metadata.emodel
"""
filepath = bluepyefe.extract.cells_pickle_output_path(get_extraction_output_directory(emodel))
return read_extraction_output(filepath)


def read_extraction_output_protocols(emodel):
"""Returns protocols output of extraction if present.
Args:
emodel (str): emodel name as in emodel_metadata.emodel
"""
filepath = bluepyefe.extract.protocols_pickle_output_path(
get_extraction_output_directory(emodel)
)
return read_extraction_output(filepath)


def interpolate_RMP(fitness_calculator_configuration):
"""If we do not have recordings with no holding, we need to estimate the RMP as:
RMP = V_hold - R_in*I_Hold
Expand Down Expand Up @@ -179,7 +226,7 @@ def extract_save_features_protocols(access_point, mapper=map):

threshold_nvalue_save = access_point.pipeline_settings.extraction_threshold_value_save
plot = access_point.pipeline_settings.plot_extraction
output_directory = f"./figures/{access_point.emodel_metadata.emodel}/efeatures_extraction/"
output_directory = get_extraction_output_directory(access_point.emodel_metadata.emodel)

efeatures, stimuli, current = bluepyefe.extract.extract_efeatures(
output_directory=output_directory,
Expand Down
24 changes: 18 additions & 6 deletions bluepyemodel/emodel_pipeline/emodel_pipeline.py
Original file line number Diff line number Diff line change
Expand Up @@ -255,11 +255,12 @@ def plot(self, only_validated=False, load_from_local=False):
instead of recomputing them. Responses are automatically saved locally when
plotting currentscapes.
"""
pp_settings = self.access_point.pipeline_settings

cell_evaluator = get_evaluator_from_access_point(
self.access_point,
include_validation_protocols=True,
record_ions_and_currents=self.access_point.pipeline_settings.plot_currentscape,
record_ions_and_currents=pp_settings.plot_currentscape,
)

chkp_paths = glob.glob("./checkpoints/**/*.pkl", recursive=True)
Expand All @@ -282,7 +283,7 @@ def plot(self, only_validated=False, load_from_local=False):
seed = int(stem.rsplit("seed=", maxsplit=1)[-1])

plotting.optimisation(
optimiser=self.access_point.pipeline_settings.optimiser,
optimiser=pp_settings.optimiser,
emodel=self.access_point.emodel_metadata.emodel,
iteration=self.access_point.emodel_metadata.iteration,
seed=seed,
Expand All @@ -292,7 +293,7 @@ def plot(self, only_validated=False, load_from_local=False):
/ "optimisation",
)

if self.access_point.pipeline_settings.plot_parameter_evolution:
if pp_settings.plot_parameter_evolution:
plotting.evolution_parameters_density(
evaluator=cell_evaluator,
checkpoint_paths=checkpoint_paths,
Expand All @@ -311,12 +312,23 @@ def plot(self, only_validated=False, load_from_local=False):
plot_scores=True,
plot_traces=True,
plot_thumbnail=True,
plot_currentscape=self.access_point.pipeline_settings.plot_currentscape,
plot_bAP_EPSP=self.access_point.pipeline_settings.plot_bAP_EPSP,
plot_currentscape=pp_settings.plot_currentscape,
plot_dendritic_ISI_CV=True,
plot_dendritic_rheobase=True,
plot_bAP_EPSP=pp_settings.plot_bAP_EPSP,
plot_IV_curve=pp_settings.plot_IV_curves,
plot_FI_curve_comparison=pp_settings.plot_FI_curve_comparison,
plot_phase_plot=pp_settings.plot_phase_plot,
plot_traces_comparison=pp_settings.plot_traces_comparison,
run_plot_custom_sinspec=pp_settings.run_plot_custom_sinspec,
IV_curve_prot_name=pp_settings.IV_curve_prot_name,
FI_curve_prot_name=pp_settings.FI_curve_prot_name,
phase_plot_settings=pp_settings.phase_plot_settings,
sinespec_settings=pp_settings.sinespec_settings,
custom_bluepyefe_cells_pklpath=pp_settings.custom_bluepyefe_cells_pklpath,
custom_bluepyefe_protocols_pklpath=pp_settings.custom_bluepyefe_protocols_pklpath,
only_validated=only_validated,
save_recordings=self.access_point.pipeline_settings.save_recordings,
save_recordings=pp_settings.save_recordings,
load_from_local=load_from_local,
cell_evaluator=cell_evaluator,
)
Expand Down
90 changes: 87 additions & 3 deletions bluepyemodel/emodel_pipeline/emodel_settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,18 @@ def __init__(
plot_currentscape=True,
plot_parameter_evolution=True,
plot_bAP_EPSP=False,
plot_IV_curves=False,
plot_FI_curve_comparison=False,
plot_traces_comparison=False,
run_plot_custom_sinspec=False,
IV_curve_prot_name="iv",
FI_curve_prot_name="idrest",
plot_phase_plot=False,
phase_plot_settings=None,
sinespec_settings=None,
currentscape_config=None,
custom_bluepyefe_cells_pklpath=None,
custom_bluepyefe_protocols_pklpath=None,
save_recordings=False,
neuron_dt=None,
cvode_minstep=0.0,
Expand Down Expand Up @@ -257,12 +268,58 @@ def __init__(
and EPSP protocols be run and plotted.
Should be True only for pyramidal cells,
since it depends on the presence of apical dendrite.
plot_IV_curves (bool): during the plotting, should peak voltage and voltage_deflection
IV curves be plotted for threshold-based sub-threshold IV protocols.
Needs pickle_cells_extraction to be set to True.
plot_FI_curve_comparison (bool): during the plotting, should FI curve be plotted
for experimental and simulated data.
Needs pickle_cells_extraction to be set to True.
plot_traces_comparison (bool): True to plot a new figure with simulated traces
on top of experimental traces.
Needs pickle_cells_extraction to be set to True.
run_plot_custom_sinspec (bool): True to run a SineSpec protocol, and plot
its voltage and current trace, along with its impedance.
IV_curve_prot_name (str): which protocol to use to plot_IV_curves.
FI_curve_prot_name (str): which protocol to use during plotting of FI curve comparison.
The protocol should be supra-threshold
and have the efeature mean_frequency associated to it.
plot_phase_plot (bool): during the plotting, should phase plot be plotted.
phase_plot_settings (dict): settings for the phase plot. Should contain the following:
"prot_names" (list of str): the names of the protocols to select for phase plot
"amplitude" (float): amplitude of the protocol to select.
Only exactly this amplitude will be selected for model.
An amplitude window is used for experimental trace selection
"amp_window" (float): amplitude window around amplitude for experimental
recording selection.Is not used for model trace selection
"relative_amp" (bool): Are amplitde and amp_window in relative amplitude (True)
or in absolute amplitude (False).
If set to None, it will default to:
{
"prot_names": ["idrest"],
"amplitude": 150,
"amp_window": 1.5,
"relative_amp": True,
}
sinespec_settings (dict): contains amplitude settings for the SineSpec protocol,
with keys 'amp' and 'threshold_based'.
'amp' should be in percentage of threshold if 'threshold_based' is True, e.g. 150,
or in nA if 'threshold_based' if false, e.g. 0.1.
If set to None, it will default to: {"amp": 0.05, "threshold_based": False}
currentscape_config (dict): currentscape configuration according to the currentscape
documentation (https://github.com/BlueBrain/Currentscape).
Note that current.names, output.savefig, output.fname and output.dir
do not need to be set, since they are automatically overwritten by BluePyEModel.
If current.names is set nonetheless, it will be used as the subset of available
currents to be selected for the plot.
custom_bluepyefe_cells_pklpath (str): file path to the cells.pkl output of BluePyEfe.
If None, will use usual file path used in BluePyEfe,
so this is to be set only to use a file at an unexpected path.
Only used in plotting functions for IV curves, IF curves and phase plot.
custom_bluepyefe_protocols_pklpath (str): file path to the
protocols.pkl output of BluePyEfe.
If None, will use usual file path used in BluePyEfe,
so this is to be set only to use a file at an unexpected path.
Only used in plotting functions for trace_comparison.
save_recordings (bool): Whether to save the responses data under a folder
named `recordings`.
neuron_dt (float): time step of the NEURON simulator. If ``None``, cvode will be used.
Expand Down Expand Up @@ -333,7 +390,6 @@ def __init__(
self.max_ngen = max_ngen
self.optimisation_checkpoint_period = optimisation_checkpoint_period
self.use_stagnation_criterion = use_stagnation_criterion
self.plot_optimisation = plot_optimisation
self.compile_mechanisms = compile_mechanisms

# Specific to threshold based optimisation
Expand Down Expand Up @@ -362,12 +418,40 @@ def __init__(
self.max_n_batch = max_n_batch
self.name_gene_map = name_gene_map

# Settings specific to the currentscape plotting
# Settings specific to the analysis (figure plotting)
self.plot_optimisation = plot_optimisation
self.plot_currentscape = plot_currentscape
self.currentscape_config = currentscape_config

self.plot_parameter_evolution = plot_parameter_evolution
self.plot_bAP_EPSP = plot_bAP_EPSP
self.plot_IV_curves = plot_IV_curves
self.plot_FI_curve_comparison = plot_FI_curve_comparison
self.plot_traces_comparison = plot_traces_comparison
if pickle_cells_extraction is False:
if any((plot_IV_curves, plot_FI_curve_comparison, plot_traces_comparison)):
logger.warning(
"You have set pickle_cells_extraction to False in the settings, "
"but plot_IV_curves, plot_FI_curve_comparison and "
"plot_traces_comparison need it to be True. "
"These plots will most likely fail."
)
self.run_plot_custom_sinspec = run_plot_custom_sinspec
self.IV_curve_prot_name = IV_curve_prot_name
self.FI_curve_prot_name = FI_curve_prot_name
self.plot_phase_plot = plot_phase_plot
self.phase_plot_settings = phase_plot_settings
if self.phase_plot_settings is None:
self.phase_plot_settings = {
"prot_names": ["idrest"],
"amplitude": 150,
"amp_window": 1.5,
"relative_amp": True,
}
self.sinespec_settings = sinespec_settings
if self.sinespec_settings is None:
self.sinespec_settings = {"amp": 0.05, "threshold_based": False}
self.custom_bluepyefe_cells_pklpath = custom_bluepyefe_cells_pklpath
self.custom_bluepyefe_protocols_pklpath = custom_bluepyefe_protocols_pklpath

# Settings specific to the recordings
self.save_recordings = save_recordings
Expand Down
Loading

0 comments on commit 8387c4d

Please sign in to comment.