Exemplo n.º 1
0
def morphology_to_dict(sections, outfile=None):
    section_map = {sec: i for i, sec in enumerate(sections)}
    result = []
    h.define_shape()

    for sec in sections:
        my_parent = parent(sec)
        my_parent_loc = -1 if my_parent is None else parent_loc(sec, my_parent)
        my_parent = -1 if my_parent is None else section_map[my_parent]
        n3d = int(h.n3d(sec=sec))
        result.append({
            'section_orientation': h.section_orientation(sec=sec),
            'parent': my_parent,
            'parent_loc': my_parent_loc,
            'x': [h.x3d(i, sec=sec) for i in xrange(n3d)],
            'y': [h.y3d(i, sec=sec) for i in xrange(n3d)],
            'z': [h.z3d(i, sec=sec) for i in xrange(n3d)],
            'diam': [h.diam3d(i, sec=sec) for i in xrange(n3d)],
            'name': sec.hname()           
        })

    if outfile is not None:
        with open(outfile, 'w') as f:
            json.dump(result, f)

    return result
Exemplo n.º 2
0
def morphology_to_dict(sections, outfile=None):
    section_map = {sec: i for i, sec in enumerate(sections)}
    result = []
    h.define_shape()

    for sec in sections:
        my_parent = parent(sec)
        my_parent_loc = -1 if my_parent is None else parent_loc(sec, my_parent)
        my_parent = -1 if my_parent is None else section_map[my_parent]
        n3d = int(h.n3d(sec=sec))
        result.append({
            'section_orientation': h.section_orientation(sec=sec),
            'parent': my_parent,
            'parent_loc': my_parent_loc,
            'x': [h.x3d(i, sec=sec) for i in xrange(n3d)],
            'y': [h.y3d(i, sec=sec) for i in xrange(n3d)],
            'z': [h.z3d(i, sec=sec) for i in xrange(n3d)],
            'diam': [h.diam3d(i, sec=sec) for i in xrange(n3d)],
            'name': sec.hname()
        })

    if outfile is not None:
        with open(outfile, 'w') as f:
            json.dump(result, f)

    return result
Exemplo n.º 3
0
def morph_per_root(root):
    morph = []
    h.define_shape()
    for sec in secs_with_root(root):
        n3d = int(h.n3d(sec=sec))
        x = [h.x3d(i, sec=sec) for i in xrange(n3d)]
        y = [h.y3d(i, sec=sec) for i in xrange(n3d)]
        z = [h.z3d(i, sec=sec) for i in xrange(n3d)]
        d = [h.diam3d(i, sec=sec) for i in xrange(n3d)]
        arc = [h.arc3d(i, sec=sec) for i in xrange(n3d)]
        length = sec.L
        half_dx = 0.5 / sec.nseg
        for seg in sec:
            morph.append(get_pts_between(x, y, z, d, arc, (seg.x - half_dx) * length, (seg.x + half_dx) * length))
    
    # add end points
    for end_pt in [0, 1]:
        for sec in secs_with_root(root):
            n3d = int(h.n3d(sec=sec))
            pt1 = [h.x3d(0, sec=sec), h.y3d(0, sec=sec), h.z3d(0, sec=sec), h.diam3d(0, sec=sec)]
            pt2 = [h.x3d(n3d - 1, sec=sec), h.y3d(n3d - 1, sec=sec), h.z3d(n3d - 1, sec=sec), h.diam3d(n3d - 1, sec=sec)]
            if h.section_orientation(sec=sec) == 0:
                morph_to_append = [pt1] if end_pt == 0 else [pt2]
            else:
                morph_to_append = [pt2] if end_pt == 0 else [pt1]
            round3(morph_to_append)
            morph.append(morph_to_append)
    return morph
Exemplo n.º 4
0
def _sort_secs(secs):
    # sort the sections
    root_secs = h.SectionList()
    root_secs.allroots()
    all_sorted = h.SectionList()
    for root in root_secs:
        all_sorted.wholetree(sec=root)
    secs_names = dict([(sec.hoc_internal_name(),sec) for sec in secs])
    for sec in secs:
        if h.section_orientation(sec=sec):
            raise RxDException('still need to deal with backwards sections')
    return [secs_names[sec.hoc_internal_name()] for sec in all_sorted if sec.hoc_internal_name() in secs_names]
