def init_adendR(self): adendR = self.adendR h.pt3dclear(sec=adendR) h.pt3dadd(-59, 0, 0, 1, sec=adendR) h.pt3dadd(-104, -44, 0, 1, sec=adendR) adendR.L = 350 adendR.diam = 1 adendR.nseg = 5 adendR.Ra = 200 adendR.cm = 2.4 adendR.insert('sAHP') adendR.gsAHPbar_sAHP = 0 adendR.insert('nap') adendR.gbar_nap = 0 adendR.insert('na3') adendR.gbar_na3 = 0.015 adendR.ar2_na3 = 1 adendR.insert('leak') adendR.glbar_leak = 0.031735 adendR.el_leak = -72 adendR.insert('kdr') adendR.gbar_kdr = 0.002 adendR.insert('kap') adendR.gkabar_kap = 0.002 adendR.insert('im') adendR.gbar_im = 0 adendR.insert('hd') adendR.ghdbar_hd = 1.5e-005 adendR.insert('capool') adendR.taucas_capool = 1000 adendR.cainf_capool = 5e-005 adendR.fcas_capool = 0.05 adendR.insert('cadyn') adendR.gcabar_cadyn = 0.00055
def init_p_dend(self): p_dend = self.p_dend h.pt3dclear(sec=p_dend) h.pt3dadd(15, 0, 0, 1, sec=p_dend) h.pt3dadd(75, 0, 0, 1, sec=p_dend) p_dend.L = 400 p_dend.diam = 5 p_dend.nseg = 7 p_dend.Ra = 200 p_dend.cm = 2.4 p_dend.insert('cadyn') p_dend.gcabar_cadyn = 0.00055 p_dend.insert('capool') p_dend.taucas_capool = 1000 p_dend.cainf_capool = 5e-005 p_dend.fcas_capool = 0.05 p_dend.insert('hd') p_dend.ghdbar_hd = 1.5e-005 p_dend.insert('im') p_dend.gbar_im = 0 p_dend.insert('kap') p_dend.gkabar_kap = 0 p_dend.insert('kdr') p_dend.gbar_kdr = 0.002 p_dend.insert('leak') p_dend.glbar_leak = 0.031735 p_dend.el_leak = -72 p_dend.insert('na3') p_dend.gbar_na3 = 0.015 p_dend.ar2_na3 = 1 p_dend.insert('nap') p_dend.gbar_nap = 0 p_dend.insert('sAHP') p_dend.gsAHPbar_sAHP = 0
def init_atrunk(self): atrunk = self.atrunk h.pt3dclear(sec=atrunk) h.pt3dadd(0, 0, 0, 1, sec=atrunk) h.pt3dadd(-59, 0, 0, 1, sec=atrunk) atrunk.L = 50 atrunk.diam = 2 atrunk.nseg = 3 atrunk.Ra = 200 atrunk.cm = 2.4 atrunk.insert('cadyn') atrunk.gcabar_cadyn = 0.00055 atrunk.insert('leak') atrunk.glbar_leak = 0.031735 atrunk.el_leak = -72 atrunk.insert('hd') atrunk.ghdbar_hd = 1.5e-005 atrunk.insert('im') atrunk.gbar_im = 0.00253 atrunk.insert('na3') atrunk.gbar_na3 = 0.015 atrunk.ar2_na3 = 1 atrunk.insert('nap') atrunk.gbar_nap = 0.000575 atrunk.insert('kdr') atrunk.gbar_kdr = 0.002 atrunk.insert('kap') atrunk.gkabar_kap = 0.002 atrunk.insert('capool') atrunk.taucas_capool = 1000 atrunk.cainf_capool = 5e-005 atrunk.fcas_capool = 0.05 atrunk.insert('sAHP') atrunk.gsAHPbar_sAHP = 0
def graph(self): #Function: graph #Input: self #Process: create dendrite branch network #Output: neuron self.soma = h.Section(name='soma', cell=self) self.dend = h.Section(name='dend', cell=self) self.dend.connect(self.soma(1)) self.dend.diam = 2 self.dend.nseg = 10 self.soma.L = self.soma.diam = 5.0 # microns h.pt3dclear(sec=self.soma) h.pt3dadd(0, 0, 0, self.soma.diam, sec=self.soma) h.pt3dadd(0 + self.soma.L, 0 + self.soma.L, 0 + self.soma.L, self.soma.diam, sec=self.soma) h.pt3dadd(0 + self.soma.L, 0 + self.soma.L, 0 + self.soma.L, self.soma.diam, sec=self.soma) h.pt3dadd(0 + self.soma.L + 10, 0 + self.soma.L + 10, 0 + self.soma.L + 10, self.soma.diam, sec=self.soma)
def draw(self): """ Draw a visual representation of the optrode """ from neuron import gui if not hasattr(self,'gOpt'): from numpy import pi self.gOpt=h.Shape(0) self.gOpt.view(-2100, -2100, 4200, 4200, 230, 450, 200.64, 200.32) self.gOpt.rotate(0, 0, 0, pi/2, 0, 0) h.pt3dclear(sec = self.sec) h.pt3dadd(self.x[0], self.y[0], self.z[0], self.diameter, sec = self.sec) h.pt3dadd(self.x[1], self.y[1], self.z[1], self.diameter, sec = self.sec) self.pOpt0 = h.IClamp(0, sec = self.sec) self.pOpt1 = h.IClamp(1, sec = self.sec) self.gOpt.point_mark(self.pOpt0, 1) # make start black self.gOpt.point_mark(self.pOpt1, 3) # make output blue self.gOpt.exec_menu("Show Diam") self.gOpt.exec_menu("3D Rotate")
def init_soma(self): soma = self.soma h.pt3dclear(sec=soma) h.pt3dadd(0, 0, 0, 1, sec=soma) h.pt3dadd(15, 0, 0, 1, sec=soma) soma.L = 25 soma.diam = 24.75 soma.nseg = 1 soma.Ra = 200 soma.cm = 2.4 soma.insert('cadyn') soma.gcabar_cadyn = 0.00055 soma.insert('leak') soma.glbar_leak = 0.031735 soma.el_leak = -72 soma.insert('hd') soma.ghdbar_hd = 1.5e-005 soma.insert('na3') soma.gbar_na3 = 0.045 soma.ar2_na3 = 1 soma.insert('nap') soma.gbar_nap = 0.000575 soma.insert('kdr') soma.gbar_kdr = 0.002 soma.insert('capool') soma.taucas_capool = 1000 soma.cainf_capool = 5e-005 soma.fcas_capool = 0.05 soma.insert('sAHP') soma.gsAHPbar_sAHP = 0.0012 soma.insert('im') soma.gbar_im = 0.00253 soma.insert('kap') soma.gkabar_kap = 0.002
def set_morphology(self): total_area = 10000 # um2 self.soma.nseg = 1 self.soma.cm = 1 # uF/cm2 diam = sqrt(total_area) # um L = diam / pi # um h.pt3dclear(sec=self.soma) h.pt3dadd(self.x, self.y, self.z, diam, sec=self.soma) h.pt3dadd(self.x, self.y, self.z + L, diam, sec=self.soma)
def set_morphology(self): total_area = 10000 # um2 self.soma.nseg = 1 self.soma.cm = 1 # uF/cm2 diam = sqrt(total_area) # um L = diam/pi # um h.pt3dclear(sec=self.soma) h.pt3dadd(self.x, self.y, self.z, diam, sec=self.soma) h.pt3dadd(self.x, self.y, self.z+L, diam, sec=self.soma)
def make_sections(self): SWC_types_inverse = {v:k for k,v in SWC_types.iteritems()} # load the tree structure that represents the morphology self.tree = btmorph.STree2() self.tree.read_SWC_tree_from_file(self.swc_filename,types=range(10)) print('There are %d nodes in the full representation of the morphology.' % len(self.tree.get_nodes())) # all the sections self.sections = [] sections_map = {} # describes how sections are connected self.sections_connections = [] # a (temporary) list of all the sections that make up the apical dendrites self.apical = [] # parse the tree for node in self.tree: if node is self.tree.root: section = h.Section(name='{0}_{1}'.format(SWC_types_inverse[node.content['p3d'].type],node.index)) self.sections.append(section) sections_map[node.index] = len(self.sections)-1 h.pt3dclear(sec=section) self.soma.append(section) elif len(node.children) == 1 and len(node.parent.children) > 1: # the parent of the current node is a branching point: start a new section section = h.Section(name='{0}_{1}'.format(SWC_types_inverse[node.content['p3d'].type],node.index)) self.sections.append(section) self.sections_connections.append((len(self.sections)-1,sections_map[node.parent.index])) sections_map[node.index] = len(self.sections)-1 h.pt3dclear(sec=section) # assign it to the proper region swc_type = node.content['p3d'].type if swc_type == SWC_types['soma']: self.soma.append(section) h.distance(sec=soma[0]) elif swc_type == SWC_types['axon']: self.axon.append(section) elif swc_type == SWC_types['basal']: self.basal.append(section) elif swc_type == SWC_types['apical']: self.apical.append(section) else: import pdb; pdb.set_trace() else: sections_map[node.index] = sections_map[node.parent.index] section = self.sections[sections_map[node.parent.index]] xyz = node.content['p3d'].xyz h.pt3dadd(float(xyz[0]),float(xyz[1]),float(xyz[2]),2*float(node.content['p3d'].radius),sec=section) # now that we have built all the sections we can subdivide those in the apical # dendrite in proximal and distal h.distance(sec=self.soma[0]) for sec in self.apical: if h.distance(0.5, sec=sec) < self.parameters['proximal_limit']: self.proximal.append(sec) else: self.distal.append(sec)
def basic_shape(self): self.soma.push() h.pt3dclear() h.pt3dadd(0, 0, 0, 1) h.pt3dadd(15, 0, 0, 1) h.pop_section() self.dend.push() h.pt3dclear() h.pt3dadd(15, 0, 0, 1) h.pt3dadd(105, 0, 0, 1) h.pop_section()
def init_dend(self): dend = self.dend h.pt3dclear(sec=dend) h.pt3dadd(0, 0, 0, 1, sec=dend) h.pt3dadd(-59, 0, 0, 1, sec=dend) dend.L = 150 dend.diam = 10 dend.nseg = 1 dend.Ra = 150 dend.cm = 1 dend.insert('pas')
def shape_soma(self): """Define 3D shape of soma. .. warning:: needed for gui representation of cell DO NOT need to call h.define_shape() explicitly! """ h.pt3dclear(sec=self.soma) # h.ptdadd(x, y, z, diam) -- if this function is run, clobbers # self.soma.diam set above h.pt3dadd(0, 0, 0, self.diam, sec=self.soma) h.pt3dadd(0, self.L, 0, self.diam, sec=self.soma)
def basic_shape(self): self.soma.push() h.pt3dclear() h.pt3dadd(0, 0, 0, 1) h.pt3dadd(20, 0, 0, 1) h.pop_section() self.dend.push() h.pt3dclear() h.pt3dadd(15, 0, 0, 1) h.pt3dadd(215, 0, 0, 1) h.pop_section()
def set_geom(self, geom): """ Create 3d geometry of the neuron. :param geom: List of 4d coordinates [x, y, z, diam]. :type geom: list """ self.push() # necessary to access Section in NEURON h.pt3dclear() for g in geom: h.pt3dadd(g[0], g[1], g[2], g[3]) h.pop_section() # restore the previously accessed Section
def position(self): ''' Adds 3D position ''' i = 0 for sec in self.all: h.pt3dclear() h.pt3dadd(self.L*i, 0, self.zpozition, self.diam) h.pt3dadd(self.L*(i+1), 0, self.zpozition, self.diam) xyz = dict(x=self.L*(i+1), y=0, z=0) self.coordinates.update({sec: xyz}) i+=1
def add_axon (self): # NB: paste-on axon if using SPI morphology (eg for comparing morph effect on dynamics) from PTAxonMorph import axonPts self.axon.append(h.Section(name="axon[0]")) self.all.append(self.axon[0]) self.axon[0].connect(self.soma[0], 0.0, 0.0) # clears 3d points h.pt3dclear() # define a logical connection point relative to the first 3-d point h.pt3dstyle(axonPts[0][0], axonPts[0][1], axonPts[0][2], axonPts[0][3], sec=self.axon[0]) # add axon points after first logical connection point for x, y, z, d in axonPts[1:]: h.pt3dadd(x, y, z, d, sec=self.axon[0])
def position(self): ''' Adds 3D position ''' i = 0 for sec in self.node: h.pt3dclear() h.pt3dadd(self.interlength * i, 0, 0, self.nodeD) h.pt3dadd((self.interlength * i + self.nodelength), 0, 0, self.nodeD) xyz = dict(x=(self.interlength * i + self.nodelength), y=0, z=0) self.coordinates.update({sec: xyz}) i += 1
def shape_3D(self): """ Set the default shape of the cell in 3D coordinates. Set soma(0) to the origin (0,0,0) and dend extending along the X-axis. """ len1 = self.soma.L h.pt3dclear(sec=self.soma) h.pt3dadd(0, 0, 0, self.soma.diam, sec=self.soma) h.pt3dadd(len1, 0, 0, self.soma.diam, sec=self.soma) len2 = self.dend.L h.pt3dclear(sec=self.dend) h.pt3dadd(len1, 0, 0, self.dend.diam, sec=self.dend) h.pt3dadd(len1 + len2, 0, 0, self.dend.diam, sec=self.dend)
def shape_3D(self): """ Set the default shape of the cell in 3D coordinates. Set soma(0) to the origin (0,0,0) and dend extending along the X-axis. """ len1 = self.soma[0].L h.pt3dclear(sec=self.soma[0]) h.pt3dadd(0, 0, 0, self.soma[0].diam, sec=self.soma[0]) h.pt3dadd(len1, 0, 0, self.soma[0].diam, sec=self.soma[0]) len2 = self.dend[0].L h.pt3dclear(sec=self.dend[0]) h.pt3dadd(len1, 0, 0, self.dend[0].diam, sec=self.dend[0]) h.pt3dadd(len1 + len2, 0, 0, self.dend[0].diam, sec=self.dend[0])
def _create_sections(self, sections, topology): """Create soma and set geometry. Notes ----- By default neuron uses xy plane for height and xz plane for depth. This is opposite for model as a whole, but convention is followed in this function ease use of gui. """ # shift cell to self.pos and reorient apical dendrite # along z direction of self.pos dx = self.pos[0] - self.sections['soma'].end_pts[0][0] dy = self.pos[1] - self.sections['soma'].end_pts[0][1] dz = self.pos[2] - self.sections['soma'].end_pts[0][2] for sec_name in sections: sec = h.Section(name=f'{self.name}_{sec_name}') self._nrn_sections[sec_name] = sec h.pt3dclear(sec=sec) h.pt3dconst(0, sec=sec) # be explicit, see documentation for pt in sections[sec_name].end_pts: h.pt3dadd(pt[0] + dx, pt[1] + dy, pt[2] + dz, 1, sec=sec) # with pt3dconst==0, these will alter the 3d points defined above! sec.L = sections[sec_name].L sec.diam = sections[sec_name].diam sec.Ra = sections[sec_name].Ra sec.cm = sections[sec_name].cm if sec.L > 100.: # 100 um sec.nseg = int(sec.L / 50.) # make dend.nseg odd for all sections if not sec.nseg % 2: sec.nseg += 1 if topology is None: topology = list() # Connects sections of THIS cell together. for connection in topology: parent_sec = self._nrn_sections[connection[0]] child_sec = self._nrn_sections[connection[2]] parent_loc = connection[1] child_loc = connection[3] child_sec.connect(parent_sec, parent_loc, child_loc) # be explicit about letting sec.L dominate over the 3d points used by # h.pt3dadd(); see # https://nrn.readthedocs.io/en/latest/python/modelspec/programmatic/topology/geometry.html?highlight=pt3dadd#pt3dadd # noqa h.define_shape()
def set_geometry(self, p_dend): """Define shape of the neuron and connect sections. Parameters ---------- p_dend : dict | None Nested dictionary. The outer dictionary has keys with names of dendrites and the inner dictionary specifies the geometry of these sections. * L: length of a section in microns * diam: diameter of a section in microns * 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 for sec in [self.soma] + self.list_dend: h.pt3dclear(sec=sec) sec_name = sec.name().split('_', 1)[1] for pt in sec_pts[sec_name]: h.pt3dadd(pt[0], pt[1], pt[2], 1, sec=sec) sec.L = sec_lens[sec_name] sec.diam = sec_diams[sec_name] # resets length,diam,etc. based on param specification for key in p_dend: # set dend props self.dends[key].L = p_dend[key]['L'] self.dends[key].diam = p_dend[key]['diam'] self.dends[key].Ra = p_dend[key]['Ra'] self.dends[key].cm = p_dend[key]['cm'] # set dend nseg if p_dend[key]['L'] > 100.: self.dends[key].nseg = int(p_dend[key]['L'] / 50.) # make dend.nseg odd for all sections if not self.dends[key].nseg % 2: self.dends[key].nseg += 1
def add_axon(self): self.axon.append(h.Section(name="axon[0]")) self.all.append(self.axon[0]) self.axon[0].connect(self.soma[0], 0.0, 0.0) # clears 3d points h.pt3dclear() # define a logical connection point relative to the first 3-d point h.pt3dstyle(axonPts[0][0], axonPts[0][1], axonPts[0][2], axonPts[0][3], sec=self.axon[0]) # add axon points after first logical connection point for x, y, z, d in axonPts[1:]: h.pt3dadd(x, y, z, d, sec=self.axon[0])
def fix_axon_peri_v2(hobj): """Replace reconstructed axon with a stub (keep order); BBP version :param hobj: hoc object """ if hasattr(hobj, 'axon'): for i,sec in enumerate(hobj.axon): h.pt3dclear(sec=sec) if i < 2: sec.L = 30 sec.diam = 1 else: sec.L = 1e-6 sec.diam = 1 h.define_shape()
def position(self, axon, last_x, plus_y): ''' Adds 3D position ''' i = 0 for sec in axon.node: h.pt3dclear() h.pt3dadd((last_x + axon.interlength * i), i * plus_y, 0, axon.nodeD) h.pt3dadd((last_x + axon.interlength * i + axon.nodelength), i * 2 * plus_y, 0, axon.nodeD) xyz = dict(x=(last_x + axon.interlength * i + axon.nodelength), y=i * 2 * plus_y, z=0) self.coordinates.update({sec: xyz}) i += 1
def init_soma(self): soma = self.soma h.pt3dclear(sec=soma) h.pt3dadd(0, 0, 0, 1, sec=soma) h.pt3dadd(15, 0, 0, 1, sec=soma) soma.L = 50 soma.diam = 50 soma.nseg = 1 soma.Ra = 150 soma.cm = 1 soma.insert('leak') soma.glbar_leak = 1 / 3333.33 soma.el_leak = -70 soma.insert('kdr') soma.gkdrbar_kdr = 0.036 soma.insert('na') soma.gnabar_na = 0.12
def test_transfer_resistance(): """Test transfer resistances calculated correctly""" from neuron import h from hnn_core.extracellular import _transfer_resistance sec = h.Section(name='dend') h.pt3dclear(sec=sec) h.pt3dadd(0, 0, 0, 1, sec=sec) h.pt3dadd(0, 1, 0, 1, sec=sec) # section oriented along y-axis sec.L = 300 sec.diam = 8 sec.nseg = 5 # NB segment lengths aren't equal! First/last segment center point is # closer to respective end point than to next/previous segment! seg_ctr_pts = [0] seg_ctr_pts.extend([seg.x * sec.L for seg in sec]) seg_ctr_pts.append(sec.L) seg_lens = np.diff(seg_ctr_pts) first_len = seg_lens[0] seg_lens = np.array([first_len] + list(seg_lens[2:])) seg_ctr_pts = seg_ctr_pts[1:-1] # remove end points again conductivity = 0.3 elec_pos = (10, 150, 0) target_vals = {'psa': list(), 'lsa': list()} for seg_idx in range(sec.nseg): # PSA: distance to middle segment == electrode x-position var_r_psa = np.sqrt(elec_pos[0] ** 2 + (elec_pos[1] - seg_ctr_pts[seg_idx]) ** 2) target_vals['psa'].append( 1000 / (4. * np.pi * conductivity * var_r_psa)) # LSA: calculate L and H variables relative to segment endpoints var_l = elec_pos[1] - (seg_ctr_pts[seg_idx] - seg_lens[seg_idx]) var_h = elec_pos[1] - (seg_ctr_pts[seg_idx] + seg_lens[seg_idx]) var_r_lsa = elec_pos[0] # just use the axial distance target_vals['lsa'].append( 1000 * np.log(np.abs( (np.sqrt(var_h ** 2 + var_r_lsa ** 2) - var_h) / (np.sqrt(var_l ** 2 + var_r_lsa ** 2) - var_l) )) / (4. * np.pi * conductivity * 2 * seg_lens[seg_idx])) for method in ['psa', 'lsa']: res = _transfer_resistance(sec, elec_pos, conductivity, method) assert_allclose(res, target_vals[method], rtol=1e-12, atol=0.)
def __init__(self): self.soma = h.Section(name="soma") h.pt3dclear() h.pt3dadd(0, 0, 0, 1) h.pt3dadd(15, 0, 0, 1) self.x = self.y = self.z = 0 self.soma.L = 10 self.soma.diam = 3.1831 self.soma.Ra = 100 self.soma.cm = 1 self.soma.insert('pas') self.soma.g_pas = 5e-5 self.soma.e_pas = -70 self.izh = h.Izh(0.5, sec=self.soma) self.izh.amp = 0 self.all = h.SectionList() self.all.append() self.make_synapses()
def shape_3D(self): """ This method defines the 3D shape of each SimpleCell object, so that it can later be drawn on a plot. It makes use of the NEURON pt3dadd() function defined for cellular compartment objects. """ somalen = self.soma.L dendlen = self.dend.L h.pt3dclear(sec=self.soma) h.pt3dadd(0, 0, 0, self.soma.diam, sec=self.soma) h.pt3dadd(somalen, 0, 0, self.soma.diam, sec=self.soma) h.pt3dclear(sec=self.dend) h.pt3dadd(somalen, 0, 0, self.dend.diam, sec=self.dend) h.pt3dadd(somalen + dendlen, 0, 0, self.dend.diam, sec=self.dend) self.all = h.SectionList() self.all.wholetree(sec=self.soma)
def set_position(self, x, y, z): """ Move electrode to new coordinates: x0, y0, z0: optrode input x1, x1, z1: optrode output """ from numpy.linalg import norm self._x=x self._y=y self._z=z xyz0,xyz1=self.xyz #self.sec.L=dist(xyz0,xyz1) self.sec.L = norm(xyz1-xyz0) h.pt3dclear(sec=self.sec) h.pt3dadd(float(x[0]), float(y[0]), float(z[0]), self.radius * 2, sec=self.sec) h.pt3dadd(float(x[1]), float(y[1]), float(z[1]), self.radius * 2, sec=self.sec) self.calc_tx() if hasattr(self, "gOpt"): self.draw() if hasattr(self, "mlab_tube"): self.display()
def position(self): ''' Adds 3D position ''' if self.numofmodel == 11 or self.numofmodel == 12: h.pt3dclear() h.pt3dadd(0, 0, self.zpozition, self.diam) h.pt3dadd(self.L, 0, self.zpozition, self.diam) xyz = dict(x=self.L, y=0, z=0) self.coordinates.update({self.branch: xyz}) for i in range(70): h.pt3dclear() h.pt3dadd(self.L * (i + 1), 0, self.zpozition, self.diam) h.pt3dadd(self.L * (i + 2), 0, self.zpozition, self.diam) xyz = dict(x=self.L * (i + 2), y=0, z=0) self.coordinates.update({self.stimsec[i]: xyz}) for i in range(70, 120): h.pt3dclear() h.pt3dadd(self.L * (i + 1), (i - 70) * 8, self.zpozition, self.diam) h.pt3dadd(self.L * (i + 2), (i - 69) * 8, self.zpozition, self.diam) xyz = dict(x=self.L * (i + 2), y=(i - 69) * 8, z=0) self.coordinates.update({self.stimsec[i]: xyz}) for i in range(120, 170): h.pt3dclear() h.pt3dadd(self.L * (i - 49), (i - 120) * (-8), self.zpozition, self.diam) h.pt3dadd(self.L * (i - 48), (i - 119) * (-8), self.zpozition, self.diam) xyz = dict(x=self.L * (i - 48), y=(i - 119) * (-8), z=0) self.coordinates.update({self.stimsec[i]: xyz}) else: i = 0 for sec in self.all: h.pt3dclear() h.pt3dadd(self.L * i, 0, self.zpozition, self.diam) h.pt3dadd(self.L * (i + 1), 0, self.zpozition, self.diam) xyz = dict(x=self.L * (i + 1), y=0, z=0) self.coordinates.update({sec: xyz}) i += 1
def shape_3D(self): """ Set the default shape of the cell in 3D coordinates. Set soma(0) to the origin (0,0,0) and dend extending along the X-axis. -Innacurate """ len1 = self.soma.L h.pt3dclear(sec=self.soma) h.pt3dadd(0, 0, 0, self.soma.diam, sec=self.soma) h.pt3dadd(0, len1, 0, self.soma.diam, sec=self.soma) len2 = self.dendL.L h.pt3dclear(sec=self.dendL) h.pt3dadd(0, len1, 0, self.dendL.diam, sec=self.dendL) h.pt3dadd(-len2 * cos(pi / 4), len2 * sin(pi / 4), 0, self.dendL.diam, sec=self.dendL) h.pt3dclear(sec=self.dendR) h.pt3dadd(0, len1, 0, self.dendR.diam, sec=self.dendR) h.pt3dadd(len2 * cos(pi / 4), len2 * sin(pi / 4), 0, self.dendR.diam, sec=self.dendR)
def basic_shape(self): h.pt3dclear(sec=self.soma) h.pt3dadd(0, 0, 0, 1, sec=self.soma) h.pt3dadd(15, 0, 0, 1, sec=self.soma) h.pt3dclear(sec=self.dend1) h.pt3dadd(15, 0, 0, 1, sec=self.dend1) h.pt3dadd(90, 0, 0, 1, sec=self.dend1) h.pt3dclear(sec=self.dend2) h.pt3dadd(0, 0, 0, 1, sec=self.dend2) h.pt3dadd(-74, 0, 0, 1, sec=self.dend2) h.pt3dclear(sec=self.axon) h.pt3dadd(15, 0, 0, 1, sec=self.axon) h.pt3dadd(15, 120, 0, 1, sec=self.axon)
def _create_sections(self, p_secs, topology): """Create soma and set geometry. Notes ----- By default neuron uses xy plane for height and xz plane for depth. This is opposite for model as a whole, but convention is followed in this function ease use of gui. """ for sec_name in p_secs: sec = h.Section(name=f'{self.name}_{sec_name}') self.sections[sec_name] = sec h.pt3dclear(sec=sec) for pt in p_secs[sec_name]['sec_pts']: h.pt3dadd(pt[0], pt[1], pt[2], 1, sec=sec) sec.L = p_secs[sec_name]['L'] sec.diam = p_secs[sec_name]['diam'] sec.Ra = p_secs[sec_name]['Ra'] sec.cm = p_secs[sec_name]['cm'] if sec.L > 100.: # 100 um sec.nseg = int(sec.L / 50.) # make dend.nseg odd for all sections if not sec.nseg % 2: sec.nseg += 1 if topology is None: topology = list() # Connects sections of THIS cell together. for connection in topology: parent_sec = self.sections[connection[0]] child_sec = self.sections[connection[2]] parent_loc = connection[1] child_loc = connection[3] child_sec.connect(parent_sec, parent_loc, child_loc)
def update_coords_and_radii(self, blender_section): self.nseg = blender_section["nseg"] self.point_count = blender_section["point_count"] self.coords = blender_section["coords"] self.radii = blender_section["radii"] nrn_section = self.nrn_section # Use 3D points as the L and diam sources h.pt3dconst(1, sec=nrn_section) # Clear the existing points - and allocate room for the incoming points h.pt3dclear(self.point_count, sec=nrn_section) # Use vectorization to add the points to section coords = np.array(self.coords).reshape((-1, 3)) diams = np.array(self.radii) * 2.0 xvec = h.Vector(coords[:, 0]) yvec = h.Vector(coords[:, 1]) zvec = h.Vector(coords[:, 2]) dvec = h.Vector(diams) h.pt3dadd(xvec, yvec, zvec, dvec, sec=nrn_section)
def basic_shape(self): self.axon.push() h.pt3dclear() h.pt3dadd(0, 0, 0, 1) h.pt3dadd(80, 0, 0, 1) h.pop_section() self.soma.push() h.pt3dclear() h.pt3dadd(80, 0, 0, 20) h.pt3dadd(100, 0, 0, 20) h.pop_section() self.dend.push() h.pt3dclear() h.pt3dadd(100, 0, 0, 2) h.pt3dadd(900, 0, 0, 2) h.pop_section()
def define_geometry(self): self.soma.nseg = 1 self.soma.L = 38.42 self.soma.diam = 26 h.pt3dclear(sec=self.soma) h.pt3dadd(0, 0, 0, 26, sec=self.soma) h.pt3dadd(0, 38.42, 0, 26, sec=self.soma) h.define_shape() self.dend1[0].nseg = 1 h.pt3dclear(sec=self.dend1[0]) h.pt3dadd(0, 38.42, 0, 10.28, sec=self.dend1[0]) h.pt3dadd(0, 50.91, 0, 10.28, sec=self.dend1[0]) h.define_shape() self.dend1[1].nseg = 1 h.pt3dclear(sec=self.dend1[1]) h.pt3dadd(0, 50.91, 0, 8.5, sec=self.dend1[1]) h.pt3dadd(0, 135.58, 0, 8.5, sec=self.dend1[1]) h.define_shape()
def __init__(self,position, record_all = 0, sigma_L = 0, gid = 0, lkg2_noise=0, lkg2_gbar=6e-5): self.record_all = record_all if record_all: print "Recording all in Grc" self.soma = h.Section(cell=self) self.soma.nseg = 1 L = 9.76 #um #(9.76e-6)**2 * 3.14159265359 * 1e-6 / (1e-2)**2 = 3 pF self.gid = gid if sigma_L == 0: self.soma.L = L self.soma.diam = L else: np.random.seed(self.gid*40) self.soma.L = np.random.normal(L, L*sigma_L, 1).clip(min=L*sigma_L) self.soma.diam = self.soma.L print "soma.L:", self.soma.L self.soma.cm = 1 self.soma.Ra = 100 # h.celsius = 37 self.lkg2_noise = lkg2_noise self.whatami = "grc" self.soma.push() h.pt3dclear() h.pt3dadd(position.item(0), position.item(1) - self.soma.L, position.item(2), self.soma.diam) h.pt3dadd(position.item(0), position.item(1) + self.soma.L, position.item(2), self.soma.diam) h.pop_section() self.record = {} self.record['L'] = h.Vector(np.array([self.soma.L])) self.record['position'] = h.Vector(position) self.soma.insert('GRANULE_LKG1') if lkg2_noise > 0: print "noise" self.noise = h.Random() # provides NOISE with random stream self.fluct = h.GRANULE_LKG2_noise(self.soma(0.5)) self.fluct.gbar = lkg2_gbar self.fluct.std_i = lkg2_noise self.fluct.tau_i = 100 self.fluct.noiseFromRandom(self.noise) # connect random generator! self.noise.MCellRan4(1, gid+1) # set lowindex to gid+1, set highindex to > 0 self.noise.normal(0,1) else: self.soma.insert('GRANULE_LKG2') #self.soma(0.5).GRANULE_LKG2.gbar = 6e-5 self.soma.insert('GRANULE_Nmda_leak') self.soma.insert('GRANULE_NA') self.soma.insert('GRANULE_NAR') self.soma.insert('GRANULE_PNA') self.soma.insert('GRANULE_KV') self.soma.insert('GRANULE_KA') self.soma.insert('GRANULE_KIR') self.soma.insert('GRANULE_KCA') self.soma.insert('GRANULE_KM') self.soma.insert('GRANULE_CA') self.soma.insert('GRANULE_CALC') h.usetable_GRANULE_NA = 1 h.usetable_GRANULE_NAR = 1 h.usetable_GRANULE_PNA = 1 h.usetable_GRANULE_KV = 1 h.usetable_GRANULE_KA = 1 h.usetable_GRANULE_KIR = 1 h.usetable_GRANULE_KCA = 0 h.usetable_GRANULE_KM = 1 h.usetable_GRANULE_CA = 1 self.soma.ena = 87.39 self.soma.ek = -84.69 self.soma.eca = 129.33 self.MF_L = [] self.GOC_L = [] self.mfncpc = [] self.gocncpc = [] self.spike = h.NetStim(0.5, sec= self.soma) self.spike.start = -10 self.spike.number = 1 self.spike.interval = 1e9 self.nc_spike = h.NetCon(self.soma(1)._ref_v, self.spike,-20,1,1, sec = self.soma) self.record['spk'] = h.Vector() self.nc_spike.record(self.record['spk']) if self.record_all: self.record['vm'] = h.Vector() self.record['vm'].record(self.soma(.5)._ref_v, sec = self.soma) self.record['time'] = h.Vector() self.record['time'].record(h._ref_t) self.nc_syn = []
def load_morphology(self): # load the tree structure that represents the morphology self.tree = btmorph.STree2() self.tree.read_SWC_tree_from_file(self.swc_filename,types=range(10)) if self.min_distance > 0.: # simplify the morphology total = len(self.tree.get_nodes()) removed = [] sys.stdout.write('Simplifying the morphology... ') sys.stdout.flush() simplify_tree(self.tree.root, self.min_distance, (SWC_types['soma'],SWC_types['axon']), removed) sys.stdout.write('removed %d nodes out of %d.\n' % (len(removed),total)) self.simplified_swc_filename = '.'.join(self.swc_filename.split('.')[:-1]) + \ '_simplified_%g_um.swc' % self.min_distance self.tree.write_SWC_tree_to_file(self.simplified_swc_filename) # all the sections, indexed by the corresponding index in the SWC file self.sections = {} # a list of all the sections that make up the soma self.soma = [] # a list of all the sections that make up the axon self.axon = [] # a list of all the sections that make up the basal dendrites self.basal = [] # a list of all the sections that make up the apical dendrites self.apical = [] # parse the tree! for node in self.tree: if node is self.tree.root: continue section = h.Section(name='sec_{0}'.format(node.index)) swc_type = node.content['p3d'].type if swc_type == SWC_types['soma']: section.cm = self.Cm['soma'] section.Ra = self.Ra['soma'] self.soma.append(section) elif swc_type == SWC_types['axon']: section.cm = self.Cm['axon'] section.Ra = self.Ra['axon'] self.axon.append(section) elif swc_type == SWC_types['basal']: section.cm = self.Cm['dend'] section.Ra = self.Ra['dend'] self.basal.append(section) elif swc_type == SWC_types['apical']: section.cm = self.Cm['dend'] section.Ra = self.Ra['dend'] self.apical.append(section) if not node.parent is None: pPos = node.parent.content['p3d'] cPos = node.content['p3d'] c_xyz = cPos.xyz p_xyz = pPos.xyz h.pt3dclear(sec=section) h.pt3dadd(float(p_xyz[0]),float(p_xyz[1]),float(p_xyz[2]),float(pPos.radius),sec=section) h.pt3dadd(float(c_xyz[0]),float(c_xyz[1]),float(c_xyz[2]),float(cPos.radius),sec=section) # nseg according to NEURON book; too high in general... section.nseg = int((section.L/(0.1*h.lambda_f(100))+0.9)/2)*2 + 1 try: section.connect(self.sections[node.parent.index],1,0) except: if not section is self.soma[0]: section.connect(self.soma[0],1,0) self.sections[node.index] = section
def createNEURONObj(self, prop): # set params for all sections for sectName,sectParams in prop['sections'].iteritems(): # create section if sectName not in self.secs: self.secs[sectName] = {} # create sect dict if doesn't exist self.secs[sectName]['hSection'] = h.Section(name=sectName) # create h Section object sec = self.secs[sectName] # pointer to section # add distributed mechanisms if 'mechs' in sectParams: for mechName,mechParams in sectParams['mechs'].iteritems(): if mechName not in sec['mechs']: sec['mechs'][mechName] = {} sec['hSection'].insert(mechName) for mechParamName,mechParamValue in mechParams.iteritems(): # add params of the mechanism mechParamValueFinal = mechParamValue for iseg,seg in enumerate(sec['hSection']): # set mech params for each segment if type(mechParamValue) in [list]: mechParamValueFinal = mechParamValue[iseg] seg.__getattribute__(mechName).__setattr__(mechParamName,mechParamValueFinal) # add point processes if 'pointps' in sectParams: for pointpName,pointpParams in sectParams['pointps'].iteritems(): #if self.tags['cellModel'] == pointpParams: # only required if want to allow setting various cell models in same rule if pointpName not in sec['pointps']: sec['pointps'][pointpName] = {} pointpObj = getattr(h, pointpParams['_type']) loc = pointpParams['_loc'] if '_loc' in pointpParams else 0.5 # set location sec['pointps'][pointpName]['hPointp'] = pointpObj(loc, sec = sec['hSection']) # create h Pointp object (eg. h.Izhi2007b) for pointpParamName,pointpParamValue in pointpParams.iteritems(): # add params of the point process if not pointpParamName.startswith('_'): setattr(sec['pointps'][pointpName]['hPointp'], pointpParamName, pointpParamValue) # add synapses if 'syns' in sectParams: for synName,synParams in sectParams['syns'].iteritems(): if synName not in sec['syns']: sec['syns'][synName] = {} synObj = getattr(h, synParams['_type']) loc = synParams['_loc'] if '_loc' in synParams else 0.5 # set location sec['syns'][synName]['hSyn'] = synObj(loc, sec = sec['hSection']) # create h Syn object (eg. h.Exp2Syn) for synParamName,synParamValue in synParams.iteritems(): # add params of the synapse if not synParamName.startswith('_'): setattr(sec['syns'][synName]['hSyn'], synParamName, synParamValue) # set geometry params if 'geom' in sectParams: for geomParamName,geomParamValue in sectParams['geom'].iteritems(): if not type(geomParamValue) in [list, dict]: # skip any list or dic params setattr(sec['hSection'], geomParamName, geomParamValue) # set 3d geometry if 'pt3d' in sectParams['geom']: h.pt3dclear(sec=sec['hSection']) x = self.tags['x'] if 'ynorm' in self.tags and 'sizeY' in f.net.params: y = self.tags['ynorm'] * f.net.params['sizeY']/1e3 # y as a func of ynorm and cortical thickness else: y = self.tags['y'] z = self.tags['z'] for pt3d in sectParams['geom']['pt3d']: h.pt3dadd(x+pt3d[0], y+pt3d[1], z+pt3d[2], pt3d[3], sec=sec['hSection']) # set topology for sectName,sectParams in prop['sections'].iteritems(): # iterate sects again for topology (ensures all exist) sec = self.secs[sectName] # pointer to section # pointer to child sec if 'topol' in sectParams: if sectParams['topol']: sec['hSection'].connect(self.secs[sectParams['topol']['parentSec']]['hSection'], sectParams['topol']['parentX'], sectParams['topol']['childX']) # make topol connection
# scale = 5 import numpy for sec in h.allsec(): if 'soma' not in sec.name(): for i in xrange(int(h.n3d(sec=sec))): d = h.diam3d(i, sec=sec) h.pt3dchange(i, d * scale, sec=sec) elif 'soma' in sec.name(): x, y, z, diam = [], [], [], [] for i in xrange(int(h.n3d(sec=sec))): x.append(h.x3d(i, sec=sec)) y.append(h.y3d(i, sec=sec)) z.append(h.z3d(i, sec=sec)) diam.append(h.diam3d(i, sec=sec)) h.pt3dclear(sec=sec) x, y, z, diam = scale * numpy.array(x), scale * numpy.array(y), scale * numpy.array(z), scale * numpy.array(diam) i = int(len(x) / 2) midptx, midpty, midptz = x[i], y[i], z[i] x -= midptx / 2. y -= midpty / 2. z -= midptz / 2. for xpt, ypt, zpt, diampt in zip(x, y, z, diam): h.pt3dadd(xpt, ypt, zpt, diampt, sec=sec) # begin with a full rotation for 40 frames for i in xrange(40): ps.rotate(0, 0, 0, 0, 6.283 / 40., 0) h.doNotify()
def fillshape(s1, s2): s2.push() h.pt3dclear() for x in s1.points: h.pt3dadd(x[0], x[1], x[2], x[3]) h.pop_section()
def shape_3D(self): h.pt3dclear(sec = self.soma[0])
def __init__(self,position): self.soma = h.Section(name='soma') self.soma.nseg = 1 self.soma.diam = 9.76 self.soma.L = 9.76 self.soma.cm = 1 self.soma.Ra = 100 #Shouldn't change a global param like this in a class... #h.celsius = 37 self.whatami = "grc" self.soma.push() h.pt3dclear() h.pt3dadd(position.item(0), position.item(1) - self.soma.L, position.item(2), self.soma.diam) h.pt3dadd(position.item(0), position.item(1) + self.soma.L, position.item(2), self.soma.diam) h.pop_section() self.soma.insert('GRANULE_LKG1') self.soma.insert('GRANULE_LKG2') self.soma.insert('GRANULE_Nmda_leak') self.soma.insert('GRANULE_NA') self.soma.insert('GRANULE_NAR') self.soma.insert('GRANULE_PNA') self.soma.insert('GRANULE_KV') self.soma.insert('GRANULE_KA') self.soma.insert('GRANULE_KIR') self.soma.insert('GRANULE_KCA') self.soma.insert('GRANULE_KM') self.soma.insert('GRANULE_CA') self.soma.insert('GRANULE_CALC') h.usetable_GRANULE_NA = 1 h.usetable_GRANULE_NAR = 1 h.usetable_GRANULE_PNA = 1 h.usetable_GRANULE_KV = 1 h.usetable_GRANULE_KA = 1 h.usetable_GRANULE_KIR = 1 h.usetable_GRANULE_KCA = 0 h.usetable_GRANULE_KM = 1 h.usetable_GRANULE_CA = 1 self.soma.ena = 87.39 self.soma.ek = -84.69 self.soma.eca = 129.33 self.MF_L = [] self.GOC_L = [] self.mfncpc = [] self.gocncpc = [] self.spike = h.NetStim(0.5, sec= self.soma) self.spike.start = -10 self.spike.number = 1 self.spike.interval = 1e9 self.nc = h.NetCon(self.soma(1)._ref_v, self.spike, sec = self.soma) self.nc.threshold=-20 self.nc.delay=0 self.nc.weight[0]=1 self.SpikeTrain_output = [h.Vector(),h.Vector()] self.nc.record(self.SpikeTrain_output[1], self.SpikeTrain_output[0], 1) self.vm = h.Vector() self.vm.record(self.soma(.5)._ref_v, sec = self.soma) self.time = h.Vector() self.time.record(h._ref_t)