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

Commit e05921d

Browse files
Merge pull request #484 from BlueBrain/numpy-scaler
New scaler: NrnSegmentSomaDistanceStepScaler
2 parents f56a38f + 21ebe16 commit e05921d

File tree

9 files changed

+119
-8
lines changed

9 files changed

+119
-8
lines changed

bluepyopt/ephys/create_hoc.py

+10
Original file line numberDiff line numberDiff line change
@@ -105,8 +105,18 @@ def range_exprs_to_hoc(range_params):
105105
for param in range_params:
106106
value = param.value_scaler.inst_distribution
107107
value = re.sub(r'math\.', '', value)
108+
value = re.sub(r'\&', '&&', value)
108109
value = re.sub('{distance}', FLOAT_FORMAT, value)
109110
value = re.sub('{value}', format_float(param.value), value)
111+
if hasattr(param.value_scaler, "step_begin"):
112+
value = re.sub(
113+
'{step_begin}',
114+
format_float(param.value_scaler.step_begin),
115+
value
116+
)
117+
value = re.sub(
118+
'{step_end}', format_float(param.value_scaler.step_end), value
119+
)
110120
ret.append(Range(param.location, param.name, value))
111121
return ret
112122

bluepyopt/ephys/parameterscalers/parameterscalers.py

+56-3
Original file line numberDiff line numberDiff line change
@@ -161,9 +161,8 @@ def inst_distribution(self):
161161
# Use this special formatting to bypass missing keys
162162
return string.Formatter().vformat(self.distribution, (), dist_dict)
163163

164-
def eval_dist(self, values, distance):
165-
"""Create the final dist string"""
166-
164+
def scale_dict(self, values, distance):
165+
"""Create scale dictionary"""
167166
scale_dict = {}
168167
if isinstance(values, dict):
169168
for k, v in values.items():
@@ -172,6 +171,12 @@ def eval_dist(self, values, distance):
172171
scale_dict["value"] = format_float(values)
173172
scale_dict["distance"] = format_float(distance)
174173

174+
return scale_dict
175+
176+
def eval_dist(self, values, distance):
177+
"""Create the final dist string"""
178+
scale_dict = self.scale_dict(values, distance)
179+
175180
return self.inst_distribution.format(**scale_dict)
176181

177182
def scale(self, values, segment, sim=None):
@@ -261,3 +266,51 @@ def acc_scale_iexpr(self, value, constant_formatter=format_float):
261266
ArbFileMorphology.region_labels['somatic'].ref
262267
)
263268
return generate_acc_scale_iexpr(iexpr, variables, constant_formatter)
269+
270+
271+
class NrnSegmentSomaDistanceStepScaler(NrnSegmentSomaDistanceScaler,
272+
ParameterScaler, DictMixin):
273+
274+
"""Scaler based on distance from soma with a step function"""
275+
SERIALIZED_FIELDS = ('name', 'comment', 'distribution', )
276+
277+
def __init__(
278+
self,
279+
name=None,
280+
distribution=None,
281+
comment='',
282+
dist_param_names=None,
283+
soma_ref_location=0.5,
284+
step_begin=None,
285+
step_end=None):
286+
"""Constructor
287+
Args:
288+
name (str): name of this object
289+
distribution (str): distribution of parameter dependent on distance
290+
from soma. string can contain `distance` and/or `value` as
291+
placeholders for the distance to the soma and parameter value
292+
respectively. It can also contain step_begin and step_end.
293+
dist_param_names (list): list of names of parameters that
294+
parametrise the distribution. These names will become
295+
attributes of this object.
296+
The distribution string should contain these names, and they
297+
will be replaced by values of the corresponding attributes
298+
soma_ref_location (float): location along the soma used as origin
299+
from which to compute the distances. Expressed as a fraction
300+
(between 0.0 and 1.0).
301+
step_begin (float): distance at which the step begins
302+
step_end (float): distance at which the step ends
303+
"""
304+
305+
super(NrnSegmentSomaDistanceStepScaler, self).__init__(
306+
name, distribution, comment, dist_param_names,
307+
soma_ref_location=soma_ref_location)
308+
self.step_begin = step_begin
309+
self.step_end = step_end
310+
311+
def scale_dict(self, values, distance):
312+
scale_dict = super().scale_dict(values, distance)
313+
scale_dict["step_begin"] = self.step_begin
314+
scale_dict["step_end"] = self.step_end
315+
316+
return scale_dict

bluepyopt/ephys/templates/cell_template.jinja2

+1-1
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ proc distribute_distance(){local x localobj sl
120120
this.soma[0] distance(0, 0.5)
121121
sprint(distfunc, "%%s %s(%%f) = %s", mech, distfunc)
122122
forsec sl for(x, 0) {
123-
sprint(stmp, distfunc, secname(), x, distance(x))
123+
sprint(stmp, distfunc, secname(), x, distance(x), distance(x))
124124
execute(stmp)
125125
}
126126
}

bluepyopt/tests/test_ephys/test_create_hoc.py

+32
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,9 @@
55
import os
66