Exemplo n.º 5
0
def _get_node_indices(species, region, sec3d, x3d, sec1d, x1d):
    # TODO: remove need for this assumption
    assert (x1d in (0, 1))
    disc_indices = region._indices_from_sec_x(sec3d, x3d)
    #print '%r(%g) connects to the 1d section %r(%g)' % (sec3d, x3d, sec1d, x1d)
    #print 'disc indices: %r' % disc_indices
    indices3d = []
    for node in species._nodes:
        if node._r == region:
            for i, j, k in disc_indices:
                if node._i == i and node._j == j and node._k == k:
                    indices3d.append(node._index)
                    #print 'found node %d with coordinates (%g, %g, %g)' % (node._index, node.x3d, node.y3d, node.z3d)
    # discard duplicates...
    # TODO: really, need to figure out all the 3d nodes connecting to a given 1d endpoint, then unique that
    indices3d = list(set(indices3d))
    #print '3d matrix indices: %r' % indices3d
    # TODO: remove the need for this assertion
    if x1d == h.section_orientation(sec=sec1d):
        # TODO: make this whole thing more efficient
        # the parent node is the nonzero index on the first row before the diagonal
        first_row = min([node._index for node in species.nodes(region)(sec1d)])
        for j in range(first_row):
            if _euler_matrix[first_row, j] != 0:
                index_1d = j
                break
        else:
            raise RxDException('should never get here; could not find parent')
    elif x1d == 1 - h.section_orientation(sec=sec1d):
        # the ending zero-volume node is the one after the last node
        # TODO: make this more efficient
        index_1d = max([node._index
                        for node in species.nodes(region)(sec1d)]) + 1
    else:
        raise RxDException(
            'should never get here; _get_node_indices apparently only partly converted to allow connecting to 1d in middle'
        )
    #print '1d index is %d' % index_1d
    return index_1d, indices3d
Exemplo n.º 6
0
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
Exemplo n.º 7
0
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
Exemplo n.º 8
0
Arquivo: rxd.py Projeto: nrnhines/nrn
def _get_node_indices(species, region, sec3d, x3d, sec1d, x1d):
    # TODO: remove need for this assumption
    assert(x1d in (0, 1))
    disc_indices = region._indices_from_sec_x(sec3d, x3d)
    #print '%r(%g) connects to the 1d section %r(%g)' % (sec3d, x3d, sec1d, x1d)
    #print 'disc indices: %r' % disc_indices
    indices3d = []
    for node in species._nodes:
        if node._r == region:
            for i, j, k in disc_indices:
                if node._i == i and node._j == j and node._k == k:
                    indices3d.append(node._index)
                    #print 'found node %d with coordinates (%g, %g, %g)' % (node._index, node.x3d, node.y3d, node.z3d)
    # discard duplicates...
    # TODO: really, need to figure out all the 3d nodes connecting to a given 1d endpoint, then unique that
    indices3d = list(set(indices3d))
    #print '3d matrix indices: %r' % indices3d
    # TODO: remove the need for this assertion
    if x1d == h.section_orientation(sec=sec1d):
        # TODO: make this whole thing more efficient
        # the parent node is the nonzero index on the first row before the diagonal
        first_row = min([node._index for node in species.nodes(region)(sec1d)])
        for j in range(first_row):
            if _euler_matrix[first_row, j] != 0:
                index_1d = j
                break
        else:
            raise RxDException('should never get here; could not find parent')
    elif x1d == 1 - h.section_orientation(sec=sec1d):
        # the ending zero-volume node is the one after the last node
        # TODO: make this more efficient
        index_1d = max([node._index for node in species.nodes(region)(sec1d)]) + 1
    else:
        raise RxDException('should never get here; _get_node_indices apparently only partly converted to allow connecting to 1d in middle')
    #print '1d index is %d' % index_1d
    return index_1d, indices3d
Exemplo n.º 9
0
 def __init__(self):
     """Create a MorphologyDB with the current NEURON morphology"""
     self._children = {sec:[] for sec in h.allsec()}
     self._parents = {}
     self._connection_pts = {}
     for sec in h.allsec():
         parent_sec = parent(sec)
         if parent_sec is not None:
             self._children[parent_sec].append(sec)
             pt = (parent_sec, parent_loc(sec, parent))
             local_pt = (sec, h.section_orientation(sec=sec))
             if pt in self._connection_pts:
                 self._connection_pts[pt].append(local_pt)
             else:
                 self._connection_pts[pt] = [pt, local_pt]
         self._parents[sec] = parent_sec
Exemplo n.º 10
0
 def __init__(self):
     """Create a MorphologyDB with the current NEURON morphology"""
     self._children = {sec: [] for sec in h.allsec()}
     self._parents = {}
     self._connection_pts = {}
     for sec in h.allsec():
         parent_sec = parent(sec)
         if parent_sec is not None:
             self._children[parent_sec].append(sec)
             pt = (parent_sec, parent_loc(sec, parent))
             local_pt = (sec, h.section_orientation(sec=sec))
             if pt in self._connection_pts:
                 self._connection_pts[pt].append(local_pt)
             else:
                 self._connection_pts[pt] = [pt, local_pt]
         self._parents[sec] = parent_sec
Exemplo n.º 11
0
 def section_orientation(self):
     """The HOC section orientation."""
     return h.section_orientation(sec=self._sec)
Exemplo n.º 12
0
Arquivo: rxd.py Projeto: nrnhines/nrn
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)
    


        """
Exemplo n.º 13
0
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
Exemplo n.º 14
0
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
Exemplo n.º 15
0
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)
        """
Exemplo n.º 16
0
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
Exemplo n.º 17
0
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
Exemplo n.º 18
0
 def section_orientation(self):
     """The HOC section orientation."""
     return h.section_orientation(sec=self._sec)
Exemplo n.º 19
0
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