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

Commit 51f7ced

Browse files
author
Jaquier Aurélien Tristan
committed
Allow custom mechanism in neuroml conversion
1 parent a76041a commit 51f7ced

File tree

3 files changed

+95
-6
lines changed

3 files changed

+95
-6
lines changed

bluepyopt/neuroml/biophys.py

Lines changed: 50 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,38 @@ def add_nml_channel_to_nml_cell_file(
207207
included_channels.append(channel_nml2_file)
208208

209209

210+
def get_channel_ion(channel, custom_channel_ion=None):
211+
"""Get ion name given channel name.
212+
213+
Arguments:
214+
channel (str): ion channel (e.g. StochKv)
215+
custom_channel_ion (dict): dict mapping channel to ion
216+
"""
217+
ion = channel_ions.get(channel, None)
218+
if ion is None and custom_channel_ion is not None:
219+
ion = custom_channel_ion.get(channel, None)
220+
if ion is None:
221+
raise KeyError(f"Ion not found for channel {channel}."
222+
" Please set channel-ion mapping using custom_channel_ion.")
223+
return ion
224+
225+
226+
def get_erev(ion, custom_ion_erevs=None):
227+
"""Get reversal potential as str given ion name.
228+
229+
Arguments:
230+
ion (str): ion name (e.g. na)
231+
custom_ion_erevs (dict): dict mapping ion to erev (reversal potential)
232+
"""
233+
erev = ion_erevs.get(ion, None)
234+
if erev is None and custom_ion_erevs is not None:
235+
erev = custom_ion_erevs.get(ion, None)
236+
if erev is None:
237+
raise KeyError(f"Reversal potentail not found for ion {ion}."
238+
" Please set ion-erev mapping using custom_ion_erevs.")
239+
return erev
240+
241+
210242
def get_arguments(
211243
params,
212244
parameter_name,
@@ -216,6 +248,8 @@ def get_arguments(
216248
variable_parameters,
217249
cond_density,
218250
release_params,
251+
custom_channel_ion=None,
252+
custom_ion_erevs=None,
219253
):
220254
"""Get arguments for channel density function.
221255
@@ -230,11 +264,13 @@ def get_arguments(
230264
parameters for non-uniform distributions
231265
cond_density (str): conductance density
232266
release_params (dict): optimized parameters
267+
custom_channel_ion (dict): dict mapping channel to ion
268+
custom_ion_erevs (dict): dict mapping ion to erev (reversal potential)
233269
"""
234270
arguments = {}
235271

236-
arguments["ion"] = channel_ions[channel]
237-
erev = ion_erevs[arguments["ion"]]
272+
arguments["ion"] = get_channel_ion(channel, custom_channel_ion)
273+
erev = get_erev(arguments["ion"], custom_ion_erevs)
238274

239275
channel_class = "ChannelDensity"
240276

@@ -331,6 +367,8 @@ def get_density(
331367
skip_non_uniform,
332368
release_params,
333369
skip_channels_copy,
370+
custom_channel_ion=None,
371+
custom_ion_erevs=None,
334372
):
335373
"""Return density.
336374
@@ -345,6 +383,8 @@ def get_density(
345383
release_params (dict): optimized parameters
346384
skip_channels_copy (bool): True to skip the copy pasting
347385
of the neuroml channel files
386+
custom_channel_ion (dict): dict mapping channel to ion
387+
custom_ion_erevs (dict): dict mapping ion to erev (reversal potential)
348388
"""
349389
channel = get_channel_from_param_name(parameter.param_name)
350390

@@ -375,6 +415,8 @@ def get_density(
375415
variable_parameters=variable_parameters,
376416
cond_density=cond_density,
377417
release_params=release_params,
418+
custom_channel_ion=custom_channel_ion,
419+
custom_ion_erevs=custom_ion_erevs,
378420
)
379421

380422
density = getattr(neuroml, channel_class)(**arguments)
@@ -413,6 +455,8 @@ def get_biophys(
413455
release_params,
414456
skip_non_uniform=False,
415457
skip_channels_copy=False,
458+
custom_channel_ion=None,
459+
custom_ion_erevs=None,
416460
):
417461
"""Get biophys in neuroml format.
418462
@@ -423,6 +467,8 @@ def get_biophys(
423467
skip_non_uniform (bool): True to skip non uniform distributions
424468
skip_channels_copy (bool): True to skip the copy pasting
425469
of the neuroml channel files
470+
custom_channel_ion (dict): dict mapping channel to ion
471+
custom_ion_erevs (dict): dict mapping ion to erev (reversal potential)
426472
"""
427473
concentrationModels = {}
428474

@@ -458,6 +504,8 @@ def get_biophys(
458504
skip_non_uniform,
459505
release_params,
460506
skip_channels_copy,
507+
custom_channel_ion,
508+
custom_ion_erevs,
461509
)
462510

463511
if density is not None:

bluepyopt/neuroml/cell.py

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,14 +27,22 @@
2727
logger = logging.getLogger(__name__)
2828

2929

30-
def create_neuroml_cell(bpo_cell, release_params, skip_channels_copy=False):
30+
def create_neuroml_cell(
31+
bpo_cell,
32+
release_params,
33+
skip_channels_copy=False,
34+
custom_channel_ion=None,
35+
custom_ion_erevs=None,
36+
):
3137
"""Create the cell.
3238
3339
Arguments:
3440
bpo_cell (ephys.CellModel): bluepyopt cell
3541
release_params (dict): the optimized parameters
3642
skip_channels_copy (bool): True to skip the copy pasting
3743
of the neuroml channel files
44+
custom_channel_ion (dict): dict mapping channel to ion
45+
custom_ion_erevs (dict): dict mapping ion to erev (reversal potential)
3846
3947
:returns: name of the cell nml file
4048
"""
@@ -74,6 +82,8 @@ def create_neuroml_cell(bpo_cell, release_params, skip_channels_copy=False):
7482
release_params,
7583
skip_non_uniform=True,
7684
skip_channels_copy=skip_channels_copy,
85+
custom_channel_ion=custom_channel_ion,
86+
custom_ion_erevs=custom_ion_erevs,
7787
)
7888

7989
# Append biophys to cell

examples/neuroml/neuroml.ipynb

Lines changed: 34 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,7 @@
176176
"- a neuroml cell file named after the bluepyopt cell's name: Here, `l5pc_0_0.cell.nml`.\n",
177177
"- a neuroml network file containing the neuroml cell, named after the bluepyopt cell's name. Here, `l5pc.net.nml`.\n",
178178
"\n",
179-
"Note that the `create_neuroml_cell` function is designed to work with the mechanisms present in `bluepyopt/neuroml/NeuroML2_mechanisms/` and will likely crash if you try to use it with custom mechanisms."
179+
"Skip this step if you want to use custom mechanisms not present in `bluepyopt/neuroml/NeuroML2_mechanisms/`."
180180
]
181181
},
182182
{
@@ -187,7 +187,38 @@
187187
"outputs": [],
188188
"source": [
189189
"cell.create_neuroml_cell(\n",
190-
" l5pc_cell, release_params, skip_channels_copy=False\n",
190+
" l5pc_cell, release_params, skip_channels_copy=False,\n",
191+
")"
192+
]
193+
},
194+
{
195+
"attachments": {},
196+
"cell_type": "markdown",
197+
"id": "a0db4c6b",
198+
"metadata": {},
199+
"source": [
200+
"If you want to create a neuroml cell with custom mechanisms that are not present in `bluepyopt/neuroml/NeuroML2_mechanisms/`, you will have to:\n",
201+
"- copy your custom mechanisms in the `.nml` format in the `./channels` directory\n",
202+
"- give as argument `custom_channel_ion`, a dict mapping channel name to ion name, e.g. `custom_channel_ion = {\"NaCustom\": \"na\"}`\n",
203+
"- if one of the ion in `custom_channel_ion` is not in pre-registered ions (na, k, hcn, ca, pas), you'll also have to give as argument `custom_ion_erevs`, a dict mapping ions to their reversal potential\n",
204+
"\n",
205+
"Below is an example of how to use the `create_neuroml_cell` function with custom mechanisms.\n",
206+
"\n",
207+
"However, be aware that `create_neuroml_cell` might not be able to deal with any given custom mechanism, and some might break it."
208+
]
209+
},
210+
{
211+
"cell_type": "code",
212+
"execution_count": null,
213+
"id": "adf01098",
214+
"metadata": {},
215+
"outputs": [],
216+
"source": [
217+
"custom_channel_ion = {\"Cl_custom_mech_name\": \"cl\"}\n",
218+
"custom_ion_erevs = {\"cl\": \"-60.0 mV\"}\n",
219+
"\n",
220+
"cell.create_neuroml_cell(\n",
221+
" l5pc_cell, release_params, skip_channels_copy=False, custom_channel_ion=custom_channel_ion, custom_ion_erevs=custom_ion_erevs,\n",
191222
")"
192223
]
193224
},
@@ -387,7 +418,7 @@
387418
"name": "python",
388419
"nbconvert_exporter": "python",
389420
"pygments_lexer": "ipython3",
390-
"version": "3.10.8"
421+
"version": "3.10.8 (main, Oct 13 2022, 10:17:43) [Clang 14.0.0 (clang-1400.0.29.102)]"
391422
},
392423
"vscode": {
393424
"interpreter": {

0 commit comments

Comments
 (0)