diff --git a/hnn_core/basket.py b/hnn_core/basket.py index 933091e35..e65d4f49e 100644 --- a/hnn_core/basket.py +++ b/hnn_core/basket.py @@ -33,7 +33,7 @@ def __init__(self, gid, pos, cell_name='Basket'): self.shape_soma() self.synapses = dict() - def _biophysics(self): + def set_biophysics(self): self.soma.insert('hh2') def _get_soma_props(self, cell_name, pos): @@ -71,7 +71,7 @@ def __init__(self, gid=-1, pos=-1): self.celltype = 'L2_basket' self._synapse_create() - self._biophysics() + self.set_biophysics() self.sect_loc = dict(proximal=['soma'], distal=['soma']) @@ -84,5 +84,5 @@ def __init__(self, gid=-1, pos=-1): self.celltype = 'L5_basket' self._synapse_create() - self._biophysics() + self.set_biophysics() self.sect_loc = dict(proximal=['soma'], distal=[]) diff --git a/hnn_core/cell.py b/hnn_core/cell.py index 9c91ab6ae..b0960faf4 100644 --- a/hnn_core/cell.py +++ b/hnn_core/cell.py @@ -105,73 +105,46 @@ def create_soma(self): self.soma.Ra = soma_props['Ra'] self.soma.cm = soma_props['cm'] - def get3dinfo(self): - """Get 3d info.""" - ls = self.get_sections() - lx, ly, lz, ldiam = [], [], [], [] - for s in ls: - for i in range(s.n3d()): - lx.append(s.x3d(i)) - ly.append(s.y3d(i)) - lz.append(s.z3d(i)) - ldiam.append(s.diam3d(i)) - return lx, ly, lz, ldiam - - def getbbox(self): - """Get cell's bounding box.""" - lx, ly, lz, ldiam = self.get3dinfo() - minx, miny, minz = 1e9, 1e9, 1e9 - maxx, maxy, maxz = -1e9, -1e9, -1e9 - for x, y, z in zip(lx, ly, lz): - minx = min(x, minx) - miny = min(y, miny) - minz = min(z, minz) - maxx = max(x, maxx) - maxy = max(y, maxy) - maxz = max(z, maxz) - return ((minx, maxx), (miny, maxy), (minz, maxz)) - - def translate3d(self, dx, dy, dz): - """Translate 3d.""" - for s in self.get_sections(): - for i in range(s.n3d()): - h.pt3dchange(i, s.x3d(i) + dx, s.y3d(i) + dy, - s.z3d(i) + dz, s.diam3d(i), sec=s) - - def translate_to(self, x, y, z): - """Translate to position.""" + def move_to_pos(self): + """Move cell to position.""" x0 = self.soma.x3d(0) y0 = self.soma.y3d(0) z0 = self.soma.z3d(0) - dx = x - x0 - dy = y - y0 - dz = z - z0 - # print('dx:',dx,'dy:',dy,'dz:',dz) - self.translate3d(dx, dy, dz) + dx = self.pos[0] * 100 - x0 + dy = self.pos[2] - y0 + dz = self.pos[1] * 100 - z0 - def move_to_pos(self): - """Move cell to position.""" - self.translate_to(self.pos[0] * 100, self.pos[2], self.pos[1] * 100) + for s in self.get_sections(): + for i in range(s.n3d()): + h.pt3dchange(i, s.x3d(i) + dx, s.y3d(i) + dy, + s.z3d(i) + dz, s.diam3d(i), sec=s) # two things need to happen here for h: # 1. dipole needs to be inserted into each section # 2. a list needs to be created with a Dipole (Point Process) in each # section at position 1 # In Cell() and not Pyr() for future possibilities - def dipole_insert(self, yscale): - """Insert dipole into each section of this cell.""" + def insert_dipole(self, yscale): + """Insert dipole into each section of this cell. + + Parameters + ---------- + yscale : dict + Dictionary of length scales to calculate dipole without + 3d shape. + """ # dends must have already been created!! # it's easier to use wholetree here, this includes soma seclist = h.SectionList() seclist.wholetree(sec=self.soma) # create a python section list list_all - self.list_all = [sec for sec in seclist] - for sect in self.list_all: + list_all = [sec for sec in seclist] + for sect in list_all: sect.insert('dipole') # Dipole is defined in dipole_pp.mod - self.dipole_pp = [h.Dipole(1, sec=sect) for sect in self.list_all] + self.dipole_pp = [h.Dipole(1, sec=sect) for sect in list_all] # setting pointers and ztan values - for sect, dpp in zip(self.list_all, self.dipole_pp): + for sect, dpp in zip(list_all, self.dipole_pp): # assign internal resistance values to dipole point process (dpp) dpp.ri = h.ri(1, sec=sect) # sets pointers in dipole mod file to the correct locations @@ -188,7 +161,7 @@ def dipole_insert(self, yscale): pos = np.array([seg.x for seg in sect.allseg()]) # diff in yvals, scaled against the pos np.array. y_long as # in longitudinal - y_scale = (yscale[sect.name()] * sect.L) * pos + y_scale = (yscale[sect.name().split('_', 1)[1]] * sect.L) * pos # y_long = (h.y3d(1, sec=sect) - h.y3d(0, sec=sect)) * pos # diff values calculate length between successive section points y_diff = np.diff(y_scale) @@ -244,14 +217,14 @@ def syn_create(self, secloc, e, tau1, tau2): Parameters ---------- - secloc : float (0. to 1.0) - The section location + secloc : instance of nrn.Segment + The section location. E.g., soma(0.5). e: float - Reverse potential + Reverse potential (in mV) tau1: float - Rise time + Rise time (in ms) tau2: float - Decay time + Decay time (in ms) Returns ------- diff --git a/hnn_core/pyramidal.py b/hnn_core/pyramidal.py index 223cfae5e..973ba1d6a 100644 --- a/hnn_core/pyramidal.py +++ b/hnn_core/pyramidal.py @@ -20,15 +20,23 @@ class Pyr(_Cell): """Pyramidal neuron. + Parameters + ---------- + gid : int + The cell ID + soma_props : dict + The soma properties + pos : tuple + The position of the cell. + celltype : str + Either 'L2_Pyramidal' or 'L5_Pyramidal' + params : dict + The params dictionary. + Attributes ---------- name : str The name of the cell, 'L5Pyr' or 'L2Pyr' - dends : dict - The dendrites. The key is the name of the dendrite - and the value is an instance of h.Section. - synapses : dict - The synapses that the cell can use for connections. list_dend : list of str List of dendrites. sect_loc : dict of list @@ -36,9 +44,25 @@ class Pyr(_Cell): names of section locations that are proximal or distal. celltype : str The cell type, 'L5_Pyramidal' or 'L2_Pyramidal' + dends : dict + The dendrites. The key is the name of the dendrite + and the value is an instance of h.Section. + synapses : dict + The synapses that the cell can use for connections. """ - def __init__(self, gid, soma_props): + def __init__(self, gid, pos, celltype, params): + + if celltype == 'L5_pyramidal': + p_all_default = get_L5Pyr_params_default() + elif celltype == 'L2_pyramidal': + p_all_default = get_L2Pyr_params_default() + + p_all = compare_dictionaries(p_all_default, params) + + # Get somatic, dendirtic, and synapse properties + soma_props = self._get_soma_props(pos, p_all) + _Cell.__init__(self, gid, soma_props) self.create_soma() # store cell_name as self variable for later use @@ -49,30 +73,36 @@ def __init__(self, gid, soma_props): self.sect_loc = dict() # for legacy use with L5Pyr self.list_dend = [] - self.celltype = 'Pyramidal' - - def get_sectnames(self): - """Create dictionary of section names with entries - to scale section lengths to length along z-axis.""" - seclist = h.SectionList() - seclist.wholetree(sec=self.soma) - d = dict((sect.name(), 1.) for sect in seclist) - for key in d.keys(): - # basal_2 and basal_3 at 45 degree angle to z-axis. - if 'basal_2' in key: - d[key] = np.sqrt(2) / 2. - elif 'basal_3' in key: - d[key] = np.sqrt(2) / 2. - # apical_oblique at 90 perpendicular to z-axis - elif 'apical_oblique' in key: - d[key] = 0. - # All basalar dendrites extend along negative z-axis - if 'basal' in key: - d[key] = -d[key] - return d + self.celltype = celltype + + p_dend = self._get_dend_props(p_all) + p_syn = self._get_syn_props(p_all) + + # Geometry + # dend Cm and dend Ra set using soma Cm and soma Ra + self.create_dends(p_dend) # just creates the sections + # sets geom properties; adjusted after translation from + # hoc (2009 model) + self.set_geometry(p_dend) + + # biophysics + self.set_biophysics(p_all) + + # insert dipole + yscale = self.secs()[3] + self.insert_dipole(yscale) + + # create synapses + self._synapse_create(p_syn) + + # insert iclamp + self.list_IClamp = [] + + # run record current soma, defined in Cell() + self.record_current_soma() def set_geometry(self, p_dend): - """Define shape of the neuron. + """Define shape of the neuron and connect sections. Parameters ---------- @@ -86,8 +116,19 @@ def set_geometry(self, p_dend): * cm: membrane capacitance in micro-Farads * Ra: axial resistivity in ohm-cm """ + sec_pts, sec_lens, sec_diams, _, topology = self.secs() + + # Connects sections of THIS cell together. + for connection in topology: + # XXX: risky to use self.soma as default. Unfortunately there isn't + # a dictionary with all the sections (including soma) + parent_sec = self.dends.get(connection[0], self.soma) + parent_loc = connection[1] + child_sec = self.dends.get(connection[2], self.soma) + child_loc = connection[3] + child_sec.connect(parent_sec, parent_loc, child_loc) + # Neuron shape based on Jones et al., 2009 - sec_pts, sec_lens, sec_diams = self.secs() for sec in [self.soma] + self.list_dend: h.pt3dclear(sec=sec) sec_name = sec.name().split('_', 1)[1] @@ -134,84 +175,84 @@ def get_sections(self): ls.append(self.dends[key]) return ls - def _get_dend_props(self): + def _get_dend_props(self, p_all): """Returns hardcoded dendritic properties.""" props = { 'apical_trunk': { - 'L': self.p_all['%s_apicaltrunk_L' % self.name], - 'diam': self.p_all['%s_apicaltrunk_diam' % self.name], - 'cm': self.p_all['%s_dend_cm' % self.name], - 'Ra': self.p_all['%s_dend_Ra' % self.name], + 'L': p_all['%s_apicaltrunk_L' % self.name], + 'diam': p_all['%s_apicaltrunk_diam' % self.name], + 'cm': p_all['%s_dend_cm' % self.name], + 'Ra': p_all['%s_dend_Ra' % self.name], }, 'apical_1': { - 'L': self.p_all['%s_apical1_L' % self.name], - 'diam': self.p_all['%s_apical1_diam' % self.name], - 'cm': self.p_all['%s_dend_cm' % self.name], - 'Ra': self.p_all['%s_dend_Ra' % self.name], + 'L': p_all['%s_apical1_L' % self.name], + 'diam': p_all['%s_apical1_diam' % self.name], + 'cm': p_all['%s_dend_cm' % self.name], + 'Ra': p_all['%s_dend_Ra' % self.name], }, 'apical_tuft': { - 'L': self.p_all['%s_apicaltuft_L' % self.name], - 'diam': self.p_all['%s_apicaltuft_diam' % self.name], - 'cm': self.p_all['%s_dend_cm' % self.name], - 'Ra': self.p_all['%s_dend_Ra' % self.name], + 'L': p_all['%s_apicaltuft_L' % self.name], + 'diam': p_all['%s_apicaltuft_diam' % self.name], + 'cm': p_all['%s_dend_cm' % self.name], + 'Ra': p_all['%s_dend_Ra' % self.name], }, 'apical_oblique': { - 'L': self.p_all['%s_apicaloblique_L' % self.name], - 'diam': self.p_all['%s_apicaloblique_diam' % self.name], - 'cm': self.p_all['%s_dend_cm' % self.name], - 'Ra': self.p_all['%s_dend_Ra' % self.name], + 'L': p_all['%s_apicaloblique_L' % self.name], + 'diam': p_all['%s_apicaloblique_diam' % self.name], + 'cm': p_all['%s_dend_cm' % self.name], + 'Ra': p_all['%s_dend_Ra' % self.name], }, 'basal_1': { - 'L': self.p_all['%s_basal1_L' % self.name], - 'diam': self.p_all['%s_basal1_diam' % self.name], - 'cm': self.p_all['%s_dend_cm' % self.name], - 'Ra': self.p_all['%s_dend_Ra' % self.name], + 'L': p_all['%s_basal1_L' % self.name], + 'diam': p_all['%s_basal1_diam' % self.name], + 'cm': p_all['%s_dend_cm' % self.name], + 'Ra': p_all['%s_dend_Ra' % self.name], }, 'basal_2': { - 'L': self.p_all['%s_basal2_L' % self.name], - 'diam': self.p_all['%s_basal2_diam' % self.name], - 'cm': self.p_all['%s_dend_cm' % self.name], - 'Ra': self.p_all['%s_dend_Ra' % self.name], + 'L': p_all['%s_basal2_L' % self.name], + 'diam': p_all['%s_basal2_diam' % self.name], + 'cm': p_all['%s_dend_cm' % self.name], + 'Ra': p_all['%s_dend_Ra' % self.name], }, 'basal_3': { - 'L': self.p_all['%s_basal3_L' % self.name], - 'diam': self.p_all['%s_basal3_diam' % self.name], - 'cm': self.p_all['%s_dend_cm' % self.name], - 'Ra': self.p_all['%s_dend_Ra' % self.name], + 'L': p_all['%s_basal3_L' % self.name], + 'diam': p_all['%s_basal3_diam' % self.name], + 'cm': p_all['%s_dend_cm' % self.name], + 'Ra': p_all['%s_dend_Ra' % self.name], }, } if self.name == 'L5Pyr': props.update({ 'apical_2': { - 'L': self.p_all['L5Pyr_apical2_L'], - 'diam': self.p_all['L5Pyr_apical2_diam'], - 'cm': self.p_all['L5Pyr_dend_cm'], - 'Ra': self.p_all['L5Pyr_dend_Ra'], + 'L': p_all['L5Pyr_apical2_L'], + 'diam': p_all['L5Pyr_apical2_diam'], + 'cm': p_all['L5Pyr_dend_cm'], + 'Ra': p_all['L5Pyr_dend_Ra'], }, }) return props - def _get_syn_props(self): + def _get_syn_props(self, p_all): return { 'ampa': { - 'e': self.p_all['%s_ampa_e' % self.name], - 'tau1': self.p_all['%s_ampa_tau1' % self.name], - 'tau2': self.p_all['%s_ampa_tau2' % self.name], + 'e': p_all['%s_ampa_e' % self.name], + 'tau1': p_all['%s_ampa_tau1' % self.name], + 'tau2': p_all['%s_ampa_tau2' % self.name], }, 'nmda': { - 'e': self.p_all['%s_nmda_e' % self.name], - 'tau1': self.p_all['%s_nmda_tau1' % self.name], - 'tau2': self.p_all['%s_nmda_tau2' % self.name], + 'e': p_all['%s_nmda_e' % self.name], + 'tau1': p_all['%s_nmda_tau1' % self.name], + 'tau2': p_all['%s_nmda_tau2' % self.name], }, 'gabaa': { - 'e': self.p_all['%s_gabaa_e' % self.name], - 'tau1': self.p_all['%s_gabaa_tau1' % self.name], - 'tau2': self.p_all['%s_gabaa_tau2' % self.name], + 'e': p_all['%s_gabaa_e' % self.name], + 'tau1': p_all['%s_gabaa_tau1' % self.name], + 'tau2': p_all['%s_gabaa_tau2' % self.name], }, 'gabab': { - 'e': self.p_all['%s_gabab_e' % self.name], - 'tau1': self.p_all['%s_gabab_tau1' % self.name], - 'tau2': self.p_all['%s_gabab_tau2' % self.name], + 'e': p_all['%s_gabab_e' % self.name], + 'tau1': p_all['%s_gabab_tau1' % self.name], + 'tau2': p_all['%s_gabab_tau2' % self.name], } } @@ -256,68 +297,35 @@ class L2Pyr(Pyr): ---------- gid : int The cell id. - p : dict + pos : tuple | None + The position of the cell. + params : dict | None The parameters dictionary. Attributes ---------- name : str The name of the cell + list_dend : list of str + List of dendrites. dends : dict The dendrites. The key is the name of the dendrite and the value is an instance of h.Section. - list_dend : list of h.Section - List of dendrites. + synapses : dict + The synapses that the cell can use for connections. """ - def __init__(self, gid=-1, pos=-1, p={}): - # Get default L2Pyr params and update them with any - # corresponding params in p - p_all_default = get_L2Pyr_params_default() - self.p_all = compare_dictionaries(p_all_default, p) - - # Get somatic, dendritic, and synapse properties - p_soma = self._get_soma_props(pos) - - # usage: Pyr.__init__(self, soma_props) - Pyr.__init__(self, gid, p_soma) - - p_dend = self._get_dend_props() - p_syn = self._get_syn_props() - - self.celltype = 'L2_pyramidal' - - # geometry - # creates dict of dends: self.dends - self.create_dends(p_dend) - self.topol() # sets the connectivity between sections - # sets geom properties; - # adjusted after translation from hoc (2009 model) - self.set_geometry(p_dend) - - # biophysics - self._biophys_soma() - self._biophys_dends() - - # dipole_insert() comes from Cell() - self.yscale = self.get_sectnames() - self.dipole_insert(self.yscale) + def __init__(self, gid=-1, pos=None, params=None): + Pyr.__init__(self, gid, pos, 'L2_pyramidal', params) - # create synapses - self._synapse_create(p_syn) - # self.__synapse_create() - - # run record_current_soma(), defined in Cell() - self.record_current_soma() - - def _get_soma_props(self, pos): + def _get_soma_props(self, pos, p_all): """Hardcoded somatic properties.""" return { 'pos': pos, - 'L': self.p_all['L2Pyr_soma_L'], - 'diam': self.p_all['L2Pyr_soma_diam'], - 'cm': self.p_all['L2Pyr_soma_cm'], - 'Ra': self.p_all['L2Pyr_soma_Ra'], + 'L': p_all['L2Pyr_soma_L'], + 'diam': p_all['L2Pyr_soma_diam'], + 'cm': p_all['L2Pyr_soma_cm'], + 'Ra': p_all['L2Pyr_soma_Ra'], 'name': 'L2Pyr', } @@ -354,43 +362,46 @@ def secs(self): 'basal_2': 2.72, 'basal_3': 2.72 } - return sec_pts, sec_lens, sec_diams - - def topol(self): - """Connects sections of THIS cell together.""" - # child.connect(parent, parent_end, {child_start=0}) - # Distal (Apical) - self.dends['apical_trunk'].connect(self.soma, 1, 0) - self.dends['apical_1'].connect(self.dends['apical_trunk'], 1, 0) - self.dends['apical_tuft'].connect(self.dends['apical_1'], 1, 0) - - # apical_oblique comes off distal end of apical_trunk - self.dends['apical_oblique'].connect(self.dends['apical_trunk'], 1, 0) - - # Proximal (basal) - self.dends['basal_1'].connect(self.soma, 0, 0) - self.dends['basal_2'].connect(self.dends['basal_1'], 1, 0) - self.dends['basal_3'].connect(self.dends['basal_1'], 1, 0) - - def _biophys_soma(self): + sec_scales = { # factor to scale the dipole by + 'soma': 1., + 'apical_trunk': 1., + 'apical_oblique': 0., + 'apical_1': 1., + 'apical_tuft': 1., + 'basal_1': -1., + 'basal_2': -np.sqrt(2.) / 2., + 'basal_3': -np.sqrt(2.) / 2. + } + # parent, parent_end, child, {child_start=0} + topology = [ + # Distal (Apical) + ['soma', 1, 'apical_trunk', 0], + ['apical_trunk', 1, 'apical_1', 0], + ['apical_1', 1, 'apical_tuft', 0], + # apical_oblique comes off distal end of apical_trunk + ['apical_trunk', 1, 'apical_oblique', 0], + # Proximal (basal) + ['soma', 0, 'basal_1', 0], + ['basal_1', 1, 'basal_2', 0], + ['basal_1', 1, 'basal_3', 0] + ] + return sec_pts, sec_lens, sec_diams, sec_scales, topology + + def set_biophysics(self, p_all): """Adds biophysics to soma.""" - # set soma biophysics specified in Pyr - # self.pyr_biophys_soma() # Insert 'hh2' mechanism self.soma.insert('hh2') - self.soma.gkbar_hh2 = self.p_all['L2Pyr_soma_gkbar_hh2'] - self.soma.gl_hh2 = self.p_all['L2Pyr_soma_gl_hh2'] - self.soma.el_hh2 = self.p_all['L2Pyr_soma_el_hh2'] - self.soma.gnabar_hh2 = self.p_all['L2Pyr_soma_gnabar_hh2'] + self.soma.gkbar_hh2 = p_all['L2Pyr_soma_gkbar_hh2'] + self.soma.gl_hh2 = p_all['L2Pyr_soma_gl_hh2'] + self.soma.el_hh2 = p_all['L2Pyr_soma_el_hh2'] + self.soma.gnabar_hh2 = p_all['L2Pyr_soma_gnabar_hh2'] # Insert 'km' mechanism # Units: pS/um^2 self.soma.insert('km') - self.soma.gbar_km = self.p_all['L2Pyr_soma_gbar_km'] + self.soma.gbar_km = p_all['L2Pyr_soma_gbar_km'] - def _biophys_dends(self): - """Defining biophysics for dendrites.""" # set dend biophysics # iterate over keys in self.dends and set biophysics for each dend for key in self.dends: @@ -401,15 +412,15 @@ def _biophys_dends(self): # Insert 'hh' mechanism self.dends[key].insert('hh2') - self.dends[key].gkbar_hh2 = self.p_all['L2Pyr_dend_gkbar_hh2'] - self.dends[key].gl_hh2 = self.p_all['L2Pyr_dend_gl_hh2'] - self.dends[key].gnabar_hh2 = self.p_all['L2Pyr_dend_gnabar_hh2'] - self.dends[key].el_hh2 = self.p_all['L2Pyr_dend_el_hh2'] + self.dends[key].gkbar_hh2 = p_all['L2Pyr_dend_gkbar_hh2'] + self.dends[key].gl_hh2 = p_all['L2Pyr_dend_gl_hh2'] + self.dends[key].gnabar_hh2 = p_all['L2Pyr_dend_gnabar_hh2'] + self.dends[key].el_hh2 = p_all['L2Pyr_dend_el_hh2'] # Insert 'km' mechanism # Units: pS/um^2 self.dends[key].insert('km') - self.dends[key].gbar_km = self.p_all['L2Pyr_dend_gbar_km'] + self.dends[key].gbar_km = p_all['L2Pyr_dend_gbar_km'] # Units for e: mV @@ -419,58 +430,32 @@ def _biophys_dends(self): class L5Pyr(Pyr): """Layer 5 Pyramidal class. + Parameters + ---------- + gid : int + The cell ID + pos : tuple | None + The position of the cell + params : dict | None + The params dictionary + Attributes ---------- name : str The name of the cell + list_dend : list of str + List of dendrites. dends : dict The dendrites. The key is the name of the dendrite and the value is an instance of h.Section. - list_dend : list of h.Section - List of dendrites. + synapses : dict + The synapses that the cell can use for connections. """ - def __init__(self, gid=-1, pos=-1, p={}): + def __init__(self, gid=-1, pos=None, params=None): """Get default L5Pyr params and update them with corresponding params in p.""" - p_all_default = get_L5Pyr_params_default() - self.p_all = compare_dictionaries(p_all_default, p) - - # Get somatic, dendirtic, and synapse properties - p_soma = self._get_soma_props(pos) - - Pyr.__init__(self, gid, p_soma) - p_dend = self._get_dend_props() - p_syn = self._get_syn_props() - - self.celltype = 'L5_pyramidal' - - # Geometry - # dend Cm and dend Ra set using soma Cm and soma Ra - self.create_dends(p_dend) # just creates the sections - self.topol() # sets the connectivity between sections - # sets geom properties; adjusted after translation from - # hoc (2009 model) - self.set_geometry(p_dend) - - # biophysics - self.__biophys_soma() - self.__biophys_dends() - - # Dictionary of length scales to calculate dipole without - # 3d shape. Comes from Pyr(). - # dipole_insert() comes from Cell() - self.yscale = self.get_sectnames() - self.dipole_insert(self.yscale) - - # create synapses - self._synapse_create(p_syn) - - # insert iclamp - self.list_IClamp = [] - - # run record current soma, defined in Cell() - self.record_current_soma() + Pyr.__init__(self, gid, pos, 'L5_pyramidal', params) def secs(self): """The geometry of the default sections in the Neuron.""" @@ -507,111 +492,111 @@ def secs(self): 'basal_2': 8.5, 'basal_3': 8.5 } - return sec_pts, sec_lens, sec_diams - - def _get_soma_props(self, pos): + sec_scales = { # factor to scale the dipole by + 'soma': 1., + 'apical_trunk': 1., + 'apical_oblique': 0., + 'apical_1': 1., + 'apical_2': 1., + 'apical_tuft': 1., + 'basal_1': -1., + 'basal_2': -np.sqrt(2.) / 2., + 'basal_3': -np.sqrt(2.) / 2. + } + topology = [ + # Distal (Apical) + ['soma', 1, 'apical_trunk', 0], + ['apical_trunk', 1, 'apical_1', 0], + ['apical_1', 1, 'apical_2', 0], + ['apical_2', 1, 'apical_tuft', 0], + # apical_oblique comes off distal end of apical_trunk + ['apical_trunk', 1, 'apical_oblique', 0], + # Proximal (basal) + ['soma', 0, 'basal_1', 0], + ['basal_1', 1, 'basal_2', 0], + ['basal_1', 1, 'basal_3', 0] + ] + return sec_pts, sec_lens, sec_diams, sec_scales, topology + + def _get_soma_props(self, pos, p_all): """Sets somatic properties. Returns dictionary.""" return { 'pos': pos, - 'L': self.p_all['L5Pyr_soma_L'], - 'diam': self.p_all['L5Pyr_soma_diam'], - 'cm': self.p_all['L5Pyr_soma_cm'], - 'Ra': self.p_all['L5Pyr_soma_Ra'], + 'L': p_all['L5Pyr_soma_L'], + 'diam': p_all['L5Pyr_soma_diam'], + 'cm': p_all['L5Pyr_soma_cm'], + 'Ra': p_all['L5Pyr_soma_Ra'], 'name': 'L5Pyr', } - def topol(self): - """Connects sections of this cell together.""" - - # child.connect(parent, parent_end, {child_start=0}) - # Distal (apical) - self.dends['apical_trunk'].connect(self.soma, 1, 0) - self.dends['apical_1'].connect(self.dends['apical_trunk'], 1, 0) - self.dends['apical_2'].connect(self.dends['apical_1'], 1, 0) - self.dends['apical_tuft'].connect(self.dends['apical_2'], 1, 0) - - # apical_oblique comes off distal end of apical_trunk - self.dends['apical_oblique'].connect(self.dends['apical_trunk'], 1, 0) - - # Proximal (basal) - self.dends['basal_1'].connect(self.soma, 0, 0) - self.dends['basal_2'].connect(self.dends['basal_1'], 1, 0) - self.dends['basal_3'].connect(self.dends['basal_1'], 1, 0) - - # adds biophysics to soma - def __biophys_soma(self): - # set soma biophysics specified in Pyr - # self.pyr_biophys_soma() + def set_biophysics(self, p_all): + "Set the biophysics for the default Pyramidal cell." # Insert 'hh2' mechanism self.soma.insert('hh2') - self.soma.gkbar_hh2 = self.p_all['L5Pyr_soma_gkbar_hh2'] - self.soma.gnabar_hh2 = self.p_all['L5Pyr_soma_gnabar_hh2'] - self.soma.gl_hh2 = self.p_all['L5Pyr_soma_gl_hh2'] - self.soma.el_hh2 = self.p_all['L5Pyr_soma_el_hh2'] + self.soma.gkbar_hh2 = p_all['L5Pyr_soma_gkbar_hh2'] + self.soma.gnabar_hh2 = p_all['L5Pyr_soma_gnabar_hh2'] + self.soma.gl_hh2 = p_all['L5Pyr_soma_gl_hh2'] + self.soma.el_hh2 = p_all['L5Pyr_soma_el_hh2'] # insert 'ca' mechanism # Units: pS/um^2 self.soma.insert('ca') - self.soma.gbar_ca = self.p_all['L5Pyr_soma_gbar_ca'] + self.soma.gbar_ca = p_all['L5Pyr_soma_gbar_ca'] # insert 'cad' mechanism # units of tau are ms self.soma.insert('cad') - self.soma.taur_cad = self.p_all['L5Pyr_soma_taur_cad'] + self.soma.taur_cad = p_all['L5Pyr_soma_taur_cad'] # insert 'kca' mechanism # units are S/cm^2? self.soma.insert('kca') - self.soma.gbar_kca = self.p_all['L5Pyr_soma_gbar_kca'] + self.soma.gbar_kca = p_all['L5Pyr_soma_gbar_kca'] # Insert 'km' mechanism # Units: pS/um^2 self.soma.insert('km') - self.soma.gbar_km = self.p_all['L5Pyr_soma_gbar_km'] + self.soma.gbar_km = p_all['L5Pyr_soma_gbar_km'] # insert 'cat' mechanism self.soma.insert('cat') - self.soma.gbar_cat = self.p_all['L5Pyr_soma_gbar_cat'] + self.soma.gbar_cat = p_all['L5Pyr_soma_gbar_cat'] # insert 'ar' mechanism self.soma.insert('ar') - self.soma.gbar_ar = self.p_all['L5Pyr_soma_gbar_ar'] - - def __biophys_dends(self): - # set dend biophysics specified in Pyr() - # self.pyr_biophys_dends() + self.soma.gbar_ar = p_all['L5Pyr_soma_gbar_ar'] # set dend biophysics not specified in Pyr() for key in self.dends: # Insert 'hh2' mechanism self.dends[key].insert('hh2') - self.dends[key].gkbar_hh2 = self.p_all['L5Pyr_dend_gkbar_hh2'] - self.dends[key].gl_hh2 = self.p_all['L5Pyr_dend_gl_hh2'] - self.dends[key].gnabar_hh2 = self.p_all['L5Pyr_dend_gnabar_hh2'] - self.dends[key].el_hh2 = self.p_all['L5Pyr_dend_el_hh2'] + self.dends[key].gkbar_hh2 = p_all['L5Pyr_dend_gkbar_hh2'] + self.dends[key].gl_hh2 = p_all['L5Pyr_dend_gl_hh2'] + self.dends[key].gnabar_hh2 = p_all['L5Pyr_dend_gnabar_hh2'] + self.dends[key].el_hh2 = p_all['L5Pyr_dend_el_hh2'] # Insert 'ca' mechanims # Units: pS/um^2 self.dends[key].insert('ca') - self.dends[key].gbar_ca = self.p_all['L5Pyr_dend_gbar_ca'] + self.dends[key].gbar_ca = p_all['L5Pyr_dend_gbar_ca'] # Insert 'cad' mechanism self.dends[key].insert('cad') - self.dends[key].taur_cad = self.p_all['L5Pyr_dend_taur_cad'] + self.dends[key].taur_cad = p_all['L5Pyr_dend_taur_cad'] # Insert 'kca' mechanism self.dends[key].insert('kca') - self.dends[key].gbar_kca = self.p_all['L5Pyr_dend_gbar_kca'] + self.dends[key].gbar_kca = p_all['L5Pyr_dend_gbar_kca'] # Insert 'km' mechansim # Units: pS/um^2 self.dends[key].insert('km') - self.dends[key].gbar_km = self.p_all['L5Pyr_dend_gbar_km'] + self.dends[key].gbar_km = p_all['L5Pyr_dend_gbar_km'] # insert 'cat' mechanism self.dends[key].insert('cat') - self.dends[key].gbar_cat = self.p_all['L5Pyr_dend_gbar_cat'] + self.dends[key].gbar_cat = p_all['L5Pyr_dend_gbar_cat'] # insert 'ar' mechanism self.dends[key].insert('ar')