77
from bluepyopt.ephys.acc import ArbLabel
8+
from bluepyopt.ephys.locations import NrnSomaDistanceCompLocation
89
from bluepyopt.ephys.parameterscalers import NrnSegmentSomaDistanceScaler
10+
from bluepyopt.ephys.parameterscalers import NrnSegmentSomaDistanceStepScaler
911

1012
from . import utils
1113
from bluepyopt.ephys import create_acc, create_hoc
@@ -151,3 +153,33 @@ def test_range_exprs_to_hoc():
151153
assert hoc[0].param_name == 'gkbar_hh'
152154
val_gt = '(-0.8696 + 2.087*exp((%.17g)*0.0031))*0.025000000000000001'
153155
assert hoc[0].value == val_gt
156+
157+
158+
@pytest.mark.unit
159+
def test_range_exprs_to_hoc_step_scaler():
160+
"""ephys.create_hoc: Test range_exprs_to_hoc with step scaler"""
161+
# apical_region = ArbLabel("region", "apic", "(tag 4)")
162+
apical_location = NrnSomaDistanceCompLocation(
163+
name='apic100',
164+
soma_distance=100,
165+
seclist_name='apical',
166+
)
167+
param_scaler = NrnSegmentSomaDistanceStepScaler(
168+
name='soma-distance-step-scaler',
169+
distribution='{value} * (0.1 + 0.9 * int('
170+
'({distance} > {step_begin}) & ('
171+
'{distance} < {step_end})))',
172+
step_begin=300,
173+
step_end=500)
174+
175+
range_expr = create_hoc.RangeExpr(
176+
location=apical_location,
177+
name="gCa_LVAstbar_Ca_LVAst",
178+
value=1,
179+
value_scaler=param_scaler
180+
)
181+
182+
hoc = create_hoc.range_exprs_to_hoc([range_expr])
183+
assert hoc[0].param_name == 'gCa_LVAstbar_Ca_LVAst'
184+
val_gt = '1 * (0.1 + 0.9 * int((%.17g > 300) && (%.17g < 500)))'
185+
assert hoc[0].value == val_gt

bluepyopt/tests/test_ephys/test_parameterscalers.py

+16
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,22 @@ def test_NrnSegmentSectionDistanceScaler_eval_dist_with_dict():
5151
== '0.5 + (1 - (abs(10 - 8) / 4)) * 1')
5252

5353

54+
@pytest.mark.unit
55+
def test_NrnSegmentSomaDistanceStepScaler_eval_dist_with_dict():
56+
"""ephys.parameterscalers: eval_dist of NrnSegmentSomaDistanceStepScaler"""
57+
58+
dist = '{value} * (0.1 + 0.9 * int(' \
59+
'({distance} > {step_begin}) & ({distance} < {step_end})))'
60+
61+
scaler = ephys.parameterscalers.NrnSegmentSomaDistanceStepScaler(
62+
distribution=dist, step_begin=300, step_end=500)
63+
64+
_values = {'value': 1}
65+
66+
assert (scaler.eval_dist(values=_values, distance=10)
67+
== '1 * (0.1 + 0.9 * int((10 > 300) & (10 < 500)))')
68+
69+
5470
@pytest.mark.unit
5571
def test_serialize():
5672
"""ephys.parameterscalers: test serialization"""

examples/stochkv/stochkv3cell.hoc

+1-1
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ proc distribute_distance(){local x localobj sl
9898
this.soma[0] distance(0, 0.5)
9999
sprint(distfunc, "%%s %s(%%f) = %s", mech, distfunc)
100100
forsec sl for(x, 0) {
101-
sprint(stmp, distfunc, secname(), x, distance(x))
101+
sprint(stmp, distfunc, secname(), x, distance(x), distance(x))
102102
execute(stmp)
103103
}
104104
}

examples/stochkv/stochkv3cell_det.hoc

+1-1
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ proc distribute_distance(){local x localobj sl
9898
this.soma[0] distance(0, 0.5)
9999
sprint(distfunc, "%%s %s(%%f) = %s", mech, distfunc)
100100
forsec sl for(x, 0) {
101-
sprint(stmp, distfunc, secname(), x, distance(x))
101+
sprint(stmp, distfunc, secname(), x, distance(x), distance(x))
102102
execute(stmp)
103103
}
104104
}

examples/stochkv/stochkvcell.hoc

+1-1
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ proc distribute_distance(){local x localobj sl
9898
this.soma[0] distance(0, 0.5)
9999
sprint(distfunc, "%%s %s(%%f) = %s", mech, distfunc)
100100
forsec sl for(x, 0) {
101-
sprint(stmp, distfunc, secname(), x, distance(x))
101+
sprint(stmp, distfunc, secname(), x, distance(x), distance(x))
102102
execute(stmp)
103103
}
104104
}

examples/stochkv/stochkvcell_det.hoc

+1-1
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ proc distribute_distance(){local x localobj sl
9898
this.soma[0] distance(0, 0.5)
9999
sprint(distfunc, "%%s %s(%%f) = %s", mech, distfunc)
100100
forsec sl for(x, 0) {
101-
sprint(stmp, distfunc, secname(), x, distance(x))
101+
sprint(stmp, distfunc, secname(), x, distance(x), distance(x))
102102
execute(stmp)
103103
}
104104
}

0 commit comments

Comments
 (0)