diff --git a/CHANGES.md b/CHANGES.md index 62fab0ad8..3881c3c38 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,3 +1,20 @@ +# Version 0.7.3 + +- Option to create section lists based on y displacement from soma (addCellParamsSecList) + +- Converted popParams, cellParams etc to object of their own class and added method to set param + +- Added 'disynapticBias' option to increase probability of B->C conns if A->B and A->C exist + +- Added function analysis.calculateDisynaptic() to count number of disynaptic conns (A->B, B->C and A->C) + +- Added 1 second between batch job submission to avoid saturating scheduler + +- Fixed bug: init randomizer so params with string-based random func are independent of cores + +- Fixed bug for newer pyplot versions: replace 'linewidths' with 'lw' + + # Version 0.7.2 - Improved NeuroML importing/exporting diff --git a/doc/source/reference.rst b/doc/source/reference.rst index d21be4935..804022b06 100644 --- a/doc/source/reference.rst +++ b/doc/source/reference.rst @@ -864,17 +864,34 @@ Analysis-related functions - Returns figure handles -* **plotShape** (showSyns = True, include = [], style = '.', siz=10, figSize = (10,8), saveData = None, saveFig = None, showFig = True): +* **plotShape** (includePost = ['all'], includePre = ['all'], showSyns = False, synStyle = '.', synSiz=3, dist=0.6, cvar=None, cvals=None, iv=False, ivprops=None, includeAxon=True, figSize = (10,8), saveData = None, saveFig = None, showFig = True): - Plot 3D cell shape using NEURON Interview PlotShape + Plot 3D cell shape using Matplotlib or NEURON Interviews PlotShape. - - *showSyns*: Show synaptic connections in 3D (True|False) - - *figSize*: Size of figure ((width, height)) - - *saveData*: File name where to save the final data used to generate the figure (None|'fileName') - - *saveFig*: File name where to save the figure (None|'fileName') - - *showFig*: Whether to show the figure or not (True|False) + - *includePre*: List of presynaptic cells to consider when plotting connections (['all',|'allCells','allNetStims',|,120,|,'E1'|,('L2', 56)|,('L5',[4,5,6])]) + - *includePost*: List of cells to show shape of (['all',|'allCells','allNetStims',|,120,|,'E1'|,('L2', 56)|,('L5',[4,5,6])]) + - *synStyle*: Style of marker to show synapses (Matplotlib markers) + - *dist*: 3D distance (like zoom) + - *synSize*: Size of marker to show synapses + - *cvar*: Variable to represent in shape plot ('numSyns'|'weightNorm') + - *cvals*: List of values to represent in shape plot; must be same as num segments (list of size num segments; ) + - *iv*: Use NEURON Interviews (instead of matplotlib) to show shape plot (True|False) + - *ivprops*: Dict of properties to plot using Interviews (dict) + - *includeAxon*: Include axon in shape plot (True|False) + - *showSyns*: Show synaptic connections in 3D (True|False) + - *figSize*: Size of figure ((width, height)) + - *saveData*: File name where to save the final data used to generate the figure; + if set to True uses filename from simConfig (None|True|'fileName') + - *saveFig*: File name where to save the figure; + if set to True uses filename from simConfig (None|True|'fileName') + - *showFig*: Whether to show the figure or not (True|False) + + - Returns figure handles + + Examples of plotShape(): + + - cfg.analysis['plotShape'] = {'includePre': ['all'], 'includePost': [('PT5B',100)], 'cvar':'numSyns','saveFig': True, 'showFig': False, 'includeAxon': False} - - Returns figure handles * **analysis.plotConn** (include = ['all'], feature = 'strength', orderBy = 'gid', figSize = (10,10), groupBy = 'pop', saveData = None, saveFig = None, showFig = True) diff --git a/examples/sandbox/sandbox.py b/examples/sandbox/sandbox.py index b07848535..f2d79a2e5 100644 --- a/examples/sandbox/sandbox.py +++ b/examples/sandbox/sandbox.py @@ -1,103 +1,100 @@ """ -params.py - -netParams is a dict containing a set of network parameters using a standardized structure - -simConfig is a dict containing a set of simulation configurations using a standardized structure - -Contributors: salvadordura@gmail.com """ -from netpyne import specs, sim - -netParams = specs.NetParams() # object of class NetParams to store the network parameters -simConfig = specs.SimConfig() # object of class SimConfig to store the simulation configuration +from netpyne import specs +from netpyne import sim # import netpyne sim module -############################################################################### -# -# MPI HH TUTORIAL PARAMS -# -############################################################################### +netParams = specs.NetParams() # object of class NetParams to store the network parameters +cfg = specs.SimConfig() # object of class SimConfig to store the simulation configuration ############################################################################### # NETWORK PARAMETERS ############################################################################### # Population parameters -netParams.popParams['PYR'] = {'cellModel': 'HH', 'cellType': 'PYR', 'numCells': 5} # add dict with params for this pop -netParams.popParams['PYR2'] = {'cellModel': 'HH', 'cellType': 'PYR2', 'numCells': 5} # add dict with params for this pop - +netParams.popParams['ExcPop'] = {'cellModel': 'HH', 'cellType': 'Exc','numCells': 50, 'yRange': [300, 500]} # add dict with params for this pop +netParams.popParams['InhPop'] = {'cellModel': 'HH', 'cellType': 'Inh','numCells': 50, 'yRange': [600, 800]} # add dict with params for this pop -# Cell parameters -## PYR cell properties -cellRule = {'conds': {'cellModel': 'HH', 'cellType': 'PYR'}, 'secs': {}} # cell rule dict -cellRule['secs']['soma'] = {'geom': {}, 'mechs': {}} # soma params dict -cellRule['secs']['soma']['geom'] = {'diam': 18.8, 'L': 18.8, 'Ra': 123.0} # soma geometry -cellRule['secs']['soma']['mechs']['hh'] = {'gnabar': 0.12, 'gkbar': 0.036, 'gl': 0.003, 'el': -70} # soma hh mechanism -cellRule['secs']['soma']['vinit'] = -71 -netParams.cellParams['PYR'] = cellRule # add dict to list of cell params +## Cell property rules +cellRule = {'conds': {'cellType': 'Exc'}, 'secs': {}} # cell rule dict +cellRule['secs']['soma'] = {'geom': {}, 'mechs': {}} # soma params dict +cellRule['secs']['soma']['geom'] = {'diam': 15, 'L': 14, 'Ra': 120.0} # soma geometry +cellRule['secs']['soma']['mechs']['hh'] = {'gnabar': 0.12, 'gkbar': 0.036, 'gl': 0.003, 'el': -70} # soma hh mechanism +netParams.cellParams['Erule'] = cellRule # add dict to list of cell params -cellRule = {'conds': {'cellModel': 'HH', 'cellType': 'PYR2'}, 'secs': {}} # cell rule dict -cellRule['secs']['soma'] = {'geom': {}, 'mechs': {}} # soma params dict -cellRule['secs']['soma']['geom'] = {'diam': 18.8, 'L': 18.8, 'Ra': 123.0} # soma geometry -cellRule['secs']['soma']['mechs']['hh'] = {'gnabar': 0.12, 'gkbar': 0.036, 'gl': 0.003, 'el': -70} # soma hh mechanism -cellRule['secs']['soma']['vinit'] = -71 -netParams.cellParams['PYR2'] = cellRule # add dict to list of cell params +cellRule = {'conds': {'cellType': 'Inh'}, 'secs': {}} # cell rule dict +cellRule['secs']['soma'] = {'geom': {}, 'mechs': {}} # soma params dict +cellRule['secs']['soma']['geom'] = {'diam': 10.0, 'L': 9.0, 'Ra': 110.0} # soma geometry +cellRule['secs']['soma']['mechs']['hh'] = {'gnabar': 0.12, 'gkbar': 0.036, 'gl': 0.003, 'el': -70} # soma hh mechanism +netParams.cellParams['Irule'] = cellRule # add dict to list of cell params # Synaptic mechanism parameters -netParams.synMechParams['AMPA'] = {'mod': 'Exp2Syn', 'tau1': 0.1, 'tau2': 1.0, 'e': 0} +netParams.synMechParams['AMPA'] = {'mod': 'Exp2Syn', 'tau1': 0.8, 'tau2': 5.3, 'e': 0} # NMDA synaptic mechanism +netParams.synMechParams['GABA'] = {'mod': 'Exp2Syn', 'tau1': 0.6, 'tau2': 8.5, 'e': -75} # GABA synaptic mechanism # Stimulation parameters -netParams.stimSourceParams['bkg'] = {'type': 'NetStim', 'rate': 10, 'noise': 0.5, 'start': 1} -netParams.stimSourceParams['bkg2'] = {'type': 'NetStim', 'rate': 10, 'noise': 0.5, 'start': 1} - -netParams.stimTargetParams['bkg->PYR1'] = {'source': 'bkg', 'conds': {'pop': 'PYR'}, 'weight': 0.1, 'delay': 'uniform(1,5)'} - - -# Connectivity parameters -netParams.connParams['PYR->PYR'] = { - 'preConds': {'pop': 'PYR'}, 'postConds': {'pop': ['PYR','PYR2']}, - 'weight': 0.002, # weight of each connection - 'delay': '0.2+normal(13.0,1.4)', # delay min=0.2, mean=13.0, var = 1.4 - 'threshold': 10, # threshold - 'convergence': 'uniform(1,15)'} # convergence (num presyn targeting postsyn) is uniformly distributed between 1 and 15 - - -############################################################################### +#netParams.stimSourceParams['bkg'] = {'type': 'NetStim', 'rate': 10, 'noise': 0.5, 'start': 1000, 'stop': 2000} +netParams.stimSourceParams['bkg'] = {'type': 'NetStim', 'interval': 10, 'noise': 0.5, 'start': 100,'number':15} +netParams.stimTargetParams['bkg->ExcPopType'] = {'source': 'bkg', 'conds': {'popLabel': 'ExcPop'}, 'weight': 0.01, 'delay': 'uniform(1,5)', 'synMech': 'AMPA'} + + +# # Connectivity parameters +netParams.connParams['ExcPop->ExcPop'] = { + 'preConds': {'popLabel': 'ExcPop'}, # presyn: PYR_E + 'postConds': {'popLabel': 'ExcPop'}, # postsyn: PYR_E + 'probability': 'max(0.1, normal(0.2,1))', + 'weight': 0.008, # weight of each connection + 'delay': 0.5, #'max(1, normal(10,2))', # gaussian distributed transmission delay (ms) + 'synMech': 'AMPA'} # target synaptic mechanism + +# netParams.connParams['ExcPop->InhPop'] = { +# 'preConds': {'popLabel': 'ExcPop'}, # presyn: PYR_E +# 'postConds': {'popLabel': 'InhPop'}, # postsyn: PYR_I +# 'probability': 0.1, # fixed probability +# 'weight': 0.003, # weight of each connection +# 'delay': 'max(1, normal(10,2))', # gaussian distributed transmission delay (ms) +# 'synMech': 'AMPA'} # target synaptic mechanism + +# netParams.connParams['InhPop->ExcPop'] = { +# 'preConds': {'popLabel': 'InhPop'}, # presyn: PYR_I +# 'postConds': {'popLabel': 'ExcPop'}, # postsyn: PYR_E +# 'probability': 0.1, # fixed probability +# 'weight': 0.006, # weight of each connection +# 'delay': 'max(1, normal(10,2))', # gaussian distributed transmission delay (ms) +# 'synMech': 'GABA'} # target synaptic mechanism + +############################################################################## # SIMULATION PARAMETERS ############################################################################### # Simulation parameters -simConfig.duration = 1*1e3 # Duration of the simulation, in ms -simConfig.dt = 'a' # Internal integration timestep to use -simConfig.seeds = {'con': 1, 'stim': 1, 'loc': 1} # Seeds for randomizers (connectivity, input stimulation and cell locations) -simConfig.createNEURONObj = 1 # create HOC objects when instantiating network -simConfig.createPyStruct = 1 # create Python structure (simulator-independent) when instantiating network -simConfig.verbose = False # show detailed messages - -simConfig.checkErrors = 0 +cfg.duration = 2*1e3 # Duration of the simulation, in ms +cfg.dt = 0.025 # Internal integration timestep to use +cfg.seeds = {'conn': 1, 'stim': 1, 'loc': 1} # Seeds for randomizers (connectivity, input stimulation and cell locations) +cfg.createNEURONObj = 1 # create HOC objects when instantiating network +cfg.createPyStruct = 1 # create Python structure (simulator-independent) when instantiating network +cfg.verbose = False # show detailed messages # Recording -simConfig.recordCells = [] # which cells to record from -simConfig.recordTraces = {'Vsoma':{'se':'soma','loc':0.5,'var':'v','conds': {'cellType': 'PYR2'}}} -simConfig.recordStim = True # record spikes of cell stims -simConfig.recordStep = 0.1 # Step size in ms to save data (eg. V traces, LFP, etc) +cfg.recordCells = [] # which cells to record from +cfg.recordTraces = {'Vsoma':{'sec':'soma','loc':0.5,'var':'v'}} +cfg.recordStim = True # record spikes of cell stims +cfg.recordStep = 0.1 # Step size in ms to save data (eg. V traces, LFP, etc) # Saving -simConfig.filename = 'HHTut' # Set file output name -simConfig.saveFileStep = 1000 # step size in ms to save data to disk -simConfig.savePickle = False # Whether or not to write spikes etc. to a .mat file -simConfig.saveMat = True +cfg.filename = 'FirstExampleOscill' # Set file output name +cfg.saveFileStep = 1000 # step size in ms to save data to disk +cfg.savePickle = True # Whether or not to write spikes etc. to a .mat file # Analysis and plotting -simConfig.analysis['plotRaster'] = {'bla':1} -#simConfig.analysis['plotTraces'] = {'include': ['all'], 'oneFigPer':'trace'} - -sim.createSimulateAnalyze() - -#data=sim.loadSimData('HHTut.mat') +# cfg.analysis['plotRaster'] = True # Plot raster +# cfg.analysis['plotTraces'] = {'include': [('ExcPop',10), ('InhPop',10)]} # Plot raster +# # cfg.analysis['plot2Dnet'] = True # Plot 2D net cells and connections +# # cfg.analysis['plotConn'] = True +sim.createSimulateAnalyze(netParams = netParams, simConfig = cfg) +import pylab; pylab.show() # this line is only necessary in certain systems where figures appear empty diff --git a/netpyne/__init__.py b/netpyne/__init__.py index 6b1320383..0c72139a1 100644 --- a/netpyne/__init__.py +++ b/netpyne/__init__.py @@ -1,3 +1,3 @@ -__version__ = '0.7.2' +__version__ = '0.7.3' __gui__ = True # global option to enable/disable graphics \ No newline at end of file diff --git a/netpyne/analysis.py b/netpyne/analysis.py index f1d8e226f..e79b0ffe5 100644 --- a/netpyne/analysis.py +++ b/netpyne/analysis.py @@ -350,7 +350,7 @@ def plotRaster (include = ['allCells'], timeRange = None, maxSpikes = 1e8, order gs = gridspec.GridSpec(2, 1,height_ratios=[2,1]) ax1=plt.subplot(gs[0]) - ax1.scatter(spkts, spkinds, 10, linewidths=lw, marker=marker, color = spkgidColors) # Create raster + ax1.scatter(spkts, spkinds, 10, lw=lw, marker=marker, color = spkgidColors) # Create raster ax1.set_xlim(timeRange) # Plot stats @@ -907,7 +907,7 @@ def invertDictMapping(d): ###################################################################################################################################################### ## Plot cell shape ###################################################################################################################################################### -def plotShape (showSyns = False, includePost = ['all'], includePre = ['all'], synStyle = '.', synSiz=3, dist=0.6, cvar=None, cvals=None, iv=False, ivprops=None, +def plotShape (includePost = ['all'], includePre = ['all'], showSyns = False, synStyle = '.', synSiz=3, dist=0.6, cvar=None, cvals=None, iv=False, ivprops=None, includeAxon=True, figSize = (10,8), saveData = None, saveFig = None, showFig = True): ''' Plot 3D cell shape using NEURON Interview PlotShape @@ -1579,6 +1579,32 @@ def plot2Dnet (include = ['allCells'], figSize = (12,12), view = 'xy', showConns return fig +###################################################################################################################################################### +## Calculate number of disynaptic connections +###################################################################################################################################################### +def calculateDisynaptic(includePost = ['allCells'], includePre = ['allCells'], includePrePre = ['allCells']): + numDis = 0 + totCon = 0 + + _, cellsPreGids, _ = getCellsInclude(includePre) + _, cellsPrePreGids, _ = getCellsInclude(includePrePre) + cellsPost, _, _ = getCellsInclude(includePost) + + + for postCell in cellsPost: + preGidsAll = [conn['preGid'] for conn in postCell['conns'] if isinstance(conn['preGid'], Number) and conn['preGid'] in cellsPreGids+cellsPrePreGids] + preGids = [gid for gid in preGidsAll if gid in cellsPreGids] + for preGid in preGids: + preCell = sim.net.allCells[preGid] + prePreGids = [conn['preGid'] for conn in preCell['conns'] if conn['preGid'] in cellsPrePreGids] + totCon += 1 + if not set(prePreGids).isdisjoint(preGidsAll): + numDis += 1 + print ' Total disynaptic connections: %d / %d (%.2f%%)' % (numDis, totCon, float(numDis)/float(totCon)*100) + sim.allSimData['disynConns'] = numDis + + return numDis + ###################################################################################################################################################### ## Calculate normalized transfer entropy diff --git a/netpyne/batch.py b/netpyne/batch.py index d036e7fd5..d2c0217b4 100644 --- a/netpyne/batch.py +++ b/netpyne/batch.py @@ -242,7 +242,7 @@ def run(self): print jobString+'\n' input.close() - # hpc torque job submission + # hpc torque job submission elif self.runCfg.get('type',None) == 'hpc_slurm': # read params or set defaults @@ -299,7 +299,9 @@ def run(self): print 'Submitting job ',jobName # master/slave bulletin board schedulling of jobs pc.submit(runJob, self.runCfg.get('script', 'init.py'), cfgSavePath, netParamsSavePath) - + + sleep(1) # avoid saturating scheduler + # wait for pc bulletin board jobs to finish try: while pc.working(): diff --git a/netpyne/cell.py b/netpyne/cell.py index 552d6e40b..4fee68ebb 100644 --- a/netpyne/cell.py +++ b/netpyne/cell.py @@ -1269,7 +1269,7 @@ def createNEURONObj (self): maxReproducibleSpks = 1e4 # num of rand spikes generated; only a subset is used; ensures reproducibility # fixed interval of duration (1 - noise)*interval - fixedInterval = np.full(((1+0.5*noise)*sim.cfg.duration/interval), [(1.0-noise)*interval]) # generate 1+0.5*noise spikes to account for noise + fixedInterval = np.full(int(((1+0.5*noise)*sim.cfg.duration/interval)), [(1.0-noise)*interval]) # generate 1+0.5*noise spikes to account for noise numSpks = len(fixedInterval) # randomize the first spike so on average it occurs at start + noise*interval diff --git a/netpyne/network.py b/netpyne/network.py index 02767c3cb..7831d024b 100644 --- a/netpyne/network.py +++ b/netpyne/network.py @@ -695,6 +695,23 @@ def _connStrToFunc (self, preCellsTags, postCellsTags, connParam): connParam[paramStrFunc+'FuncVars'] = {strVar: dictVars[strVar] for strVar in strVars} + ############################################################################### + ### Disynaptic bias for probability + ############################################################################### + def _disynapticBiasProb(self, origProbability, bias, prePreGids, postPreGids, disynCounter, maxImbalance=10): + probability = float(origProbability) + factor = bias/origProbability + #bias = min(bias, origProbability) # don't modify more than orig, so can compensate + if not set(prePreGids).isdisjoint(postPreGids) and disynCounter < maxImbalance: + probability = min(origProbability + bias, 1.0) + disynCounter += factor #1 + elif disynCounter > -maxImbalance: + probability = max(origProbability - (min(origProbability + bias, 1.0) - origProbability), 0.0) + disynCounter -= 1 + #print disynCounter, origProbability, probability + return probability, disynCounter + + ############################################################################### ### Full connectivity ############################################################################### @@ -723,21 +740,28 @@ def probConn (self, preCellsTags, postCellsTags, connParam): ''' Generates connections between all pre and post-syn cells based on probability values''' if sim.cfg.verbose: print 'Generating set of probabilistic connections (rule: %s) ...' % (connParam['label']) - allRands = {(preGid,postGid): self.rand.uniform(0,1) for preGid in preCellsTags for postGid in postCellsTags} # Create an array of random numbers for checking each connection - + allRands = {(preGid,postGid): self.rand.uniform(0,1) for preGid in preCellsTags for postGid in postCellsTags} # Create an array of random numbers for checking each connection # get list of params that have a lambda function paramsStrFunc = [param for param in [p+'Func' for p in self.connStringFuncParams] if param in connParam] + if isinstance(connParam.get('disynapticBias', None), Number): # calculate the conn preGids of the each pre and post cell + allPreGids = sim._gatherAllCellConnPreGids() + prePreGids = {gid: allPreGids[gid] for gid in preCellsTags} + postPreGids = {gid: allPreGids[gid] for gid in postCellsTags} + minProb = 0.01*connParam['probability'] if isinstance(connParam['probability'], Number) else 0.001 + maxImbalance = len(preCellsTags)*len(postCellsTags)*minProb + + disynCounter = 0 # counter for disynaptic connections modified, to keep balance (keep same avg prob) for postCellGid,postCellTags in postCellsTags.iteritems(): # for each postsyn cell if postCellGid in self.lid2gid: # check if postsyn is in this node for preCellGid, preCellTags in preCellsTags.iteritems(): # for each presyn cell probability = connParam['probabilityFunc'][preCellGid,postCellGid] if 'probabilityFunc' in connParam else connParam['probability'] + if isinstance(connParam.get('disynapticBias', None), Number): + probability, disynCounter = self._disynapticBiasProb(probability, connParam['disynapticBias'], prePreGids[preCellGid], postPreGids[postCellGid], disynCounter, maxImbalance) - for paramStrFunc in paramsStrFunc: # call lambda functions to get weight func args - connParam[paramStrFunc+'Args'] = {k:v if isinstance(v, Number) else v(preCellTags,postCellTags) for k,v in connParam[paramStrFunc+'Vars'].iteritems()} - - if probability >= allRands[preCellGid,postCellGid]: - #rand.Random123(preCellGid, postCellGid, sim.cfg.seeds['conn']) # randomize for pre- post- gid + if probability >= allRands[preCellGid,postCellGid]: + for paramStrFunc in paramsStrFunc: # call lambda functions to get weight func args + connParam[paramStrFunc+'Args'] = {k:v if isinstance(v, Number) else v(preCellTags,postCellTags) for k,v in connParam[paramStrFunc+'Vars'].iteritems()} self._addCellConn(connParam, preCellGid, postCellGid) # add connection @@ -763,8 +787,6 @@ def convConn (self, preCellsTags, postCellsTags, connParam): for paramStrFunc in paramsStrFunc: # call lambda functions to get weight func args connParam[paramStrFunc+'Args'] = {k:v if isinstance(v, Number) else v(preCellTags,postCellTags) for k,v in connParam[paramStrFunc+'Vars'].iteritems()} - - #seed(sim.id32('%d'%(sim.cfg.seeds['conn']+postCellGid+preCellGid))) if preCellGid != postCellGid: # if not self-connection self._addCellConn(connParam, preCellGid, postCellGid) # add connection @@ -790,8 +812,7 @@ def divConn (self, preCellsTags, postCellsTags, connParam): for paramStrFunc in paramsStrFunc: # call lambda functions to get weight func args connParam[paramStrFunc+'Args'] = {k:v if isinstance(v, Number) else v(preCellTags,postCellTags) for k,v in connParam[paramStrFunc+'Vars'].iteritems()} - - #seed(sim.id32('%d'%(sim.cfg.seeds['conn']+postCellGid+preCellGid))) + if preCellGid != postCellGid: # if not self-connection self._addCellConn(connParam, preCellGid, postCellGid) # add connection @@ -836,6 +857,12 @@ def _addCellConn (self, connParam, preCellGid, postCellGid): # set final param values paramStrFunc = self.connStringFuncParams finalParam = {} + + # initialize randomizer for string-based funcs that use rand (except for conv conn which already init) + args = [x for param in paramStrFunc if param+'FuncArgs' in connParam for x in connParam[param+'FuncArgs'] ] + if 'rand' in args and connParam['connFunc'] not in ['convConn']: + self.rand.Random123(preCellGid, postCellGid, sim.cfg.seeds['conn']) + for param in paramStrFunc: if param+'List' in connParam: finalParam[param] = connParam[param+'List'][preCellGid,postCellGid] diff --git a/netpyne/simFuncs.py b/netpyne/simFuncs.py index 9f10519d0..1356021ce 100644 --- a/netpyne/simFuncs.py +++ b/netpyne/simFuncs.py @@ -8,7 +8,7 @@ __all__ = [] __all__.extend(['initialize', 'setNet', 'setNetParams', 'setSimCfg', 'createParallelContext', 'setupRecording', 'clearAll', 'setGlobals']) # init and setup -__all__.extend(['preRun', 'runSim', 'runSimWithIntervalFunc', '_gatherAllCellTags', '_gatherCells', 'gatherData']) # run and gather +__all__.extend(['preRun', 'runSim', 'runSimWithIntervalFunc', '_gatherAllCellTags', '_gatherAllCellConnPreGids', '_gatherCells', 'gatherData']) # run and gather __all__.extend(['saveData', 'loadSimCfg', 'loadNetParams', 'loadNet', 'loadSimData', 'loadAll']) # saving and loading __all__.extend(['popAvgRates', 'id32', 'copyReplaceItemObj', 'clearObj', 'replaceItemObj', 'replaceNoneObj', 'replaceFuncObj', 'replaceDictODict', 'readCmdLineArgs', 'getCellsList', 'cellByGid',\ 'timing', 'version', 'gitversion', 'loadBalance','_init_stim_randomizer']) # misc/utilities @@ -441,23 +441,23 @@ def copyReplaceItemObj (obj, keystart, newval, objCopy='ROOT'): if objCopy=='ROOT': objCopy = [] for item in obj: - if type(item) in [list]: + if isinstance(item, list): objCopy.append([]) copyReplaceItemObj(item, keystart, newval, objCopy[-1]) - elif type(item) in [dict, Dict]: + elif isinstance(item, (dict, Dict)): objCopy.append({}) copyReplaceItemObj(item, keystart, newval, objCopy[-1]) else: objCopy.append(item) - elif type(obj) in [dict, Dict]: + elif isinstance(obj, (dict, Dict)): if objCopy == 'ROOT': objCopy = Dict() for key,val in obj.iteritems(): if type(val) in [list]: objCopy[key] = [] copyReplaceItemObj(val, keystart, newval, objCopy[key]) - elif type(val) in [dict, Dict]: + elif isinstance(val, (dict, Dict)): objCopy[key] = {} copyReplaceItemObj(val, keystart, newval, objCopy[key]) elif key.startswith(keystart): @@ -473,14 +473,14 @@ def copyReplaceItemObj (obj, keystart, newval, objCopy='ROOT'): def clearObj (obj): if type(obj) == list: for item in obj: - if type(item) in [list, dict, Dict, ODict]: + if isinstance(item, (list, dict, Dict, ODict)): clearObj(item) del item - elif type(obj) in [dict, Dict, ODict]: + elif isinstance(obj, (dict, Dict, ODict)): for key in obj.keys(): val = obj[key] - if type(val) in [list, dict, Dict, ODict]: + if isinstance(item, (dict, Dict))(val, (list, dict, Dict, ODict)): clearObj(val) del obj[key] return obj @@ -509,13 +509,13 @@ def replaceItemObj (obj, keystart, newval): def replaceKeys (obj, oldkey, newkey): if type(obj) == list: for item in obj: - if type(item) in [list, dict, Dict, ODict, OrderedDict]: + if isinstance(item, (list, dict, Dict, ODict, OrderedDict)): replaceKeys(item, oldkey, newkey) - elif type(obj) in [dict, Dict, ODict, OrderedDict]: + elif isinstance(obj, (dict, Dict, ODict, OrderedDict)): for key in obj.keys(): val = obj[key] - if type(val) in [list, dict, Dict, ODict, OrderedDict]: + if isinstance(val, (list, dict, Dict, ODict, OrderedDict)): replaceKeys(val, oldkey, newkey) if key == oldkey: obj[newkey] = obj.pop(oldkey) @@ -546,12 +546,12 @@ def replaceFuncObj (obj): def replaceNoneObj (obj): if type(obj) == list:# or type(obj) == tuple: for item in obj: - if type(item) in [list, dict, Dict, ODict]: + if isinstance(item, (list, dict, Dict, ODict)): replaceNoneObj(item) - elif type(obj) in [dict, Dict, ODict]: + elif isinstance(obj, (dict, Dict, ODict)): for key,val in obj.iteritems(): - if type(val) in [list, dict, Dict, ODict]: + if isinstance(val, (list, dict, Dict, ODict)): replaceNoneObj(val) if val == None: obj[key] = [] @@ -566,38 +566,38 @@ def replaceNoneObj (obj): def replaceDictODict (obj): if type(obj) == list: for item in obj: - if type(item) == Dict: + if isinstance(item, Dict): item = item.todict() - elif type(item) == ODict: + elif isinstance(item, ODict): item = item.toOrderedDict() - if type(item) in [list, dict, OrderedDict]: + if isinstance(item, (list, dict, OrderedDict)): replaceDictODict(item) - elif type(obj) in [dict, OrderedDict, Dict, ODict]: + elif isinstance(obj, (dict, OrderedDict, Dict, ODict)): for key,val in obj.iteritems(): - if type(val) == Dict: + if isinstance(val, Dict): obj[key] = val.todict() - elif type(val) == ODict: + elif isinstance(val, ODict): obj[key] = val.toOrderedDict() - if type(val) in [list, dict, OrderedDict]: + if isinstance(val, (list, dict, OrderedDict)): replaceDictODict(val) # elif type(obj) == Dict: # obj = obj.todict() # for key,val in obj.iteritems(): - # if type(val) in [list, dict, Dict, ODict]: + # if isinstance(item, (dict, Dict))(val, (list, dict, Dict, ODict)): # replaceDictODict(val) # elif type(obj) == ODict: # print obj.keys() # obj = obj.toOrderedDict() # for key,val in obj.iteritems(): - # if type(val) in [list, dict, Dict, ODict]: + # if isinstance(item, (dict, Dict))(val, (list, dict, Dict, ODict)): # replaceDictODict(val) # elif type(obj) == dict: # for key,val in obj.iteritems(): - # if type(val) in [list, dict, Dict, ODict]: + # if isinstance(item, (dict, Dict))(val, (list, dict, Dict, ODict)): # replaceDictODict(val) return obj @@ -612,9 +612,9 @@ def tupleToStr (obj): elif type(item) == tuple: obj[obj.index(item)] = str(item) - elif type(obj) == dict or type(obj) == ODict: + elif isinstance(obj, (dict, ODict)): for key,val in obj.iteritems(): - if type(val) in [list, dict, ODict]: + if isinstance(val, (list, dict, ODict)): tupleToStr(val) elif type(val) == tuple: obj[key] = str(val) # also replace empty dicts with empty list @@ -974,6 +974,30 @@ def _gatherAllCellTags (): return allCellTags +############################################################################### +### Gather tags from cells +############################################################################### +def _gatherAllCellConnPreGids (): + data = [{cell.gid: [conn['preGid'] for conn in cell.conns] for cell in sim.net.cells}]*sim.nhosts # send cells data to other nodes + gather = sim.pc.py_alltoall(data) # collect cells data from other nodes (required to generate connections) + sim.pc.barrier() + allCellConnPreGids = {} + for dataNode in gather: + allCellConnPreGids.update(dataNode) + + # clean to avoid mem leaks + for node in gather: + if node: + node.clear() + del node + for item in data: + if item: + item.clear() + del item + + return allCellConnPreGids + + ############################################################################### ### Gather data from nodes ############################################################################### diff --git a/netpyne/specs.py b/netpyne/specs.py index c9adb6838..1bf5cf27f 100644 --- a/netpyne/specs.py +++ b/netpyne/specs.py @@ -202,6 +202,91 @@ def __setstate__ (self, d): self = self.fromOrderedDict(d) +class PopParams (ODict): + def setParam(self, label, param, value): + if label in self: + d = self[label] + else: + return False + + dimParams = ['numCells', 'density', 'gridSpacing'] + if param in dimParams: + for removeParam in dimParams: d.pop(removeParam, None) # remove other properties + + d[param] = value + + return True + +class CellParams (ODict): + def setParam(self, label, param, value): + if label in self: + d = self[label] + else: + return False + + d[param] = value + + return True + +class ConnParams (ODict): + def setParam(self, label, param, value): + if label in self: + d = self[label] + else: + return False + + d[param] = value + + return True + + +class SynMechParams (ODict): + def setParam(self, label, param, value): + if label in self: + d = self[label] + else: + return False + + d[param] = value + + return True + +class SubConnParams (ODict): + def setParam(self, label, param, value): + if label in self: + d = self[label] + else: + return False + + d[param] = value + + return True + + +class StimSourceParams (ODict): + def setParam(self, label, param, value): + if label in self: + d = self[label] + else: + return False + + d[param] = value + + return True + + +class StimTargetParams (ODict): + def setParam(self, label, param, value): + if label in self: + d = self[label] + else: + return False + + d[param] = value + + return True + + ############################################################################### # NETWORK PARAMETERS CLASS ############################################################################### @@ -228,24 +313,24 @@ def __init__(self, netParamsDict=None): self.propVelocity = 500.0 # propagation velocity (um/ms) # Cell params dict - self.cellParams = ODict() + self.cellParams = CellParams() # Population params dict - self.popParams = ODict() # create list of populations - each item will contain dict with pop params + self.popParams = PopParams() # create list of populations - each item will contain dict with pop params self.popTagsCopiedToCells = ['cellModel', 'cellType'] # Synaptic mechanism params dict - self.synMechParams = ODict() + self.synMechParams = SynMechParams() # Connectivity params dict - self.connParams = ODict() + self.connParams = ConnParams() # Subcellular connectivity params dict - self.subConnParams = ODict() + self.subConnParams = SubConnParams() # Stimulation source and target params dicts - self.stimSourceParams = ODict() - self.stimTargetParams = ODict() + self.stimSourceParams = StimSourceParams() + self.stimTargetParams = StimTargetParams() # fill in params from dict passed as argument if netParamsDict: @@ -355,7 +440,7 @@ def importCellParamsFromNet(self, labelList, condsList, fileName, cellNameList, return self.cellParams - def addCellParamsSecList(self, label, secListName, somaDist): + def addCellParamsSecList(self, label, secListName, somaDist=None, somaDistY=None): import numpy as np if label in self.cellParams: @@ -364,19 +449,28 @@ def addCellParamsSecList(self, label, secListName, somaDist): print 'Error adding secList: netParams.cellParams does not contain %s' % (label) return - if not isinstance(somaDist, list) or len(somaDist) != 2: + if somaDist is not None and (not isinstance(somaDist, list) or len(somaDist) != 2): print 'Error adding secList: somaDist should be a list with 2 elements' return + if somaDistY is not None and (not isinstance(somaDistY, list) or len(somaDistY) != 2): + print 'Error adding secList: somaDistY should be a list with 2 elements' + return + + secList = [] for secName, sec in cellRule.secs.iteritems(): if 'pt3d' in sec['geom']: pt3d = sec['geom']['pt3d'] midpoint = int(len(pt3d)/2) x,y,z = pt3d[midpoint][0:3] - distSec = np.linalg.norm(np.array([x,y,z])) - if distSec >= somaDist[0] and distSec <= somaDist[1]: - secList.append(secName) + if somaDist: + distSec = np.linalg.norm(np.array([x,y,z])) + if distSec >= somaDist[0] and distSec <= somaDist[1]: + secList.append(secName) + elif somaDistY: + if y >= somaDistY[0] and y <= somaDistY[1]: + secList.append(secName) else: print 'Error adding secList: Sections do not contain 3d points' diff --git a/netpyne/tests/tests.py b/netpyne/tests/tests.py index 8f561e11e..73d98d909 100644 --- a/netpyne/tests/tests.py +++ b/netpyne/tests/tests.py @@ -16,7 +16,7 @@ from netpyne import utils VALID_SHAPES = ['cuboid', 'ellipsoid', 'cylinder'] -POP_NUMCELLS_PARAMS = ['Density','NumCells','GridSpacing'] +POP_NUMCELLS_PARAMS = ['density', 'numCells', 'gridSpacing'] VALID_GEOMETRIES = ['cm', 'L', 'diam', 'Ra', 'pt3d', 'nseg'] VALID_GEOMETRIES_SUBSET = ['L', 'diam', 'Ra'] PT_3D = 'pt3d' diff --git a/sdnotes.org b/sdnotes.org index 70a579c85..c37145129 100644 --- a/sdnotes.org +++ b/sdnotes.org @@ -6995,7 +6995,7 @@ Ohio Wesleyan University ** Cortex, Schizophrenia (Cristoph Metzner, Hertfordshire) ** Spinal cord circuits (Vittorio Caggiano, IBM Watson) ** Convert hoc models (Ben Latimer, Missouri) -** Thalamocortical stimulation (Brenyn Jungmann, Missouri) +** Thalamocortical stimulation (Brenyn Jungmann, Nahir lab,Missouri) ** Fear circuits (Aliyah Taylor, Princeton/Missouri) ** Macaque M1 TMS (Aman Aberra, Duke)