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

Commit e127613

Browse files
Merge pull request #181 from BlueBrain/store-threshold-data
store and re-use threshold current data
2 parents 626f780 + 098dd56 commit e127613

File tree

5 files changed

+45
-13
lines changed

5 files changed

+45
-13
lines changed

bluepyemodel/access_point/local.py

+1
Original file line numberDiff line numberDiff line change
@@ -666,6 +666,7 @@ def format_emodel_data(self, model_data):
666666
passedValidation=model_data.get("validated", None),
667667
seed=model_data.get("seed", None),
668668
emodel_metadata=emodel_metadata,
669+
threshold_data=model_data.get("threshold_data", None),
669670
)
670671

671672
return emodel

bluepyemodel/emodel_pipeline/emodel.py

+7
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,7 @@ def __init__(
122122
emodel_metadata=None,
123123
workflow_id=None,
124124
nexus_images=None, # pylint: disable=unused-argument
125+
threshold_data=None,
125126
):
126127
"""Init
127128
@@ -138,6 +139,10 @@ def __init__(
138139
workflow_id (str): EModelWorkflow id on nexus.
139140
nexus_images (list): list of pdfs associated to the emodel.
140141
Not used, retained for legacy purposes only.
142+
threshold_data (dict): contains rmp, Rin, holding current and threshold current values
143+
to avoid re-computation of related protocols. Keys must match the 'output_key'
144+
used in respective protocols. If None, threshold-related protocols will be
145+
re-computed each time protocols are run.
141146
"""
142147

143148
self.emodel_metadata = emodel_metadata
@@ -175,6 +180,7 @@ def __init__(
175180

176181
self.responses = {}
177182
self.evaluator = None
183+
self.threshold_data = threshold_data if threshold_data is not None else {}
178184

179185
def copy_pdf_dependencies_to_new_path(self, seed, overwrite=False):
180186
"""Copy pdf dependencies to new path using allen notation"""
@@ -212,4 +218,5 @@ def as_dict(self):
212218
"passedValidation": self.passed_validation,
213219
"nexus_images": pdf_dependencies,
214220
"seed": self.seed,
221+
"threshold_data": self.threshold_data,
215222
}

bluepyemodel/evaluation/evaluation.py

+10-1
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
from bluepyemodel.access_point import get_access_point
2828
from bluepyemodel.access_point.local import LocalAccessPoint
2929
from bluepyemodel.evaluation.evaluator import create_evaluator
30+
from bluepyemodel.evaluation.protocols import ProtocolRunner
3031
from bluepyemodel.model import model
3132
from bluepyemodel.tools.mechanisms import compile_mechs_in_emodel_dir
3233
from bluepyemodel.tools.mechanisms import delete_compiled_mechanisms
@@ -120,14 +121,18 @@ def get_responses(to_run):
120121
121122
Args:
122123
to_run (dict): of the form
123-
to_run = {"evaluator": CellEvaluator, "parameters": Dict}
124+
to_run = {"evaluator": CellEvaluator, "parameters": Dict, "threshold_data": Dict}
124125
"""
125126

126127
eva = to_run["evaluator"]
127128
params = to_run["parameters"]
128129

129130
eva.cell_model.unfreeze(params)
130131

132+
for prot in eva.fitness_protocols.values():
133+
if to_run.get("threshold_data", {}) and isinstance(prot, ProtocolRunner):
134+
prot.threshold_data = to_run["threshold_data"]
135+
131136
responses = eva.run_protocols(protocols=eva.fitness_protocols.values(), param_values=params)
132137
responses["evaluator"] = eva
133138

@@ -142,6 +147,7 @@ def compute_responses(
142147
preselect_for_validation=False,
143148
store_responses=False,
144149
load_from_local=False,
150+
recompute_threshold_protocols=False,
145151
):
146152
"""Compute the responses of the emodel to the optimisation and validation protocols.
147153
@@ -157,6 +163,8 @@ def compute_responses(
157163
only select models that have not been through validation yet.
158164
store_responses (bool): whether to locally store the responses.
159165
load_from_local (bool): True to load responses from locally saved recordings.
166+
recompute_threshold_protocols (bool): True to re-compute rmp, rin, holding current and
167+
threshold current even when threshold output is available.
160168
Returns:
161169
emodels (list): list of emodels.
162170
"""
@@ -183,6 +191,7 @@ def compute_responses(
183191
{
184192
"evaluator": copy.deepcopy(cell_evaluator),
185193
"parameters": mo.parameters,
194+
"threshold_data": {} if recompute_threshold_protocols else mo.threshold_data,
186195
}
187196
)
188197

bluepyemodel/evaluation/protocols.py

+22-12
Original file line numberDiff line numberDiff line change
@@ -958,6 +958,7 @@ def __init__(self, protocols, name="ProtocolRunner"):
958958

959959
self.protocols = protocols
960960
self.execution_order = self.compute_execution_order()
961+
self.threshold_data = {}
961962

962963
def _add_to_execution_order(self, protocol, execution_order, before_index=None):
963964
"""Recursively adds protocols to the execution order while making sure that their
@@ -996,19 +997,28 @@ def run(self, cell_model, param_values, sim=None, isolate=None, timeout=None):
996997
cell_model.freeze(param_values)
997998

998999
for protocol_name in self.execution_order:
999-
logger.debug("Computing protocol %s", protocol_name)
1000-
new_responses = self.protocols[protocol_name].run(
1001-
cell_model,
1002-
param_values={},
1003-
sim=sim,
1004-
isolate=isolate,
1005-
timeout=timeout,
1006-
responses=responses,
1007-
)
1000+
prot_output_key = getattr(self.protocols[protocol_name], "output_key", None)
1001+
if prot_output_key in self.threshold_data:
1002+
logger.debug(
1003+
"Skipping protocol %s, using saved value %s",
1004+
protocol_name,
1005+
self.threshold_data[prot_output_key],
1006+
)
1007+
new_responses = {prot_output_key, self.threshold_data[prot_output_key]}
1008+
else:
1009+
logger.debug("Computing protocol %s", protocol_name)
1010+
new_responses = self.protocols[protocol_name].run(
1011+
cell_model,
1012+
param_values={},
1013+
sim=sim,
1014+
isolate=isolate,
1015+
timeout=timeout,
1016+
responses=responses,
1017+
)
10081018

1009-
if new_responses is None or any(v is None for v in new_responses.values()):
1010-
logger.debug("None in responses, exiting evaluation")
1011-
break
1019+
if new_responses is None or any(v is None for v in new_responses.values()):
1020+
logger.debug("None in responses, exiting evaluation")
1021+
break
10121022

10131023
responses.update(new_responses)
10141024

bluepyemodel/validation/validation.py

+5
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,11 @@ def validate(access_point, mapper, preselect_for_validation=False):
130130
)
131131
)
132132

133+
# save threshold computation results
134+
model.threshold_data = {
135+
key: output for key, output in model.responses.items() if key[:4] == "bpo_"
136+
}
137+
133138
access_point.store_or_update_emodel(model)
134139

135140
return emodels

0 commit comments

Comments
 (0)