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

Commit 9dd09e6

Browse files
committed
create a submodule for arbor's dsl inside parameterscalers
1 parent b973162 commit 9dd09e6

File tree

3 files changed

+201
-180
lines changed

3 files changed

+201
-180
lines changed
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
from .parameterscalers import *

bluepyopt/ephys/parameterscalers.py renamed to bluepyopt/ephys/parameterscalers/arbor_dsl.py

Lines changed: 2 additions & 180 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
"""Parameter scaler classes"""
1+
"""Module that generates Arbor's iexpr expression language."""
22

33
"""
4-
Copyright (c) 2016-2020, EPFL/Blue Brain Project
4+
Copyright (c) 2016-2022, EPFL/Blue Brain Project
55
66
This file is part of BluePyOpt <https://github.com/BlueBrain/BluePyOpt>
77
@@ -19,185 +19,8 @@
1919
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
2020
"""
2121

22-
# pylint: disable=W0511
23-
24-
import string
2522
import ast
2623

27-
from bluepyopt.ephys.base import BaseEPhys
28-
from bluepyopt.ephys.serializer import DictMixin
29-
from bluepyopt.ephys.morphologies import ArbFileMorphology
30-
31-
FLOAT_FORMAT = '%.17g'
32-
33-
34-
def format_float(value):
35-
"""Return formatted float string"""
36-
return FLOAT_FORMAT % value
37-
38-
39-
class MissingFormatDict(dict):
40-
41-
"""Extend dict for string formatting with missing values"""
42-
43-
def __missing__(self, key): # pylint: disable=R0201
44-
"""Return string with format key for missing keys"""
45-
return '{' + key + '}'
46-
47-
48-
class ParameterScaler(BaseEPhys):
49-
50-
"""Parameter scalers"""
51-
pass
52-
53-
# TODO get rid of the 'segment' here
54-
55-
56-
class NrnSegmentLinearScaler(ParameterScaler, DictMixin):
57-
58-
"""Linear scaler"""
59-
SERIALIZED_FIELDS = ('name', 'comment', 'multiplier', 'offset', )
60-
61-
def __init__(
62-
self,
63-
name=None,
64-
multiplier=1.0,
65-
offset=0.0,
66-
comment=''):
67-
"""Constructor
68-
69-
Args:
70-
name (str): name of this object
71-
multiplier (float): slope of the linear scaler
72-
offset (float): intercept of the linear scaler
73-
"""
74-
75-
super(NrnSegmentLinearScaler, self).__init__(name, comment)
76-
self.multiplier = multiplier
77-
self.offset = offset
78-
79-
def scale(self, value, segment=None, sim=None): # pylint: disable=W0613
80-
"""Scale a value based on a segment"""
81-
82-
return self.multiplier * value + self.offset
83-
84-
def __str__(self):
85-
"""String representation"""
86-
87-
return '%s * value + %s' % (self.multiplier, self.offset)
88-
89-
90-
class NrnSegmentSomaDistanceScaler(ParameterScaler, DictMixin):
91-
92-
"""Scaler based on distance from soma"""
93-
SERIALIZED_FIELDS = ('name', 'comment', 'distribution', )
94-
95-
def __init__(
96-
self,
97-
name=None,
98-
distribution=None,
99-
comment='',
100-
dist_param_names=None,
101-
soma_ref_location=0.5):
102-
"""Constructor
103-
104-
Args:
105-
name (str): name of this object
106-
distribution (str): distribution of parameter dependent on distance
107-
from soma. string can contain `distance` and/or `value` as
108-
placeholders for the distance to the soma and parameter value
109-
respectivily
110-
dist_params (list): list of names of parameters that parametrise
111-
the distribution. These names will become attributes of this
112-
object.
113-
The distribution string should contain these names, and they
114-
will be replaced by values of the corresponding attributes
115-
soma_ref_location (float): location along the soma used as origin
116-
from which to compute the distances. Expressed as a fraction
117-
(between 0.0 and 1.0).
118-
"""
119-
120-
super(NrnSegmentSomaDistanceScaler, self).__init__(name, comment)
121-
self.distribution = distribution
122-
123-
self.dist_param_names = dist_param_names
124-
self.soma_ref_location = soma_ref_location
125-
126-
if not (0. <= self.soma_ref_location <= 1.):
127-
raise ValueError('soma_ref_location must be between 0 and 1.')
128-
129-
if self.dist_param_names is not None:
130-
for dist_param_name in self.dist_param_names:
131-
if dist_param_name not in self.distribution:
132-
raise ValueError(
133-
'NrnSegmentSomaDistanceScaler: "{%s}" '
134-
'missing from distribution string "%s"' %
135-
(dist_param_name, distribution))
136-
setattr(self, dist_param_name, None)
137-
138-
@property
139-
def inst_distribution(self):
140-
"""The instantiated distribution"""
141-
142-
dist_dict = MissingFormatDict()
143-
144-
if self.dist_param_names is not None:
145-
for dist_param_name in self.dist_param_names:
146-
dist_param_value = getattr(self, dist_param_name)
147-
if dist_param_value is None:
148-
raise ValueError('NrnSegmentSomaDistanceScaler: %s '
149-
'was uninitialised' % dist_param_name)
150-
dist_dict[dist_param_name] = dist_param_value
151-
152-
# Use this special formatting to bypass missing keys
153-
return string.Formatter().vformat(self.distribution, (), dist_dict)
154-
155-
def eval_dist(self, value, distance):
156-
"""Create the final dist string"""
157-
158-
scale_dict = {}
159-
scale_dict['distance'] = format_float(distance)
160-
scale_dict['value'] = format_float(value)
161-
162-
return self.inst_distribution.format(**scale_dict)
163-
164-
def scale(self, value, segment, sim=None):
165-
"""Scale a value based on a segment"""
166-
167-
# TODO soma needs other addressing scheme
168-
169-
soma = segment.sec.cell().soma[0]
170-
171-
# Initialise origin
172-
sim.neuron.h.distance(0, self.soma_ref_location, sec=soma)
173-
174-
distance = sim.neuron.h.distance(1, segment.x, sec=segment.sec)
175-
176-
# Find something to generalise this
177-
import math # pylint:disable=W0611 #NOQA
178-
179-
# This eval is unsafe (but is it ever dangerous ?)
180-
# pylint: disable=W0123
181-
return eval(self.eval_dist(value, distance))
182-
183-
def acc_scale_iexpr(self, value, constant_formatter=format_float):
184-
"""Generate Arbor scale iexpr for a given value"""
185-
186-
iexpr = self.inst_distribution
187-
188-
variables = dict(
189-
value=value,
190-
distance='(distance %s)' % # could be a ctor param if required
191-
ArbFileMorphology.region_labels['somatic'].ref
192-
)
193-
194-
return generate_arbor_iexpr(iexpr, variables, constant_formatter)
195-
196-
def __str__(self):
197-
"""String representation"""
198-
199-
return self.distribution
200-
20124

20225
# Utilities to generate Arbor S-expressions for morphologically
20326
# inhomogeneous parameter scalers
@@ -410,7 +233,6 @@ def generate_arbor_iexpr(iexpr, variables, constant_formatter):
410233

411234
# Parse expression
412235
scaler_ast = ast.parse(scaler_expr)
413-
414236
# Turn into scaling expression, replacing non-linear occurrences of value
415237
value_eliminator = ArbIExprValueEliminator(
416238
variable_name='_arb_parse_iexpr_value',

0 commit comments

Comments
 (0)