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

Commit 8a25348

Browse files
authored
Merge pull request #395 from arnaudon/trunk_location
location along trunk
2 parents d1ba9f4 + 6c87d26 commit 8a25348

File tree

2 files changed

+140
-2
lines changed

2 files changed

+140
-2
lines changed

bluepyopt/ephys/locations.py

Lines changed: 70 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525

2626
from bluepyopt.ephys.base import BaseEPhys
2727
from bluepyopt.ephys.serializer import DictMixin
28+
import numpy as np
2829

2930

3031
class Location(BaseEPhys):
@@ -354,7 +355,7 @@ def __init__(
354355
name,
355356
soma_distance=soma_distance,
356357
seclist_name=sec_name,
357-
comment=''
358+
comment=comment,
358359
)
359360
self.sec_index = sec_index
360361

@@ -392,6 +393,74 @@ def instantiate(self, sim=None, icell=None):
392393
return self.find_icomp(sim, branches)
393394

394395

396+
class NrnTrunkSomaDistanceCompLocation(NrnSecSomaDistanceCompLocation):
397+
"""Location at a distance from soma along a main direction.
398+
399+
We search for the section that is the furthest away from some along
400+
a direction, and pick a location at a given distance from soma along
401+
the path to that section.
402+
403+
If direction == 'radial', the largest radial direction is used.
404+
405+
This is most useful to follow the trunk of an apical dendrite
406+
without knowing the apical point, but only that apical trunk goes along y.
407+
"""
408+
409+
def __init__(
410+
self,
411+
name,
412+
soma_distance=None,
413+
sec_index=None,
414+
sec_name=None,
415+
direction=None,
416+
comment=""
417+
):
418+
"""Constructor
419+
420+
Args:
421+
name (str): name of this object
422+
soma_distance (float): distance from soma to this compartment
423+
sec_index (int): index of the section to consider
424+
sec_name (str): name of Neuron sections (ex: 'apic')
425+
direction (list of 3 elements): 3d vector representing direction,
426+
if None, default is [0, 1, 0]
427+
"""
428+
super(NrnTrunkSomaDistanceCompLocation, self).__init__(
429+
name,
430+
soma_distance=soma_distance,
431+
sec_index=sec_index,
432+
sec_name=sec_name,
433+
comment=comment
434+
)
435+
436+
if direction is None:
437+
direction = [0.0, 1.0, 0.0]
438+
self.direction = direction
439+
440+
def set_sec_index(self, icell=None):
441+
"""Search for the point furthest away along given direction."""
442+
points = np.array(
443+
[
444+
[
445+
section.x3d(section.n3d() - 1),
446+
section.y3d(section.n3d() - 1),
447+
section.z3d(section.n3d() - 1),
448+
]
449+
for section in getattr(icell, self.seclist_name)
450+
]
451+
)
452+
if self.direction == 'radial':
453+
self.sec_index = int(np.argmax(np.linalg.norm(points, axis=1)))
454+
else:
455+
self.sec_index = int(np.argmax(points.dot(self.direction)))
456+
457+
def instantiate(self, sim=None, icell=None):
458+
""" """
459+
if self.sec_index is None:
460+
self.set_sec_index(icell=icell)
461+
return super().instantiate(sim=sim, icell=icell)
462+
463+
395464
class EPhysLocInstantiateException(Exception):
396465

397466
"""All exception generated by location instantiation"""

bluepyopt/tests/test_ephys/test_locations.py

Lines changed: 70 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121

2222
# pylint:disable=W0612, W0201
2323
import json
24-
24+
import numpy as np
2525

2626
import pytest
2727

@@ -272,6 +272,75 @@ class Cell(object):
272272
assert comp == dend4(0.5)
273273

274274

275+
@pytest.mark.unit
276+
class TestNrnTrunkSomaDistanceCompLocation(object):
277+
278+
"""Test class for NrnTrunkSomaDistanceCompLocation"""
279+
280+
def setup(self):
281+
"""Setup"""
282+
self.loc = ephys.locations.NrnTrunkSomaDistanceCompLocation(
283+
'test',
284+
soma_distance=150,
285+
sec_name='testdend')
286+
self.loc_other = ephys.locations.NrnTrunkSomaDistanceCompLocation(
287+
'test',
288+
soma_distance=350,
289+
sec_name='testdend')
290+
291+
assert self.loc.name == 'test'
292+
self.sim = ephys.simulators.NrnSimulator()
293+
294+
def test_instantiate(self):
295+
"""ephys.locations.NrnSomaDistanceCompLocation: test instantiate"""
296+
297+
# Create a little test class with a soma and two dendritic sections
298+
class Cell(object):
299+
300+
"""Cell class"""
301+
pass
302+
cell = Cell()
303+
soma = self.sim.neuron.h.Section(name="soma[0]")
304+
cell.soma = [soma]
305+
cell.testdend = self.sim.neuron.h.SectionList()
306+
dend1 = self.sim.neuron.h.Section(name='dend[0]')
307+
dend2 = self.sim.neuron.h.Section(name='dend[1]')
308+
dend3 = self.sim.neuron.h.Section(name='dend[2]')
309+
dend4 = self.sim.neuron.h.Section(name='dend[3]')
310+
dend5 = self.sim.neuron.h.Section(name='dend[4]')
311+
312+
cell.testdend.append(sec=dend1)
313+
cell.testdend.append(sec=dend2)
314+
cell.testdend.append(sec=dend3)
315+
cell.testdend.append(sec=dend4)
316+
cell.testdend.append(sec=dend5)
317+
318+
x0 = self.sim.neuron.h.Vector([0] * 10)
319+
d = self.sim.neuron.h.Vector([1] * 10)
320+
321+
x1 = self.sim.neuron.h.Vector(np.linspace(0, 100, 10))
322+
self.sim.neuron.h.pt3dadd(x0, x1, x0, d, sec=dend1)
323+
x2 = self.sim.neuron.h.Vector(np.linspace(100, 200, 10))
324+
self.sim.neuron.h.pt3dadd(x0, x2, x0, d, sec=dend2)
325+
x3 = self.sim.neuron.h.Vector(np.linspace(200, 300, 10))
326+
self.sim.neuron.h.pt3dadd(x0, x3, x0, d, sec=dend3)
327+
x4 = self.sim.neuron.h.Vector(np.linspace(300, 400, 10))
328+
self.sim.neuron.h.pt3dadd(x0, x4, x0, d, sec=dend4)
329+
x5 = self.sim.neuron.h.Vector(np.linspace(400, 500, 10))
330+
self.sim.neuron.h.pt3dadd(x0, x5, x0, d, sec=dend5)
331+
332+
dend1.connect(soma(0.5), 0.0)
333+
dend2.connect(dend1(1.0), 0.0)
334+
dend3.connect(dend1(1.0), 0.0)
335+
dend4.connect(dend3(1.0), 0.0)
336+
dend5.connect(dend4(1.0), 0.0)
337+
338+
comp = self.loc.instantiate(sim=self.sim, icell=cell)
339+
assert comp == dend3(0.5)
340+
comp = self.loc_other.instantiate(sim=self.sim, icell=cell)
341+
assert comp == dend5(0.5)
342+
343+
275344
@pytest.mark.unit
276345
def test_serialize():
277346
"""ephys.locations: Test serialize functionality"""

0 commit comments

Comments
 (0)