Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

allow non-specific currents not starting with 'i' #145

Merged
merged 7 commits into from
Jun 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading