Skip to content

Commit

Permalink
Merge pull request #172 from BlueBrain/fix-plotting
Browse files Browse the repository at this point in the history
Fix plotting
  • Loading branch information
AurelienJaquier authored Oct 1, 2024
2 parents f909cf9 + 03186b4 commit 1cfd34f
Show file tree
Hide file tree
Showing 8 changed files with 153 additions and 119 deletions.
3 changes: 2 additions & 1 deletion .pylintrc
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@
#W0622 - redefined-builti
#C0325 - superfluous-parens
#R0205 - useless-object-inheritance
disable=C0103,R0904,R0903,W0511,R0801,R0401,I0013,W0622,C0325,R0205,C0302,C0415,E1133,C0112,C0116,W0221,W1514,C0413,W0105
#R0917 - too-many-positional-arguments
disable=C0103,R0904,R0903,W0511,R0801,R0401,I0013,W0622,C0325,R0205,C0302,C0415,E1133,C0112,C0116,W0221,W1514,C0413,W0105,R0917

[FORMAT]
# Maximum number of characters on a single line.
Expand Down
5 changes: 3 additions & 2 deletions bluepyemodel/emodel_pipeline/emodel_pipeline.py
Original file line number Diff line number Diff line change
Expand Up @@ -245,7 +245,7 @@ def validation(self, preselect_for_validation=False):
preselect_for_validation=preselect_for_validation,
)

def plot(self, only_validated=False, load_from_local=False):
def plot(self, only_validated=False, load_from_local=False, seeds=None):
"""Plot the results of the optimisation in a subfolder called "figures".
Args:
Expand All @@ -254,6 +254,7 @@ def plot(self, only_validated=False, load_from_local=False):
load_from_local (bool): if True, loads responses of the e-models from local files
instead of recomputing them. Responses are automatically saved locally when
plotting currentscapes.
seeds (list): list of seeds to use for plot. If None, all emodels will be plotted.
"""
pp_settings = self.access_point.pipeline_settings

