"""
utils.py
Useful functions related to the parameters file
Contributors: salvador dura@gmail.com
"""
import os, sys
from neuron import h
def getSecName (sec, dirCellSecNames = None):
if dirCellSecNames is None: dirCellSecNames = {}
if '>.' in sec.name():
fullSecName = sec.name().split('>.')[1]
elif '.' in sec.name():
fullSecName = sec.name().split('.')[1]
else:
fullSecName = sec.name()
if '[' in fullSecName: # if section is array element
secNameTemp = fullSecName.split('[')[0]
secIndex = int(fullSecName.split('[')[1].split(']')[0])
secName = secNameTemp+'_'+str(secIndex) #(secNameTemp,secIndex)
else:
secName = fullSecName
secIndex = -1
if secName in dirCellSecNames: # get sec names from python
secName = dirCellSecNames[secName]
return secName
def importCellParams (fileName, labels, values, key = None):
params = {}
if fileName.endswith('.py'):
try:
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'), locals()) # import module dynamically
modulePointer = tempModule
paramLabels = getattr(modulePointer, labels) # tuple with labels
paramValues = getattr(modulePointer, values) # variable with paramValues
if key: # if paramValues = dict
paramValues = paramValues[key]
params = dict(list(zip(paramLabels, paramValues)))
sys.path.remove(filePath)
except:
print("Error loading cell parameter values from " + fileName)
else:
print("Trying to import izhi params from a file without the .py extension")
return params
def mechVarList ():
msname = h.ref('')
varList = {}
for i, mechtype in enumerate(['mechs','pointps']):
mt = h.MechanismType(i) # either distributed mechs (0) or point process (1)
varList[mechtype] = {}
for j in range(int(mt.count())):
mt.select(j)
mt.selected(msname)
ms = h.MechanismStandard(msname[0], 1) # PARAMETER (modifiable)
varList[mechtype][msname[0]] = []
propName = h.ref('')
for var in range(int(ms.count())):
k = ms.name(propName, var)
varList[mechtype][msname[0]].append(propName[0])
return varList
def _equal_dicts (d1, d2, ignore_keys):
ignored = set(ignore_keys)
for k1, v1 in d1.items():
if k1 not in ignored and (k1 not in d2 or d2[k1] != v1):
return False
for k2, v2 in d2.items():
if k2 not in ignored and k2 not in d1:
return False
return True
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
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'), 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
sys.path.remove(filePath)
else:
print("File name should be either .hoc or .py file")
return
secDic, secListDic, synMechs = getCellParams(cell)
return secDic, secListDic, synMechs
def importCellsFromNet (netParams, fileName, labelList, condsList, cellNamesList, importSynMechs):
h.initnrn()
''' Import cell from HOC template or python file into framework format (dict of sections, with geom, topol, mechs, syns)'''
if fileName.endswith('.hoc'):
print('Importing from .hoc network not yet supported')
return
# h.load_file(fileName)
# for cellName in cellNames:
# cell = getattr(h, cellName) # create cell using template, passing dict with args
# secDic, secListDic, synMechs = getCellParams(cell)
elif fileName.endswith('.py'):
origDir = os.getcwd()
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
os.chdir(filePath)
print('\nRunning network in %s to import cells into NetPyNE ...\n'%(fileName))
print(h.name_declared('hcurrent'))
from neuron import load_mechanisms
load_mechanisms(filePath)
exec(('import ' + moduleName + ' as tempModule'), globals(), locals()) # import module dynamically
modulePointer = tempModule
sys.path.remove(filePath)
else:
print("File name should be either .hoc or .py file")
return
for label, conds, cellName in zip(labelList, condsList, cellNamesList):
print('\nImporting %s from %s ...'%(cellName, fileName))
exec('cell = tempModule' + '.' + cellName)
#cell = getattr(modulePointer, cellName) # get cell object
secs, secLists, synMechs = getCellParams(cell)
cellRule = {'conds': conds, 'secs': secs, 'secLists': secLists}
netParams.addCellParams(label, cellRule)
if importSynMechs:
for synMech in synMechs: netParams.addSynMechParams(synMech.pop('label'), synMech)
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.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'
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 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 = {}
# 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
# cellRule['secs'] = secDic
# if secListDic:
# cellRule['secLists'] = secListDic
# dictionary to translate params, fitness functions into more readable form - sam n
dtrans = {}
dtrans['FI'] = 'FI'
dtrans['ISIVolt'] = 'ISI Voltage'
dtrans['InstRate'] = 'Inst Rate'
dtrans['SpikeShape'] = 'Spike Shape'
dtrans['SpikePeak'] = 'Spike Peak'
dtrans['SpikeW'] = 'Spike Width'
dtrans['SpikeSlope'] = 'Spike Slope'
dtrans['SpikeThresh'] = 'Spike Thresh'
dtrans['VoltDiff'] = 'Subthresh Volt'
dtrans['morph.nax_gbar'] = dtrans['SPI6.gbar_nax'] = r'$\bar g_{Na}$'
dtrans['morph.kBK_caVhminShift'] = dtrans['SPI6.kBK_caVhminShift'] = r'$Shift_{BK}$'
dtrans['morph.cadad_taur'] = dtrans['SPI6.cadad_taur'] = r'$\tau_{Ca}$'
dtrans['morph.kdr_gbar'] = dtrans['SPI6.gbar_kdr'] = r'$\bar g_{Kdr}$'
dtrans['morph.cal_gcalbar'] = dtrans['SPI6.cal_gcalbar'] = r'$\bar p_L$'
dtrans['morph.kBK_gpeak'] = dtrans['SPI6.kBK_gpeak'] = r'$\bar g_{BK}$'
dtrans['morph.kap_gbar'] = dtrans['SPI6.gbar_kap'] = r'$\bar g_{KA}$'
dtrans['morph.can_gcanbar'] = dtrans['SPI6.can_gcanbar'] = r'$\bar p_N$'
dtrans['morph.kdmc_gbar'] = dtrans['SPI6.gbar_kdmc'] = r'$\bar g_{KD}$'
dtrans['morph.cadad_depth'] = dtrans['SPI6.cadad_depth'] = r'$depth_{Ca}$'
dtrans['SPI6.kap_vhalfl'] = r'$v1/2l_{KA}$'
dtrans['SPI6.kap_vhalfn'] = r'$v1/2n_{KA}$'
dtrans['SPI6.kap_tq'] = 'h.tq_kap'
dtrans['SPI6.kdr_vhalfn'] = r'$v1/2n_{Kdr}$'