From 495816768d640a77fe32bf9f2588cb4697884db3 Mon Sep 17 00:00:00 2001 From: Mainak Jas Date: Tue, 4 May 2021 17:23:09 -0400 Subject: [PATCH] ENH: sec_pts is documented + sect_loc is updated transparently? --- hnn_core/cell.py | 12 ++++++++++-- hnn_core/cells_default.py | 30 ++++++++++++++---------------- hnn_core/tests/test_cell.py | 8 ++++---- 3 files changed, 28 insertions(+), 22 deletions(-) diff --git a/hnn_core/cell.py b/hnn_core/cell.py index e763efc64..eff90fa77 100644 --- a/hnn_core/cell.py +++ b/hnn_core/cell.py @@ -74,6 +74,8 @@ class Cell: Parameters ---------- + name : str + The name of the cell. pos : tuple The (x, y, z) coordinates. gid : int or None (optional) @@ -114,7 +116,8 @@ class Cell: names of section locations that are proximal or distal. """ - def __init__(self, pos, gid=None): + def __init__(self, name, pos, gid=None): + self.name = name self.pos = pos self.soma = None self.dends = dict() @@ -242,7 +245,7 @@ def _create_sections(self, p_secs, topology): child_loc = connection[3] child_sec.connect(parent_sec, parent_loc, child_loc) - def build(self, p_secs, p_syn, topology): + def build(self, p_secs, p_syn, topology, sect_loc): """Build cell in Neuron. Parameters @@ -267,6 +270,9 @@ def build(self, p_secs, p_syn, topology): specifying the location in the section to connect and parent_sec and child_sec are names of the connecting sections. + sect_loc : dict of list + Can have keys 'proximal' or 'distal' each containing + names of section locations that are proximal or distal. Examples -------- @@ -277,6 +283,7 @@ def build(self, p_secs, p_syn, topology): 'diam': 20, 'cm': 0.85, 'Ra': 200., + 'sec_pts': [[0, 0, 0], [0, 39., 0]], 'syns': ['ampa', 'gabaa', 'nmda'], 'mechs' : { 'ca': { @@ -289,6 +296,7 @@ def build(self, p_secs, p_syn, topology): self._create_sections(p_secs, topology) self._create_synapses(p_secs, p_syn) self._set_biophysics(p_secs) + self.sect_loc = sect_loc def move_to_pos(self): """Move cell to position.""" diff --git a/hnn_core/cells_default.py b/hnn_core/cells_default.py index 45acb715e..3392839dc 100644 --- a/hnn_core/cells_default.py +++ b/hnn_core/cells_default.py @@ -165,9 +165,6 @@ def basket(pos, cell_name='L2Basket', gid=None): cell : instance of BasketSingle The basket cell. """ - cell = Cell(pos=pos, gid=gid) - cell.name = cell_name - p_secs = dict() p_secs['soma'] = _get_basket_soma_props(cell_name) p_syn = _get_basket_syn_props() @@ -179,11 +176,12 @@ def basket(pos, cell_name='L2Basket', gid=None): p_secs[sec_name]['sec_pts'] = sec_pts[sec_name] if cell_name == 'L2Basket': - cell.sect_loc = dict(proximal=['soma'], distal=['soma']) + sect_loc = dict(proximal=['soma'], distal=['soma']) elif cell_name == 'L5Basket': - cell.sect_loc = dict(proximal=['soma'], distal=[]) + sect_loc = dict(proximal=['soma'], distal=[]) - cell.build(p_secs, p_syn, topology) + cell = Cell(cell_name, pos=pos, gid=gid) + cell.build(p_secs, p_syn, topology, sect_loc) return cell @@ -205,10 +203,9 @@ def pyramidal(pos, celltype, override_params=None, gid=None): yet attached to a network. Once the GID is set, it cannot be changed. """ - cell = Cell(pos=pos, gid=gid) if celltype == 'L5_pyramidal': p_all_default = get_L5Pyr_params_default() - cell.name = 'L5Pyr' + cell_name = 'L5Pyr' # units = ['pS/um^2', 'S/cm^2', 'pS/um^2', '??', 'tau', '??'] mechanisms = { 'hh2': ['gkbar_hh2', 'gnabar_hh2', @@ -226,7 +223,7 @@ def pyramidal(pos, celltype, override_params=None, gid=None): sec_pts, _, _, yscale, topology = _secs_L5Pyr() elif celltype == 'L2_pyramidal': p_all_default = get_L2Pyr_params_default() - cell.name = 'L2Pyr' + cell_name = 'L2Pyr' mechanisms = { 'km': ['gbar_km'], 'hh2': ['gkbar_hh2', 'gnabar_hh2', @@ -244,14 +241,14 @@ def pyramidal(pos, celltype, override_params=None, gid=None): prop_names = ['L', 'diam', 'Ra', 'cm'] # Get somatic, dendritic, and synapse properties - p_soma = _get_pyr_soma_props(p_all, cell.name) - p_dend = _get_dend_props(p_all, cell_type=cell.name, + p_soma = _get_pyr_soma_props(p_all, cell_name) + p_dend = _get_dend_props(p_all, cell_type=cell_name, section_names=section_names, prop_names=prop_names) - p_syn = _get_pyr_syn_props(p_all, cell.name) + p_syn = _get_pyr_syn_props(p_all, cell_name) p_secs = p_dend.copy() p_secs['soma'] = p_soma - p_mech = _get_mechanisms(p_all, cell.name, ['soma'] + section_names, + p_mech = _get_mechanisms(p_all, cell_name, ['soma'] + section_names, mechanisms) for key in p_secs: p_secs[key]['mechs'] = p_mech[key] @@ -267,10 +264,11 @@ def pyramidal(pos, celltype, override_params=None, gid=None): for sec_name in p_secs: p_secs[sec_name]['sec_pts'] = sec_pts[sec_name] - cell.sect_loc['proximal'] = ['apicaloblique', 'basal2', 'basal3'] - cell.sect_loc['distal'] = ['apicaltuft'] + sect_loc = {'proximal': ['apicaloblique', 'basal2', 'basal3'], + 'distal': ['apicaltuft']} - cell.build(p_secs, p_syn, topology) + cell = Cell(name=cell_name, pos=pos, gid=gid) + cell.build(p_secs, p_syn, topology, sect_loc=sect_loc) # insert dipole yscale = yscale diff --git a/hnn_core/tests/test_cell.py b/hnn_core/tests/test_cell.py index 23172d763..69901013d 100644 --- a/hnn_core/tests/test_cell.py +++ b/hnn_core/tests/test_cell.py @@ -11,16 +11,16 @@ def test_cell(): """Test cells object.""" pos = (0., 0., 0.) - + name = 'test' # GID is assigned exactly once for each cell, either at initialisation... - cell = Cell(pos=pos, gid=42) + cell = Cell(name, pos=pos, gid=42) assert cell.gid == 42 with pytest.raises(RuntimeError, match='Global ID for this cell already assigned!'): cell.gid += 1 # ... or later # cells can exist fine without gid - cell = Cell(pos=pos) + cell = Cell(name, pos=pos) assert cell.gid is None # check that it's initialised to None with pytest.raises(ValueError, match='gid must be an integer'): @@ -30,7 +30,7 @@ def test_cell(): with pytest.raises(ValueError, match='gid must be an integer'): # test init checks gid - cell = Cell(pos=pos, gid='one') + cell = Cell(name, pos=pos, gid='one') # test that ExpSyn always takes nrn.Segment, not float with pytest.raises(TypeError, match='secloc must be instance of'):