From 012e32e17e9b27482a6d7c4ea5225f536bcd3878 Mon Sep 17 00:00:00 2001 From: Padraig Gleeson Date: Thu, 23 Feb 2017 18:52:04 +0000 Subject: [PATCH 01/37] Enables connection of NetCons from nml cells which are just spike sources --- netpyne/cell.py | 38 ++++++++++++++++++++++++++++++++++++++ netpyne/neuromlFuncs.py | 37 ++++++++++++++++++++++++------------- netpyne/pop.py | 38 ++++++++++++++++++++++---------------- netpyne/sim.py | 2 +- 4 files changed, 85 insertions(+), 30 deletions(-) diff --git a/netpyne/cell.py b/netpyne/cell.py index 6dff19106..1ca0923b0 100644 --- a/netpyne/cell.py +++ b/netpyne/cell.py @@ -1418,3 +1418,41 @@ def wrapper(*args, **kwargs): # def addSynMechsNEURONObj (self): # print 'Error: Function not yet implemented for Point Neurons' + + +############################################################################### +# +# NeuroML2 CELL CLASS +# +############################################################################### + +class NML2Cell (CompartCell): + ''' Class for NeuroML2 neuron models: No different than CompartCell ''' + + +############################################################################### +# +# NeuroML2 SPIKE SOURCE CLASS +# +############################################################################### + +class NML2SpikeSource (CompartCell): + ''' Class for NeuroML2 spiking neuron models: based on CompartCell, + but the NetCon connects to the mechanism on the one section whose NET_RECEIVE + block will emit events + ''' + + def associateGid (self, threshold = 10.0): + print("associateGid... %s, %s"%(self.gid,self.tags)) + + if sim.cfg.createNEURONObj: + sim.pc.set_gid2node(self.gid, sim.rank) # this is the key call that assigns cell gid to a particular node + + nc = h.NetCon(self.secs['soma']['pointps'][self.tags['cellType']].hPointp, None) + + #### nc.threshold = threshold # not used.... + sim.pc.cell(self.gid, nc, 1) # associate a particular output stream of events + del nc # discard netcon + sim.net.gid2lid[self.gid] = len(sim.net.lid2gid) + sim.net.lid2gid.append(self.gid) # index = local id; value = global id + diff --git a/netpyne/neuromlFuncs.py b/netpyne/neuromlFuncs.py index 6f5bba6ac..03f949fc3 100644 --- a/netpyne/neuromlFuncs.py +++ b/netpyne/neuromlFuncs.py @@ -430,7 +430,7 @@ def exportNeuroML2 (reference, connections=True, stimulations=True): for np_pop in net.pops.values(): index = 0 print("Adding population: %s"%np_pop.tags) - positioned = len(np_pop.cellGids)>0 + type = 'populationList' if not np_pop.tags['cellModel'] == 'NetStim': comp_id = populations_vs_components[np_pop.tags['popLabel']] @@ -635,8 +635,9 @@ class NetPyNEBuilder(DefaultNetworkHandler): gids = OrderedDict() next_gid = 0 - def __init__(self, netParams): + def __init__(self, netParams, verbose = False): self.netParams = netParams + self.verbose = verbose def finalise(self): @@ -678,7 +679,7 @@ def _get_prox_dist(self, seg, seg_ids_vs_segs): # def handleNetwork(self, network_id, notes, temperature=None): if temperature: - self.log.warn("\n****************\n Need to set temperature to %s!!!\n********************"%temperature) + print("\n****************\n Need to set temperature to %s!!!\n********************"%temperature) # @@ -686,7 +687,7 @@ def handleNetwork(self, network_id, notes, temperature=None): # def handlePopulation(self, population_id, component, size, component_obj): - self.log.info("A population: %s with %i of %s (%s)"%(population_id,size,component,component_obj)) + if self.verbose: print("A population: %s with %i of %s (%s)"%(population_id,size,component,component_obj)) self.pop_ids_vs_components[population_id] = component_obj @@ -695,15 +696,16 @@ def handlePopulation(self, population_id, component, size, component_obj): popInfo=OrderedDict() popInfo['popLabel'] = population_id popInfo['cellModel'] = component - popInfo['cellType'] = component - popInfo['originalFormat'] = 'NeuroML2' # This parameter is required to distinguish NML2 "point processes" from artificial cells + popInfo['originalFormat'] = 'NeuroML2' # This parameter is required to distinguish NML2 "point processes" from abstract cells popInfo['cellsList'] = [] self.popParams[population_id] = popInfo - from neuroml import Cell + from neuroml import Cell, BaseCell if isinstance(component_obj,Cell): + popInfo['cellType'] = component + cell = component_obj cellRule = {'conds':{'cellType': component, 'cellModel': component}, @@ -889,7 +891,14 @@ def handlePopulation(self, population_id, component, size, component_obj): self.pop_ids_vs_seg_ids_vs_segs[population_id] = seg_ids_vs_segs else: - + + popInfo['cellType'] = component + + if self.verbose: print("Abstract cell: %s"%(isinstance(component_obj,BaseCell))) + + if not isinstance(component_obj,BaseCell): + popInfo['originalFormat'] = 'NeuroML2_SpikeSource' + cellRule = {'label': component, 'conds': {'cellType': component, 'cellModel': component}, @@ -923,7 +932,7 @@ def handlePopulation(self, population_id, component, size, component_obj): soma['pointps'][component] = {'mod':component} cellRule['secs'] = {'soma': soma} # add sections to dict self.cellParams[component] = cellRule - + self.gids[population_id] = [-1]*size @@ -973,7 +982,7 @@ def handleLocation(self, id, population_id, component, x, y, z): # def handleProjection(self, projName, prePop, postPop, synapse, hasWeights=False, hasDelays=False, type="projection", synapse_obj=None, pre_synapse_obj=None): - self.log.debug("A projection: %s (%s) from %s -> %s with syn: %s" % (projName, type, prePop, postPop, synapse)) + if self.verbose: print("A projection: %s (%s) from %s -> %s with syn: %s" % (projName, type, prePop, postPop, synapse)) self.projection_infos[projName] = (projName, prePop, postPop, synapse, type) self.connections[projName] = [] @@ -1045,7 +1054,7 @@ def handleSingleInput(self, inputListId, id, cellId, segId = 0, fract = 0.5): 'conds': {'popLabel':pop_id, 'cellList': [cellId]}} - print("Input: %s[%s] on %s, cellId: %i, seg: %i (nrn: %s), fract: %f (nrn: %f); ref: %s" % (inputListId,id,pop_id,cellId,segId,nrn_sec,fract,nrn_fract,stimId)) + if self.verbose: print("Input: %s[%s] on %s, cellId: %i, seg: %i (nrn: %s), fract: %f (nrn: %f); ref: %s" % (inputListId,id,pop_id,cellId,segId,nrn_sec,fract,nrn_fract,stimId)) # TODO: build just one stimLists/stimSources entry for the inputList # Issue: how to specify the sec/loc per individual stim?? @@ -1066,6 +1075,8 @@ def importNeuroML2(fileName, simConfig): print("Importing NeuroML 2 network from: %s"%fileName) nmlHandler = None + + verbose = False if fileName.endswith(".nml"): @@ -1074,7 +1085,7 @@ def importNeuroML2(fileName, simConfig): from neuroml.hdf5.NeuroMLXMLParser import NeuroMLXMLParser - nmlHandler = NetPyNEBuilder(netParams) + nmlHandler = NetPyNEBuilder(netParams, verbose=verbose) currParser = NeuroMLXMLParser(nmlHandler) # The XML handler knows of the structure of NeuroML and calls appropriate functions in NetworkHandler @@ -1092,7 +1103,7 @@ def importNeuroML2(fileName, simConfig): from neuroml.hdf5.NeuroMLHdf5Parser import NeuroMLHdf5Parser - nmlHandler = NetPyNEBuilder(netParams) + nmlHandler = NetPyNEBuilder(netParams, verbose=verbose) currParser = NeuroMLHdf5Parser(nmlHandler) # The HDF5 handler knows of the structure of NeuroML and calls appropriate functions in NetworkHandler diff --git a/netpyne/pop.py b/netpyne/pop.py index c4ae255cc..8b45e22e9 100644 --- a/netpyne/pop.py +++ b/netpyne/pop.py @@ -288,23 +288,29 @@ def createCellsGrid (self): def _setCellClass (self): - # set cell class: CompartCell for compartmental cells of PointCell for point neurons (NetStims, IntFire1,...) - try: # check if cellModel corresponds to an existing point process mechanism; if so, use PointCell - # Make sure it's not a NeuroML2 based cell - assert(not ('originalFormat' in self.tags and self.tags['originalFormat'] == 'NeuroML2')) - - tmp = getattr(h, self.tags['cellModel']) - self.cellModelClass = sim.PointCell - excludeTags = ['popLabel', 'cellModel', 'cellType', 'numCells', 'density', - 'xRange', 'yRange', 'zRange', 'xnormRange', 'ynormRange', 'znormRange', 'vref'] - params = {k: v for k,v in self.tags.iteritems() if k not in excludeTags} - self.tags['params'] = params - for k in self.tags['params']: self.tags.pop(k) - sim.net.params.popTagsCopiedToCells.append('params') - except: - self.cellModelClass = sim.CompartCell # otherwise assume has sections and some cellParam rules apply to it; use CompartCell - # print "Error: cellModel=%s not a key in netParam.cellParams or a point process mechanism (eg. NetStim or IntFire1)" % (self.tags['cellModel']) + # Check whether it's a NeuroML2 based cell + if 'originalFormat' in self.tags: + if self.tags['originalFormat'] == 'NeuroML2': + self.cellModelClass = sim.NML2Cell + if self.tags['originalFormat'] == 'NeuroML2_SpikeSource': + self.cellModelClass = sim.NML2SpikeSource + + else: + # set cell class: CompartCell for compartmental cells of PointCell for point neurons (NetStims, IntFire1,...) + try: # check if cellModel corresponds to an existing point process mechanism; if so, use PointCell + + tmp = getattr(h, self.tags['cellModel']) + self.cellModelClass = sim.PointCell + excludeTags = ['popLabel', 'cellModel', 'cellType', 'numCells', 'density', + 'xRange', 'yRange', 'zRange', 'xnormRange', 'ynormRange', 'znormRange', 'vref'] + params = {k: v for k,v in self.tags.iteritems() if k not in excludeTags} + self.tags['params'] = params + for k in self.tags['params']: self.tags.pop(k) + sim.net.params.popTagsCopiedToCells.append('params') + except: + self.cellModelClass = sim.CompartCell # otherwise assume has sections and some cellParam rules apply to it; use CompartCell + # print "Error: cellModel=%s not a key in netParam.cellParams or a point process mechanism (eg. NetStim or IntFire1)" % (self.tags['cellModel']) def __getstate__ (self): diff --git a/netpyne/sim.py b/netpyne/sim.py index a21650427..88cb1b4c8 100644 --- a/netpyne/sim.py +++ b/netpyne/sim.py @@ -19,7 +19,7 @@ from wrappers import * import analysis from network import Network -from cell import CompartCell, PointCell +from cell import CompartCell, PointCell, NML2Cell, NML2SpikeSource from pop import Pop import utils from neuron import h From d7ee561a504c0b511f3792ad65a4d383550b46dc Mon Sep 17 00:00:00 2001 From: Padraig Gleeson Date: Tue, 28 Feb 2017 14:51:48 +0000 Subject: [PATCH 02/37] Initial check for weight!=1 in electrical conns --- netpyne/neuromlFuncs.py | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/netpyne/neuromlFuncs.py b/netpyne/neuromlFuncs.py index 03f949fc3..8ecf7ee9c 100644 --- a/netpyne/neuromlFuncs.py +++ b/netpyne/neuromlFuncs.py @@ -496,7 +496,10 @@ def exportNeuroML2 (reference, connections=True, stimulations=True): else: ''' ''' - + weight = conn['weight'] + if weight!=1: + raise Exception('Cannot yet support inputs where weight !=1!') + connection = neuroml.ElectricalConnectionInstance(id=index, \ pre_cell="../%s/%i/%s"%(popPre, conn['indexPre'], populations_vs_components[popPre]), \ pre_segment=0, \ @@ -1038,10 +1041,12 @@ def handleInputList(self, inputListId, population_id, component, size, input_com # # Overridden from DefaultNetworkHandler # - def handleSingleInput(self, inputListId, id, cellId, segId = 0, fract = 0.5): + def handleSingleInput(self, inputListId, id, cellId, segId = 0, fract = 0.5, weight=1.0): pop_id = self.popStimLists[inputListId]['conds']['popLabel'] nrn_sec, nrn_fract = self._convert_to_nrn_section_location(pop_id,segId,fract) + if weight!=1: + raise Exception('Cannot yet support inputs where weight !=1!') #seg_name = self.pop_ids_vs_seg_ids_vs_segs[pop_id][segId].name if self.pop_ids_vs_seg_ids_vs_segs.has_key(pop_id) else 'soma' @@ -1161,11 +1166,14 @@ def importNeuroML2(fileName, simConfig): connParam = {'delay':delay,'weight':weight,'synsPerConn':1, 'sec':post_seg, 'loc':post_fract, 'threshold':threshold} if ptype == 'electricalProjection': + + if weight!=1: + raise Exception('Cannot yet support inputs where weight !=1!') connParam = {'synsPerConn': 1, 'sec': post_seg, 'loc': post_fract, 'gapJunction': True, - 'weight': 1} + 'weight': weight} else: connParam = {'delay': delay, 'weight': weight, From 8574f678ec7689a7814973c4d88f229d341154f1 Mon Sep 17 00:00:00 2001 From: Padraig Gleeson Date: Fri, 3 Mar 2017 10:30:23 +0000 Subject: [PATCH 03/37] Reduce logging output --- netpyne/neuromlFuncs.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/netpyne/neuromlFuncs.py b/netpyne/neuromlFuncs.py index 8ecf7ee9c..97caa0d26 100644 --- a/netpyne/neuromlFuncs.py +++ b/netpyne/neuromlFuncs.py @@ -1137,7 +1137,7 @@ def importNeuroML2(fileName, simConfig): for proj_id in nmlHandler.projection_infos.keys(): projName, prePop, postPop, synapse, ptype = nmlHandler.projection_infos[proj_id] - print("Creating connections for %s (%s): %s->%s via %s"%(projName, ptype, prePop, postPop, synapse)) + if sim.cfg.verbose: print("Creating connections for %s (%s): %s->%s via %s"%(projName, ptype, prePop, postPop, synapse)) preComp = nmlHandler.pop_ids_vs_components[prePop] From 2498806333a712cab6278737afd50f75a30b0365 Mon Sep 17 00:00:00 2001 From: salvadord Date: Fri, 10 Mar 2017 16:01:24 -0500 Subject: [PATCH 04/37] - Added option to skip batch job based on custom existing job filename (eg. 'skipCustom': '.run') --- CHANGES.md | 4 ++++ netpyne/batch.py | 2 ++ 2 files changed, 6 insertions(+) diff --git a/CHANGES.md b/CHANGES.md index 20462ab85..f308e26fd 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,3 +1,7 @@ +# Version 0.6.9 + +- Added option to skip batch job based on custom existing job filename (eg. 'skipCustom': '.run') + # Version 0.6.8 - Keep track of last host after distributing cells of each pop (improves load balance) (issues #41 #196) diff --git a/netpyne/batch.py b/netpyne/batch.py index d289cc193..caeafb416 100644 --- a/netpyne/batch.py +++ b/netpyne/batch.py @@ -156,6 +156,8 @@ def run(self): print 'Skipping job %s since output file already exists...' % (jobName) elif self.runCfg.get('skipCfg', False) and glob.glob(jobName+'_cfg.json'): print 'Skipping job %s since cfg file already exists...' % (jobName) + elif self.runCfg.get('skipCustom', None) and glob.glob(jobName+self.runCfg['skipCustom']): + print 'Skipping job %s since %s file already exists...' % (jobName, self.runCfg['skipCustom']) else: # save simConfig json to saveFolder self.cfg.simLabel = simLabel From 7ad7d72cc07615648f1e4c7e965ee4c2e07ceecf Mon Sep 17 00:00:00 2001 From: salvadord Date: Sun, 12 Mar 2017 17:13:35 -0400 Subject: [PATCH 05/37] Added option to specify netParams .py file for batch --- CHANGES.md | 2 ++ netpyne/batch.py | 44 ++++++++++++++++++++++---------------------- netpyne/simFuncs.py | 8 +++++++- 3 files changed, 31 insertions(+), 23 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index f308e26fd..db5f70a14 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -2,6 +2,8 @@ - Added option to skip batch job based on custom existing job filename (eg. 'skipCustom': '.run') +- Option to specify netParams .py file for batch + # Version 0.6.8 - Keep track of last host after distributing cells of each pop (improves load balance) (issues #41 #196) diff --git a/netpyne/batch.py b/netpyne/batch.py index caeafb416..2bbbcd324 100644 --- a/netpyne/batch.py +++ b/netpyne/batch.py @@ -19,11 +19,11 @@ # function to run single job using ParallelContext bulletin board (master/slave) # func needs to be outside of class -def runJob(script, cfgSavePath): +def runJob(script, cfgSavePath, netParamsSavePath): from subprocess import Popen, PIPE print '\nJob in rank id: ',pc.id() - command = 'nrniv %s simConfig=%s' % (script, cfgSavePath) + command = 'nrniv %s simConfig=%s netParams=%s' % (script, cfgSavePath, netParamsSavePath) print command+'\n' proc = Popen(command.split(' '), stdout=PIPE, stderr=PIPE) print proc.stdout.read() @@ -85,8 +85,8 @@ def run(self): os.system('cp ' + os.path.realpath(__file__) + ' ' + targetFile) # copy netParams source to folder - targetFile = self.saveFolder+'/'+self.batchLabel+'_netParams.py' - os.system('cp ' + self.netParamsFile + ' ' + targetFile) + netParamsSavePath = self.saveFolder+'/'+self.batchLabel+'_netParams.py' + os.system('cp ' + self.netParamsFile + ' ' + netParamsSavePath) # import cfg cfgModuleName = os.path.basename(self.cfgFile).split('.')[0] @@ -178,7 +178,7 @@ def run(self): queueName = self.runCfg.get('queueName', 'default') nodesppn = 'nodes=1:ppn=%d'%(numproc) - command = 'mpiexec -np %d nrniv -python -mpi %s simConfig=%s' % (numproc, script, cfgSavePath) + command = 'mpiexec -np %d nrniv -python -mpi %s simConfig=%s netParams=%s' % (numproc, script, cfgSavePath, netParamsSavePath) output, input = popen2('qsub') # Open a pipe to the qsub command. @@ -213,24 +213,24 @@ def run(self): script = self.runCfg.get('script', 'init.py') walltime = self.runCfg.get('walltime', '00:30:00') numproc = nodes*coresPerNode - command = 'ibrun -np %d nrniv -python -mpi %s simConfig=%s' % (numproc, script, cfgSavePath) + command = 'ibrun -np %d nrniv -python -mpi %s simConfig=%s netParams=%s' % (numproc, script, cfgSavePath, netParamsSavePath) jobString = """#!/bin/bash -#SBATCH --job-name=%s -#SBATCH -A %s -#SBATCH -t %s -#SBATCH --nodes=%d -#SBATCH --ntasks-per-node=%d -#SBATCH -o %s.run -#SBATCH -e %s.err -#SBATCH --mail-user=%s -#SBATCH --mail-type=end - -source ~/.bashrc -cd %s -%s -wait -""" % (jobName, allocation, walltime, nodes, coresPerNode, jobName, jobName, email, folder, command) + #SBATCH --job-name=%s + #SBATCH -A %s + #SBATCH -t %s + #SBATCH --nodes=%d + #SBATCH --ntasks-per-node=%d + #SBATCH -o %s.run + #SBATCH -e %s.err + #SBATCH --mail-user=%s + #SBATCH --mail-type=end + + source ~/.bashrc + cd %s + %s + wait + """ % (jobName, allocation, walltime, nodes, coresPerNode, jobName, jobName, email, folder, command) # Send job_string to qsub # output, input = popen2('sbatch') # Open a pipe to the qsub command. @@ -253,7 +253,7 @@ def run(self): jobName = self.saveFolder+'/'+simLabel print 'Submitting job ',jobName # master/slave bulletin board schedulling of jobs - pc.submit(runJob, self.runCfg.get('script', 'init.py'), cfgSavePath) + pc.submit(runJob, self.runCfg.get('script', 'init.py'), cfgSavePath, netParamsSavePath) # wait for pc bulletin board jobs to finish try: diff --git a/netpyne/simFuncs.py b/netpyne/simFuncs.py index 50b0435c3..c61e3007d 100644 --- a/netpyne/simFuncs.py +++ b/netpyne/simFuncs.py @@ -14,6 +14,7 @@ 'timing', 'version', 'gitversion', 'loadBalance']) # misc/utilities import sys +import os from time import time from datetime import datetime import cPickle as pk @@ -562,7 +563,12 @@ def readCmdLineArgs (): __main__.cfg = cfg elif arg.startswith('netParams='): netParamsPath = arg.split('netParams=')[1] - netParams = sim.loadNetParams(netParamsPath, setLoaded=False) + if netParamsPath.endswith('.json'): + netParams = sim.loadNetParams(netParamsPath, setLoaded=False) + elif netParamsPath.endswith('py'): + netParamsModule = imp.load_source(os.path.basename(netParamsPath).split('.')[0], netParamsPath) + netParams = netParamsModule.netParams + print 'Importing netParams from %s' %(netParamsPath) if not cfgPath: try: From f88e7e325d348513f4c59291febe21c989bfb542 Mon Sep 17 00:00:00 2001 From: salvadord Date: Sun, 12 Mar 2017 17:25:02 -0400 Subject: [PATCH 06/37] Fixed bug in hpc slurm script --- netpyne/batch.py | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/netpyne/batch.py b/netpyne/batch.py index 2bbbcd324..38d2a1117 100644 --- a/netpyne/batch.py +++ b/netpyne/batch.py @@ -216,20 +216,20 @@ def run(self): command = 'ibrun -np %d nrniv -python -mpi %s simConfig=%s netParams=%s' % (numproc, script, cfgSavePath, netParamsSavePath) jobString = """#!/bin/bash - #SBATCH --job-name=%s - #SBATCH -A %s - #SBATCH -t %s - #SBATCH --nodes=%d - #SBATCH --ntasks-per-node=%d - #SBATCH -o %s.run - #SBATCH -e %s.err - #SBATCH --mail-user=%s - #SBATCH --mail-type=end - - source ~/.bashrc - cd %s - %s - wait +#SBATCH --job-name=%s +#SBATCH -A %s +#SBATCH -t %s +#SBATCH --nodes=%d +#SBATCH --ntasks-per-node=%d +#SBATCH -o %s.run +#SBATCH -e %s.err +#SBATCH --mail-user=%s +#SBATCH --mail-type=end + +source ~/.bashrc +cd %s +%s +wait """ % (jobName, allocation, walltime, nodes, coresPerNode, jobName, jobName, email, folder, command) # Send job_string to qsub From 56e7c776ef8dae7ca49397a5e66af81eb190494d Mon Sep 17 00:00:00 2001 From: salvadord Date: Thu, 16 Mar 2017 10:19:37 -0400 Subject: [PATCH 07/37] modified hpc_torque batch to accept nodes and ppn --- CHANGES.md | 4 +++- examples/HHTut/HHTut.py | 4 ++-- netpyne/analysis.py | 13 +++++++++---- netpyne/batch.py | 6 ++++-- netpyne/simFuncs.py | 1 + 5 files changed, 19 insertions(+), 9 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index db5f70a14..02e60d50b 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -2,7 +2,9 @@ - Added option to skip batch job based on custom existing job filename (eg. 'skipCustom': '.run') -- Option to specify netParams .py file for batch +- Added option to specify netParams .py file for batch + +- Modified hpc_torque batch to accept nodes and ppn # Version 0.6.8 diff --git a/examples/HHTut/HHTut.py b/examples/HHTut/HHTut.py index e3f346b0f..30c08f149 100644 --- a/examples/HHTut/HHTut.py +++ b/examples/HHTut/HHTut.py @@ -25,7 +25,7 @@ ############################################################################### # Population parameters -netParams.popParams['PYR'] = {'cellModel': 'HH', 'cellType': 'PYR', 'numCells': 100} # add dict with params for this pop +netParams.popParams['PYR'] = {'cellmodel': 'HH', 'cellType': 'PYR', 'numCells': 100} # add dict with params for this pop # Cell parameters @@ -49,7 +49,7 @@ # Connectivity parameters netParams.connParams['PYR->PYR'] = { - 'preConds': {'popLabel': 'PYR'}, 'postConds': {'popLabel': 'PYR'}, + 'preConds': {'popLabel': 'PYT'}, 'postConds': {'popLabel': 'PYR'}, 'weight': 0.002, # weight of each connection 'delay': '0.2+gauss(13.0,1.4)', # delay min=0.2, mean=13.0, var = 1.4 'threshold': 10, # threshold diff --git a/netpyne/analysis.py b/netpyne/analysis.py index 152790ade..8a0a24822 100644 --- a/netpyne/analysis.py +++ b/netpyne/analysis.py @@ -929,6 +929,10 @@ def plotShape (showSyns = False, includePre = ['all'], includePost = ['all'], sy if 'weightNorm' in sec: secs.append(sec['hSec']) cvals.extend(sec['weightNorm']) + + cvals = np.array(cvals) + cvals = cvals/min(cvals) + # numSyns elif cvar == 'numSyns': for cellPost in cellsPost: @@ -940,13 +944,14 @@ def plotShape (showSyns = False, includePre = ['all'], includePost = ['all'], sy for conn in conns: nsyns[int(round(conn['loc']*nseg))-1] += 1 cvals.extend(nsyns) - cvals = np.array(cvals) + cvals = np.array(cvals) if not secs: secs = [s['hSec'] for cellPost in cellsPost for s in cellPost.secs.values()] if not includeAxon: - secs = [sec for sec in secs if 'axon' not in secs.hname()] + secs = [sec for sec in secs if 'axon' not in sec.hname()] # Plot shapeplot + cbLabels = {'numSyns': 'number of synapses', 'weightNorm': 'weight scaling'} fig=plt.figure(figsize=(10,10)) shapeax = plt.subplot(111, projection='3d') shapeax.elev=90 # 90 @@ -956,11 +961,11 @@ def plotShape (showSyns = False, includePre = ['all'], includePost = ['all'], sy cmap=plt.cm.jet #YlOrBr_r morph.shapeplot(h,shapeax, sections=secs, cvals=cvals, cmap=cmap) fig.subplots_adjust(left=0, right=1, bottom=0, top=1) - if cvals and len(cvals)>0: + if not cvals==None and len(cvals)>0: sm = plt.cm.ScalarMappable(cmap=cmap, norm=plt.Normalize(vmin=np.min(cvals), vmax=np.max(cvals))) sm._A = [] # fake up the array of the scalar mappable cb = plt.colorbar(sm, fraction=0.15, shrink=0.5, pad=0.01, aspect=20) - cb.set_label('number of synapses', rotation=90) + cb.set_label(cbLabels[cvar], rotation=90) if showSyns: synColor='red' diff --git a/netpyne/batch.py b/netpyne/batch.py index 38d2a1117..588496e43 100644 --- a/netpyne/batch.py +++ b/netpyne/batch.py @@ -172,11 +172,13 @@ def run(self): sleepInterval = self.runCfg.get('sleepInterval', 1) sleep(sleepInterval) - numproc = self.runCfg.get('numproc', 1) + nodes = self.runCfg.get('nodes', 1) + ppn = self.runCfg.get('ppn', 1) script = self.runCfg.get('script', 'init.py') walltime = self.runCfg.get('walltime', '00:30:00') queueName = self.runCfg.get('queueName', 'default') - nodesppn = 'nodes=1:ppn=%d'%(numproc) + nodesppn = 'nodes=$d:ppn=%d'%(nodes,ppn) + numproc = nodes*ppn command = 'mpiexec -np %d nrniv -python -mpi %s simConfig=%s netParams=%s' % (numproc, script, cfgSavePath, netParamsSavePath) diff --git a/netpyne/simFuncs.py b/netpyne/simFuncs.py index c61e3007d..ab8fbaf2b 100644 --- a/netpyne/simFuncs.py +++ b/netpyne/simFuncs.py @@ -69,6 +69,7 @@ def initialize (netParams = None, simConfig = None, net = None): def setNet (net): sim.net = net + ############################################################################### # Set network params to use in simulation ############################################################################### From 9d0e1a79d092170c9986ee254b577f8589f261cd Mon Sep 17 00:00:00 2001 From: salvadord Date: Thu, 16 Mar 2017 10:32:29 -0400 Subject: [PATCH 08/37] modified hpc_torque batch to accept nodes and ppn --- netpyne/batch.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/netpyne/batch.py b/netpyne/batch.py index 588496e43..84c772090 100644 --- a/netpyne/batch.py +++ b/netpyne/batch.py @@ -177,7 +177,7 @@ def run(self): script = self.runCfg.get('script', 'init.py') walltime = self.runCfg.get('walltime', '00:30:00') queueName = self.runCfg.get('queueName', 'default') - nodesppn = 'nodes=$d:ppn=%d'%(nodes,ppn) + nodesppn = 'nodes=%d:ppn=%d'%(nodes,ppn) numproc = nodes*ppn command = 'mpiexec -np %d nrniv -python -mpi %s simConfig=%s netParams=%s' % (numproc, script, cfgSavePath, netParamsSavePath) From 52a0766a189292ba9b700a5ba63b2758abe51723 Mon Sep 17 00:00:00 2001 From: salvadord Date: Thu, 16 Mar 2017 10:44:47 -0400 Subject: [PATCH 09/37] added extra color to plotting color list --- netpyne/analysis.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/netpyne/analysis.py b/netpyne/analysis.py index 8a0a24822..635dee70a 100644 --- a/netpyne/analysis.py +++ b/netpyne/analysis.py @@ -25,11 +25,11 @@ colorList = [[0.42,0.67,0.84], [0.90,0.76,0.00], [0.42,0.83,0.59], [0.90,0.32,0.00], [0.34,0.67,0.67], [0.90,0.59,0.00], [0.42,0.82,0.83], [1.00,0.85,0.00], [0.33,0.67,0.47], [1.00,0.38,0.60], [0.57,0.67,0.33], [0.5,0.2,0.0], - [0.71,0.82,0.41], [0.0,0.2,0.5], + [0.71,0.82,0.41], [0.0,0.2,0.5], [0.70,0.32,0.10], [0.42,0.67,0.84], [0.90,0.76,0.00], [0.42,0.83,0.59], [0.90,0.32,0.00], [0.34,0.67,0.67], [0.90,0.59,0.00], [0.42,0.82,0.83], [1.00,0.85,0.00], [0.33,0.67,0.47], [1.00,0.38,0.60], [0.57,0.67,0.33], [0.5,0.2,0.0], - [0.71,0.82,0.41], [0.0,0.2,0.5]] + [0.71,0.82,0.41], [0.0,0.2,0.5], [0.70,0.32,0.10]] ###################################################################################################################################################### ## Wrapper to run analysis functions in simConfig From 60c7d6909294bb710d9c01b516652c4d458bd170 Mon Sep 17 00:00:00 2001 From: salvadord Date: Thu, 16 Mar 2017 11:08:24 -0400 Subject: [PATCH 10/37] - Fixed bug in plotConn bar graphs --- CHANGES.md | 2 ++ netpyne/analysis.py | 6 +++--- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 02e60d50b..dab99285a 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -6,6 +6,8 @@ - Modified hpc_torque batch to accept nodes and ppn +- Fixed bug in plotConn bar graphs + # Version 0.6.8 - Keep track of last host after distributing cells of each pop (improves load balance) (issues #41 #196) diff --git a/netpyne/analysis.py b/netpyne/analysis.py index 635dee70a..a1b90dd91 100644 --- a/netpyne/analysis.py +++ b/netpyne/analysis.py @@ -1426,9 +1426,9 @@ def list_of_dict_unique_by_key(seq, key): SBG = stackedBarGraph.StackedBarGrapher() fig = plt.figure(figsize=figSize) - ax = fig.add_plt.subplot(111) - SBG.stackedBarplt.plot(ax, connMatrix.transpose(), colorList, xLabels=popsPost, gap = 0.1, scale=False, xlabel='postsynaptic', ylabel = feature) - title ('Connection '+feature+' stacked bar graph') + ax = fig.add_subplot(111) + SBG.stackedBarPlot(ax, connMatrix.transpose(), colorList, xLabels=popsPost, gap = 0.1, scale=False, xlabel='postsynaptic', ylabel = feature) + plt.title ('Connection '+feature+' stacked bar graph') plt.legend(popsPre) plt.tight_layout() From 98e5e261f09972f01909f1f94caa3d0b4ecab639 Mon Sep 17 00:00:00 2001 From: salvadord Date: Thu, 16 Mar 2017 13:53:47 -0400 Subject: [PATCH 11/37] added support/stackedBarGraph.py --- CHANGES.md | 1 + netpyne/support/stackedBarGraph.py | 295 +++++++++++++++++++++++++++++ 2 files changed, 296 insertions(+) create mode 100644 netpyne/support/stackedBarGraph.py diff --git a/CHANGES.md b/CHANGES.md index dab99285a..ee19da252 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -8,6 +8,7 @@ - Fixed bug in plotConn bar graphs + # Version 0.6.8 - Keep track of last host after distributing cells of each pop (improves load balance) (issues #41 #196) diff --git a/netpyne/support/stackedBarGraph.py b/netpyne/support/stackedBarGraph.py new file mode 100644 index 000000000..5c6f2653c --- /dev/null +++ b/netpyne/support/stackedBarGraph.py @@ -0,0 +1,295 @@ +#!/usr/bin/env python +############################################################################### +# # +# stackedBarGraph.py - code for creating purdy stacked bar graphs # +# # +############################################################################### +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see . # +# # +############################################################################### + +__author__ = "Michael Imelfort; modified by salvadordura@gmail.com" +__copyright__ = "Copyright 2014" +__credits__ = ["Michael Imelfort"] +__license__ = "GPL3" +__version__ = "0.0.1" +__maintainer__ = "Michael Imelfort" +__email__ = "mike@mikeimelfort.com" +__status__ = "Development" + +############################################################################### + +import numpy as np +from matplotlib import pyplot as plt + +############################################################################### + +class StackedBarGrapher: + """Container class""" + def __init__(self): pass + + def demo(self): + d = np.array([[101.,0.,0.,0.,0.,0.,0.], + [92.,3.,0.,4.,5.,6.,0.], + [56.,7.,8.,9.,23.,4.,5.], + [81.,2.,4.,5.,32.,33.,4.], + [0.,45.,2.,3.,45.,67.,8.], + [99.,5.,0.,0.,0.,43.,56.]]) + + d_heights = [1.,2.,3.,4.,5.,6.] + d_widths = [.5,1.,3.,2.,1.,2.] + d_labels = ["fred","julie","sam","peter","rob","baz"] + d_colors = ['#2166ac', '#fee090', '#fdbb84', '#fc8d59', '#e34a33', '#b30000', '#777777'] + gap = 0.05 + + fig = plt.figure() + ax1 = fig.add_subplot(321) + self.stackedBarPlot(ax1, + d, + d_colors, + edgeCols=['#000000']*7, + xLabels=d_labels, + ) + plt.title("Straight up stacked bars") + + ax2 = fig.add_subplot(322) + self.stackedBarPlot(ax2, + d, + d_colors, + edgeCols=['#000000']*7, + xLabels=d_labels, + scale=True + ) + plt.title("Scaled bars") + + ax3 = fig.add_subplot(323) + self.stackedBarPlot(ax3, + d, + d_colors, + edgeCols=['#000000']*7, + xLabels=d_labels, + heights=d_heights, + yTicks=7, + ) + plt.title("Bars with set heights") + + ax4 = fig.add_subplot(324) + self.stackedBarPlot(ax4, + d, + d_colors, + edgeCols=['#000000']*7, + xLabels=d_labels, + yTicks=7, + widths=d_widths, + scale=True + ) + plt.title("Scaled bars with set widths") + + ax5 = fig.add_subplot(325) + self.stackedBarPlot(ax5, + d, + d_colors, + edgeCols=['#000000']*7, + xLabels=d_labels, + gap=gap + ) + plt.title("Straight up stacked bars + gaps") + + ax6 = fig.add_subplot(326) + self.stackedBarPlot(ax6, + d, + d_colors, + edgeCols=['#000000']*7, + xLabels=d_labels, + scale=True, + gap=gap, + endGaps=True + ) + plt.title("Scaled bars + gaps + end gaps") + + # We change the fontsize of minor ticks label + fig.subplots_adjust(bottom=0.4) + + plt.tight_layout() + plt.show() + plt.close(fig) + del fig + + def stackedBarPlot(self, + ax, # axes to plot onto + data, # data to plot + cols, # colors for each level + xLabels = None, # bar specific labels + yTicks = 6., # information used for making y ticks ["none", or [[tick_pos1, tick_pos2, ... ],[tick_label_1, tick_label2, ...]] + edgeCols=None, # colors for edges + showFirst=-1, # only plot the first bars + scale=False, # scale bars to same height + widths=None, # set widths for each bar + heights=None, # set heights for each bar + ylabel='', # label for x axis + xlabel='', # label for y axis + gap=0., # gap between bars + endGaps=False # allow gaps at end of bar chart (only used if gaps != 0.) + ): + +#------------------------------------------------------------------------------ +# data fixeratering + + # make sure this makes sense + if showFirst != -1: + showFirst = np.min([showFirst, np.shape(data)[0]]) + data_copy = np.copy(data[:showFirst]).transpose().astype('float') + data_shape = np.shape(data_copy) + if heights is not None: + heights = heights[:showFirst] + if widths is not None: + widths = widths[:showFirst] + showFirst = -1 + else: + data_copy = np.copy(data).transpose() + data_shape = np.shape(data_copy) + + # determine the number of bars and corresponding levels from the shape of the data + num_bars = data_shape[1] + levels = data_shape[0] + + if widths is None: + widths = np.array([1] * num_bars) + x = np.arange(num_bars) + else: + x = [0] + for i in range(1, len(widths)): + x.append(x[i-1] + (widths[i-1] + widths[i])/2) + + # stack the data -- + # replace the value in each level by the cumulative sum of all preceding levels + data_stack = np.reshape([float(i) for i in np.ravel(np.cumsum(data_copy, axis=0))], data_shape) + + # scale the data is needed + if scale: + data_copy /= data_stack[levels-1] + data_stack /= data_stack[levels-1] + if heights is not None: + print "WARNING: setting scale and heights does not make sense." + heights = None + elif heights is not None: + data_copy /= data_stack[levels-1] + data_stack /= data_stack[levels-1] + for i in np.arange(num_bars): + data_copy[:,i] *= heights[i] + data_stack[:,i] *= heights[i] + +#------------------------------------------------------------------------------ +# ticks + + if yTicks is not "none": + # it is either a set of ticks or the number of auto ticks to make + real_ticks = True + try: + k = len(yTicks[1]) + except: + real_ticks = False + + if not real_ticks: + yTicks = float(yTicks) + if scale: + # make the ticks line up to 100 % + y_ticks_at = np.arange(yTicks)/(yTicks-1) + y_tick_labels = np.array(["%0.2f"%(i * 100) for i in y_ticks_at]) + else: + # space the ticks along the y axis + y_ticks_at = np.arange(yTicks)/(yTicks-1)*np.max(data_stack) + y_tick_labels = np.array([str(i) for i in y_ticks_at]) + yTicks=(y_ticks_at, y_tick_labels) + +#------------------------------------------------------------------------------ +# plot + + if edgeCols is None: + edgeCols = ["none"]*len(cols) + + # take cae of gaps + gapd_widths = [i - gap for i in widths] + + # bars + ax.bar(x, + data_stack[0], + color=cols[0], + edgecolor=edgeCols[0], + width=gapd_widths, + linewidth=0.5, + align='center' + ) + + for i in np.arange(1,levels): + ax.bar(x, + data_copy[i], + bottom=data_stack[i-1], + color=cols[i], + edgecolor=edgeCols[i], + width=gapd_widths, + linewidth=0.5, + align='center' + ) + + # borders + ax.spines["top"].set_visible(False) + ax.spines["right"].set_visible(False) + ax.spines["bottom"].set_visible(False) + ax.spines["left"].set_visible(False) + + # make ticks if necessary + # if yTicks is not "none": + # ax.tick_params(axis='y', which='both', labelsize=8, direction="out") + # ax.yaxis.tick_left() + # plt.yticks(yTicks[0], yTicks[1]) + # else: + # plt.yticks([], []) + + if xLabels is not None: + ax.tick_params(axis='x', which='both')#, labelsize=8, direction="out") + ax.xaxis.tick_bottom() + plt.xticks(x, xLabels) #, rotation='vertical') + else: + plt.xticks([], []) + + # limits + if endGaps: + ax.set_xlim(-1.*widths[0]/2. - gap/2., np.sum(widths)-widths[0]/2. + gap/2.) + else: + ax.set_xlim(-1.*widths[0]/2. + gap/2., np.sum(widths)-widths[0]/2. - gap/2.) + ax.set_ylim(0, yTicks[0][-1])#np.max(data_stack)) + + # labels + if xlabel != '': + plt.xlabel(xlabel) + if ylabel != '': + plt.ylabel(ylabel) + + +############################################################################### +############################################################################### +############################################################################### +############################################################################### + +if __name__ == '__main__': + + SBG = StackedBarGrapher() + SBG.demo() + +############################################################################### +############################################################################### +############################################################################### +############################################################################### From 40507f95ffc52ea8600996efc688ae7e1e666f79 Mon Sep 17 00:00:00 2001 From: Padraig Gleeson Date: Fri, 17 Mar 2017 10:07:42 +0000 Subject: [PATCH 12/37] @salvadord I believe this was causing the fail in tests on Travis --- examples/HHTut/HHTut.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/HHTut/HHTut.py b/examples/HHTut/HHTut.py index 30c08f149..e670c3ff4 100644 --- a/examples/HHTut/HHTut.py +++ b/examples/HHTut/HHTut.py @@ -25,7 +25,7 @@ ############################################################################### # Population parameters -netParams.popParams['PYR'] = {'cellmodel': 'HH', 'cellType': 'PYR', 'numCells': 100} # add dict with params for this pop +netParams.popParams['PYR'] = {'cellModel': 'HH', 'cellType': 'PYR', 'numCells': 100} # add dict with params for this pop # Cell parameters From b3b39406e4b7257a77d309a3827e39f2816376cc Mon Sep 17 00:00:00 2001 From: salvadord Date: Sat, 18 Mar 2017 14:27:43 -0400 Subject: [PATCH 13/37] Fixed bug: missing hRandom for NetStim populations --- CHANGES.md | 2 + examples/HHTut/HHTut.py | 2 +- examples/sandbox/sandbox.py | 92 +++++++++++++++++++------------------ netpyne/analysis.py | 9 ++-- netpyne/cell.py | 7 ++- netpyne/simFuncs.py | 25 ++++++++-- 6 files changed, 80 insertions(+), 57 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index ee19da252..5329aa816 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -8,6 +8,8 @@ - Fixed bug in plotConn bar graphs +- Fixed bug: missing hRandom for NetStim populations + # Version 0.6.8 diff --git a/examples/HHTut/HHTut.py b/examples/HHTut/HHTut.py index 30c08f149..e670c3ff4 100644 --- a/examples/HHTut/HHTut.py +++ b/examples/HHTut/HHTut.py @@ -25,7 +25,7 @@ ############################################################################### # Population parameters -netParams.popParams['PYR'] = {'cellmodel': 'HH', 'cellType': 'PYR', 'numCells': 100} # add dict with params for this pop +netParams.popParams['PYR'] = {'cellModel': 'HH', 'cellType': 'PYR', 'numCells': 100} # add dict with params for this pop # Cell parameters diff --git a/examples/sandbox/sandbox.py b/examples/sandbox/sandbox.py index 4d705c5d6..90bcceb22 100644 --- a/examples/sandbox/sandbox.py +++ b/examples/sandbox/sandbox.py @@ -27,6 +27,26 @@ simConfig = specs.SimConfig() # dictionary to store sets of simulation configurations +############################################################################### +# SIMULATION PARAMETERS +############################################################################### + +# Simulation parameters +simConfig.duration = 1.0*1e3 # Duration of the simulation, in ms +simConfig.dt = 0.1 # Internal integration timestep to use +simConfig.createNEURONObj = 1 # create HOC objects when instantiating network +simConfig.createPyStruct = 1 # create Python structure (simulator-independent) when instantiating network +simConfig.verbose = 0 #False # show detailed messages + +# Recording +simConfig.recordTraces = {'Vsoma':{'sec':'soma','loc':0.5,'var':'v'}} + +# # Analysis and plotting +simConfig.analysis['plotRaster'] = {'figSize': (20,8)} #True +#simConfig.analysis['plot2Dnet'] = True + + + ############################################################################### # NETWORK PARAMETERS ############################################################################### @@ -38,9 +58,9 @@ # Population parameters -netParams.popParams['PYR1'] = {'cellModel': 'HH', 'cellType': 'PYR', 'gridSpacing': 10, 'xRange': [30,60]} # pop of HH cells -netParams.popParams['PYR2'] = {'cellModel': 'HH', 'cellType': 'PYR', 'gridSpacing': 5, 'yRange': [20,40]} # pop of HH cells -#netParams.popParams['artifVec'] = {'cellModel': 'VecStim', 'numCells': 10000, 'interval': 100, 'noise': 0.5, 'start': 50} # pop of NetStims +#netParams.popParams['PYR1'] = {'cellModel': 'HH', 'cellType': 'PYR', 'gridSpacing': 10, 'xRange': [30,60]} # pop of HH cells +#netParams.popParams['PYR2'] = {'cellModel': 'HH', 'cellType': 'PYR', 'gridSpacing': 5, 'yRange': [20,40]} # pop of HH cells +netParams.popParams['artifVec'] = {'cellModel': 'NetStim', 'numCells': 100, 'interval': 100, 'noise': 0.5, 'start': 50} # pop of NetStims # netParams.popParams['artif1'] = {'cellModel': 'VecStim', 'numCells': 100, 'rate': [0,5], 'noise': 1.0, 'start': 50}#, # 'pulses': [{'start': 200, 'end': 300, 'rate': 50, 'noise':0.2}, {'start': 500, 'end': 800, 'rate': 30, 'noise':0.5}]} # pop of NetStims @@ -49,8 +69,8 @@ # Stimulation parameters -# netParams.stimSourceParams['background'] = {'type': 'NetStim', 'interval': 100, 'number': 1e5, 'start': 500, 'noise': 0.5} # stim using NetStims after 500ms -# netParams.stimTargetParams['bkg->PYR1'] = {'source': 'background', 'conds': {'popLabel': 'PYR1'}, 'sec':'soma', 'loc': 0.5, 'weight': 0.5, 'delay': 1} +#netParams.stimSourceParams['background'] = {'type': 'NetStim', 'interval': 100, 'number': 1e5, 'start': 500, 'noise': 0.5} # stim using NetStims after 500ms +#netParams.stimTargetParams['bkg->PYR1'] = {'source': 'background', 'conds': {'popLabel': 'PYR1'}, 'sec':'soma', 'loc': 0.5, 'weight': 0.5, 'delay': 1} # Cell parameters @@ -62,47 +82,29 @@ netParams.cellParams['PYR'] = cellParams -# Connections -netParams.connParams['artif1->PYR1'] = { - 'preConds': {'popLabel': 'artif1'}, 'postConds': {'popLabel': 'PYR1'}, - 'convergence': 4, - 'weight': 0.005, - 'synMech': 'AMPA', - 'delay': 'uniform(1,5)', - 'synsPerConn': 1} +# # Connections +# netParams.connParams['artif1->PYR1'] = { +# 'preConds': {'popLabel': 'artif1'}, 'postConds': {'popLabel': 'PYR1'}, +# 'convergence': 4, +# 'weight': 0.005, +# 'synMech': 'AMPA', +# 'delay': 'uniform(1,5)', +# 'synsPerConn': 1} + +# netParams.connParams['PYR2->PYR1'] = { +# 'preConds': {'popLabel': 'PYR2'}, 'postConds': {'popLabel': 'PYR1'}, +# 'probability': 0.1, +# 'weight': 0.2, +# 'delay': 'uniform(1,5)', +# 'synsPerConn': 1} + +# netParams.addConnParams('artif1->PYR2', +# {'preConds': {'popLabel': 'artif1'}, 'postConds': {'popLabel': 'PYR2'}, +# 'divergence': 3, +# 'weight': 0.05, +# 'delay': 3, +# 'synsPerConn': 1}) -netParams.connParams['PYR2->PYR1'] = { - 'preConds': {'popLabel': 'PYR2'}, 'postConds': {'popLabel': 'PYR1'}, - 'probability': 0.1, - 'weight': 0.2, - 'delay': 'uniform(1,5)', - 'synsPerConn': 1} - -netParams.addConnParams('artif1->PYR2', - {'preConds': {'popLabel': 'artif1'}, 'postConds': {'popLabel': 'PYR2'}, - 'divergence': 3, - 'weight': 0.05, - 'delay': 3, - 'synsPerConn': 1}) - - -############################################################################### -# SIMULATION PARAMETERS -############################################################################### - -# Simulation parameters -simConfig.duration = 0.1*1e3 # Duration of the simulation, in ms -simConfig.dt = 0.1 # Internal integration timestep to use -simConfig.createNEURONObj = 1 # create HOC objects when instantiating network -simConfig.createPyStruct = 1 # create Python structure (simulator-independent) when instantiating network -simConfig.verbose = 0 #False # show detailed messages - -# Recording -simConfig.recordTraces = {'Vsoma':{'sec':'soma','loc':0.5,'var':'v'}} - -# # Analysis and plotting -simConfig.analysis['plotRaster'] = True -simConfig.analysis['plot2Dnet'] = True ############################################################################### diff --git a/netpyne/analysis.py b/netpyne/analysis.py index a1b90dd91..06e4585e8 100644 --- a/netpyne/analysis.py +++ b/netpyne/analysis.py @@ -539,11 +539,11 @@ def plotSpikeHist (include = ['allCells', 'eachPop'], timeRange = None, binSize if not overlay: plt.subplot(len(include),1,iplot+1) # if subplot, create new subplot - title (str(subset), fontsize=fontsiz) + plt.title (str(subset), fontsize=fontsiz) color = 'blue' if graphType == 'line': - plot (histoT, histoCount, linewidth=1.0, color = color) + plt.plot (histoT, histoCount, linewidth=1.0, color = color) elif graphType == 'bar': plt.bar(histoT, histoCount, width = binSize, color = color) @@ -956,7 +956,7 @@ def plotShape (showSyns = False, includePre = ['all'], includePost = ['all'], sy shapeax = plt.subplot(111, projection='3d') shapeax.elev=90 # 90 shapeax.azim=-90 # -90 - shapeax.dist=0.8*shapeax.dist + shapeax.dist=0.6*shapeax.dist plt.axis('equal') cmap=plt.cm.jet #YlOrBr_r morph.shapeplot(h,shapeax, sections=secs, cvals=cvals, cmap=cmap) @@ -974,7 +974,8 @@ def plotShape (showSyns = False, includePre = ['all'], includePost = ['all'], sy for synMech in sec['synMechs']: morph.mark_locations(h, sec['hSec'], synMech['loc'], markspec=synStyle, color=synColor, markersize=synSiz) - plt.title(str(includePre)+' -> '+str(includePost) + ' ' + str(cvar)) + #plt.title(str(includePre)+' -> '+str(includePost) + ' ' + str(cvar)) + shapeax.set_xticklabels([]) # save figure if saveFig: diff --git a/netpyne/cell.py b/netpyne/cell.py index 6dff19106..99e58d2c2 100644 --- a/netpyne/cell.py +++ b/netpyne/cell.py @@ -1149,7 +1149,8 @@ class PointCell (Cell): def __init__ (self, gid, tags, create=True, associateGid=True): super(PointCell, self).__init__(gid, tags) self.hPointp = None - self.params = deepcopy(self.tags.pop('params')) + if 'params' in self.tags: + self.params = deepcopy(self.tags.pop('params')) if create and sim.cfg.createNEURONObj: self.createNEURONObj() # create cell @@ -1181,8 +1182,10 @@ def createNEURONObj (self): except: pass - # set number and seed for NetStims + # add random num generator, and set number and seed for NetStims if self.tags['cellModel'] == 'NetStim': + rand = h.Random() + self.hRandom = rand if 'number' not in self.params: params['number'] = 1e9 setattr(self.hPointp, 'number', params['number']) diff --git a/netpyne/simFuncs.py b/netpyne/simFuncs.py index ab8fbaf2b..164952123 100644 --- a/netpyne/simFuncs.py +++ b/netpyne/simFuncs.py @@ -149,9 +149,21 @@ def loadNet (filename, data=None, instantiate=True): # create new CompartCell object and add attributes, but don't create sections or associate gid yet # TO DO: assumes CompartCell -- add condition to load PointCell cell = sim.CompartCell(gid=cellLoad['gid'], tags=cellLoad['tags'], create=False, associateGid=False) - cell.secs = Dict(cellLoad['secs']) - cell.conns = [Dict(conn) for conn in cellLoad['conns']] - cell.stims = [Dict(stim) for stim in cellLoad['stims']] + try: + cell.secs = Dict(cellLoad['secs']) + except: + if sim.cfg.verbose: ' Unable to load cell secs' + + try: + cell.conns = [Dict(conn) for conn in cellLoad['conns']] + except: + if sim.cfg.verbose: ' Unable to load cell conns' + + try: + cell.stims = [Dict(stim) for stim in cellLoad['stims']] + except: + if sim.cfg.verbose: ' Unable to load cell stims' + sim.net.cells.append(cell) print(' Created %d cells' % (len(sim.net.cells))) print(' Created %d connections' % (sum([len(c.conns) for c in sim.net.cells]))) @@ -168,8 +180,11 @@ def loadNet (filename, data=None, instantiate=True): # create all NEURON Netcons, NetStims, etc sim.pc.barrier() for cell in sim.net.cells: - cell.addStimsNEURONObj() # add stims first so can then create conns between netstims - cell.addConnsNEURONObj() + try: + cell.addStimsNEURONObj() # add stims first so can then create conns between netstims + cell.addConnsNEURONObj() + except: + if sim.cfg.verbose: ' Unable to load instantiate cell conns or stims' print(' Added NEURON objects to %d cells' % (len(sim.net.cells))) From 940cd0ccc539bae39784cc5f9d1d8f08ad5d5c82 Mon Sep 17 00:00:00 2001 From: salvadord Date: Sat, 18 Mar 2017 15:51:00 -0400 Subject: [PATCH 14/37] Fixed bug: VectStim spike generation now reproducible for different durations --- CHANGES.md | 2 ++ examples/sandbox/sandbox.py | 21 +++++++------ netpyne/cell.py | 62 +++++++++++++++++++++++++++++++------ 3 files changed, 67 insertions(+), 18 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 5329aa816..7251845e7 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -10,6 +10,8 @@ - Fixed bug: missing hRandom for NetStim populations +- Fixed bug: VectStim generation spike generation now reproducible for different durations + # Version 0.6.8 diff --git a/examples/sandbox/sandbox.py b/examples/sandbox/sandbox.py index 90bcceb22..1d54657c9 100644 --- a/examples/sandbox/sandbox.py +++ b/examples/sandbox/sandbox.py @@ -32,7 +32,7 @@ ############################################################################### # Simulation parameters -simConfig.duration = 1.0*1e3 # Duration of the simulation, in ms +simConfig.duration = 1.5*1e3 # Duration of the simulation, in ms simConfig.dt = 0.1 # Internal integration timestep to use simConfig.createNEURONObj = 1 # create HOC objects when instantiating network simConfig.createPyStruct = 1 # create Python structure (simulator-independent) when instantiating network @@ -42,7 +42,7 @@ simConfig.recordTraces = {'Vsoma':{'sec':'soma','loc':0.5,'var':'v'}} # # Analysis and plotting -simConfig.analysis['plotRaster'] = {'figSize': (20,8)} #True +#simConfig.analysis['plotRaster'] = {'figSize': (20,8)} #True #simConfig.analysis['plot2Dnet'] = True @@ -60,12 +60,13 @@ # Population parameters #netParams.popParams['PYR1'] = {'cellModel': 'HH', 'cellType': 'PYR', 'gridSpacing': 10, 'xRange': [30,60]} # pop of HH cells #netParams.popParams['PYR2'] = {'cellModel': 'HH', 'cellType': 'PYR', 'gridSpacing': 5, 'yRange': [20,40]} # pop of HH cells -netParams.popParams['artifVec'] = {'cellModel': 'NetStim', 'numCells': 100, 'interval': 100, 'noise': 0.5, 'start': 50} # pop of NetStims +netParams.popParams['artifVec'] = {'cellModel': 'VecStim', 'numCells': 1, 'interval': 100, 'noise': 0.5, 'start': 50, + 'pulses':[{'start': 1000, 'end': 1400, 'rate': 100, 'noise': 0.5}]} # pop of NetStims # netParams.popParams['artif1'] = {'cellModel': 'VecStim', 'numCells': 100, 'rate': [0,5], 'noise': 1.0, 'start': 50}#, # 'pulses': [{'start': 200, 'end': 300, 'rate': 50, 'noise':0.2}, {'start': 500, 'end': 800, 'rate': 30, 'noise':0.5}]} # pop of NetStims # Synaptic mechanism parameters -netParams.synMechParams['AMPA'] = {'mod': 'Exp2Syn', 'tau1': 0.1, 'tau2': 1.0, 'e': 0} +# netParams.synMechParams['AMPA'] = {'mod': 'Exp2Syn', 'tau1': 0.1, 'tau2': 1.0, 'e': 0} # Stimulation parameters @@ -75,11 +76,11 @@ # Cell parameters ## PYR cell properties -cellParams = Dict() -cellParams.secs.soma.geom = {'diam': 18.8, 'L': 18.8, 'Ra': 123.0} -cellParams.secs.soma.mechs.hh = {'gnabar': 0.12, 'gkbar': 0.036, 'gl': 0.003, 'el': -70} -cellParams.conds = {'cellType': 'PYR'} -netParams.cellParams['PYR'] = cellParams +# cellParams = Dict() +# cellParams.secs.soma.geom = {'diam': 18.8, 'L': 18.8, 'Ra': 123.0} +# cellParams.secs.soma.mechs.hh = {'gnabar': 0.12, 'gkbar': 0.036, 'gl': 0.003, 'el': -70} +# cellParams.conds = {'cellType': 'PYR'} +# netParams.cellParams['PYR'] = cellParams # # Connections @@ -112,6 +113,8 @@ ############################################################################### sim.createSimulateAnalyze() + + #sim.create() #sim.gatherData() diff --git a/netpyne/cell.py b/netpyne/cell.py index 99e58d2c2..43992e452 100644 --- a/netpyne/cell.py +++ b/netpyne/cell.py @@ -1211,6 +1211,9 @@ def createNEURONObj (self): # 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 + numSpks = len(fixedInterval) + + maxReproducibleSpks = 1e4 # num of rand spikes generated; only a subset is used; ensures reproducibility # randomize the first spike so on average it occurs at start + noise*interval # invl = (1. - noise)*mean + noise*mean*erand() - interval*(1. - noise) @@ -1221,11 +1224,39 @@ def createNEURONObj (self): # plus negexp interval of mean duration noise*interval. Note that the most likely negexp interval has duration 0. rand = h.Random() rand.Random123(self.gid, sim.id32('%d'%(self.params['seed']))) - vec = h.Vector(len(fixedInterval)) - rand.negexp(noise*interval) - vec.setrand(rand) - negexpInterval = np.array(vec) - spkTimes = np.cumsum(fixedInterval + negexpInterval) + (start - interval*(1-noise)) + + # Method 1: vec length depends on duration -- not reproducible + # vec = h.Vector(numSpks) + # rand.negexp(noise*interval) + # vec.setrand(rand) + # negexpInterval= np.array(vec) + # #print negexpInterval + # spkTimes = np.cumsum(fixedInterval + negexpInterval) + (start - interval*(1-noise)) + + if numSpks < 100: + # Method 2: vec length=1, slower but reproducible + vec = h.Vector(1) + rand.negexp(noise*interval) + negexpInterval = [] + for i in range(numSpks): + vec.setrand(rand) + negexpInterval.append(vec.x[0]) # = np.array(vec)[0:len(fixedInterval)] + spkTimes = np.cumsum(fixedInterval + np.array(negexpInterval)) + (start - interval*(1-noise)) + + elif numSpks < maxReproducibleSpks: + # Method 3: vec length=maxReproducibleSpks, then select subset; slower but reproducible + vec = h.Vector(maxReproducibleSpks) + rand.negexp(noise*interval) + vec.setrand(rand) + negexpInterval = np.array(vec.c(0,len(fixedInterval)-1)) + spkTimes = np.cumsum(fixedInterval + negexpInterval) + (start - interval*(1-noise)) + + else: + print '\nError: VecStim num spks per cell > %d' % (maxReproducibleSpks) + import sys + sys.exit() + + print spkTimes # pulse list: start, end, rate, noise if 'pulses' in self.params: @@ -1251,6 +1282,7 @@ def createNEURONObj (self): # fixed interval of duration (1 - noise)*interval fixedInterval = np.full(((1+1.5*noise)*(end-start)/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 # invl = (1. - noise)*mean + noise*mean*erand() - interval*(1. - noise) @@ -1263,11 +1295,23 @@ def createNEURONObj (self): # plus negexp interval of mean duration noise*interval. Note that the most likely negexp interval has duration 0. rand = h.Random() rand.Random123(self.gid, sim.id32('%d'%(self.params['seed']))) - vec = h.Vector(len(fixedInterval)) + + # Method 1: vec length depends on duration -- not reproducible + # vec = h.Vector(len(fixedInterval)) + # rand.negexp(noise*interval) + # vec.setrand(rand) + # negexpInterval = np.array(vec) + # pulseSpikes = np.cumsum(fixedInterval + negexpInterval) + (start - interval*(1-noise)) + + # Method 2: vec length=1, slower but reproducible + vec = h.Vector(1) rand.negexp(noise*interval) - vec.setrand(rand) - negexpInterval = np.array(vec) - pulseSpikes = np.cumsum(fixedInterval + negexpInterval) + (start - interval*(1-noise)) + negexpInterval = [] + for i in range(numSpks): + vec.setrand(rand) + negexpInterval.append(vec.x[0]) # = np.array(vec)[0:len(fixedInterval)] + pulseSpikes = np.cumsum(fixedInterval + np.array(negexpInterval)) + (start - interval*(1-noise)) + pulseSpikes[pulseSpikes < start] = start spkTimes = np.append(spkTimes, pulseSpikes[pulseSpikes <= end]) From 1c3c5f50fd88989d528aecd2106db11e403b3435 Mon Sep 17 00:00:00 2001 From: salvadord Date: Mon, 20 Mar 2017 11:16:52 -0400 Subject: [PATCH 15/37] removed debugging print statement --- CHANGES.md | 2 +- netpyne/cell.py | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 7251845e7..89a2ecdd4 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -10,7 +10,7 @@ - Fixed bug: missing hRandom for NetStim populations -- Fixed bug: VectStim generation spike generation now reproducible for different durations +- Fixed bug: VectStim spike generation now reproducible for different durations # Version 0.6.8 diff --git a/netpyne/cell.py b/netpyne/cell.py index 43992e452..daaaf72aa 100644 --- a/netpyne/cell.py +++ b/netpyne/cell.py @@ -1256,8 +1256,6 @@ def createNEURONObj (self): import sys sys.exit() - print spkTimes - # pulse list: start, end, rate, noise if 'pulses' in self.params: for pulse in self.params['pulses']: From fdd82143b36c30dae16a0f51849f352b3f5fa161 Mon Sep 17 00:00:00 2001 From: salvadord Date: Mon, 20 Mar 2017 21:26:48 -0400 Subject: [PATCH 16/37] - Fixed bug in batch grouped params --- CHANGES.md | 2 ++ examples/sandbox/sandbox.py | 37 +++++++++++++++++++------------------ netpyne/batch.py | 6 ++++-- 3 files changed, 25 insertions(+), 20 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 89a2ecdd4..ac923939b 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -12,6 +12,8 @@ - Fixed bug: VectStim spike generation now reproducible for different durations +- Fixed bug in batch grouped params + # Version 0.6.8 diff --git a/examples/sandbox/sandbox.py b/examples/sandbox/sandbox.py index 1d54657c9..b7fbbef3b 100644 --- a/examples/sandbox/sandbox.py +++ b/examples/sandbox/sandbox.py @@ -32,13 +32,14 @@ ############################################################################### # Simulation parameters -simConfig.duration = 1.5*1e3 # Duration of the simulation, in ms +simConfig.duration = 0.5*1e3 # Duration of the simulation, in ms simConfig.dt = 0.1 # Internal integration timestep to use simConfig.createNEURONObj = 1 # create HOC objects when instantiating network simConfig.createPyStruct = 1 # create Python structure (simulator-independent) when instantiating network -simConfig.verbose = 0 #False # show detailed messages +simConfig.verbose = 1 #False # show detailed messages # Recording +simConfig.recordCells = [('PYR1',5), 8] simConfig.recordTraces = {'Vsoma':{'sec':'soma','loc':0.5,'var':'v'}} # # Analysis and plotting @@ -58,7 +59,7 @@ # Population parameters -#netParams.popParams['PYR1'] = {'cellModel': 'HH', 'cellType': 'PYR', 'gridSpacing': 10, 'xRange': [30,60]} # pop of HH cells +netParams.popParams['PYR1'] = {'cellModel': 'HH', 'cellType': 'PYR', 'gridSpacing': 10, 'xRange': [30,60]} # pop of HH cells #netParams.popParams['PYR2'] = {'cellModel': 'HH', 'cellType': 'PYR', 'gridSpacing': 5, 'yRange': [20,40]} # pop of HH cells netParams.popParams['artifVec'] = {'cellModel': 'VecStim', 'numCells': 1, 'interval': 100, 'noise': 0.5, 'start': 50, 'pulses':[{'start': 1000, 'end': 1400, 'rate': 100, 'noise': 0.5}]} # pop of NetStims @@ -76,21 +77,21 @@ # Cell parameters ## PYR cell properties -# cellParams = Dict() -# cellParams.secs.soma.geom = {'diam': 18.8, 'L': 18.8, 'Ra': 123.0} -# cellParams.secs.soma.mechs.hh = {'gnabar': 0.12, 'gkbar': 0.036, 'gl': 0.003, 'el': -70} -# cellParams.conds = {'cellType': 'PYR'} -# netParams.cellParams['PYR'] = cellParams - - -# # Connections -# netParams.connParams['artif1->PYR1'] = { -# 'preConds': {'popLabel': 'artif1'}, 'postConds': {'popLabel': 'PYR1'}, -# 'convergence': 4, -# 'weight': 0.005, -# 'synMech': 'AMPA', -# 'delay': 'uniform(1,5)', -# 'synsPerConn': 1} +cellParams = Dict() +cellParams.secs.soma.geom = {'diam': 18.8, 'L': 18.8, 'Ra': 123.0} +cellParams.secs.soma.mechs.hh = {'gnabar': 0.12, 'gkbar': 0.036, 'gl': 0.003, 'el': -70} +cellParams.conds = {'cellType': 'PYR'} +netParams.cellParams['PYR'] = cellParams + + +# Connections +netParams.connParams['artif1->PYR1'] = { + 'preConds': {'popLabel': 'artif1'}, 'postConds': {'popLabel': 'PYR1'}, + 'convergence': 4, + 'weight': 0.005, + 'synMech': 'AMPA', + 'delay': 'uniform(1,5)', + 'synsPerConn': 1} # netParams.connParams['PYR2->PYR1'] = { # 'preConds': {'popLabel': 'PYR2'}, 'postConds': {'popLabel': 'PYR1'}, diff --git a/netpyne/batch.py b/netpyne/batch.py index 84c772090..78ace4e72 100644 --- a/netpyne/batch.py +++ b/netpyne/batch.py @@ -96,10 +96,10 @@ def run(self): # iterate over all param combinations if self.method == 'grid': groupedParams = False - for p in self.params: + for p in self.params: if 'group' not in p: p['group'] = False # by default set linear to False - elif 'group' == True: + elif p['group'] == True: groupedParams = True labelList, valuesList = zip(*[(p['label'], p['values']) for p in self.params if p['group'] == False]) @@ -110,6 +110,7 @@ def run(self): labelListGroup, valuesListGroup = zip(*[(p['label'], p['values']) for p in self.params if p['group'] == True]) valueCombGroups = izip(*(valuesListGroup)) indexCombGroups = izip(*[range(len(x)) for x in valuesListGroup]) + labelList = labelListGroup+labelList else: valueCombGroups = [(0,)] # this is a hack -- improve! indexCombGroups = [(0,)] @@ -127,6 +128,7 @@ def run(self): if groupedParams: # temporary hack - improve iComb = iCombG+iCombNG pComb = pCombG+pCombNG + else: iComb = iCombNG pComb = pCombNG From 4fd50b0c17d5b63788a16c16aaaf8da38a447a6a Mon Sep 17 00:00:00 2001 From: salvadord Date: Tue, 21 Mar 2017 12:50:49 -0400 Subject: [PATCH 17/37] Fixed bug: getCellsList() only checked for tuples but when load from json converted to list --- CHANGES.md | 2 ++ netpyne/simFuncs.py | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGES.md b/CHANGES.md index ac923939b..e708b3e4c 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -14,6 +14,8 @@ - Fixed bug in batch grouped params +- Fixed bug: getCellsList() only checked for tuples but when load from json converted to list + # Version 0.6.8 diff --git a/netpyne/simFuncs.py b/netpyne/simFuncs.py index 164952123..6f35e6daa 100644 --- a/netpyne/simFuncs.py +++ b/netpyne/simFuncs.py @@ -683,7 +683,7 @@ def getCellsList (include): cellGids.extend(list(sim.net.pops[condition].cellGids)) #[c.gid for c in sim.net.cells if c.tags['popLabel']==condition]) - elif isinstance(condition, tuple): # subset of a pop with relative indices + elif isinstance(condition, tuple) or isinstance(condition, list): # subset of a pop with relative indices cellsPop = [gid for gid,tags in allCellTags.iteritems() if tags['popLabel']==condition[0]] if isinstance(condition[1], list): cellGids.extend([gid for i,gid in enumerate(cellsPop) if i in condition[1]]) From 4b43ae0df65c67b17b3994089b52b968eddae5ee Mon Sep 17 00:00:00 2001 From: salvadord Date: Thu, 23 Mar 2017 14:31:56 -0400 Subject: [PATCH 18/37] temporary change to test cell recording on multiple cores --- netpyne/simFuncs.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/netpyne/simFuncs.py b/netpyne/simFuncs.py index 6f35e6daa..c46cc4a65 100644 --- a/netpyne/simFuncs.py +++ b/netpyne/simFuncs.py @@ -28,7 +28,6 @@ - ############################################################################### # initialize variables and MPI ############################################################################### @@ -652,6 +651,9 @@ def setupRecording (): # get actual cell objects to record from, both from recordCell and plotCell lists cellsRecord = getCellsList(sim.cfg.recordCells)+cellsPlot + #print cellsPlot + print [c.gid for c in cellsRecord] + for key in sim.cfg.recordTraces.keys(): sim.simData[key] = Dict() # create dict to store traces for cell in cellsRecord: cell.recordTraces() # call recordTraces function for each cell @@ -685,6 +687,8 @@ def getCellsList (include): elif isinstance(condition, tuple) or isinstance(condition, list): # subset of a pop with relative indices cellsPop = [gid for gid,tags in allCellTags.iteritems() if tags['popLabel']==condition[0]] + #print sim.rank,condition[0],cellsPop + if isinstance(condition[1], list): cellGids.extend([gid for i,gid in enumerate(cellsPop) if i in condition[1]]) elif isinstance(condition[1], int): From f618b8af2040c708115eba4622f02c7166c586e7 Mon Sep 17 00:00:00 2001 From: salvadord Date: Thu, 23 Mar 2017 14:59:42 -0400 Subject: [PATCH 19/37] temporary change to test cell recording on multiple cores --- netpyne/simFuncs.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/netpyne/simFuncs.py b/netpyne/simFuncs.py index c46cc4a65..7660c7092 100644 --- a/netpyne/simFuncs.py +++ b/netpyne/simFuncs.py @@ -687,7 +687,7 @@ def getCellsList (include): elif isinstance(condition, tuple) or isinstance(condition, list): # subset of a pop with relative indices cellsPop = [gid for gid,tags in allCellTags.iteritems() if tags['popLabel']==condition[0]] - #print sim.rank,condition[0],cellsPop + print sim.rank,condition[0],cellsPop[0], cellsPop[-1] if isinstance(condition[1], list): cellGids.extend([gid for i,gid in enumerate(cellsPop) if i in condition[1]]) From 596d8437832dbc4920d803bf1424f241cc9b7214 Mon Sep 17 00:00:00 2001 From: salvadord Date: Thu, 23 Mar 2017 15:52:50 -0400 Subject: [PATCH 20/37] temporary change to test cell recording on multiple cores --- netpyne/simFuncs.py | 1 + 1 file changed, 1 insertion(+) diff --git a/netpyne/simFuncs.py b/netpyne/simFuncs.py index 7660c7092..ed8839bc4 100644 --- a/netpyne/simFuncs.py +++ b/netpyne/simFuncs.py @@ -687,6 +687,7 @@ def getCellsList (include): elif isinstance(condition, tuple) or isinstance(condition, list): # subset of a pop with relative indices cellsPop = [gid for gid,tags in allCellTags.iteritems() if tags['popLabel']==condition[0]] + cellsPop.sort() print sim.rank,condition[0],cellsPop[0], cellsPop[-1] if isinstance(condition[1], list): From 4d836ffedffed0269533ff2328157ede165977d4 Mon Sep 17 00:00:00 2001 From: salvadord Date: Thu, 23 Mar 2017 16:03:46 -0400 Subject: [PATCH 21/37] temporary change to test cell recording on multiple cores --- netpyne/simFuncs.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/netpyne/simFuncs.py b/netpyne/simFuncs.py index ed8839bc4..f850ce574 100644 --- a/netpyne/simFuncs.py +++ b/netpyne/simFuncs.py @@ -652,7 +652,7 @@ def setupRecording (): cellsRecord = getCellsList(sim.cfg.recordCells)+cellsPlot #print cellsPlot - print [c.gid for c in cellsRecord] + #print [c.gid for c in cellsRecord] for key in sim.cfg.recordTraces.keys(): sim.simData[key] = Dict() # create dict to store traces for cell in cellsRecord: cell.recordTraces() # call recordTraces function for each cell @@ -671,6 +671,8 @@ def getCellsList (include): else: allCellTags = {cell.gid: cell.tags for cell in sim.net.cells} + print sim.rank, len(allCellTags), allCellTags.keys()[0], allCellTags.keys()[-1] + cellGids = [] cells = [] for condition in include: @@ -688,7 +690,7 @@ def getCellsList (include): elif isinstance(condition, tuple) or isinstance(condition, list): # subset of a pop with relative indices cellsPop = [gid for gid,tags in allCellTags.iteritems() if tags['popLabel']==condition[0]] cellsPop.sort() - print sim.rank,condition[0],cellsPop[0], cellsPop[-1] + #print sim.rank,condition[0],cellsPop[0], cellsPop[-1] if isinstance(condition[1], list): cellGids.extend([gid for i,gid in enumerate(cellsPop) if i in condition[1]]) From f952870d3848a2198e3ac063d1d4bf9dbdc0ca91 Mon Sep 17 00:00:00 2001 From: salvadord Date: Thu, 23 Mar 2017 17:45:44 -0400 Subject: [PATCH 22/37] Fixed bug so cell treshold is set by default to sim.net.defaultThreshold --- CHANGES.md | 1 + netpyne/cell.py | 6 ++++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index e708b3e4c..36cb4a2c0 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -16,6 +16,7 @@ - Fixed bug: getCellsList() only checked for tuples but when load from json converted to list +- Fixed bug so cell treshold is set by default to sim.net.defaultThreshold # Version 0.6.8 diff --git a/netpyne/cell.py b/netpyne/cell.py index daaaf72aa..bd7a2cc99 100644 --- a/netpyne/cell.py +++ b/netpyne/cell.py @@ -503,7 +503,7 @@ def addConnsNEURONObj(self): self._addConnPlasticity(conn['plast'], self.secs[conn['sec']], netcon, 0) - def associateGid (self, threshold = 10.0): + def associateGid (self, threshold = None): if self.secs: if sim.cfg.createNEURONObj: sim.pc.set_gid2node(self.gid, sim.rank) # this is the key call that assigns cell gid to a particular node @@ -521,6 +521,7 @@ def associateGid (self, threshold = 10.0): break if not nc: # if still haven't created netcon nc = h.NetCon(sec['hSec'](loc)._ref_v, None, sec=sec['hSec']) + threshold = threshold if threshold is not None else sim.net.params.defaultThreshold nc.threshold = threshold sim.pc.cell(self.gid, nc, 1) # associate a particular output stream of events del nc # discard netcon @@ -1320,13 +1321,14 @@ def createNEURONObj (self): self.hPointp.play(self.hSpkTimes.from_python(spkTimes)) - def associateGid (self, threshold = 10.0): + def associateGid (self, threshold = None): if sim.cfg.createNEURONObj: sim.pc.set_gid2node(self.gid, sim.rank) # this is the key call that assigns cell gid to a particular node if 'vref' in self.tags: nc = h.NetCon(self.hPointp.__getattribute__('_ref_'+self.tags['vref']), None) else: nc = h.NetCon(self.hPointp, None) + threshold = threshold if threshold is not None else sim.net.params.defaultThreshold nc.threshold = threshold sim.pc.cell(self.gid, nc, 1) # associate a particular output stream of events del nc # discard netcon From 0259e9641d405f20ac370c4e885976907f0a9c0a Mon Sep 17 00:00:00 2001 From: salvadord Date: Thu, 23 Mar 2017 21:35:02 -0400 Subject: [PATCH 23/37] fixed bug recording cells when using multiple cores (list vs tuple) --- netpyne/simFuncs.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/netpyne/simFuncs.py b/netpyne/simFuncs.py index f850ce574..e4741227e 100644 --- a/netpyne/simFuncs.py +++ b/netpyne/simFuncs.py @@ -666,13 +666,13 @@ def setupRecording (): ### Get cells list for recording based on set of conditions ############################################################################### def getCellsList (include): - if sim.nhosts > 1 and any(isinstance(cond, tuple) for cond in include): # Gather tags from all cells + if sim.nhosts > 1 and any(isinstance(cond, tuple) or isinstance(cond,list) for cond in include): # Gather tags from all cells allCellTags = sim._gatherAllCellTags() else: allCellTags = {cell.gid: cell.tags for cell in sim.net.cells} print sim.rank, len(allCellTags), allCellTags.keys()[0], allCellTags.keys()[-1] - + cellGids = [] cells = [] for condition in include: From 9894b674d8d261a9f62e0e1d097073a4ca0420da Mon Sep 17 00:00:00 2001 From: salvadord Date: Thu, 23 Mar 2017 21:47:54 -0400 Subject: [PATCH 24/37] remove debugging prints --- netpyne/simFuncs.py | 8 -------- 1 file changed, 8 deletions(-) diff --git a/netpyne/simFuncs.py b/netpyne/simFuncs.py index e4741227e..e1593117e 100644 --- a/netpyne/simFuncs.py +++ b/netpyne/simFuncs.py @@ -651,9 +651,6 @@ def setupRecording (): # get actual cell objects to record from, both from recordCell and plotCell lists cellsRecord = getCellsList(sim.cfg.recordCells)+cellsPlot - #print cellsPlot - #print [c.gid for c in cellsRecord] - for key in sim.cfg.recordTraces.keys(): sim.simData[key] = Dict() # create dict to store traces for cell in cellsRecord: cell.recordTraces() # call recordTraces function for each cell @@ -671,8 +668,6 @@ def getCellsList (include): else: allCellTags = {cell.gid: cell.tags for cell in sim.net.cells} - print sim.rank, len(allCellTags), allCellTags.keys()[0], allCellTags.keys()[-1] - cellGids = [] cells = [] for condition in include: @@ -685,12 +680,9 @@ def getCellsList (include): elif isinstance(condition, basestring): # entire pop cellGids.extend(list(sim.net.pops[condition].cellGids)) - #[c.gid for c in sim.net.cells if c.tags['popLabel']==condition]) elif isinstance(condition, tuple) or isinstance(condition, list): # subset of a pop with relative indices cellsPop = [gid for gid,tags in allCellTags.iteritems() if tags['popLabel']==condition[0]] - cellsPop.sort() - #print sim.rank,condition[0],cellsPop[0], cellsPop[-1] if isinstance(condition[1], list): cellGids.extend([gid for i,gid in enumerate(cellsPop) if i in condition[1]]) From 49d5bdca6dde14c3e660c5f1cc75a40983a79291 Mon Sep 17 00:00:00 2001 From: Padraig Gleeson Date: Fri, 24 Mar 2017 17:16:38 +0000 Subject: [PATCH 25/37] Improved support for handling random stimulations in NeuroML2 cells Ensures reproducability of sims across different numbers of processors --- examples/NeuroMLImport/poissonFiringSyn.mod | 67 +++++++++++++++++++-- netpyne/cell.py | 24 +++++++- netpyne/neuromlFuncs.py | 32 +++++++--- netpyne/simFuncs.py | 10 ++- 4 files changed, 116 insertions(+), 17 deletions(-) diff --git a/examples/NeuroMLImport/poissonFiringSyn.mod b/examples/NeuroMLImport/poissonFiringSyn.mod index ceb3514c7..2e5836bb7 100644 --- a/examples/NeuroMLImport/poissonFiringSyn.mod +++ b/examples/NeuroMLImport/poissonFiringSyn.mod @@ -26,7 +26,9 @@ NEURON { RANGE syn0_g : exposure RANGE syn0_i : exposure - + : Based on netstim.mod + THREADSAFE : only true if every instance has its own distinct Random + POINTER donotuse } UNITS { @@ -70,7 +72,7 @@ ASSIGNED { rate_tsince (ms/ms) rate_syn0_A (/ms) rate_syn0_B (/ms) - + donotuse } STATE { @@ -164,10 +166,67 @@ PROCEDURE rates() { } -: Returns a float between 0 and max +: Returns a float between 0 and max; implementation of random() as used in LEMS FUNCTION random_float(max) { - random_float = scop_random()*max + : This is not ideal, getting an exponential dist random number and then turning back to uniform + : However this is the easiest what to ensure mod files with random methods fit into NEURON's + : internal framework for managing internal number generation. + random_float = exp(-1*erand())*max } +:**************************************************** +: Methods copied from netstim.mod in NEURON source + + +PROCEDURE seed(x) { + set_seed(x) +} + +VERBATIM +double nrn_random_pick(void* r); +void* nrn_random_arg(int argpos); +ENDVERBATIM + + +FUNCTION erand() { +VERBATIM + if (_p_donotuse) { + /* + :Supports separate independent but reproducible streams for + : each instance. However, the corresponding hoc Random + : distribution MUST be set to Random.negexp(1) + */ + _lerand = nrn_random_pick(_p_donotuse); + }else{ + /* only can be used in main thread */ + if (_nt != nrn_threads) { + hoc_execerror("multithread random in NetStim"," only via hoc Random"); + } +ENDVERBATIM + : the old standby. Cannot use if reproducible parallel sim + : independent of nhost or which host this instance is on + : is desired, since each instance on this cpu draws from + : the same stream + erand = exprand(1) +VERBATIM + } +ENDVERBATIM +} + +PROCEDURE noiseFromRandom() { +VERBATIM + { + void** pv = (void**)(&_p_donotuse); + if (ifarg(1)) { + *pv = nrn_random_arg(1); + }else{ + *pv = (void*)0; + } + } +ENDVERBATIM +} + +: End of methods copied from netstim.mod in NEURON source:**************************************************** + diff --git a/netpyne/cell.py b/netpyne/cell.py index 1ca0923b0..b42ac17f6 100644 --- a/netpyne/cell.py +++ b/netpyne/cell.py @@ -966,7 +966,7 @@ def addStim (self, params): (params['source'], params['type'], self.gid, params['sec'], params['loc'], stringParams)) else: - if sim.cfg.verbose: print('Adding exotic stim (NeuroML2 based?): %s'% params['type']) + if sim.cfg.verbose: print('Adding exotic stim (NeuroML 2 based?): %s'% params) stim = getattr(h, params['type'])(sec['hSec'](params['loc'])) stimParams = {k:v for k,v in params.iteritems() if k not in ['type', 'source', 'loc', 'sec', 'label']} stringParams = '' @@ -975,6 +975,16 @@ def addStim (self, params): print "Can't set point process paramaters of type vector eg. VClamp.amp[3]" pass #setattr(stim, stimParamName._ref_[0], stimParamValue[0]) + elif 'originalFormat' in params: + if sim.cfg.verbose: print(' originalFormat: %s'%(params['originalFormat'])) + if params['originalFormat']=='NeuroML2_stochastic_input': + rand = h.Random() + rand.Random123(params['stim_count'], sim.id32('%d'%(sim.cfg.seeds['stim']))) + rand.negexp(1) + stim.noiseFromRandom(rand) + self.stims.append(Dict()) # add new stim to Cell object + randContainer = self.stims[-1] + randContainer['NeuroML2_stochastic_input_rand'] = rand else: setattr(stim, stimParamName, stimParamValue) stringParams = stringParams + ', ' + stimParamName +'='+ str(stimParamValue) @@ -1443,7 +1453,6 @@ class NML2SpikeSource (CompartCell): ''' def associateGid (self, threshold = 10.0): - print("associateGid... %s, %s"%(self.gid,self.tags)) if sim.cfg.createNEURONObj: sim.pc.set_gid2node(self.gid, sim.rank) # this is the key call that assigns cell gid to a particular node @@ -1455,4 +1464,15 @@ def associateGid (self, threshold = 10.0): del nc # discard netcon sim.net.gid2lid[self.gid] = len(sim.net.lid2gid) sim.net.lid2gid.append(self.gid) # index = local id; value = global id + + def initRandom(self): + + rand = h.Random() + self.stims.append(Dict()) # add new stim to Cell object + randContainer = self.stims[-1] + randContainer['hRandom'] = rand + seed = sim.cfg.seeds['stim'] + randContainer['seed'] = seed + self.secs['soma']['pointps'][self.tags['cellType']].hPointp.noiseFromRandom(rand) # use random number generator + #print("Created Random: %s with %s (%s)"%(rand,seed, sim.cfg.seeds)) diff --git a/netpyne/neuromlFuncs.py b/netpyne/neuromlFuncs.py index 97caa0d26..707e73b40 100644 --- a/netpyne/neuromlFuncs.py +++ b/netpyne/neuromlFuncs.py @@ -637,6 +637,7 @@ class NetPyNEBuilder(DefaultNetworkHandler): gids = OrderedDict() next_gid = 0 + stochastic_input_count = 0 def __init__(self, netParams, verbose = False): self.netParams = netParams @@ -701,6 +702,9 @@ def handlePopulation(self, population_id, component, size, component_obj): popInfo['cellModel'] = component popInfo['originalFormat'] = 'NeuroML2' # This parameter is required to distinguish NML2 "point processes" from abstract cells popInfo['cellsList'] = [] + + if population_id=='pop': + print("\n\n*****************************\nReconsider calling your population 'pop'; it leads to some errors!\n*****************************\n\n") self.popParams[population_id] = popInfo @@ -820,8 +824,6 @@ def handlePopulation(self, population_id, component, size, component_obj): cellRule['secs'][section_name]['ions'][cm.ion]['e'] = erev for cm in cell.biophysical_properties.membrane_properties.channel_density_nernsts: - raise Exception(" not yet supported!") - group = 'all' if not cm.segment_groups else cm.segment_groups for section_name in seg_grps_vs_nrn_sections[group]: gmax = pynml.convert_to_units(cm.cond_density,'S_per_cm2') @@ -1022,10 +1024,19 @@ def handleConnection(self, projName, id, prePop, postPop, synapseType, \ def handleInputList(self, inputListId, population_id, component, size, input_comp_obj=None): DefaultNetworkHandler.printInputInformation(self,inputListId, population_id, component, size) + import neuroml - self.popStimSources[inputListId] = {'label': inputListId, 'type': component} + format = 'NeuroML2' + if isinstance(input_comp_obj,neuroml.PoissonFiringSynapse): + format = 'NeuroML2_stochastic_input' + self.popStimSources[inputListId] = {'label': inputListId, 'type': component, 'originalFormat': format} self.popStimLists[inputListId] = {'source': inputListId, 'conds': {'popLabel':population_id}} + + + if component=='IClamp': + print("\n\n*****************************\nReconsider calling your input 'IClamp' in NeuroML; it leads to some errors due to clash with native NEURON IClamp!\n*****************************\n\n") + exit() # TODO: build just one stimLists/stimSources entry for the inputList # Issue: how to specify the sec/loc per individual stim?? @@ -1052,7 +1063,13 @@ def handleSingleInput(self, inputListId, id, cellId, segId = 0, fract = 0.5, wei stimId = "%s_%s_%s_%s_%s_%s"%(inputListId, id,pop_id,cellId,nrn_sec,(str(fract)).replace('.','_')) - self.stimSources[stimId] = {'label': stimId, 'type': self.popStimSources[inputListId]['type']} + self.stimSources[stimId] = {'label': stimId, + 'type': self.popStimSources[inputListId]['type'], + 'originalFormat': self.popStimSources[inputListId]['originalFormat']} + if self.popStimSources[inputListId]['originalFormat'] == 'NeuroML2_stochastic_input': + self.stimSources[stimId]['stim_count'] = self.stochastic_input_count + self.stochastic_input_count +=1 + self.stimLists[stimId] = {'source': stimId, 'sec':nrn_sec, 'loc': nrn_fract, @@ -1098,7 +1115,7 @@ def importNeuroML2(fileName, simConfig): nmlHandler.finalise() - print('Finished import: %s'%nmlHandler.gids) + print('Finished import of NeuroML2; populations vs gids NML has calculated: %s'%nmlHandler.gids) #print('Connections: %s'%nmlHandler.connections) if fileName.endswith(".h5"): @@ -1124,16 +1141,15 @@ def importNeuroML2(fileName, simConfig): #pp.pprint(netParams) #pp.pprint(simConfig) - sim.net.createPops() cells = sim.net.createCells() # instantiate network cells based on defined populations # Check gids equal.... for popLabel,pop in sim.net.pops.iteritems(): - #print("%s: %s, %s"%(popLabel,pop, pop.cellGids)) + if sim.cfg.verbose: print("gid: %s: %s, %s"%(popLabel,pop, pop.cellGids)) for gid in pop.cellGids: - assert(gid in nmlHandler.gids[popLabel]) + assert gid in nmlHandler.gids[popLabel] for proj_id in nmlHandler.projection_infos.keys(): projName, prePop, postPop, synapse, ptype = nmlHandler.projection_infos[proj_id] diff --git a/netpyne/simFuncs.py b/netpyne/simFuncs.py index ab8fbaf2b..363e1a002 100644 --- a/netpyne/simFuncs.py +++ b/netpyne/simFuncs.py @@ -768,6 +768,10 @@ def printRunTime(): if cell.tags.get('cellModel') == 'NetStim': cell.hRandom.Random123(cell.gid, sim.id32('%d'%(cell.params['seed']))) cell.hRandom.negexp(1) + pop = sim.net.pops[cell.tags['popLabel']] + if 'originalFormat' in pop.tags and pop.tags['originalFormat'] == 'NeuroML2_SpikeSource': + if sim.cfg.verbose: print("== Setting random generator in NeuroML spike generator") + cell.initRandom() for stim in cell.stims: if 'hRandom' in stim: stim['hRandom'].Random123(cell.gid, sim.id32('%d'%(stim['seed']))) @@ -857,7 +861,7 @@ def gatherData (): if not sim.cfg.saveCellConns: for cell in sim.net.cells: cell.conns = [] - + simDataVecs = ['spkt','spkid','stims']+sim.cfg.recordTraces.keys() if sim.nhosts > 1: # only gather if >1 nodes netPopsCellGids = {popLabel: list(pop.cellGids) for popLabel,pop in sim.net.pops.iteritems()} @@ -947,7 +951,7 @@ def gatherData (): pop['cellGids'] = sorted(allPopsCellGids[popLabel]) sim.net.allPops = allPops - + # clean to avoid mem leaks for node in gather: if node: @@ -957,7 +961,7 @@ def gatherData (): if item: item.clear() del item - + else: # if single node, save data in same format as for multiple nodes for consistency if sim.cfg.createNEURONObj: sim.net.allCells = [Dict(c.__getstate__()) for c in sim.net.cells] From fd1370ca58d9d9ef08a104e1f34fabab7f0547e6 Mon Sep 17 00:00:00 2001 From: salvadord Date: Mon, 3 Apr 2017 12:47:47 -0400 Subject: [PATCH 26/37] Fixed bug plotting NetStims (created as stims) in raster, spikeHist and ratePSD; Fixed bug plotting overlayed spikeHist over raster plot --- CHANGES.md | 4 + examples/HHTut/HHTut.py | 14 +++- examples/sandbox/sandbox.py | 41 ++++++---- netpyne/analysis.py | 149 +++++++++++++++++++++--------------- netpyne/network.py | 1 - netpyne/simFuncs.py | 8 +- netpyne/utils.py | 4 +- sdnotes.org | 3 +- 8 files changed, 133 insertions(+), 91 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 36cb4a2c0..185539309 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -6,6 +6,8 @@ - Modified hpc_torque batch to accept nodes and ppn +- Fixed bug plotting NetStims (created as stims) in raster, spikeHist and ratePSD + - Fixed bug in plotConn bar graphs - Fixed bug: missing hRandom for NetStim populations @@ -18,6 +20,8 @@ - Fixed bug so cell treshold is set by default to sim.net.defaultThreshold +- Fixed bug plotting overlayed spikeHist over raster plot + # Version 0.6.8 - Keep track of last host after distributing cells of each pop (improves load balance) (issues #41 #196) diff --git a/examples/HHTut/HHTut.py b/examples/HHTut/HHTut.py index e670c3ff4..fcda62905 100644 --- a/examples/HHTut/HHTut.py +++ b/examples/HHTut/HHTut.py @@ -25,12 +25,20 @@ ############################################################################### # Population parameters -netParams.popParams['PYR'] = {'cellModel': 'HH', 'cellType': 'PYR', 'numCells': 100} # add dict with params for this pop +netParams.popParams['PYR'] = {'cellModel': 'HH', 'cellType': 'PYR', 'numCells': 100, 'yRange': [300, 500], 'color': 'red'} # add dict with params for this pop +netParams.popParams['PYR'] = {'cellModel': 'HH', 'cellType': 'PYR2', 'numCells': 100} # add dict with params for this pop # Cell parameters ## PYR cell properties -cellRule = {'conds': {'cellModel': 'HH', 'cellType': 'PYR'}, 'secs': {}} # cell rule dict +cellRule = {'conds': {'cellModel': 'HH', 'cellType': 'PYT'}, '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 + +cellRule = {'conds': {'color': 'red'}, '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 @@ -49,7 +57,7 @@ # Connectivity parameters netParams.connParams['PYR->PYR'] = { - 'preConds': {'popLabel': 'PYT'}, 'postConds': {'popLabel': 'PYR'}, + 'preConds': {'popLabel': 'PYR'}, 'postConds': {'popLabel': 'PYR'}, 'weight': 0.002, # weight of each connection 'delay': '0.2+gauss(13.0,1.4)', # delay min=0.2, mean=13.0, var = 1.4 'threshold': 10, # threshold diff --git a/examples/sandbox/sandbox.py b/examples/sandbox/sandbox.py index b7fbbef3b..1786ec65d 100644 --- a/examples/sandbox/sandbox.py +++ b/examples/sandbox/sandbox.py @@ -59,15 +59,15 @@ # Population parameters -netParams.popParams['PYR1'] = {'cellModel': 'HH', 'cellType': 'PYR', 'gridSpacing': 10, 'xRange': [30,60]} # pop of HH cells -#netParams.popParams['PYR2'] = {'cellModel': 'HH', 'cellType': 'PYR', 'gridSpacing': 5, 'yRange': [20,40]} # pop of HH cells -netParams.popParams['artifVec'] = {'cellModel': 'VecStim', 'numCells': 1, 'interval': 100, 'noise': 0.5, 'start': 50, - 'pulses':[{'start': 1000, 'end': 1400, 'rate': 100, 'noise': 0.5}]} # pop of NetStims +netParams.popParams['PYR1'] = {'cellModel': 'HH', 'cellType': 'PYR', 'numCells': 1} # 'gridSpacing': 10, 'xRange': [30,60]} # pop of HH cells +netParams.popParams['PYR2'] = {'cellModel': 'HH', 'cellType': 'PYR', 'numCells': 1} # 'gridSpacing': 5, 'yRange': [20,40]} # pop of HH cells +#netParams.popParams['artifVec'] = {'cellModel': 'VecStim', 'numCells': 1, 'interval': 100, 'noise': 0.5, 'start': 50, +# 'pulses':[{'start': 1000, 'end': 1400, 'rate': 100, 'noise': 0.5}]} # pop of NetStims # netParams.popParams['artif1'] = {'cellModel': 'VecStim', 'numCells': 100, 'rate': [0,5], 'noise': 1.0, 'start': 50}#, # 'pulses': [{'start': 200, 'end': 300, 'rate': 50, 'noise':0.2}, {'start': 500, 'end': 800, 'rate': 30, 'noise':0.5}]} # pop of NetStims # Synaptic mechanism parameters -# netParams.synMechParams['AMPA'] = {'mod': 'Exp2Syn', 'tau1': 0.1, 'tau2': 1.0, 'e': 0} +netParams.synMechParams['AMPA'] = {'mod': 'Exp2Syn', 'tau1': 0.1, 'tau2': 1.0, 'e': 0} # Stimulation parameters @@ -85,20 +85,27 @@ # Connections -netParams.connParams['artif1->PYR1'] = { - 'preConds': {'popLabel': 'artif1'}, 'postConds': {'popLabel': 'PYR1'}, - 'convergence': 4, - 'weight': 0.005, - 'synMech': 'AMPA', +# netParams.connParams['artif1->PYR1'] = { +# 'preConds': {'popLabel': 'artif1'}, 'postConds': {'popLabel': 'PYR1'}, +# 'convergence': 4, +# 'weight': 0.005, +# 'synMech': 'AMPA', +# 'delay': 'uniform(1,5)', +# 'synsPerConn': 1} + +netParams.connParams['PYR1->PYR2_1'] = { + 'preConds': {'popLabel': 'PYR1'}, 'postConds': {'popLabel': 'PYR2'}, + 'probability': 0.1, + 'weight': 0.2, 'delay': 'uniform(1,5)', - 'synsPerConn': 1} + 'synsPerConn': 1} -# netParams.connParams['PYR2->PYR1'] = { -# 'preConds': {'popLabel': 'PYR2'}, 'postConds': {'popLabel': 'PYR1'}, -# 'probability': 0.1, -# 'weight': 0.2, -# 'delay': 'uniform(1,5)', -# 'synsPerConn': 1} +netParams.connParams['PYR1->PYR2_2'] = { + 'preConds': {'popLabel': 'PYR1'}, 'postConds': {'popLabel': 'PYR2'}, + 'probability': 0.1, + 'weight': 0.4, + 'delay': 'uniform(1,5)', + 'synsPerConn': 1} # netParams.addConnParams('artif1->PYR2', # {'preConds': {'popLabel': 'artif1'}, 'postConds': {'popLabel': 'PYR2'}, diff --git a/netpyne/analysis.py b/netpyne/analysis.py index 06e4585e8..291be8284 100644 --- a/netpyne/analysis.py +++ b/netpyne/analysis.py @@ -173,30 +173,30 @@ def syncMeasure (): ###################################################################################################################################################### def getCellsInclude(include): allCells = sim.net.allCells - allNetStimPops = [popLabel for popLabel,pop in sim.net.allPops.iteritems() if pop['tags'].get('cellModel')=='NetStim'] + allNetStimLabels = sim.net.params.stimSourceParams.keys() cellGids = [] cells = [] - netStimPops = [] + netStimLabels = [] for condition in include: if condition == 'all': # all cells + Netstims cellGids = [c['gid'] for c in allCells] cells = list(allCells) - netStimPops = list(allNetStimPops) - return cells, cellGids, netStimPops + netStimLabels = list(allNetStimLabels) + return cells, cellGids, netStimLabels elif condition == 'allCells': # all cells cellGids = [c['gid'] for c in allCells] cells = list(allCells) elif condition == 'allNetStims': # all cells + Netstims - netStimPops = list(allNetStimPops) + netStimLabels = list(allNetStimLabels) elif isinstance(condition, int): # cell gid cellGids.append(condition) elif isinstance(condition, basestring): # entire pop - if condition in allNetStimPops: - netStimPops.append(condition) + if condition in allNetStimLabels: + netStimLabels.append(condition) else: cellGids.extend([c['gid'] for c in allCells if c['tags']['popLabel']==condition]) @@ -211,7 +211,7 @@ def getCellsInclude(include): cells = [cell for cell in allCells if cell['gid'] in cellGids] cells = sorted(cells, key=lambda k: k['gid']) - return cells, cellGids, netStimPops + return cells, cellGids, netStimLabels ###################################################################################################################################################### @@ -252,17 +252,17 @@ def plotRaster (include = ['allCells'], timeRange = None, maxSpikes = 1e8, order # [0.71,0.82,0.41], [0.0,0.2,0.5]] # Select cells to include - cells, cellGids, netStimPops = getCellsInclude(include) - selectedPops = [cell['tags']['popLabel'] for cell in cells]+netStimPops + cells, cellGids, netStimLabels = getCellsInclude(include) + selectedPops = [cell['tags']['popLabel'] for cell in cells] popLabels = [pop for pop in sim.net.allPops if pop in selectedPops] # preserves original ordering + if netStimLabels: popLabels.append('NetStims') popColors = {popLabel: colorList[ipop%len(colorList)] for ipop,popLabel in enumerate(popLabels)} # dict with color for each pop if len(cellGids) > 0: gidColors = {cell['gid']: popColors[cell['tags']['popLabel']] for cell in cells} # dict with color for each gid try: spkgids,spkts = zip(*[(spkgid,spkt) for spkgid,spkt in zip(sim.allSimData['spkid'],sim.allSimData['spkt']) if spkgid in cellGids]) except: - print 'No spikes available to plot raster' - return None + spkgids, spkts = [], [] spkgidColors = [gidColors[spkgid] for spkgid in spkgids] # Order by @@ -291,23 +291,29 @@ def plotRaster (include = ['allCells'], timeRange = None, maxSpikes = 1e8, order # Add NetStim spikes spkts,spkgidColors = list(spkts), list(spkgidColors) + numCellSpks = len(spkts) numNetStims = 0 - for netStimPop in netStimPops: - cellStims = [cellStim for cell,cellStim in sim.allSimData['stims'].iteritems() if netStimPop in cellStim] - if len(cellStims) > 0: + for netStimLabel in netStimLabels: + netStimSpks = [spk for cell,stims in sim.allSimData['stims'].iteritems() \ + for stimLabel,stimSpks in stims.iteritems() for spk in stimSpks if stimLabel == netStimLabel] + if len(netStimSpks) > 0: lastInd = max(spkinds) if len(spkinds)>0 else 0 - spktsNew = [spkt for cellStim in cellStims for spkt in cellStim[netStimPop] ] - spkindsNew = [lastInd+1+i for i,cellStim in enumerate(cellStims) for spkt in cellStim[netStimPop]] + spktsNew = netStimSpks + spkindsNew = [lastInd+1+i for i in range(len(netStimSpks))] spkts.extend(spktsNew) spkinds.extend(spkindsNew) for i in range(len(spktsNew)): - spkgidColors.append(popColors[netStimPop]) - numNetStims += len(cellStims) + spkgidColors.append(popColors['NetStims']) + numNetStims += 1 if len(cellGids)>0 and numNetStims: ylabelText = ylabelText + ' and NetStims (at the end)' elif numNetStims: ylabelText = ylabelText + 'NetStims' + if numCellSpks+numNetStims == 0: + print 'No spikes available to plot raster' + return None + # Time Range if timeRange == [0,sim.cfg.duration]: pass @@ -327,7 +333,6 @@ def plotRaster (include = ['allCells'], timeRange = None, maxSpikes = 1e8, order spkgidColors = spkgidColors[:maxSpikes] timeRange[1] = max(spkts) - # Calculate spike histogram if spikeHist: histo = np.histogram(spkts, bins = np.arange(timeRange[0], timeRange[1], spikeHistBin)) @@ -341,25 +346,32 @@ def plotRaster (include = ['allCells'], timeRange = None, maxSpikes = 1e8, order if spikeHist == 'subplot': 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.set_xlim(timeRange) # Plot stats gidPops = [cell['tags']['popLabel'] for cell in cells] - popNumCells = [float(gidPops.count(pop)) for pop in popLabels] + popNumCells = [float(gidPops.count(pop)) for pop in popLabels] if numCellSpks else [0] * len(popLabels) totalSpikes = len(spkts) totalConnections = sum([len(cell['conns']) for cell in cells]) - numCells = len(cells) - firingRate = float(totalSpikes)/numCells/(timeRange[1]-timeRange[0])*1e3 if totalSpikes>0 else 0 # Calculate firing rate + numCells = len(cells) + firingRate = float(totalSpikes)/(numCells+numNetStims)/(timeRange[1]-timeRange[0])*1e3 if totalSpikes>0 else 0 # Calculate firing rate connsPerCell = totalConnections/float(numCells) if numCells>0 else 0 # Calculate the number of connections per cell if popRates: avgRates = {} - for pop, popNum in zip(popLabels, popNumCells): - if numCells > 0: - tsecs = (timeRange[1]-timeRange[0])/1e3 - avgRates[pop] = len([spkid for spkid in spkinds if sim.net.allCells[int(spkid)]['tags']['popLabel']==pop])/popNum/tsecs - + tsecs = (timeRange[1]-timeRange[0])/1e3 + for i,(pop, popNum) in enumerate(zip(popLabels, popNumCells)): + if numCells > 0 and pop != 'NetStims': + if numCellSpks == 0: + avgRates[pop] = 0 + else: + avgRates[pop] = len([spkid for spkid in spkinds[:numCellSpks-1] if sim.net.allCells[int(spkid)]['tags']['popLabel']==pop])/popNum/tsecs + if numNetStims: + popNumCells[-1] = numNetStims + avgRates['NetStims'] = len([spkid for spkid in spkinds[numCellSpks:]])/numNetStims/tsecs + # Plot synchrony lines if syncLines: for spkt in spkts: @@ -368,18 +380,7 @@ def plotRaster (include = ['allCells'], timeRange = None, maxSpikes = 1e8, order else: plt.title('cells=%i syns/cell=%0.1f rate=%0.1f Hz' % (numCells,connsPerCell,firingRate), fontsize=fontsiz) - # Plot spike hist - if spikeHist == 'overlay': - ax2 = ax1.twinx() - ax2.plot (histoT, histoCount, linewidth=0.5) - ax2.set_ylabel('Spike count', fontsize=fontsiz) # add yaxis label in opposite side - ax2.set_xlim(timeRange) - elif spikeHist == 'subplot': - ax2=plt.subplot(gs[1]) - plot (histoT, histoCount, linewidth=1.0) - ax2.set_xlabel('Time (ms)', fontsize=fontsiz) - ax2.set_ylabel('Spike count', fontsize=fontsiz) - ax2.set_xlim(timeRange) + if orderInverse: plt.gca().invert_yaxis() # Axis ax1.set_xlabel('Time (ms)', fontsize=fontsiz) @@ -387,11 +388,9 @@ def plotRaster (include = ['allCells'], timeRange = None, maxSpikes = 1e8, order ax1.set_xlim(timeRange) ax1.set_ylim(-1, len(cells)+numNetStims+1) - if orderInverse: plt.gca().invert_yaxis() - # Add legend if popRates: - popLabelRates = [popLabel + ' (%.3g Hz)'%(avgRates[popLabel]) for popLabel in popLabels] + popLabelRates = [popLabel + ' (%.3g Hz)'%(avgRates[popLabel]) for popLabel in popLabels if popLabel in avgRates] if labels == 'legend': for ipop,popLabel in enumerate(popLabels): @@ -407,7 +406,7 @@ def plotRaster (include = ['allCells'], timeRange = None, maxSpikes = 1e8, order color = 'k' tx = 1.01 margin = 1.0/numCells/2 - tys = [(popLen/numCells)*(1-2*margin) for popLen in popNumCells] + tys = [(float(popLen)/numCells)*(1-2*margin) for popLen in popNumCells] tysOffset = list(cumsum(tys))[:-1] tysOffset.insert(0, 0) labels = popLabelRates if popRates else popLabels @@ -421,6 +420,18 @@ def plotRaster (include = ['allCells'], timeRange = None, maxSpikes = 1e8, order maxLabelLen = max([len(l) for l in labels]) plt.subplots_adjust(right=(1.0-0.011*maxLabelLen)) + # Plot spike hist + if spikeHist == 'overlay': + ax2 = ax1.twinx() + ax2.plot (histoT, histoCount, linewidth=0.5) + ax2.set_ylabel('Spike count', fontsize=fontsiz) # add yaxis label in opposite side + ax2.set_xlim(timeRange) + elif spikeHist == 'subplot': + ax2=plt.subplot(gs[1]) + ax2.plot (histoT, histoCount, linewidth=1.0) + ax2.set_xlabel('Time (ms)', fontsize=fontsiz) + ax2.set_ylabel('Spike count', fontsize=fontsiz) + ax2.set_xlim(timeRange) # save figure data if saveData: @@ -500,7 +511,7 @@ def plotSpikeHist (include = ['allCells', 'eachPop'], timeRange = None, binSize # Plot separate line for each entry in include for iplot,subset in enumerate(include): - cells, cellGids, netStimPops = getCellsInclude([subset]) + cells, cellGids, netStimLabels = getCellsInclude([subset]) numNetStims = 0 # Select cells to include @@ -512,20 +523,20 @@ def plotSpikeHist (include = ['allCells', 'eachPop'], timeRange = None, binSize else: spkinds,spkts = [],[] - # Add NetStim spikes spkts, spkinds = list(spkts), list(spkinds) numNetStims = 0 - for netStimPop in netStimPops: - if 'stims' in sim.allSimData: - cellStims = [cellStim for cell,cellStim in sim.allSimData['stims'].iteritems() if netStimPop in cellStim] - if len(cellStims) > 0: + if 'stims' in sim.allSimData: + for netStimLabel in netStimLabels: + netStimSpks = [spk for cell,stims in sim.allSimData['stims'].iteritems() \ + for stimLabel,stimSpks in stims.iteritems() for spk in stimSpks if stimLabel == netStimLabel] + if len(netStimSpks) > 0: lastInd = max(spkinds) if len(spkinds)>0 else 0 - spktsNew = [spkt for cellStim in cellStims for spkt in cellStim[netStimPop] ] - spkindsNew = [lastInd+1+i for i,cellStim in enumerate(cellStims) for spkt in cellStim[netStimPop]] + spktsNew = netStimSpks + spkindsNew = [lastInd+1+i for i in range(len(netStimSpks))] spkts.extend(spktsNew) spkinds.extend(spkindsNew) - numNetStims += len(cellStims) + numNetStims += 1 histo = np.histogram(spkts, bins = np.arange(timeRange[0], timeRange[1], binSize)) histoT = histo[1][:-1]+binSize/2 @@ -640,7 +651,7 @@ def plotRatePSD (include = ['allCells', 'eachPop'], timeRange = None, binSize = # Plot separate line for each entry in include for iplot,subset in enumerate(include): - cells, cellGids, netStimPops = getCellsInclude([subset]) + cells, cellGids, netStimLabels = getCellsInclude([subset]) numNetStims = 0 # Select cells to include @@ -656,16 +667,17 @@ def plotRatePSD (include = ['allCells', 'eachPop'], timeRange = None, binSize = # Add NetStim spikes spkts, spkinds = list(spkts), list(spkinds) numNetStims = 0 - for netStimPop in netStimPops: - if 'stims' in sim.allSimData: - cellStims = [cellStim for cell,cellStim in sim.allSimData['stims'].iteritems() if netStimPop in cellStim] - if len(cellStims) > 0: + if 'stims' in sim.allSimData: + for netStimLabel in netStimLabels: + netStimSpks = [spk for cell,stims in sim.allSimData['stims'].iteritems() \ + for stimLabel,stimSpks in stims.iteritems() for spk in stimSpks if stimLabel == netStimLabel] + if len(netStimSpks) > 0: lastInd = max(spkinds) if len(spkinds)>0 else 0 - spktsNew = [spkt for cellStim in cellStims for spkt in cellStim[netStimPop] ] - spkindsNew = [lastInd+1+i for i,cellStim in enumerate(cellStims) for spkt in cellStim[netStimPop]] + spktsNew = netStimSpks + spkindsNew = [lastInd+1+i for i in range(len(netStimSpks))] spkts.extend(spktsNew) spkinds.extend(spkindsNew) - numNetStims += len(cellStims) + numNetStims += 1 histo = np.histogram(spkts, bins = np.arange(timeRange[0], timeRange[1], binSize)) histoT = histo[1][:-1]+binSize/2 @@ -892,10 +904,21 @@ def invertDictMapping(d): ###################################################################################################################################################### ## Plot cell shape ###################################################################################################################################################### -def plotShape (showSyns = False, includePre = ['all'], includePost = ['all'], synStyle = '.', synSiz=3, cvar=None, cvals=None, iv=False, ivprops=None, +def plotShape (showSyns = False, includePost = ['all'], includePre = ['all'], 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 + - includePre: (['all',|'allCells','allNetStims',|,120,|,'E1'|,('L2', 56)|,('L5',[4,5,6])]): List of presynaptic cells to consider + when plotting connections (default: ['all']) + - includePost: (['all',|'allCells','allNetStims',|,120,|,'E1'|,('L2', 56)|,('L5',[4,5,6])]): List of cells to show shape of (default: ['all']) + - synStyle: Style of marker to show synapses (default: '.') + - dist: 3D distance (like zoom) (default: 0.6) + - synSize: Size of marker to show synapses (default: 3) + - cvar: ('numSyns'|'weightNorm') Variable to represent in shape plot (default: None) + - cvals: List of values to represent in shape plot; must be same as num segments (default: None) + - iv: Use NEURON Interviews (instead of matplotlib) to show shape plot (default: None) + - ivprops: Dict of properties to plot using Interviews (default: None) + - includeAxon: Include axon in shape plot (default: True) - showSyns (True|False): Show synaptic connections in 3D - figSize ((width, height)): Size of figure (default: (10,8)) - saveData (None|True|'fileName'): File name where to save the final data used to generate the figure; @@ -956,7 +979,7 @@ def plotShape (showSyns = False, includePre = ['all'], includePost = ['all'], sy shapeax = plt.subplot(111, projection='3d') shapeax.elev=90 # 90 shapeax.azim=-90 # -90 - shapeax.dist=0.6*shapeax.dist + shapeax.dist=dist*shapeax.dist plt.axis('equal') cmap=plt.cm.jet #YlOrBr_r morph.shapeplot(h,shapeax, sections=secs, cvals=cvals, cmap=cmap) diff --git a/netpyne/network.py b/netpyne/network.py index 1d703d3e3..a4f5f1278 100644 --- a/netpyne/network.py +++ b/netpyne/network.py @@ -455,7 +455,6 @@ def connectCells (self): sim.cfg.createNEURONObj = False sim.cfg.addSynMechs = False - for connParamLabel,connParamTemp in self.params.connParams.iteritems(): # for each conn rule or parameter set connParam = connParamTemp.copy() connParam['label'] = connParamLabel diff --git a/netpyne/simFuncs.py b/netpyne/simFuncs.py index e1593117e..c04b2ac25 100644 --- a/netpyne/simFuncs.py +++ b/netpyne/simFuncs.py @@ -618,9 +618,9 @@ def setupRecording (): # stim spike recording if 'plotRaster' in sim.cfg.analysis: if isinstance(sim.cfg.analysis['plotRaster'],dict) and 'include' in sim.cfg.analysis['plotRaster']: - netStimPops = [popLabel for popLabel,pop in sim.net.pops.iteritems() if pop.tags['cellModel']=='NetStim']+['allNetStims'] + netStimLabels = sim.net.params.stimSourceParams.keys()+['allNetStims'] for item in sim.cfg.analysis['plotRaster']['include']: - if item in netStimPops: + if item in netStimLabels: sim.cfg.recordStim = True break @@ -629,9 +629,9 @@ def setupRecording (): sim.cfg.recordStim = True elif (isinstance(sim.cfg.analysis['plotSpikeHist'],dict) and 'include' in sim.cfg.analysis['plotSpikeHist']) : - netStimPops = [popLabel for popLabel,pop in sim.net.pops.iteritems() if pop.tags['cellModel']=='NetStim']+['allNetStims', 'eachPop'] + netStimLabels = sim.net.params.stimSourceParams.keys()+['allNetStims','eachPop'] for item in sim.cfg.analysis['plotSpikeHist']['include']: - if item in netStimPops: + if item in netStimLabels: sim.cfg.recordStim = True break diff --git a/netpyne/utils.py b/netpyne/utils.py index 356999225..54e8464c4 100644 --- a/netpyne/utils.py +++ b/netpyne/utils.py @@ -149,7 +149,7 @@ def importCell (fileName, cellName, cellArgs = None, cellInstance = False): 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'): + if fileName.endswith('.hoc') or fileName.endswith('.tem'): h.load_file(fileName) if not cellInstance: if isinstance(cellArgs, dict): @@ -189,7 +189,7 @@ def importCellsFromNet (netParams, fileName, labelList, condsList, cellNamesList 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'): + if fileName.endswith('.hoc') or fileName.endswith('.tem'): print 'Importing from .hoc network not yet supported' return # h.load_file(fileName) diff --git a/sdnotes.org b/sdnotes.org index b5ef771e8..23f62e209 100644 --- a/sdnotes.org +++ b/sdnotes.org @@ -2810,7 +2810,8 @@ Christian G. Fink, PhD Assistant Professor of Physics and Neuroscience Ohio Wesleyan University -** Learning (Birgit Kriener, Einevoll lab, University of Oslo) +** Learning, dendritic computations (Birgit Kriener, Einevoll lab, University of Oslo) +** Thalamocortical epilespy (Andrew Knox, Cincinatti) * Related tools ** NEURON Multiscale simulator From a1b503912a85dbb8e1362a3a938ea99b20402fe7 Mon Sep 17 00:00:00 2001 From: salvadord Date: Mon, 3 Apr 2017 13:19:25 -0400 Subject: [PATCH 27/37] Fixed bug: use Random123() instead of netstim.noiseFromRandom for NetStim stims --- CHANGES.md | 3 +++ netpyne/cell.py | 3 +-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 185539309..df4aae024 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -12,6 +12,8 @@ - Fixed bug: missing hRandom for NetStim populations +- Fixed bug: use Random123() instead of netstim.noiseFromRandom for NetStim stims + - Fixed bug: VectStim spike generation now reproducible for different durations - Fixed bug in batch grouped params @@ -22,6 +24,7 @@ - Fixed bug plotting overlayed spikeHist over raster plot + # Version 0.6.8 - Keep track of last host after distributing cells of each pop (improves load balance) (issues #41 #196) diff --git a/netpyne/cell.py b/netpyne/cell.py index bd7a2cc99..ec853ba26 100644 --- a/netpyne/cell.py +++ b/netpyne/cell.py @@ -108,9 +108,8 @@ def addNetStim (self, params, stimContainer=None): else: netstim = h.NetStim() netstim.interval = params['rate']**-1*1e3 # inverse of the frequency and then convert from Hz^-1 to ms - netstim.noise = params['noise'] # note: random number generator initialized via noiseFromRandom() from sim.preRun() + netstim.noise = params['noise'] # note: random number generator initialized via Random123() from sim.preRun() netstim.start = params['start'] - netstim.noiseFromRandom(rand) # use random number generator netstim.number = params['number'] stimContainer['hNetStim'] = netstim # add netstim object to dict in stim list From 161df27eb5b836726c67435373cc5f3e6e487423 Mon Sep 17 00:00:00 2001 From: salvadord Date: Mon, 3 Apr 2017 18:17:34 -0400 Subject: [PATCH 28/37] Fixed bug in plotShape when includeAxon=False --- CHANGES.md | 2 ++ netpyne/analysis.py | 15 +++++++++++---- netpyne/network.py | 1 + 3 files changed, 14 insertions(+), 4 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index df4aae024..6c2fea5ba 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -24,6 +24,8 @@ - Fixed bug plotting overlayed spikeHist over raster plot +- Fixed bug in plotShape when includeAxon=False + # Version 0.6.8 diff --git a/netpyne/analysis.py b/netpyne/analysis.py index 291be8284..b94a6332d 100644 --- a/netpyne/analysis.py +++ b/netpyne/analysis.py @@ -305,6 +305,9 @@ def plotRaster (include = ['allCells'], timeRange = None, maxSpikes = 1e8, order for i in range(len(spktsNew)): spkgidColors.append(popColors['NetStims']) numNetStims += 1 + else: + pass + #print netStimLabel+' produced no spikes' if len(cellGids)>0 and numNetStims: ylabelText = ylabelText + ' and NetStims (at the end)' elif numNetStims: @@ -948,7 +951,8 @@ def plotShape (showSyns = False, includePost = ['all'], includePre = ['all'], sy # weighNorm if cvar == 'weightNorm': for cellPost in cellsPost: - for sec in cellPost.secs.values(): + cellSecs = cellPost.secs.values() if includeAxon else [s for s in cellPost.secs.values() if 'axon' not in s['hSec'].hname()] + for sec in cellSecs: if 'weightNorm' in sec: secs.append(sec['hSec']) cvals.extend(sec['weightNorm']) @@ -959,7 +963,8 @@ def plotShape (showSyns = False, includePost = ['all'], includePre = ['all'], sy # numSyns elif cvar == 'numSyns': for cellPost in cellsPost: - for secLabel,sec in cellPost.secs.iteritems(): + cellSecs = cellPost.secs if includeAxon else {k:s for k,s in cellPost.secs.iteritems() if 'axon' not in s['hSec'].hname()} + for secLabel,sec in cellSecs.iteritems(): nseg=sec['hSec'].nseg nsyns = [0] * nseg secs.append(sec['hSec']) @@ -967,11 +972,13 @@ def plotShape (showSyns = False, includePost = ['all'], includePre = ['all'], sy for conn in conns: nsyns[int(round(conn['loc']*nseg))-1] += 1 cvals.extend(nsyns) + print secLabel, nsyns + cvals = np.array(cvals) if not secs: secs = [s['hSec'] for cellPost in cellsPost for s in cellPost.secs.values()] - if not includeAxon: - secs = [sec for sec in secs if 'axon' not in sec.hname()] + # if not includeAxon: + # secs = [sec for sec in secs if 'axon' not in sec.hname()] # Plot shapeplot cbLabels = {'numSyns': 'number of synapses', 'weightNorm': 'weight scaling'} diff --git a/netpyne/network.py b/netpyne/network.py index a4f5f1278..3edb828ae 100644 --- a/netpyne/network.py +++ b/netpyne/network.py @@ -422,6 +422,7 @@ def subcellularConn(self, allCellTags, allPopTags): elif newLoc == 1.0: newLoc = 0.99999 conn['sec'] = newSec conn['loc'] = newLoc + print newSec,newLoc # find grouped conns if subConnParam.get('groupSynMechs', None) and conn['synMech'] in subConnParam['groupSynMechs']: From 0dcd34c294ecd160f616b7cc0ea856d9b474b392 Mon Sep 17 00:00:00 2001 From: salvadord Date: Wed, 5 Apr 2017 11:00:06 -0400 Subject: [PATCH 29/37] fixed bug in plotRaster orderInverse --- examples/sandbox/sandbox.py | 14 ++++++++------ netpyne/analysis.py | 6 ++---- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/examples/sandbox/sandbox.py b/examples/sandbox/sandbox.py index 1786ec65d..85bb1fedd 100644 --- a/examples/sandbox/sandbox.py +++ b/examples/sandbox/sandbox.py @@ -32,11 +32,11 @@ ############################################################################### # Simulation parameters -simConfig.duration = 0.5*1e3 # Duration of the simulation, in ms +simConfig.duration = 1.0*1e3 # Duration of the simulation, in ms simConfig.dt = 0.1 # Internal integration timestep to use simConfig.createNEURONObj = 1 # create HOC objects when instantiating network simConfig.createPyStruct = 1 # create Python structure (simulator-independent) when instantiating network -simConfig.verbose = 1 #False # show detailed messages +simConfig.verbose = 0 #False # show detailed messages # Recording simConfig.recordCells = [('PYR1',5), 8] @@ -59,8 +59,8 @@ # Population parameters -netParams.popParams['PYR1'] = {'cellModel': 'HH', 'cellType': 'PYR', 'numCells': 1} # 'gridSpacing': 10, 'xRange': [30,60]} # pop of HH cells -netParams.popParams['PYR2'] = {'cellModel': 'HH', 'cellType': 'PYR', 'numCells': 1} # 'gridSpacing': 5, 'yRange': [20,40]} # pop of HH cells +netParams.popParams['PYR1'] = {'cellModel': 'HH', 'cellType': 'PYR', 'numCells': 100} # 'gridSpacing': 10, 'xRange': [30,60]} # pop of HH cells +netParams.popParams['PYR2'] = {'cellModel': 'HH', 'cellType': 'PYR', 'numCells': 100} # 'gridSpacing': 5, 'yRange': [20,40]} # pop of HH cells #netParams.popParams['artifVec'] = {'cellModel': 'VecStim', 'numCells': 1, 'interval': 100, 'noise': 0.5, 'start': 50, # 'pulses':[{'start': 1000, 'end': 1400, 'rate': 100, 'noise': 0.5}]} # pop of NetStims # netParams.popParams['artif1'] = {'cellModel': 'VecStim', 'numCells': 100, 'rate': [0,5], 'noise': 1.0, 'start': 50}#, @@ -71,8 +71,8 @@ # Stimulation parameters -#netParams.stimSourceParams['background'] = {'type': 'NetStim', 'interval': 100, 'number': 1e5, 'start': 500, 'noise': 0.5} # stim using NetStims after 500ms -#netParams.stimTargetParams['bkg->PYR1'] = {'source': 'background', 'conds': {'popLabel': 'PYR1'}, 'sec':'soma', 'loc': 0.5, 'weight': 0.5, 'delay': 1} +netParams.stimSourceParams['background'] = {'type': 'NetStim', 'interval': 20, 'number': 1e5, 'start': 500, 'noise': 0.5} # stim using NetStims after 500ms +netParams.stimTargetParams['bkg->PYR1'] = {'source': 'background', 'conds': {'popLabel': 'PYR1'}, 'sec':'soma', 'loc': 0.5, 'weight': 0.5, 'delay': 1} # Cell parameters @@ -119,6 +119,8 @@ ############################################################################### # RUN SIM ############################################################################### +simConfig.analysis['plotRaster'] = {'saveFig': True, 'showFig':True, 'labels': 'overlay', 'popRates': True, + 'orderInverse': True, 'figSize': (12,10), 'lw': 0.6, 'marker': '|'} sim.createSimulateAnalyze() diff --git a/netpyne/analysis.py b/netpyne/analysis.py index b94a6332d..2dba83804 100644 --- a/netpyne/analysis.py +++ b/netpyne/analysis.py @@ -383,8 +383,6 @@ def plotRaster (include = ['allCells'], timeRange = None, maxSpikes = 1e8, order else: plt.title('cells=%i syns/cell=%0.1f rate=%0.1f Hz' % (numCells,connsPerCell,firingRate), fontsize=fontsiz) - if orderInverse: plt.gca().invert_yaxis() - # Axis ax1.set_xlabel('Time (ms)', fontsize=fontsiz) ax1.set_ylabel(ylabelText, fontsize=fontsiz) @@ -436,6 +434,8 @@ def plotRaster (include = ['allCells'], timeRange = None, maxSpikes = 1e8, order ax2.set_ylabel('Spike count', fontsize=fontsiz) ax2.set_xlim(timeRange) + if orderInverse: plt.gca().invert_yaxis() + # save figure data if saveData: figData = {'spkTimes': spkts, 'spkInds': spkinds, 'spkColors': spkgidColors, 'cellGids': cellGids, 'sortedGids': sortedGids, 'numNetStims': numNetStims, @@ -972,8 +972,6 @@ def plotShape (showSyns = False, includePost = ['all'], includePre = ['all'], sy for conn in conns: nsyns[int(round(conn['loc']*nseg))-1] += 1 cvals.extend(nsyns) - print secLabel, nsyns - cvals = np.array(cvals) if not secs: secs = [s['hSec'] for cellPost in cellsPost for s in cellPost.secs.values()] From c5f643e30b0fe7caf4f0e90fdb97304fdbba0a9f Mon Sep 17 00:00:00 2001 From: salvadord Date: Wed, 5 Apr 2017 12:59:08 -0400 Subject: [PATCH 30/37] removed temp print --- netpyne/network.py | 1 - 1 file changed, 1 deletion(-) diff --git a/netpyne/network.py b/netpyne/network.py index 3edb828ae..a4f5f1278 100644 --- a/netpyne/network.py +++ b/netpyne/network.py @@ -422,7 +422,6 @@ def subcellularConn(self, allCellTags, allPopTags): elif newLoc == 1.0: newLoc = 0.99999 conn['sec'] = newSec conn['loc'] = newLoc - print newSec,newLoc # find grouped conns if subConnParam.get('groupSynMechs', None) and conn['synMech'] in subConnParam['groupSynMechs']: From e6eeb300c2ed7c78094c2864c60fd07436cc58ac Mon Sep 17 00:00:00 2001 From: salvadord Date: Thu, 6 Apr 2017 13:58:46 -0400 Subject: [PATCH 31/37] plotShape now shows real diameters in interviews by default; New option to import cell with sections not inside an object --- CHANGES.md | 5 +++++ examples/HHTut/HHTut.py | 2 +- netpyne/analysis.py | 1 + netpyne/utils.py | 5 ++++- sdnotes.org | 26 ++++++++++++++++++++++++++ 5 files changed, 37 insertions(+), 2 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 6c2fea5ba..474d9c2f2 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -6,6 +6,10 @@ - Modified hpc_torque batch to accept nodes and ppn +- New option to import cell with sections not inside an object + +- plotShape now shows real diameters in interviews by default + - Fixed bug plotting NetStims (created as stims) in raster, spikeHist and ratePSD - Fixed bug in plotConn bar graphs @@ -27,6 +31,7 @@ - Fixed bug in plotShape when includeAxon=False + # Version 0.6.8 - Keep track of last host after distributing cells of each pop (improves load balance) (issues #41 #196) diff --git a/examples/HHTut/HHTut.py b/examples/HHTut/HHTut.py index fcda62905..48e0631a1 100644 --- a/examples/HHTut/HHTut.py +++ b/examples/HHTut/HHTut.py @@ -26,7 +26,7 @@ # Population parameters netParams.popParams['PYR'] = {'cellModel': 'HH', 'cellType': 'PYR', 'numCells': 100, 'yRange': [300, 500], 'color': 'red'} # add dict with params for this pop -netParams.popParams['PYR'] = {'cellModel': 'HH', 'cellType': 'PYR2', 'numCells': 100} # add dict with params for this pop +netParams.popParams['PYR'] = {'cellModel': 'NetStim', 'cellType': 'PYR2', 'numCells': 100} # add dict with params for this pop # Cell parameters diff --git a/netpyne/analysis.py b/netpyne/analysis.py index 2dba83804..9ffb77217 100644 --- a/netpyne/analysis.py +++ b/netpyne/analysis.py @@ -1042,6 +1042,7 @@ def plotShape (showSyns = False, includePost = ['all'], includePre = ['all'], sy fig.observe(secList) fig.color_list(secList, ivprops['colorSecs']) fig.flush() + fig.show(0) # show real diam # save figure if saveFig: if isinstance(saveFig, basestring): diff --git a/netpyne/utils.py b/netpyne/utils.py index 54e8464c4..f11f30fd1 100644 --- a/netpyne/utils.py +++ b/netpyne/utils.py @@ -157,7 +157,10 @@ def importCell (fileName, cellName, cellArgs = None, cellInstance = False): else: cell = getattr(h, cellName)(*cellArgs) # create cell using template, passing list with args else: - cell = getattr(h, cellName) + try: + cell = getattr(h, cellName) + except: + cell = None 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) diff --git a/sdnotes.org b/sdnotes.org index 23f62e209..05067015a 100644 --- a/sdnotes.org +++ b/sdnotes.org @@ -2785,6 +2785,32 @@ if (isCellOnNode("SampleCellGroup", 0)) { - cant check if rules exist for particular cellModel, since could be applied based on other features (eg. yfrac); so have to make condition of point process make prioritary: 1st check if cellModel==point process -> PointCell; otherwise CompartCell +* 17Apr05 Error checking +** populationParams +- cellModel: required, arbitrary value or pointprocess; +-- if arbitrary then create compartCell() and use cellParams +-- if pointtprocess then create pointCell() and don't need cellParams + +- cellType: not required, but recommended; arbitrary value; used to associate population with cellParam rules + +- numCells, density or gridSpacing - at least 1 required +-- numCells: fixed number of cells (integer) +-- density: num cells per mm3 (float) +-- gridSpacing: fixed spacing between cells (um) + +- xRange, yRange, zRange: optional, absolute allowed range to place cells; check within network size +- xnormRange, ynormRange, znormRange: optional, normalized allowed range to place cells; check within 0,1 + +- for NetStims: +rate - Firing rate in Hz (note this is the inverse of the NetStim interval property). +noise - Fraction of noise in NetStim (0 = deterministic; 1 = completely random). +number - Max number of spikes generated (default = 1e12) +seed - Seed for randomizer (optional; defaults to value set in simConfig.seeds[‘stim’]) + +- check netParams network dimensions: +-- netParams.sizeX, sizeY, sizeZ - net dimensions in um; check not 0 or negative +-- shape - check either 'cuboid', 'cylinder' or 'ellipsoid' + * Netpyne Models/Users ** Github examples folder ** Documentation tutorials From 35313c554c7b5e08926a9d115d6f12f5bc6b3426 Mon Sep 17 00:00:00 2001 From: salvadord Date: Fri, 7 Apr 2017 15:37:41 -0400 Subject: [PATCH 32/37] Added option to set threshold when loading weightNorm --- CHANGES.md | 2 ++ netpyne/specs.py | 9 ++++++++- sdnotes.org | 8 ++++++++ 3 files changed, 18 insertions(+), 1 deletion(-) diff --git a/CHANGES.md b/CHANGES.md index 474d9c2f2..7d19f5f43 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -10,6 +10,8 @@ - plotShape now shows real diameters in interviews by default +- Added option to set threshold when loading weightNorm + - Fixed bug plotting NetStims (created as stims) in raster, spikeHist and ratePSD - Fixed bug in plotConn bar graphs diff --git a/netpyne/specs.py b/netpyne/specs.py index d5362da67..3e4bf6758 100644 --- a/netpyne/specs.py +++ b/netpyne/specs.py @@ -402,7 +402,7 @@ def renameCellParamsSec(self, label, oldSec, newSec): if sec['topol'].get('parentSec') == oldSec: sec['topol']['parentSec'] = newSec - def addCellParamsWeightNorm(self, label, fileName): + def addCellParamsWeightNorm(self, label, fileName, threshold=1000): import pickle if label in self.cellParams: cellRule = self.cellParams[label] @@ -412,8 +412,15 @@ def addCellParamsWeightNorm(self, label, fileName): with open(fileName, 'r') as fileObj: weightNorm = pickle.load(fileObj) + try: + somaWeightNorm = weightNorm['soma'][0] + except: + print 'Error setting weightNorm: no soma section available to set threshold' + return for sec, wnorm in weightNorm.iteritems(): if sec in cellRule['secs']: + wnorm = [min(wn,threshold*somaWeightNorm) for wn in wnorm] + print wnorm cellRule['secs'][sec]['weightNorm'] = wnorm # add weight normalization factors for each section diff --git a/sdnotes.org b/sdnotes.org index 05067015a..69c65474e 100644 --- a/sdnotes.org +++ b/sdnotes.org @@ -2811,6 +2811,14 @@ seed - Seed for randomizer (optional; defaults to value set in simConfig.seeds[ -- netParams.sizeX, sizeY, sizeZ - net dimensions in um; check not 0 or negative -- shape - check either 'cuboid', 'cylinder' or 'ellipsoid' +* 17Apr07 GUI +** gantt chart comments +- start before sept +- have minor demo (pics) by Oct so can include in grant -- maybe move standalone to later +- import cells should be together with netPArams UI +- should all fit within avail budget -- if not, give us tasks that we can do + + * Netpyne Models/Users ** Github examples folder ** Documentation tutorials From 344770cf0548f24a48eb4e8a29e086cf42e1246a Mon Sep 17 00:00:00 2001 From: salvadord Date: Fri, 7 Apr 2017 18:50:47 -0400 Subject: [PATCH 33/37] removed debugging print statement --- netpyne/specs.py | 1 - 1 file changed, 1 deletion(-) diff --git a/netpyne/specs.py b/netpyne/specs.py index 3e4bf6758..382f369b7 100644 --- a/netpyne/specs.py +++ b/netpyne/specs.py @@ -420,7 +420,6 @@ def addCellParamsWeightNorm(self, label, fileName, threshold=1000): for sec, wnorm in weightNorm.iteritems(): if sec in cellRule['secs']: wnorm = [min(wn,threshold*somaWeightNorm) for wn in wnorm] - print wnorm cellRule['secs'][sec]['weightNorm'] = wnorm # add weight normalization factors for each section From 5acecf618879fedd4e53c8f6961e08418376ac2f Mon Sep 17 00:00:00 2001 From: salvadord Date: Mon, 10 Apr 2017 13:43:21 -0400 Subject: [PATCH 34/37] fixed bug in analysis.py - fig.plt. --- netpyne/analysis.py | 20 ++++++++++---------- sdnotes.org | 29 ++++++++++++++++++++++++++++- 2 files changed, 38 insertions(+), 11 deletions(-) diff --git a/netpyne/analysis.py b/netpyne/analysis.py index 9ffb77217..b13e5810d 100644 --- a/netpyne/analysis.py +++ b/netpyne/analysis.py @@ -378,7 +378,7 @@ def plotRaster (include = ['allCells'], timeRange = None, maxSpikes = 1e8, order # Plot synchrony lines if syncLines: for spkt in spkts: - ax1.plt.plot((spkt, spkt), (0, len(cells)+numNetStims), 'r-', linewidth=0.1) + ax1.plot((spkt, spkt), (0, len(cells)+numNetStims), 'r-', linewidth=0.1) plt.title('cells=%i syns/cell=%0.1f rate=%0.1f Hz sync=%0.2f' % (numCells,connsPerCell,firingRate,syncMeasure()), fontsize=fontsiz) else: plt.title('cells=%i syns/cell=%0.1f rate=%0.1f Hz' % (numCells,connsPerCell,firingRate), fontsize=fontsiz) @@ -1384,9 +1384,9 @@ def list_of_dict_unique_by_key(seq, key): if graphType == 'matrix': # Create plot fig = plt.figure(figsize=figSize) - fig.plt.subplots_adjust(right=0.98) # Less space on right - fig.plt.subplots_adjust(top=0.96) # Less space on top - fig.plt.subplots_adjust(bottom=0.02) # Less space on bottom + fig.subplots_adjust(right=0.98) # Less space on right + fig.subplots_adjust(top=0.96) # Less space on top + fig.subplots_adjust(bottom=0.02) # Less space on bottom h = plt.axes() plt.imshow(connMatrix, interpolation='nearest', cmap='jet', vmin=np.nanmin(connMatrix), vmax=np.nanmax(connMatrix)) #_bicolormap(gap=0) @@ -1830,12 +1830,12 @@ def plotWeightChanges(): if sim.usestdp: # create plot figh = plt.figure(figsize=(1.2*8,1.2*6)) - figh.plt.subplots_adjust(left=0.02) # Less space on left - figh.plt.subplots_adjust(right=0.98) # Less space on right - figh.plt.subplots_adjust(top=0.96) # Less space on bottom - figh.plt.subplots_adjust(bottom=0.02) # Less space on bottom - figh.plt.subplots_adjust(wspace=0) # More space between - figh.plt.subplots_adjust(hspace=0) # More space between + figh.subplots_adjust(left=0.02) # Less space on left + figh.subplots_adjust(right=0.98) # Less space on right + figh.subplots_adjust(top=0.96) # Less space on bottom + figh.subplots_adjust(bottom=0.02) # Less space on bottom + figh.subplots_adjust(wspace=0) # More space between + figh.subplots_adjust(hspace=0) # More space between h = plt.axes() # create data matrix diff --git a/sdnotes.org b/sdnotes.org index 69c65474e..80b2d0012 100644 --- a/sdnotes.org +++ b/sdnotes.org @@ -2812,12 +2812,39 @@ seed - Seed for randomizer (optional; defaults to value set in simConfig.seeds[ -- shape - check either 'cuboid', 'cylinder' or 'ellipsoid' * 17Apr07 GUI -** gantt chart comments +** gantt chart - start before sept - have minor demo (pics) by Oct so can include in grant -- maybe move standalone to later - import cells should be together with netPArams UI - should all fit within avail budget -- if not, give us tasks that we can do +** gantt chart +*** infrastructure +- improv design - required +- migrate to npm - started, dependencies managed, needs to happen and easier to maintain, required +- update to latest jupyter - doesn't need to happen +- improve interaction - need to understand +- sync mechs - almost 0 +- decouple components - postpone until see if required, maybe refactor in future +- refactor + bug fixing - cell builder issue +*** standalone application - nice to have +*** transition - will become smaller +*** NetPyNE UI +netPAramsUI + simConfigUI - for chickens +*** Network support +- map geppetoo - required +- performance to load bigger models - 10k +- visualization - simplify 3 different levels +- advance - remove +- ability to simulate large nets +- visualize results - focus on netpyne/matplotlib, and use Neuron-UI voltage trace +*** Support for parallel simulation +- run from commandline +- maybe don't need - just use to sketch out +*** embed python UI into Geppetto +- nice to have, but not essential +*** bug fixing + * Netpyne Models/Users ** Github examples folder From d8ce640e6a22171dc14a960a97f92e15ae6605e5 Mon Sep 17 00:00:00 2001 From: salvadord Date: Mon, 10 Apr 2017 14:08:43 -0400 Subject: [PATCH 35/37] load weightNorm now checks for secs starting with 'soma' --- netpyne/specs.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/netpyne/specs.py b/netpyne/specs.py index 382f369b7..f6e8bcfa6 100644 --- a/netpyne/specs.py +++ b/netpyne/specs.py @@ -412,8 +412,10 @@ def addCellParamsWeightNorm(self, label, fileName, threshold=1000): with open(fileName, 'r') as fileObj: weightNorm = pickle.load(fileObj) + try: - somaWeightNorm = weightNorm['soma'][0] + somaSec = next((k for k in weightNorm.keys() if k.startswith('soma')),None) + somaWeightNorm = weightNorm[somaSec][0] except: print 'Error setting weightNorm: no soma section available to set threshold' return From e20acb126b0490e2ab722a462cc811a031ecd12e Mon Sep 17 00:00:00 2001 From: Padraig Gleeson Date: Tue, 11 Apr 2017 11:58:12 +0100 Subject: [PATCH 36/37] Adding support for conds on recordTraces Example: simConfig.recordTraces['of0_iafPop2_0_soma_v'] = {'sec':'soma','loc':0.5,'var':'v','conds':{'popLabel':'iafPop2','cellLabel':0}} More info on what's been recorded is printed whn simulation is run --- netpyne/cell.py | 109 +++++++++++++++++++++++++++----------------- netpyne/simFuncs.py | 13 +++++- 2 files changed, 80 insertions(+), 42 deletions(-) diff --git a/netpyne/cell.py b/netpyne/cell.py index b42ac17f6..86e5dad58 100644 --- a/netpyne/cell.py +++ b/netpyne/cell.py @@ -128,50 +128,77 @@ def __getstate__ (self): def recordTraces (self): # set up voltagse recording; recdict will be taken from global context for key, params in sim.cfg.recordTraces.iteritems(): - try: - ptr = None - if 'loc' in params: - if 'mech' in params: # eg. soma(0.5).hh._ref_gna - ptr = self.secs[params['sec']]['hSec'](params['loc']).__getattribute__(params['mech']).__getattribute__('_ref_'+params['var']) - elif 'synMech' in params: # eg. soma(0.5).AMPA._ref_g - sec = self.secs[params['sec']] - synMech = next((synMech for synMech in sec['synMechs'] if synMech['label']==params['synMech'] and synMech['loc']==params['loc']), None) - ptr = synMech['hSyn'].__getattribute__('_ref_'+params['var']) - else: # eg. soma(0.5)._ref_v - ptr = self.secs[params['sec']]['hSec'](params['loc']).__getattribute__('_ref_'+params['var']) - elif 'synMech' in params: # special case where want to record from multiple synMechs - if 'sec' in params: - sec = self.secs[params['sec']] - synMechs = [synMech for synMech in sec['synMechs'] if synMech['label']==params['synMech']] - ptr = [synMech['hSyn'].__getattribute__('_ref_'+params['var']) for synMech in synMechs] - secLocs = [params.sec+str(synMech['loc']) for synMech in synMechs] - else: - ptr = [] - secLocs = [] - for secName,sec in self.secs.iteritems(): + + conditionsMet = 1 + + if 'conds' in params: + for (condKey,condVal) in params['conds'].iteritems(): # check if all conditions are met + # choose what to comapare to + if condKey in ['postGid']: + compareTo = self.gid + else: + compareTo = self.tags[condKey] + + # check if conditions met + if isinstance(condVal, list) and isinstance(condVal[0], Number): + if compareTo < condVal[0] or compareTo > condVal[1]: + conditionsMet = 0 + break + elif isinstance(condVal, list) and isinstance(condVal[0], basestring): + if compareTo not in condVal: + conditionsMet = 0 + break + elif compareTo != condVal: + conditionsMet = 0 + break + + if conditionsMet: + try: + ptr = None + if 'loc' in params: + if 'mech' in params: # eg. soma(0.5).hh._ref_gna + ptr = self.secs[params['sec']]['hSec'](params['loc']).__getattribute__(params['mech']).__getattribute__('_ref_'+params['var']) + elif 'synMech' in params: # eg. soma(0.5).AMPA._ref_g + sec = self.secs[params['sec']] + synMech = next((synMech for synMech in sec['synMechs'] if synMech['label']==params['synMech'] and synMech['loc']==params['loc']), None) + ptr = synMech['hSyn'].__getattribute__('_ref_'+params['var']) + else: # eg. soma(0.5)._ref_v + ptr = self.secs[params['sec']]['hSec'](params['loc']).__getattribute__('_ref_'+params['var']) + elif 'synMech' in params: # special case where want to record from multiple synMechs + if 'sec' in params: + sec = self.secs[params['sec']] synMechs = [synMech for synMech in sec['synMechs'] if synMech['label']==params['synMech']] - ptr.extend([synMech['hSyn'].__getattribute__('_ref_'+params['var']) for synMech in synMechs]) - secLocs.extend([secName+'_'+str(synMech['loc']) for synMech in synMechs]) + ptr = [synMech['hSyn'].__getattribute__('_ref_'+params['var']) for synMech in synMechs] + secLocs = [params.sec+str(synMech['loc']) for synMech in synMechs] + else: + ptr = [] + secLocs = [] + for secName,sec in self.secs.iteritems(): + synMechs = [synMech for synMech in sec['synMechs'] if synMech['label']==params['synMech']] + ptr.extend([synMech['hSyn'].__getattribute__('_ref_'+params['var']) for synMech in synMechs]) + secLocs.extend([secName+'_'+str(synMech['loc']) for synMech in synMechs]) - else: - if 'pointp' in params: # eg. soma.izh._ref_u - if params['pointp'] in self.secs[params['sec']]['pointps']: - ptr = self.secs[params['sec']]['pointps'][params['pointp']]['hPointp'].__getattribute__('_ref_'+params['var']) - elif 'var' in params: # point process cell eg. cell._ref_v - ptr = self.hPointp.__getattribute__('_ref_'+params['var']) - - if ptr: # if pointer has been created, then setup recording - if isinstance(ptr, list): - sim.simData[key]['cell_'+str(self.gid)] = {} - for ptrItem,secLoc in zip(ptr, secLocs): - sim.simData[key]['cell_'+str(self.gid)][secLoc] = h.Vector(sim.cfg.duration/sim.cfg.recordStep+1).resize(0) - sim.simData[key]['cell_'+str(self.gid)][secLoc].record(ptrItem, sim.cfg.recordStep) else: - sim.simData[key]['cell_'+str(self.gid)] = h.Vector(sim.cfg.duration/sim.cfg.recordStep+1).resize(0) - sim.simData[key]['cell_'+str(self.gid)].record(ptr, sim.cfg.recordStep) - if sim.cfg.verbose: print ' Recording ', key, 'from cell ', self.gid, ' with parameters: ',str(params) - except: - if sim.cfg.verbose: print ' Cannot record ', key, 'from cell ', self.gid + if 'pointp' in params: # eg. soma.izh._ref_u + if params['pointp'] in self.secs[params['sec']]['pointps']: + ptr = self.secs[params['sec']]['pointps'][params['pointp']]['hPointp'].__getattribute__('_ref_'+params['var']) + elif 'var' in params: # point process cell eg. cell._ref_v + ptr = self.hPointp.__getattribute__('_ref_'+params['var']) + + if ptr: # if pointer has been created, then setup recording + if isinstance(ptr, list): + sim.simData[key]['cell_'+str(self.gid)] = {} + for ptrItem,secLoc in zip(ptr, secLocs): + sim.simData[key]['cell_'+str(self.gid)][secLoc] = h.Vector(sim.cfg.duration/sim.cfg.recordStep+1).resize(0) + sim.simData[key]['cell_'+str(self.gid)][secLoc].record(ptrItem, sim.cfg.recordStep) + else: + sim.simData[key]['cell_'+str(self.gid)] = h.Vector(sim.cfg.duration/sim.cfg.recordStep+1).resize(0) + sim.simData[key]['cell_'+str(self.gid)].record(ptr, sim.cfg.recordStep) + if sim.cfg.verbose: print ' Recording ', key, 'from cell ', self.gid, ' with parameters: ',str(params) + except: + if sim.cfg.verbose: print ' Cannot record ', key, 'from cell ', self.gid + else: + if sim.cfg.verbose: print ' Conditions preclude recording ', key, ' from cell ', self.gid #else: # if sim.cfg.verbose: print ' NOT recording ', key, 'from cell ', self.gid, ' with parameters: ',str(params) diff --git a/netpyne/simFuncs.py b/netpyne/simFuncs.py index 363e1a002..56166ab52 100644 --- a/netpyne/simFuncs.py +++ b/netpyne/simFuncs.py @@ -639,6 +639,17 @@ def setupRecording (): for key in sim.cfg.recordTraces.keys(): sim.simData[key] = Dict() # create dict to store traces for cell in cellsRecord: cell.recordTraces() # call recordTraces function for each cell + + cat = 0 + total = 0 + for key in sim.simData: + if sim.cfg.verbose: print(" Recording: %s:"%key) + if len(sim.simData[key])>0: cat+=1 + for k2 in sim.simData[key]: + if sim.cfg.verbose: print(" %s"%k2) + total+=1 + print("Recording %s traces of %s types on node %i"%(total, cat, sim.rank)) + timing('stop', 'setrecordTime') @@ -787,7 +798,7 @@ def runSim (): preRun() init() - if sim.rank == 0: print('\nRunning...') + if sim.rank == 0: print('\nRunning simulation for %s ms...'%sim.cfg.duration) sim.pc.psolve(sim.cfg.duration) sim.pc.barrier() # Wait for all hosts to get to this point From 43d83f14e8fd920c647ca1b14a030f37d7c261c8 Mon Sep 17 00:00:00 2001 From: salvadord Date: Wed, 12 Apr 2017 11:22:24 -0400 Subject: [PATCH 37/37] VERSION 0.6.9 --- CHANGES.md | 4 ++++ netpyne/__init__.py | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGES.md b/CHANGES.md index 7d19f5f43..0c657272d 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,5 +1,7 @@ # Version 0.6.9 +- Improved support for NeuroML export + - Added option to skip batch job based on custom existing job filename (eg. 'skipCustom': '.run') - Added option to specify netParams .py file for batch @@ -12,6 +14,8 @@ - Added option to set threshold when loading weightNorm +- Added support for conditions on recordTraces + - Fixed bug plotting NetStims (created as stims) in raster, spikeHist and ratePSD - Fixed bug in plotConn bar graphs diff --git a/netpyne/__init__.py b/netpyne/__init__.py index 281e97d35..27f78d214 100644 --- a/netpyne/__init__.py +++ b/netpyne/__init__.py @@ -1,3 +1,3 @@ -__version__ = '0.6.8' +__version__ = '0.6.9' __gui__ = True # global option to enable/disable graphics \ No newline at end of file