Skip to content

Commit

Permalink
Merge pull request #145 from BlueBrain/fix-ion-current
Browse files Browse the repository at this point in the history
allow non-specific currents not starting with 'i'
  • Loading branch information
AurelienJaquier authored Jun 24, 2024
2 parents 8f9e098 + 8a0c42f commit 730166e
Show file tree
Hide file tree
Showing 6 changed files with 42 additions and 38 deletions.
5 changes: 3 additions & 2 deletions bluepyemodel/access_point/access_point.py
Original file line number Diff line number Diff line change
Expand Up @@ -284,9 +284,10 @@ def get_ion_currents_concentrations(self):
mechs = self.get_available_mechanisms()
if mechs is None:
return None, None
ion_currents = list(chain.from_iterable([mech.get_current() for mech in mechs]))
# use list(set(...)) to only keep unique occurences
ion_currents = list(set(chain.from_iterable([mech.get_current() for mech in mechs])))
ionic_concentrations = list(
chain.from_iterable([mech.ionic_concentrations for mech in mechs])
set(chain.from_iterable([mech.ionic_concentrations for mech in mechs]))
)
# append i_pas which is present by default
ion_currents.append("i_pas")
Expand Down
9 changes: 6 additions & 3 deletions bluepyemodel/access_point/forge_access_point.py
Original file line number Diff line number Diff line change
Expand Up @@ -411,24 +411,27 @@ def retrieve(self, id_):

return None

def fetch(self, filters):
def fetch(self, filters, cross_bucket=None):
"""Fetch resources based on filters.
Args:
filters (dict): keys and values used for the "WHERE". Should include "type" or "id".
cross_bucket (bool): whether to also fetch from other projects or not.
Returns:
resources (list): list of resources
"""

if "type" not in filters and "id" not in filters:
raise AccessPointException("Search filters should contain either 'type' or 'id'.")

if cross_bucket is None:
cross_bucket = self.cross_bucket

logger.debug("Searching: %s", filters)

