Source code for

Module for adding stimulations to networks


from __future__ import print_function
from __future__ import unicode_literals
from __future__ import division
from __future__ import absolute_import

from future import standard_library
from numbers import Number
except NameError:
    basestring = str

# -----------------------------------------------------------------------------
#  Add stims
# -----------------------------------------------------------------------------
[docs]def addStims(self): """ Function for/to <short description of ``> Parameters ---------- self : <type> <Short description of self> **Default:** *required* """ from .. import sim sim.timing('start', 'stimsTime') if self.params.stimSourceParams and self.params.stimTargetParams: if sim.rank==0: print('Adding stims...') if sim.nhosts > 1: # Gather tags from all cells allCellTags = sim._gatherAllCellTags() else: allCellTags = {cell.gid: cell.tags for cell in self.cells} # allPopTags = {i: pop.tags for i,pop in enumerate(self.pops)} # gather tags from pops so can connect NetStim pops sources = self.params.stimSourceParams for targetLabel, target in self.params.stimTargetParams.items(): # for each target parameter set if 'sec' not in target: target['sec'] = None # if section not specified, make None (will be assigned to first section in cell) if 'loc' not in target: target['loc'] = None # if location not specified, make None source = sources.get(target['source']) postCellsTags = allCellTags for condKey,condValue in target['conds'].items(): # Find subset of cells that match postsyn criteria if condKey in ['x','y','z','xnorm','ynorm','znorm']: postCellsTags = {gid: tags for (gid,tags) in postCellsTags.items() if condValue[0] <= tags.get(condKey, None) < condValue[1]} # dict with post Cell objects} # dict with pre cell tags elif condKey == 'cellList': pass elif isinstance(condValue, list): postCellsTags = {gid: tags for (gid,tags) in postCellsTags.items() if tags.get(condKey, None) in condValue} # dict with post Cell objects else: postCellsTags = {gid: tags for (gid,tags) in postCellsTags.items() if tags.get(condKey, None) == condValue} # dict with post Cell objects # subset of cells from selected pops (by relative indices) if 'cellList' in target['conds']: orderedPostGids = sorted(postCellsTags.keys()) gidList = [orderedPostGids[i] for i in target['conds']['cellList']] postCellsTags = {gid: tags for (gid,tags) in postCellsTags.items() if gid in gidList} # initialize randomizer in case used in string-based function (see issue #89 for more details) self.rand.Random123(sim.hashStr('stim_'+source['type']), sim.hashList(sorted(postCellsTags)), sim.cfg.seeds['stim']) # calculate params if string-based funcs strParams = self._stimStrToFunc(postCellsTags, source, target) # loop over postCells and add stim target for postCellGid in postCellsTags: # for each postsyn cell if postCellGid in self.gid2lid: # check if postsyn is in this node's list of gids postCell = self.cells[[postCellGid]] # get Cell object # stim target params params = {} params['label'] = targetLabel params['source'] = target['source'] params['sec'] = strParams['secList'][postCellGid] if 'secList' in strParams else target['sec'] params['loc'] = strParams['locList'][postCellGid] if 'locList' in strParams else target['loc'] if source['type'] == 'NetStim': # for NetStims add weight+delay or default values params['weight'] = strParams['weightList'][postCellGid] if 'weightList' in strParams else target.get('weight', 1.0) params['delay'] = strParams['delayList'][postCellGid] if 'delayList' in strParams else target.get('delay', 1.0) params['synsPerConn'] = strParams['synsPerConnList'][postCellGid] if 'synsPerConnList' in strParams else target.get('synsPerConn', 1) params['synMech'] = target.get('synMech', None) for p in ['Weight', 'Delay', 'Loc']: if 'synMech'+p+'Factor' in target: params['synMech'+p+'Factor'] = target.get('synMech'+p+'Factor') if 'originalFormat' in source and source['originalFormat'] == 'NeuroML2': if 'weight' in target: params['weight'] = target['weight'] for sourceParam in source: # copy source params params[sourceParam] = strParams[sourceParam+'List'][postCellGid] if sourceParam+'List' in strParams else source.get(sourceParam) if source['type'] == 'NetStim': self._addCellStim(params, postCell) # call method to add connections (sort out synMechs first) else: postCell.addStim(params) # call cell method to add connection print((' Number of stims on node %i: %i ' % (sim.rank, sum([len(cell.stims) for cell in self.cells])))) sim.pc.barrier() sim.timing('stop', 'stimsTime') if sim.rank == 0 and sim.cfg.timing: print((' Done; cell stims creation time = %0.2f s.' % sim.timingData['stimsTime'])) return [cell.stims for cell in self.cells]
# ----------------------------------------------------------------------------- # Set parameters and add stim # ----------------------------------------------------------------------------- def _addCellStim(self, stimParam, postCell): # convert synMech param to list (if not already) if not isinstance(stimParam.get('synMech'), list): stimParam['synMech'] = [stimParam.get('synMech')] # generate dict with final params for each synMech paramPerSynMech = ['weight', 'delay', 'loc'] finalParam = {} for i, synMech in enumerate(stimParam.get('synMech')): for param in paramPerSynMech: finalParam[param+'SynMech'] = stimParam.get(param) if len(stimParam['synMech']) > 1: if isinstance (stimParam.get(param), list): # get weight from list for each synMech finalParam[param+'SynMech'] = stimParam[param][i] elif 'synMech'+param.title()+'Factor' in stimParam: # adapt weight for each synMech finalParam[param+'SynMech'] = stimParam[param] * stimParam['synMech'+param.title()+'Factor'][i] params = {k: stimParam.get(k) for k,v in stimParam.items()} params['synMech'] = synMech params['loc'] = finalParam['locSynMech'] params['weight'] = finalParam['weightSynMech'] params['delay'] = finalParam['delaySynMech'] postCell.addStim(params=params) # ----------------------------------------------------------------------------- # Convert stim param string to function # ----------------------------------------------------------------------------- def _stimStrToFunc(self, postCellsTags, sourceParams, targetParams): # list of params that have a function passed in as a string #params = sourceParams+targetParams params = sourceParams.copy() params.update(targetParams) paramsStrFunc = [param for param in self.stimStringFuncParams+self.connStringFuncParams if param in params and isinstance(params[param], basestring) and params[param] not in ['variable']] # dict to store correspondence between string and actual variable dictVars = {} dictVars['post_x'] = lambda postConds: postConds['x'] dictVars['post_y'] = lambda postConds: postConds['y'] dictVars['post_z'] = lambda postConds: postConds['z'] dictVars['post_xnorm'] = lambda postConds: postConds['xnorm'] dictVars['post_ynorm'] = lambda postConds: postConds['ynorm'] dictVars['post_znorm'] = lambda postConds: postConds['znorm'] dictVars['rand'] = lambda unused1: self.rand # add netParams variables for k,v in self.params.__dict__.items(): if isinstance(v, Number): dictVars[k] = v # for each parameter containing a function, calculate lambda function and arguments from netpyne.specs.utils import generateStringFunction strParams = {} for paramStrFunc in paramsStrFunc: strFunc = params[paramStrFunc] # string containing function lambdaFunc, strVars = generateStringFunction(strFunc, list(dictVars.keys())) # store lambda function and func vars in connParam (for weight, delay and synsPerConn since only calculated for certain conns) params[paramStrFunc+'Func'] = lambdaFunc params[paramStrFunc+'FuncVars'] = {strVar: dictVars[strVar] for strVar in strVars} # replace lambda function (with args as dict of lambda funcs) with list of values strParams[paramStrFunc+'List'] = {postGid: params[paramStrFunc+'Func'](**{k:v if isinstance(v, Number) else v(postCellTags) for k,v in params[paramStrFunc+'FuncVars'].items()}) for postGid,postCellTags in sorted(postCellsTags.items())} return strParams