Expand Down Expand Up @@ -306,7 +307,7 @@ def plot(self, only_validated=False, load_from_local=False):
return plotting.plot_models(
access_point=self.access_point,
mapper=self.mapper,
seeds=None,
seeds=seeds,
figures_dir=pathlib.Path("./figures") / self.access_point.emodel_metadata.emodel,
plot_distributions=True,
plot_scores=True,
Expand Down
31 changes: 24 additions & 7 deletions bluepyemodel/emodel_pipeline/plotting.py
Original file line number Diff line number Diff line change
Expand Up @@ -861,11 +861,12 @@ def plot_bAP(
apical_distances, apical_values = apical_feature.get_distances_feature_values(responses)
basal_distances, basal_values = basal_feature.get_distances_feature_values(responses)

if 0 in apical_distances:
apical_x_fit, apical_y_fit = bAP_fit(apical_feature, apical_distances, apical_values)
if 0 in basal_distances:
basal_x_fit, basal_y_fit = bAP_fit(basal_feature, basal_distances, basal_values)

if apical_values is None or basal_values is None:
logger.warning(
"Cannot plot figure for bAP because dendrite feature could not be computed. "
"This can happen when the emodel is bad and cannot even compute curent threshold."
)
return fig, ax
if len(apical_distances) != len(apical_values) or len(basal_distances) != len(basal_values):
logger.warning(
"Cannot plot figure for bAP because of mismatch between "
Expand All @@ -874,6 +875,11 @@ def plot_bAP(
)
return fig, ax

if 0 in apical_distances:
apical_x_fit, apical_y_fit = bAP_fit(apical_feature, apical_distances, apical_values)
if 0 in basal_distances:
basal_x_fit, basal_y_fit = bAP_fit(basal_feature, basal_distances, basal_values)

ax.scatter(
apical_distances,
apical_values,
Expand Down Expand Up @@ -1667,6 +1673,18 @@ def plot_sinespec(
current_key = f"{prot_name}.iclamp.i"
voltage_key = f"{prot_name}.soma.v"

fig, axs = plt.subplots(3, figsize=(6, 12))

if voltage_key not in responses or current_key not in responses:
logger.warning(
"Could not find sinespec responses %s for emodel with seed %s. "
"This is most probably due to a bad model unable to compute threshold. "
"Skipping Sinespec plot.",
model.emodel_metadata.emodel,
model.seed,
)
return fig, axs

freq, smooth_Z = get_impedance(
responses[voltage_key]["time"],
responses[voltage_key]["voltage"],
Expand All @@ -1676,9 +1694,8 @@ def plot_sinespec(
efel_settings,
)
if freq is None or smooth_Z is None:
return None, None
return fig, axs

fig, axs = plt.subplots(3, figsize=(6, 12))
# current trace
axs[0].plot(responses[current_key]["time"], responses[current_key]["voltage"])
axs[0].set_xlabel("Time (ms)")
Expand Down
12 changes: 11 additions & 1 deletion bluepyemodel/emodel_pipeline/plotting_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -385,14 +385,22 @@ def get_simulated_FI_curve_for_plotting(evaluator, responses, prot_name):
protocol_name = get_protocol_name(val)
amp_temp = float(protocol_name.split("_")[-1])
if "mean_frequency" in val:
simulated_freq.append(values[val])
mean_freq = values[val]
# Expects a one-sized array or None.
# If list is a mix of arrays and Nones, matplotlib will raise an error when trying
# to turn the list into a numpy array.
# -> turn one-sized array into number
mean_freq = mean_freq[0] if mean_freq is not None else None
simulated_freq.append(mean_freq)
if "bpo_threshold_current" in responses:
simulated_amp_rel.append(amp_temp)
simulated_amp.append(rel_to_abs_amplitude(amp_temp, responses))
else:
simulated_amp_rel.append(numpy.nan)
simulated_amp.append(amp_temp)

# turn Nones into NaNs
simulated_freq = numpy.asarray(simulated_freq, dtype=float)
return simulated_amp_rel, simulated_amp, simulated_freq


Expand Down Expand Up @@ -514,6 +522,8 @@ def get_sinespec_evaluator(evaluator, sinespec_settings, efel_settings):
FixedDtRecordingCustom(f"{prot_name}.soma.v", location=soma_loc, variable="v"),
FixedDtRecordingStimulus(f"{prot_name}.iclamp.i", location=None, variable="i"),
],
# with constant Vm change, cvode would actually take longer to compute than fixed dt
cvode_active=False,
)
new_prots[prot_name] = sinespec_prot

Expand Down
18 changes: 17 additions & 1 deletion bluepyemodel/model/model.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,11 +56,27 @@ def multi_locations(section_name, additional_multiloc_map):
if additional_multiloc_map is not None:
multiloc_map.update(additional_multiloc_map)

return [
seclist_locations = [
ephys.locations.NrnSeclistLocation(sec, seclist_name=sec)
for sec in multiloc_map.get(section_name, [section_name])
]

for sec_loc in seclist_locations:
# all and myelinated are also accepted
if (
sec_loc.seclist_name not in multiloc_map["allact"]
and sec_loc.seclist_name != "all"
and sec_loc.seclist_name != "myelinated"
):
logger.warning(
"Section location %s not in expected locations %s. "
"This might make the cell crash at run time.",
sec_loc.seclist_name,
multiloc_map["allact"],
)

return seclist_locations


def define_distributions(distributions_definition, morphology=None):
"""Create a list of ParameterScaler from a the definition of channel distributions
Expand Down
4 changes: 2 additions & 2 deletions bluepyemodel/tasks/luigi_tools.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ def __init__(self, *args, **kwargs):
species=self.species,
brain_region=self.brain_region,
iteration_tag=self.iteration_tag,
**EmodelAPIConfig().api_args
**EmodelAPIConfig().api_args,
)

def get_mapper(self):
Expand Down Expand Up @@ -112,7 +112,7 @@ def __init__(
species=species,
brain_region=brain_region,
iteration_tag=iteration_tag,
**EmodelAPIConfig().api_args
**EmodelAPIConfig().api_args,
)


Expand Down
94 changes: 94 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
[build-system]
requires = ["setuptools >= 64", "setuptools_scm"]
build-backend = "setuptools.build_meta"

[project]
name = "bluepyemodel"
authors = [
{name = "Blue Brain Project, EPFL"},
]
description="Blue Brain Python Electrical Modeling Pipeline"
readme = "README.rst"
license = {file = "LICENSE.txt"}
requires-python = ">= 3.9"
dynamic = ["version"]
dependencies = [
"numpy",
"scipy",
"pandas",
"ipyparallel>=6.3",
"tqdm",
"pyyaml",
"gitpython",
"bluepyopt>=1.14.10",
"bluepyefe>=2.2.0",
"neurom>=3.0",
"efel>=5.5.5",
"configparser",
"neuron>=8.0",
"morph_tool>=2.8",
"morphio",
"fasteners>=0.16",
"jinja2>=3.0.3",
"currentscape>=0.0.11",
]
keywords=[
"computational neuroscience",
"simulation",
"analysis",
"parameters",
"Blue Brain Project",
]
classifiers=[
"Development Status :: 5 - Production/Stable",
"Environment :: Console",
"License :: OSI Approved :: Apache Software License",
"Operating System :: POSIX",
"Topic :: Scientific/Engineering",
"Programming Language :: Python :: 3",
"Topic :: Utilities",
]

[project.optional-dependencies]
luigi = [
"luigi>=3.0",
"luigi-tools>=0.0.12",
]
docs = [
"graphviz",
"sphinx",
"sphinx-bluebrain-theme",
"luigi>=3.0",
"luigi-tools>=0.0.12",
]
test = [
"pytest>=6.2",
"dictdiffer>=0.8",
]
nexus = [
"nexusforge>=0.8.2",
"entity_management>=1.2",
"pyJWT>=2.1.0",
]
all = [
"luigi>=3.0",
"luigi-tools>=0.0.12",
"nexusforge>=0.8.2",
"entity_management>=1.2",
"pyJWT>=2.1.0",
"pytest>=6.2",
"dictdiffer>=0.8",
]

[project.urls]
Homepage = "https://github.com/BlueBrain/BluePyEModel"

[tool.setuptools]
include-package-data = true

[tool.setuptools.packages.find]
exclude = ["tests",]

[tool.setuptools_scm]
version_scheme = "python-simplified-semver"
local_scheme = "no-local-version"
105 changes: 0 additions & 105 deletions setup.py

This file was deleted.

0 comments on commit 1cfd34f

Please sign in to comment.