resources = self.forge.search(
filters,
cross_bucket=self.cross_bucket,
cross_bucket=cross_bucket,
limit=self.limit,
debug=self.debug,
search_endpoint=self.search_endpoint,
Expand Down
51 changes: 24 additions & 27 deletions bluepyemodel/access_point/nexus.py
Original file line number Diff line number Diff line change
Expand Up @@ -1067,8 +1067,9 @@ def get_available_mechanisms(self, filters=None):
filter = {"type": "SubCellularModelScript"}
if filters:
filter.update(filters)
resources = self.access_point.fetch(filter)

# do not look in other projects for these resources,
# because resources have 'full' metadata only in a few projects.
resources = self.access_point.fetch(filter, cross_bucket=False)
if resources is None:
logger.warning("No SubCellularModelScript mechanisms available")
return None
Expand All @@ -1086,6 +1087,9 @@ def get_available_mechanisms(self, filters=None):
stochastic = r.stochastic if hasattr(r, "stochastic") else None

parameters = {}
ion_currents = []
non_specific_currents = []
ionic_concentrations = []
if hasattr(r, "exposesParameter"):
exposes_parameters = r.exposesParameter
if not isinstance(exposes_parameters, list):
Expand All @@ -1094,33 +1098,26 @@ def get_available_mechanisms(self, filters=None):
if ep.type == "ConductanceDensity":
lower_limit = ep.lowerLimit if hasattr(ep, "lowerLimit") else None
upper_limit = ep.upperLimit if hasattr(ep, "upperLimit") else None
if hasattr(r, "mod"):
parameters[f"{ep.name}_{r.mod.suffix}"] = [
lower_limit,
upper_limit,
]
# resource name is the mech SUFFIX
parameters[f"{ep.name}_{r.name}"] = [lower_limit, upper_limit]
elif ep.type == "CurrentDensity":
if not hasattr(ep, "ionName"):
logger.warning(
"Will not add %s current, "
"because 'ionName' field was not found in %s.",
ep.name,
r.name,
)
elif ep.ionName == "non-specific":
non_specific_currents.append(ep.name)
else:
parameters[f"{ep.name}_{r.nmodlParameters.suffix}"] = [
lower_limit,
upper_limit,
]
ion_currents.append(ep.name)
ionic_concentrations.append(f"{ep.ionName}i")
elif ep.type == "IonConcentration":
ionic_concentrations.append(ep.name)

ion_currents = []
ionic_concentrations = []
# technically, also adds non-specific currents to ion_currents list,
# because they are not distinguished in nexus for now, but
# the code should work nevertheless
ions = []
if hasattr(r, "mod") and hasattr(r.mod, "ion"):
ions = r.mod.ion if isinstance(r.mod.ion, list) else [r.mod.ion]
elif hasattr(r, "ion"):
ions = r.ion if isinstance(r.ion, list) else [r.ion]

for ion in ions:
if hasattr(ion, "label"):
ion_name = ion.label.lower()
ion_currents.append(f"i{ion_name}")
ionic_concentrations.append(f"{ion_name}i")
# remove duplicates
ionic_concentrations = list(set(ionic_concentrations))

mech = MechanismConfiguration(
r.name,
Expand Down
7 changes: 4 additions & 3 deletions bluepyemodel/emodel_pipeline/plotting.py
Original file line number Diff line number Diff line change
Expand Up @@ -1495,12 +1495,13 @@ def get_ordered_currentscape_keys(keys):

if curr_name == "v":
ordered_keys[prot_name][loc_name]["voltage_key"] = name
elif curr_name[0] == "i":
ordered_keys[prot_name][loc_name]["current_keys"].append(name)
ordered_keys[prot_name][loc_name]["current_names"].append(curr_name)
elif curr_name[-1] == "i":
ordered_keys[prot_name][loc_name]["ion_conc_keys"].append(name)
ordered_keys[prot_name][loc_name]["ion_conc_names"].append(curr_name)
# assumes we don't have any extra-cellular concentrations (that ends with 'o')
else:
ordered_keys[prot_name][loc_name]["current_keys"].append(name)
ordered_keys[prot_name][loc_name]["current_names"].append(curr_name)

return ordered_keys

Expand Down
2 changes: 1 addition & 1 deletion bluepyemodel/evaluation/evaluator.py
Original file line number Diff line number Diff line change
Expand Up @@ -1020,7 +1020,7 @@ def add_recordings_to_evaluator(cell_evaluator, vars, use_fixed_dt_recordings=Fa
"""Add a recording for each new variable for each protocol in cell evaluator."""
# add recording for each protocol x new variable combination
for prot in cell_evaluator.fitness_protocols["main_protocol"].protocols.values():
if prot.name not in PRE_PROTOCOLS:
if prot.name == "SearchThresholdCurrent" or prot.name not in PRE_PROTOCOLS:
base_rec = prot.recordings[0]
for var in vars:
location = base_rec.location
Expand Down
6 changes: 4 additions & 2 deletions bluepyemodel/tools/mechanisms.py
Original file line number Diff line number Diff line change
Expand Up @@ -129,8 +129,10 @@ def get_mechanism_currents(mech_file):
ionic_concentrations.append(ion_var_name)
elif "NONSPECIFIC_CURRENT" in line:
var_name = line.split("NONSPECIFIC_CURRENT ")[1].rstrip("\n").split(" ")[0]
if var_name[0] == "i":
nonspecific_currents.append(var_name)
# here, we do not check if first letter is i, because
# NONSPECIFIC_CURRENT should indicate a current,
# and some special current do no start with i, e.g. 'lk'
nonspecific_currents.append(var_name)

return ion_currs, nonspecific_currents, ionic_concentrations

Expand Down

0 comments on commit 730166e

Please sign in to comment.