def parent_loc(sec, trueparent): """Return the position on the (true) parent where sec is connected Note that h.section_orientation(sec=sec) is which end of the section is connected. """ # TODO: would I ever have a parent but not a trueparent (or vice versa) sref = h.SectionRef(sec=sec) parent = sref.parent().sec while parent != trueparent: sec, parent = parent, h.SectionRef(sec=sec).parent().sec return h.parent_connection(sec=sec)
def parent(sec): """Return the parent of sec or None if sec is a root""" sref = h.SectionRef(sec=sec) if sref.has_trueparent(): return sref.trueparent().sec elif sref.has_parent(): temp = sref.parent().sec # check if temp owns the connection point if h.SectionRef(sec=temp).has_parent() and h.parent_connection(sec=temp) == h.section_orientation(sec=temp): # connection point belongs to temp's ancestor return parent(temp) return temp else: return None
def parent(sec): """Return the parent of sec or None if sec is a root""" sref = h.SectionRef(sec=sec) if sref.has_trueparent(): return sref.trueparent().sec elif sref.has_parent(): temp = sref.parent().sec # check if temp owns the connection point if h.SectionRef(sec=temp).has_parent() and h.parent_connection( sec=temp) == h.section_orientation(sec=temp): # connection point belongs to temp's ancestor return parent(temp) return temp else: return None
def _setup_matrices(): global _linmodadd, _linmodadd_c, _diffusion_matrix, _linmodadd_b, _last_dt, _c_diagonal, _euler_matrix global _cur_node_indices global _zero_volume_indices, _nonzero_volume_indices # TODO: this sometimes seems to get called twice. Figure out why and fix, if possible. n = len(_node_get_states()) if species._has_3d: _euler_matrix = _scipy_sparse_dok_matrix((n, n), dtype=float) for sr in list(_species_get_all_species().values()): s = sr() if s is not None: s._setup_matrices3d(_euler_matrix) _diffusion_matrix = -_euler_matrix _euler_matrix = _euler_matrix.tocsr() _update_node_data(True) # NOTE: if we also have 1D, this will be replaced with the correct values below _zero_volume_indices = [] _nonzero_volume_indices = list(range(len(_node_get_states()))) if species._has_1d: n = species._1d_submatrix_n() # TODO: initialization is slow. track down why _last_dt = None _c_diagonal = None for sr in list(_species_get_all_species().values()): s = sr() if s is not None: s._assign_parents() _update_node_data(True) # remove old linearmodeladdition _linmodadd = None _linmodadd_cur = None if n: # create sparse matrix for C in cy'+gy=b _linmodadd_c = _scipy_sparse_dok_matrix((n, n)) # most entries are 1 except those corresponding to the 0 and 1 ends # create the matrix G if not species._has_3d: # if we have both, then put the 1D stuff into the matrix that already exists for 3D _diffusion_matrix = _scipy_sparse_dok_matrix((n, n)) for sr in list(_species_get_all_species().values()): s = sr() if s is not None: #print '_diffusion_matrix.shape = %r, n = %r, species._has_3d = %r' % (_diffusion_matrix.shape, n, species._has_3d) s._setup_diffusion_matrix(_diffusion_matrix) s._setup_c_matrix(_linmodadd_c) # modify C for cases where no diffusive coupling of 0, 1 ends # TODO: is there a better way to handle no diffusion? for i in range(n): if not _diffusion_matrix[i, i]: _linmodadd_c[i, i] = 1 # and the vector b _linmodadd_b = _h_vector(n) # setup for induced membrane currents _cur_node_indices = [] for rptr in _all_reactions: r = rptr() if r is not None: r._setup_membrane_fluxes(_cur_node_indices, _cur_map) #_cvode_object.re_init() _linmodadd_c = _linmodadd_c.tocsr() if species._has_3d: _euler_matrix = -_diffusion_matrix volumes = node._get_data()[0] _zero_volume_indices = numpy.where(volumes == 0)[0] _nonzero_volume_indices = volumes.nonzero()[0] if species._has_1d and species._has_3d: # TODO: add connections to matrix; for now: find them hybrid_neighbors = collections.defaultdict(lambda: []) hybrid_diams = {} dxs = set() for sr in list(_species_get_all_species().values()): s = sr() if s is not None: if s._nodes and s._secs: # have both 1D and 3D, so find the neighbors # for each of the 3D sections, find the parent sections for r in s._regions: dxs.add(r._dx) for sec in r._secs3d: parent_sec = morphology.parent(sec) # are any of these a match with a 1d section? if s._has_region_section(r, parent_sec): # this section has a 1d section that is a parent index1d, indices3d = _get_node_indices(s, r, sec, h.section_orientation(sec=sec), parent_sec, h.parent_connection(sec=sec)) hybrid_neighbors[index1d] += indices3d hybrid_diams[index1d] = parent_sec(h.parent_connection(sec=sec)).diam else: for sec1d in r._secs1d: parent_1d = morphology.parent(sec1d) if parent_1d == sec: # it is the parent of a 1d section index1d, indices3d = _get_node_indices(s, r, sec, h.parent_connection(sec=sec1d), sec1d, h.section_orientation(sec=sec1d)) hybrid_neighbors[index1d] += indices3d hybrid_diams[index1d] = sec1d(h.section_orientation(sec=sec1d)).diam break elif parent_1d == parent_sec: # it connects to the parent of a 1d section index1d, indices3d = _get_node_indices(s, r, sec, h.section_orientation(sec=sec), sec1d, h.section_orientation(sec=sec1d)) hybrid_neighbors[index1d] += indices3d hybrid_diams[index1d] = sec1d(h.section_orientation(sec=sec1d)).diam break if len(dxs) > 1: raise RxDException('currently require a unique value for dx') dx = dxs.pop() diffs = node._diffs n = len(_node_get_states()) # TODO: validate that we're doing the right thing at boundaries for index1d in list(hybrid_neighbors.keys()): neighbors3d = set(hybrid_neighbors[index1d]) # NOTE: splitting the connection area equally across all the connecting nodes area = (numpy.pi * 0.25 * hybrid_diams[index1d] ** 2) / len(neighbors3d) for i in neighbors3d: d = diffs[i] vol = node._volumes[i] rate = d * area / (vol * dx / 2.) # make the connections on the 3d side _euler_matrix[i, i] -= rate _euler_matrix[i, index1d] += rate # make the connections on the 1d side (scale by vol because conserving mass not volume) _euler_matrix[index1d, index1d] -= rate * vol _euler_matrix[index1d, i] += rate * vol #print 'index1d row sum:', sum(_euler_matrix[index1d, j] for j in xrange(n)) #print 'index1d col sum:', sum(_euler_matrix[j, index1d] for j in xrange(n)) # we do this last because of performance issues with changing sparsity of csr matrices if _diffusion_matrix is not None: _diffusion_matrix = _diffusion_matrix.tocsr() if _euler_matrix is not None: _euler_matrix = _euler_matrix.tocsr() if species._has_1d: if species._has_3d: _diffusion_matrix = -_euler_matrix n = species._1d_submatrix_n() if n: matrix = _diffusion_matrix[_zero_volume_indices].tocsr() indptr = matrix.indptr matrixdata = matrix.data count = len(_zero_volume_indices) for row, i in enumerate(_zero_volume_indices): d = _diffusion_matrix[i, i] if d: matrixdata[indptr[row] : indptr[row + 1]] /= -d matrix[row, i] = 0 else: matrixdata[indptr[row] : indptr[row + 1]] = 0 global _mat_for_zero_volume_nodes _mat_for_zero_volume_nodes = matrix # TODO: _mat_for_zero_volume_nodes is used for CVode. # Figure out if/how it has to be changed for hybrid 1D/3D sims (probably just augment with identity? or change how its used to avoid multiplying by I) """
def parents(secs): return ['%s(%g)' % (h.SectionRef(sec=sec).parent().sec.name(), h.parent_connection(sec=sec)) if h.SectionRef(sec=sec).has_parent() else None for sec in secs]
def _setup_matrices(): global _linmodadd, _linmodadd_c, _diffusion_matrix, _linmodadd_b, _last_dt, _c_diagonal, _euler_matrix global _cur_node_indices global _zero_volume_indices, _nonzero_volume_indices # TODO: this sometimes seems to get called twice. Figure out why and fix, if possible. n = len(_node_get_states()) if species._has_3d: _euler_matrix = _scipy_sparse_dok_matrix((n, n), dtype=float) for sr in list(_species_get_all_species().values()): s = sr() if s is not None: s._setup_matrices3d(_euler_matrix) _diffusion_matrix = -_euler_matrix _euler_matrix = _euler_matrix.tocsr() _update_node_data(True) # NOTE: if we also have 1D, this will be replaced with the correct values below _zero_volume_indices = [] _nonzero_volume_indices = list(range(len(_node_get_states()))) if species._has_1d: n = species._1d_submatrix_n() # TODO: initialization is slow. track down why _last_dt = None _c_diagonal = None for sr in list(_species_get_all_species().values()): s = sr() if s is not None: s._assign_parents() _update_node_data(True) # remove old linearmodeladdition _linmodadd = None _linmodadd_cur = None if n: # create sparse matrix for C in cy'+gy=b _linmodadd_c = _scipy_sparse_dok_matrix((n, n)) # most entries are 1 except those corresponding to the 0 and 1 ends # create the matrix G if not species._has_3d: # if we have both, then put the 1D stuff into the matrix that already exists for 3D _diffusion_matrix = _scipy_sparse_dok_matrix((n, n)) for sr in list(_species_get_all_species().values()): s = sr() if s is not None: #print '_diffusion_matrix.shape = %r, n = %r, species._has_3d = %r' % (_diffusion_matrix.shape, n, species._has_3d) s._setup_diffusion_matrix(_diffusion_matrix) s._setup_c_matrix(_linmodadd_c) # modify C for cases where no diffusive coupling of 0, 1 ends # TODO: is there a better way to handle no diffusion? for i in range(n): if not _diffusion_matrix[i, i]: _linmodadd_c[i, i] = 1 # and the vector b _linmodadd_b = _h_vector(n) # setup for induced membrane currents _cur_node_indices = [] for rptr in _all_reactions: r = rptr() if r is not None: r._setup_membrane_fluxes(_cur_node_indices, _cur_map) #_cvode_object.re_init() _linmodadd_c = _linmodadd_c.tocsr() if species._has_3d: _euler_matrix = -_diffusion_matrix volumes = node._get_data()[0] _zero_volume_indices = numpy.where(volumes == 0)[0] _nonzero_volume_indices = volumes.nonzero()[0] if species._has_1d and species._has_3d: # TODO: add connections to matrix; for now: find them hybrid_neighbors = collections.defaultdict(lambda: []) hybrid_diams = {} dxs = set() for sr in list(_species_get_all_species().values()): s = sr() if s is not None: if s._nodes and s._secs: # have both 1D and 3D, so find the neighbors # for each of the 3D sections, find the parent sections for r in s._regions: dxs.add(r._dx) for sec in r._secs3d: parent_sec = morphology.parent(sec) # are any of these a match with a 1d section? if s._has_region_section(r, parent_sec): # this section has a 1d section that is a parent index1d, indices3d = _get_node_indices( s, r, sec, h.section_orientation(sec=sec), parent_sec, h.parent_connection(sec=sec)) hybrid_neighbors[index1d] += indices3d hybrid_diams[index1d] = parent_sec( h.parent_connection(sec=sec)).diam else: for sec1d in r._secs1d: parent_1d = morphology.parent(sec1d) if parent_1d == sec: # it is the parent of a 1d section index1d, indices3d = _get_node_indices( s, r, sec, h.parent_connection(sec=sec1d), sec1d, h.section_orientation(sec=sec1d)) hybrid_neighbors[index1d] += indices3d hybrid_diams[index1d] = sec1d( h.section_orientation( sec=sec1d)).diam break elif parent_1d == parent_sec: # it connects to the parent of a 1d section index1d, indices3d = _get_node_indices( s, r, sec, h.section_orientation(sec=sec), sec1d, h.section_orientation(sec=sec1d)) hybrid_neighbors[index1d] += indices3d hybrid_diams[index1d] = sec1d( h.section_orientation( sec=sec1d)).diam break if len(dxs) > 1: raise RxDException('currently require a unique value for dx') dx = dxs.pop() diffs = node._diffs n = len(_node_get_states()) # TODO: validate that we're doing the right thing at boundaries for index1d in list(hybrid_neighbors.keys()): neighbors3d = set(hybrid_neighbors[index1d]) # NOTE: splitting the connection area equally across all the connecting nodes area = (numpy.pi * 0.25 * hybrid_diams[index1d]**2) / len(neighbors3d) for i in neighbors3d: d = diffs[i] vol = node._volumes[i] rate = d * area / (vol * dx / 2.) # make the connections on the 3d side _euler_matrix[i, i] -= rate _euler_matrix[i, index1d] += rate # make the connections on the 1d side (scale by vol because conserving mass not volume) _euler_matrix[index1d, index1d] -= rate * vol _euler_matrix[index1d, i] += rate * vol #print 'index1d row sum:', sum(_euler_matrix[index1d, j] for j in xrange(n)) #print 'index1d col sum:', sum(_euler_matrix[j, index1d] for j in xrange(n)) # we do this last because of performance issues with changing sparsity of csr matrices if _diffusion_matrix is not None: _diffusion_matrix = _diffusion_matrix.tocsr() if _euler_matrix is not None: _euler_matrix = _euler_matrix.tocsr() if species._has_1d: if species._has_3d: _diffusion_matrix = -_euler_matrix n = species._1d_submatrix_n() if n: matrix = _diffusion_matrix[_zero_volume_indices].tocsr() indptr = matrix.indptr matrixdata = matrix.data count = len(_zero_volume_indices) for row, i in enumerate(_zero_volume_indices): d = _diffusion_matrix[i, i] if d: matrixdata[indptr[row]:indptr[row + 1]] /= -d matrix[row, i] = 0 else: matrixdata[indptr[row]:indptr[row + 1]] = 0 global _mat_for_zero_volume_nodes _mat_for_zero_volume_nodes = matrix # TODO: _mat_for_zero_volume_nodes is used for CVode. # Figure out if/how it has to be changed for hybrid 1D/3D sims (probably just augment with identity? or change how its used to avoid multiplying by I) """
def getCellParams(cell): dirCell = dir(cell) if 'all_sec' in dirCell: secs = cell.all_sec elif 'sec' in dirCell: secs = [cell.sec] elif 'allsec' in dir(h): secs = [sec for sec in h.allsec()] elif 'soma' in dirCell: secs = [cell.soma] else: secs = [] # create dict with hname of each element in dir(cell) dirCellHnames = {} for dirCellName in dirCell: try: dirCellHnames.update( {getattr(cell, dirCellName).hname(): dirCellName}) except: pass # create dict with dir(cell) name corresponding to each hname dirCellSecNames = {} for sec in secs: dirCellSecNames.update({ hname: name for hname, name in dirCellHnames.iteritems() if hname == sec.hname() }) secDic = {} synMechs = [] for sec in secs: # create new section dict with name of section secName = getSecName(sec, dirCellSecNames) if len(secs) == 1: secName = 'soma' # if just one section rename to 'soma' secDic[secName] = { 'geom': {}, 'topol': {}, 'mechs': {} } # create dictionary to store sec info # store geometry properties standardGeomParams = ['L', 'nseg', 'diam', 'Ra', 'cm'] secDir = dir(sec) for geomParam in standardGeomParams: #if geomParam in secDir: try: secDic[secName]['geom'][geomParam] = sec.__getattribute__( geomParam) except: pass # store 3d geometry sec.push() # access current section so ismembrane() works numPoints = int(h.n3d()) if numPoints: points = [] for ipoint in range(numPoints): x = h.x3d(ipoint) y = h.y3d(ipoint) z = h.z3d(ipoint) diam = h.diam3d(ipoint) points.append((x, y, z, diam)) secDic[secName]['geom']['pt3d'] = points # store mechanisms varList = mechVarList( ) # list of properties for all density mechanisms and point processes ignoreMechs = ['dist'] # dist only used during cell creation ignoreVars = [] # mechDic = {} ionDic = {} for mech in dir(sec(0.5)): if h.ismembrane( mech ) and mech not in ignoreMechs: # check if membrane mechanism if not mech.endswith('_ion'): # exclude ions mechDic[mech] = {} # create dic for mechanism properties varNames = [ varName.replace('_' + mech, '') for varName in varList['mechs'][mech] ] varVals = [] for varName in varNames: if varName not in ignoreVars: try: varVals = [ seg.__getattribute__( mech).__getattribute__(varName) for seg in sec ] if len(set(varVals)) == 1: varVals = varVals[0] mechDic[mech][varName] = varVals except: pass #print 'Could not read variable %s from mechanism %s'%(varName,mech) # store ions elif mech.endswith('_ion'): ionName = mech.split('_ion')[0] varNames = [ varName.replace('_' + mech, '').replace(ionName, '') for varName in varList['mechs'][mech] ] varNames.append('e') varVals = [] ionDic[ionName] = {} # create dic for mechanism properties for varName in varNames: varNameSplit = varName if varName not in ignoreVars: try: varVals = [ seg.__getattribute__(varNameSplit + ionName) for seg in sec ] if len(set(varVals)) == 1: varVals = varVals[0] ionDic[ionName][varNameSplit] = varVals except: pass #print 'Could not read variable %s from mechanism %s'%(varName,mech) secDic[secName]['mechs'] = mechDic if len(ionDic) > 0: secDic[secName]['ions'] = ionDic # add synapses and point neurons # for now read fixed params, but need to find way to read only synapse params pointps = {} for seg in sec: for ipoint, point in enumerate(seg.point_processes()): pointpMod = point.hname().split('[')[0] varNames = varList['pointps'][pointpMod] if any([ s in pointpMod.lower() for s in ['syn', 'ampa', 'gaba', 'nmda', 'glu'] ]): #if 'synMech' in pptype.lower(): # if syn in name of point process then assume synapse synMech = {} synMech['label'] = pointpMod + '_' + str(len(synMechs)) synMech['mod'] = pointpMod #synMech['loc'] = seg.x for varName in varNames: try: synMech[varName] = point.__getattribute__(varName) except: print 'Could not read variable %s from synapse %s' % ( varName, synMech['label']) if not [ _equal_dicts( synMech, synMech2, ignore_keys=['label']) for synMech2 in synMechs ]: synMechs.append(synMech) else: # assume its a non-synapse point process pointpName = pointpMod + '_' + str(len(pointps)) pointps[pointpName] = {} pointps[pointpName]['mod'] = pointpMod pointps[pointpName]['loc'] = seg.x for varName in varNames: try: pointps[pointpName][ varName] = point.__getattribute__(varName) # special condition for Izhi model, to set vinit=vr # if varName == 'vr': secDic[secName]['vinit'] = point.__getattribute__(varName) except: print 'Could not read %s variable from point process %s' % ( varName, pointpName) if pointps: secDic[secName]['pointps'] = pointps # store topology (keep at the end since h.SectionRef messes remaining loop) secRef = h.SectionRef(sec=sec) if secRef.has_parent(): secDic[secName]['topol']['parentSec'] = getSecName( secRef.parent().sec, dirCellSecNames) secDic[secName]['topol']['parentX'] = h.parent_connection() secDic[secName]['topol']['childX'] = h.section_orientation() h.pop_section() # to prevent section stack overflow # store section lists secLists = h.List('SectionList') if int(secLists.count()): secListDic = {} for i in xrange(int(secLists.count())): # loop over section lists hname = secLists.o(i).hname() if hname in dirCellHnames: # use python variable name secListName = dirCellHnames[hname] else: secListName = hname secListDic[secListName] = [ getSecName(sec, dirCellSecNames) for sec in secLists.o(i) ] else: secListDic = {} # celsius warning if hasattr(h, 'celsius'): if h.celsius != 6.3: # if not default value print "Warning: h.celsius=%.4g in imported file -- you can set this value in simConfig['hParams']['celsius']" % ( h.celsius) # clean h.initnrn() del (cell) # delete cell import gc gc.collect() return secDic, secListDic, synMechs
def getCellParams(cell): dirCell = dir(cell) if 'all_sec' in dirCell: secs = cell.all_sec elif 'sec' in dirCell: secs = [cell.sec] elif 'allsec' in dir(h): secs = [sec for sec in h.allsec()] elif 'soma' in dirCell: secs = [cell.soma] else: secs = [] # create dict with hname of each element in dir(cell) dirCellHnames = {} for dirCellName in dirCell: try: dirCellHnames.update({getattr(cell, dirCellName).hname(): dirCellName}) except: pass # create dict with dir(cell) name corresponding to each hname dirCellSecNames = {} for sec in secs: dirCellSecNames.update({hname: name for hname,name in dirCellHnames.iteritems() if hname == sec.hname()}) secDic = {} synMechs = [] for sec in secs: # create new section dict with name of section secName = getSecName(sec, dirCellSecNames) if len(secs) == 1: secName = 'soma' # if just one section rename to 'soma' secDic[secName] = {'geom': {}, 'topol': {}, 'mechs': {}} # create dictionary to store sec info # store geometry properties standardGeomParams = ['L', 'nseg', 'diam', 'Ra', 'cm'] secDir = dir(sec) for geomParam in standardGeomParams: #if geomParam in secDir: try: secDic[secName]['geom'][geomParam] = sec.__getattribute__(geomParam) except: pass # store 3d geometry sec.push() # access current section so ismembrane() works numPoints = int(h.n3d()) if numPoints: points = [] for ipoint in range(numPoints): x = h.x3d(ipoint) y = h.y3d(ipoint) z = h.z3d(ipoint) diam = h.diam3d(ipoint) points.append((x, y, z, diam)) secDic[secName]['geom']['pt3d'] = points # store mechanisms varList = mechVarList() # list of properties for all density mechanisms and point processes ignoreMechs = ['dist'] # dist only used during cell creation ignoreVars = [] # mechDic = {} ionDic = {} for mech in dir(sec(0.5)): if h.ismembrane(mech) and mech not in ignoreMechs: # check if membrane mechanism if not mech.endswith('_ion'): # exclude ions mechDic[mech] = {} # create dic for mechanism properties varNames = [varName.replace('_'+mech, '') for varName in varList['mechs'][mech]] varVals = [] for varName in varNames: if varName not in ignoreVars: try: varVals = [seg.__getattribute__(mech).__getattribute__(varName) for seg in sec] if len(set(varVals)) == 1: varVals = varVals[0] mechDic[mech][varName] = varVals except: pass #print 'Could not read variable %s from mechanism %s'%(varName,mech) # store ions elif mech.endswith('_ion'): ionName = mech.split('_ion')[0] varNames = [varName.replace('_'+mech, '').replace(ionName,'') for varName in varList['mechs'][mech]] varNames.append('e') varVals = [] ionDic[ionName] = {} # create dic for mechanism properties for varName in varNames: varNameSplit = varName if varName not in ignoreVars: try: varVals = [seg.__getattribute__(varNameSplit+ionName) for seg in sec] if len(set(varVals)) == 1: varVals = varVals[0] ionDic[ionName][varNameSplit] = varVals except: pass #print 'Could not read variable %s from mechanism %s'%(varName,mech) secDic[secName]['mechs'] = mechDic if len(ionDic)>0: secDic[secName]['ions'] = ionDic # add synapses and point neurons # for now read fixed params, but need to find way to read only synapse params pointps = {} for seg in sec: for ipoint,point in enumerate(seg.point_processes()): pointpMod = point.hname().split('[')[0] varNames = varList['pointps'][pointpMod] if any([s in pointpMod.lower() for s in ['syn', 'ampa', 'gaba', 'nmda', 'glu']]): #if 'synMech' in pptype.lower(): # if syn in name of point process then assume synapse synMech = {} synMech['label'] = pointpMod + '_' + str(len(synMechs)) synMech['mod'] = pointpMod #synMech['loc'] = seg.x for varName in varNames: try: synMech[varName] = point.__getattribute__(varName) except: print 'Could not read variable %s from synapse %s'%(varName,synMech['label']) if not [_equal_dicts(synMech, synMech2, ignore_keys=['label']) for synMech2 in synMechs]: synMechs.append(synMech) else: # assume its a non-synapse point process pointpName = pointpMod + '_'+ str(len(pointps)) pointps[pointpName] = {} pointps[pointpName]['mod'] = pointpMod pointps[pointpName]['loc'] = seg.x for varName in varNames: try: pointps[pointpName][varName] = point.__getattribute__(varName) # special condition for Izhi model, to set vinit=vr # if varName == 'vr': secDic[secName]['vinit'] = point.__getattribute__(varName) except: print 'Could not read %s variable from point process %s'%(varName,pointpName) if pointps: secDic[secName]['pointps'] = pointps # store topology (keep at the end since h.SectionRef messes remaining loop) secRef = h.SectionRef(sec=sec) if secRef.has_parent(): secDic[secName]['topol']['parentSec'] = getSecName(secRef.parent().sec, dirCellSecNames) secDic[secName]['topol']['parentX'] = h.parent_connection() secDic[secName]['topol']['childX'] = h.section_orientation() h.pop_section() # to prevent section stack overflow # store section lists secLists = h.List('SectionList') if int(secLists.count()): secListDic = {} for i in xrange(int(secLists.count())): # loop over section lists hname = secLists.o(i).hname() if hname in dirCellHnames: # use python variable name secListName = dirCellHnames[hname] else: secListName = hname secListDic[secListName] = [getSecName(sec, dirCellSecNames) for sec in secLists.o(i)] else: secListDic = {} # celsius warning if hasattr(h, 'celsius'): if h.celsius != 6.3: # if not default value print "Warning: h.celsius=%.4g in imported file -- you can set this value in simConfig['hParams']['celsius']"%(h.celsius) # clean h.initnrn() del(cell) # delete cell import gc; gc.collect() return secDic, secListDic, synMechs
def getCellParams(cell, varList={}, origGlob={}): dirCell = dir(cell) if 'all_sec' in dirCell: secs = cell.all_sec elif 'sec' in dirCell: secs = [cell.sec] elif 'allsec' in dir(h): secs = [sec for sec in h.allsec()] elif 'soma' in dirCell: secs = [cell.soma] else: secs = [] # create dict with hname of each element in dir(cell) dirCellHnames = {} for dirCellName in [d for d in dirCell if not d.startswith('__') ]: # avoid attributes starting with '__' dirCellObject = getattr(cell, dirCellName) if isinstance(dirCellObject, list): for i, dirCellObjectItem in enumerate(dirCellObject): try: if dirCellObjectItem.hname( ) not in dirCellHnames: # give preference to dict entries dirCellHnames.update({ dirCellObjectItem.hname(): dirCellName + '_' + str(i) }) except: pass elif isinstance(dirCellObject, dict): for k, v in dirCellObject.items(): try: dirCellHnames.update({v.hname(): k}) except: pass else: try: dirCellHnames.update({dirCellObject.hname(): dirCellName}) except: pass # create dict with dir(cell) name corresponding to each hname dirCellSecNames = {} for sec in secs: dirCellSecNames.update({ hname: name for hname, name in dirCellHnames.items() if hname == sec.hname() }) secDic = {} synMechs = [] for sec in secs: # create new section dict with name of section secName = getSecName(sec, dirCellSecNames) # if len(secs) == 1: secName = 'soma' # if just one section rename to 'soma' -- REMOVED, doesn't always apply secDic[secName] = { 'geom': {}, 'topol': {}, 'mechs': {} } # create dictionary to store sec info # store geometry properties standardGeomParams = ['L', 'nseg', 'diam', 'Ra', 'cm'] secDir = dir(sec) for geomParam in standardGeomParams: #if geomParam in secDir: try: secDic[secName]['geom'][geomParam] = sec.__getattribute__( geomParam) except: pass # store 3d geometry sec.push() # access current section so ismembrane() works numPoints = int(h.n3d()) if numPoints: points = [] for ipoint in range(numPoints): x = h.x3d(ipoint) y = h.y3d(ipoint) z = h.z3d(ipoint) diam = h.diam3d(ipoint) points.append((x, y, z, diam)) secDic[secName]['geom']['pt3d'] = points # store mechanisms #varList = mechVarList() # list of properties for all density mechanisms and point processes ignoreMechs = ['dist'] # dist only used during cell creation ignoreVars = [] # mechDic = {} ionDic = {} for mech in dir(sec(0.5)): if h.ismembrane( mech ) and mech not in ignoreMechs: # check if membrane mechanism if not mech.endswith('_ion'): # exclude ions mechDic[mech] = {} # create dic for mechanism properties varNames = [ varName.replace('_' + mech, '') for varName in varList['mechs'][mech] ] varVals = [] for varName in varNames: if varName not in ignoreVars: try: varVals = [ seg.__getattribute__( mech).__getattribute__(varName) for seg in sec ] if len(set(varVals)) == 1: varVals = varVals[0] mechDic[mech][varName] = varVals except: pass #print 'Could not read variable %s from mechanism %s'%(varName,mech) # store ions elif mech.endswith('_ion'): ionName = mech.split('_ion')[0] varNames = [ varName.replace('_' + mech, '').replace(ionName, '') for varName in varList['mechs'][mech] ] varNames.append('e') varVals = [] ionDic[ionName] = {} # create dic for mechanism properties for varName in varNames: varNameSplit = varName if varName not in ignoreVars: try: if varNameSplit in [ 'i', 'o' ]: # var name after ion name (eg. 'nai', 'nao') varVals = [ seg.__getattribute__(ionName + varNameSplit) for seg in sec ] else: # var name before ion name (eg. 'ena') varVals = [ seg.__getattribute__(varNameSplit + ionName) for seg in sec ] if len(set(varVals)) == 1: varVals = varVals[0] ionDic[ionName][varNameSplit] = varVals except: pass #print 'Could not read variable %s from mechanism %s'%(varName,mech) secDic[secName]['mechs'] = mechDic if len(ionDic) > 0: secDic[secName]['ions'] = ionDic # add synapses and point neurons # for now read fixed params, but need to find way to read only synapse params pointps = {} for seg in sec: for ipoint, point in enumerate(seg.point_processes()): pointpMod = point.hname().split('[')[0] varNames = varList['pointps'][pointpMod] if any([ s in pointpMod.lower() for s in ['syn', 'ampa', 'gaba', 'nmda', 'glu'] ]): #if 'synMech' in pptype.lower(): # if syn in name of point process then assume synapse synMech = {} synMech['label'] = pointpMod + '_' + str(len(synMechs)) synMech['mod'] = pointpMod #synMech['loc'] = seg.x for varName in varNames: try: synMech[varName] = point.__getattribute__(varName) except: print( 'Could not read variable %s from synapse %s' % (varName, synMech['label'])) if not any([ _equal_dicts( synMech, synMech2, ignore_keys=['label']) for synMech2 in synMechs ]): synMechs.append(synMech) else: # assume its a non-synapse point process pointpName = pointpMod + '_' + str(len(pointps)) pointps[pointpName] = {} pointps[pointpName]['mod'] = pointpMod pointps[pointpName]['loc'] = seg.x for varName in varNames: try: pointps[pointpName][ varName] = point.__getattribute__(varName) # special condition for Izhi model, to set vinit=vr # if varName == 'vr': secDic[secName]['vinit'] = point.__getattribute__(varName) except: print( 'Could not read %s variable from point process %s' % (varName, pointpName)) if pointps: secDic[secName]['pointps'] = pointps # store topology (keep at the end since h.SectionRef messes remaining loop) secRef = h.SectionRef(sec=sec) if secRef.has_parent(): secDic[secName]['topol']['parentSec'] = getSecName( secRef.parent().sec, dirCellSecNames) secDic[secName]['topol']['parentX'] = h.parent_connection() secDic[secName]['topol']['childX'] = h.section_orientation() h.pop_section() # to prevent section stack overflow # store section lists secLists = h.List('SectionList') if int(secLists.count()): secListDic = {} for i in range(int(secLists.count())): # loop over section lists hname = secLists.o(i).hname() if hname in dirCellHnames: # use python variable name secListName = dirCellHnames[hname] else: secListName = hname secListDic[secListName] = [ getSecName(sec, dirCellSecNames) for sec in secLists.o(i) ] else: secListDic = {} # globals mechsList = list(varList['mechs'].keys()) if 'mechs' in varList else [] pointpsList = list( varList['pointps'].keys()) if 'pointps' in varList else [] globs = getGlobals(mechsList + pointpsList, origGlob=origGlob) if 'v_init' in globs: # set v_init for each section (allows for cells with differnet vinits) for sec in list(secDic.values()): sec['vinit'] = globs['v_init'] # clean cell = None for i in range(len(secs)): tmp = secs.pop() del tmp import gc gc.collect() return secDic, secListDic, synMechs, globs
def importCell (fileName, cellName, cellArgs = None): h.initnrn() if cellArgs is None: cellArgs = [] # Define as empty list if not otherwise defined ''' Import cell from HOC template or python file into framework format (dict of sections, with geom, topol, mechs, syns)''' if fileName.endswith('.hoc'): h.load_file(fileName) if isinstance(cellArgs, dict): cell = getattr(h, cellName)(**cellArgs) # create cell using template, passing dict with args else: cell = getattr(h, cellName)(*cellArgs) # create cell using template, passing list with args secs = list(cell.allsec()) dirCell = dir(cell) elif fileName.endswith('.py'): filePath,fileNameOnly = os.path.split(fileName) # split path from filename if filePath not in sys.path: # add to path if not there (need to import module) sys.path.insert(0, filePath) moduleName = fileNameOnly.split('.py')[0] # remove .py to obtain module name exec('import ' + moduleName + ' as tempModule') in globals(), locals() # import module dynamically modulePointer = tempModule if isinstance(cellArgs, dict): cell = getattr(modulePointer, cellName)(**cellArgs) # create cell using template, passing dict with args else: cell = getattr(modulePointer, cellName)(*cellArgs) # create cell using template, passing list with args dirCell = dir(cell) if 'all_sec' in dirCell: secs = cell.all_sec elif 'sec' in dirCell: secs = [cell.sec] elif 'allsec' in dir(h): secs = [sec for sec in h.allsec()] elif 'soma' in dirCell: secs = [cell.soma] else: secs = [] sys.path.remove(filePath) else: print "File name should be either .hoc or .py file" return # create dict with hname of each element in dir(cell) dirCellHnames = {} for dirCellName in dirCell: try: dirCellHnames.update({getattr(cell, dirCellName).hname(): dirCellName}) except: pass # create dict with dir(cell) name corresponding to each hname dirCellSecNames = {} for sec in secs: dirCellSecNames.update({hname: name for hname,name in dirCellHnames.iteritems() if hname == sec.hname()}) secDic = {} synMechs = [] for sec in secs: # create new section dict with name of section secName = getSecName(sec, dirCellSecNames) if len(secs) == 1: secName = 'soma' # if just one section rename to 'soma' secDic[secName] = {'geom': {}, 'topol': {}, 'mechs': {}} # create dictionary to store sec info # store geometry properties standardGeomParams = ['L', 'nseg', 'diam', 'Ra', 'cm'] secDir = dir(sec) for geomParam in standardGeomParams: #if geomParam in secDir: try: secDic[secName]['geom'][geomParam] = sec.__getattribute__(geomParam) except: pass # store 3d geometry numPoints = int(h.n3d()) if numPoints: points = [] for ipoint in range(numPoints): x = h.x3d(ipoint) y = h.y3d(ipoint) z = h.z3d(ipoint) diam = h.diam3d(ipoint) points.append((x, y, z, diam)) secDic[secName]['geom']['pt3d'] = points # store mechanisms varList = mechVarList() # list of properties for all density mechanisms and point processes ignoreMechs = ['dist'] # dist only used during cell creation mechDic = {} sec.push() # access current section so ismembrane() works for mech in dir(sec(0.5)): if h.ismembrane(mech) and mech not in ignoreMechs: # check if membrane mechanism mechDic[mech] = {} # create dic for mechanism properties varNames = [varName.replace('_'+mech, '') for varName in varList['mechs'][mech]] varVals = [] for varName in varNames: try: varVals = [seg.__getattribute__(mech).__getattribute__(varName) for seg in sec] if len(set(varVals)) == 1: varVals = varVals[0] mechDic[mech][varName] = varVals except: pass #print 'Could not read variable %s from mechanism %s'%(varName,mech) secDic[secName]['mechs'] = mechDic # add synapses and point neurons # for now read fixed params, but need to find way to read only synapse params pointps = {} for seg in sec: for ipoint,point in enumerate(seg.point_processes()): pointpMod = point.hname().split('[')[0] varNames = varList['pointps'][pointpMod] if any([s in pointpMod.lower() for s in ['syn', 'ampa', 'gaba', 'nmda', 'glu']]): #if 'synMech' in pptype.lower(): # if syn in name of point process then assume synapse synMech = {} synMech['label'] = pointpMod + '_' + str(len(synMechs)) synMech['mod'] = pointpMod #synMech['loc'] = seg.x for varName in varNames: try: synMech[varName] = point.__getattribute__(varName) except: print 'Could not read variable %s from synapse %s'%(varName,synMech['label']) if not [_equal_dicts(synMech, synMech2, ignore_keys=['label']) for synMech2 in synMechs]: synMechs.append(synMech) else: # assume its a non-synapse point process pointpName = pointpMod + '_'+ str(len(pointps)) pointps[pointpName] = {} pointps[pointpName]['mod'] = pointpMod pointps[pointpName]['loc'] = seg.x for varName in varNames: try: pointps[pointpName][varName] = point.__getattribute__(varName) # special condition for Izhi model, to set vinit=vr # if varName == 'vr': secDic[secName]['vinit'] = point.__getattribute__(varName) except: print 'Could not read %s variable from point process %s'%(varName,pointpName) if pointps: secDic[secName]['pointps'] = pointps # store topology (keep at the end since h.SectionRef messes remaining loop) secRef = h.SectionRef(sec=sec) if secRef.has_parent(): secDic[secName]['topol']['parentSec'] = getSecName(secRef.parent().sec, dirCellSecNames) secDic[secName]['topol']['parentX'] = h.parent_connection() secDic[secName]['topol']['childX'] = h.section_orientation() h.pop_section() # to prevent section stack overflow # # store synMechs in input argument # if synMechs: # for synMech in synMechs: synMechParams.append(synMech) # store section lists secLists = h.List('SectionList') if int(secLists.count()): secListDic = {} for i in xrange(int(secLists.count())): # loop over section lists hname = secLists.o(i).hname() if hname in dirCellHnames: # use python variable name secListName = dirCellHnames[hname] else: secListName = hname secListDic[secListName] = [getSecName(sec, dirCellSecNames) for sec in secLists.o(i)] else: secListDic = {} # celsius warning if hasattr(h, 'celsius'): if h.celsius != 6.3: # if not default value print "Warning: h.celsius=%.4g in imported file %s -- you can set this value in simConfig['hParams']['celsius']"%(h.celsius, fileName) # clean h.initnrn() del(cell) # delete cell import gc; gc.collect() return secDic, secListDic, synMechs
def importCell(fileName, cellName, cellArgs = {}): ''' Import cell from HOC template or python file into framework format (dict of sections, with geom, topol, mechs, syns)''' if fileName.endswith('.hoc'): h.load_file(fileName) cell = getattr(h, cellName)(**cellArgs) # arguments correspond to zloc, type and id -- remove in future (not used internally) secList = list(cell.allsec()) dirCell = dir(cell) elif fileName.endswith('.py'): filePath,fileNameOnly = os.path.split(fileName) # split path from filename if filePath not in sys.path: # add to path if not there (need to import module) sys.path.insert(0, filePath) moduleName = fileNameOnly.split('.py')[0] # remove .py to obtain module name exec('import ' + moduleName + ' as tempModule') in globals(), locals() # import module dynamically modulePointer = tempModule cell = getattr(modulePointer, cellName)(**cellArgs) # create cell and pass type as argument dirCell = dir(cell) if 'all_sec' in dirCell: secList = cell.all_sec elif 'sec' in dirCell: secList = [cell.sec] elif 'allsec' in dir(h): secList = [sec for sec in h.allsec()] elif 'soma' in dirCell: secList = [cell.soma] else: secList = [] sys.path.remove(filePath) else: print "File name should be either .hoc or .py file" return # create dict with hname of each element in dir(cell) dirCellHnames = {} for dirCellName in dirCell: try: dirCellHnames.update({cell.__dict__[dirCellName].hname(): dirCellName}) except: pass # create dict with dir(cell) name corresponding to each hname dirCellSecNames = {} for sec in secList: dirCellSecNames.update({hname: name for hname,name in dirCellHnames.iteritems() if hname == sec.hname()}) secDic = {} for sec in secList: # create new section dict with name of section secName = getSecName(sec, dirCellSecNames) if len(secList) == 1: secName = 'soma' # if just one section rename to 'soma' secDic[secName] = {'geom': {}, 'topol': {}, 'mechs': {}, 'syns': {}} # create dictionary to store sec info # store geometry properties standardGeomParams = ['L', 'nseg', 'diam', 'Ra', 'cm'] secDir = dir(sec) for geomParam in standardGeomParams: #if geomParam in secDir: try: secDic[secName]['geom'][geomParam] = sec.__getattribute__(geomParam) except: pass # store 3d geometry numPoints = int(h.n3d()) if numPoints: points = [] for ipoint in range(numPoints): x = h.x3d(ipoint) y = h.y3d(ipoint) z = h.z3d(ipoint) diam = h.diam3d(ipoint) points.append((x, y, z, diam)) secDic[secName]['geom']['pt3d'] = points # store mechanisms varList = mechVarList() # list of properties for all density mechanisms and point processes ignoreMechs = ['dist'] # dist only used during cell creation mechDic = {} for mech in dir(sec(0.5)): if h.ismembrane(mech) and mech not in ignoreMechs: # check if membrane mechanism mechDic[mech] = {} # create dic for mechanism properties varNames = [varName.replace('_'+mech, '') for varName in varList['mechs'][mech]] varVals = [] for varName in varNames: try: varVals = [seg.__getattribute__(mech).__getattribute__(varName) for seg in sec] if len(set(varVals)) == 1: varVals = varVals[0] mechDic[mech][varName] = varVals except: pass #print 'Could not read variable %s from mechanism %s'%(varName,mech) secDic[secName]['mechs'] = mechDic # add synapses and point neurons # for now read fixed params, but need to find way to read only synapse params syns = {} pointps = {} for seg in sec: for ipoint,point in enumerate(seg.point_processes()): pptype = point.hname().split('[')[0] varNames = varList['pointps'][pptype] if any([s in pptype.lower() for s in ['syn', 'ampa', 'gaba', 'nmda', 'glu']]): #if 'syn' in pptype.lower(): # if syn in name of point process then assume synapse synName = pptype + '_' + str(len(syns)) syns[synName] = {} syns[synName]['_type'] = pptype syns[synName]['_loc'] = seg.x for varName in varNames: try: syns[synName][varName] = point.__getattribute__(varName) except: print 'Could not read variable %s from synapse %s'%(varName,synName) else: # assume its a non-synapse point process pointpName = pptype + '_'+ str(len(pointps)) pointps[pointpName] = {} pointps[pointpName]['_type'] = pptype pointps[pointpName]['_loc'] = seg.x for varName in varNames: try: pointps[pointpName][varName] = point.__getattribute__(varName) # special condition for Izhi model, to set vinit=vr # if varName == 'vr': secDic[secName]['vinit'] = point.__getattribute__(varName) except: print 'Could not read %s variable from point process %s'%(varName,synName) if syns: secDic[secName]['syns'] = syns if pointps: secDic[secName]['pointps'] = pointps # store topology (keep at the end since h.SectionRef messes remaining loop) secRef = h.SectionRef(sec=sec) if secRef.has_parent(): secDic[secName]['topol']['parentSec'] = getSecName(secRef.parent().sec, dirCellSecNames) secDic[secName]['topol']['parentX'] = h.parent_connection() secDic[secName]['topol']['childX'] = h.section_orientation() del(cell) # delete cell import gc; gc.collect() return secDic