Changeset 377
- Timestamp:
- 06/19/08 18:01:38 (5 months ago)
- Files:
-
- trunk/src/neuron2/__init__.py (modified) (18 diffs)
- trunk/src/neuron2/cells.py (modified) (2 diffs)
- trunk/src/neuron2/connectors.py (modified) (4 diffs)
- trunk/src/neuron2/simulator.py (moved) (moved from trunk/src/neuron2/utility.py) (3 diffs)
- trunk/test/neuron2tests.py (modified) (5 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/src/neuron2/__init__.py
r376 r377 8 8 9 9 from pyNN.random import * 10 from pyNN.neuron2 .utility import *10 from pyNN.neuron2 import simulator 11 11 from pyNN import common, utility 12 12 from pyNN.neuron2.cells import * … … 21 21 22 22 # Global variables 23 gid_counter = 024 initialised = False25 running = False26 23 quit_on_end = True 27 24 recorder_list = [] … … 37 34 simulator but not by others. 38 35 """ 39 global initialised, quit_on_end, running, parallel_context, initializer 40 if not initialised: 41 h('min_delay = 0') 42 h('tstop = 0') 43 parallel_context = neuron.ParallelContext() 44 parallel_context.spike_compress(1,0) 45 cvode = neuron.CVode() 46 initializer = Initializer() 36 global quit_on_end 37 if not simulator.state.initialized: 47 38 utility.init_logging("neuron2.log.%d" % rank(), debug) 48 39 logging.info("Initialization of NEURON (use setup(.., debug=True) to see a full logfile)") 49 h.dt = timestep50 h.tstop = 051 h.min_delay = min_delay52 running = False40 simulator.state.initialized = True 41 simulator.state.dt = timestep 42 simulator.state.min_delay = min_delay 43 simulator.reset() 53 44 if 'quit_on_end' in extra_params: 54 45 quit_on_end = extra_params['quit_on_end'] 55 46 if extra_params.has_key('use_cvode'): 56 cvode.active(int(extra_params['use_cvode']))47 simulator.state.cvode.active(int(extra_params['use_cvode'])) 57 48 return rank() 58 49 … … 61 52 for recorder in recorder_list: 62 53 recorder.write(gather=False, compatible_output=compatible_output) 63 parallel_context.runworker() 64 parallel_context.done() 65 if quit_on_end: 66 logging.info("Finishing up with NEURON.") 67 h.quit() 54 simulator.finalize(quit_on_end) 68 55 69 56 def run(simtime): 70 57 """Run the simulation for simtime ms.""" 71 global running 72 if not running: 73 running = True 74 local_minimum_delay = parallel_context.set_maxstep(10) 75 h.finitialize() 76 h.tstop = 0 77 logging.debug("local_minimum_delay on host #%d = %g" % (rank(), local_minimum_delay)) 78 if num_processes() > 1: 79 assert local_minimum_delay >= get_min_delay(),\ 80 "There are connections with delays (%g) shorter than the minimum delay (%g)" % (local_minimum_delay, get_min_delay()) 81 h.tstop = simtime 82 logging.info("Running the simulation for %d ms" % simtime) 83 parallel_context.psolve(h.tstop) 84 return get_current_time() 58 simulator.run(simtime) 85 59 86 60 # ============================================================================== … … 90 64 def get_current_time(): 91 65 """Return the current time in the simulation.""" 92 return h.t66 return simulator.state.t 93 67 common.get_current_time = get_current_time 94 68 95 69 def get_time_step(): 96 return h.dt70 return simulator.state.dt 97 71 common.get_time_step = get_time_step 98 72 99 73 def get_min_delay(): 100 return h.min_delay74 return simulator.state.min_delay 101 75 common.get_min_delay = get_min_delay 102 76 103 77 def num_processes(): 104 return int(parallel_context.nhost())78 return simulator.state.num_processes 105 79 106 80 def rank(): 107 81 """Return the MPI rank.""" 108 return int(parallel_context.id())82 return simulator.state.mpi_rank 109 83 110 84 def list_standard_models(): … … 120 94 gid = int(self) 121 95 self._cell = cell_model(**cell_parameters) # create the cell object 122 parallel_context.set_gid2node(gid, rank()) # assign the gid to this node 123 nc = neuron.NetCon(self._cell.source, None) # } associate the cell spike source 124 parallel_context.cell(gid, nc.hoc_obj) # } with the gid (using a temporary NetCon) 96 simulator.register_gid(gid, self._cell.source) 125 97 self.parent = parent 126 98 … … 144 116 Function used by both `create()` and `Population.__init__()` 145 117 """ 146 global gid_counter147 118 assert n > 0, 'n must be a positive integer' 148 119 if isinstance(cellclass, basestring): # cell defined in hoc template 149 120 try: 150 cell_model = getattr( h, cellclass)121 cell_model = getattr(simulator.h, cellclass) 151 122 except AttributeError: 152 123 raise common.InvalidModelError("There is no hoc template called %s" % cellclass) … … 159 130 cell_model = cellclass 160 131 cell_parameters = param_dict 161 first_id = gid_counter162 last_id = gid_counter + n132 first_id = simulator.state.gid_counter 133 last_id = simulator.state.gid_counter + n 163 134 all_ids = numpy.array([id for id in range(first_id, last_id)], ID) 164 135 # mask_local is used to extract those elements from arrays that apply to the cells on the current node … … 168 139 all_ids[i] = ID(id) 169 140 all_ids[i]._build_cell(cell_model, cell_parameters, parent=parent) 170 gid_counter += n141 simulator.state.gid_counter += n 171 142 return all_ids, mask_local, first_id, last_id 172 143 … … 180 151 for id in all_ids[mask_local]: 181 152 id.cellclass = cellclass 182 initializer.register(*all_ids[mask_local])153 simulator.initializer.register(*all_ids[mask_local]) 183 154 all_ids = all_ids.tolist() # not sure this is desirable, but it is consistent with the other modules 184 155 if len(all_ids) == 1: 185 156 all_ids = all_ids[0] 186 157 return all_ids 187 188 def _single_connect(source, target, weight, delay, synapse_type):189 """190 Private function to connect two neurons.191 Used by `connect()` and the `Connector` classes.192 """193 global gid_counter194 if not isinstance(source, int) or source > gid_counter or source < 0:195 errmsg = "Invalid source ID: %s (gid_counter=%d)" % (source, gid_counter)196 raise common.ConnectionError(errmsg)197 if not isinstance(target, ID):198 raise common.ConnectionError("Invalid target ID: %s" % target)199 if synapse_type is None:200 synapse_type = weight>=0 and 'excitatory' or 'inhibitory'201 if weight is None:202 weight = common.DEFAULT_WEIGHT203 if "cond" in target.cellclass.__name__:204 weight = abs(weight) # weights must be positive for conductance-based synapses205 elif synapse_type == 'inhibitory' and weight > 0:206 weight *= -1 # and negative for inhibitory, current-based synapses207 if delay is None:208 delay = get_min_delay()209 elif delay < get_min_delay():210 raise common.ConnectionError("delay (%s) is too small (< %s)" % (delay, get_min_delay()))211 synapse_object = getattr(target._cell, synapse_type).hoc_obj212 nc = parallel_context.gid_connect(int(source), synapse_object)213 nc.weight[0] = weight214 nc.delay = delay215 return nc216 158 217 159 def connect(source, target, weight=None, delay=None, synapse_type=None, p=1, rng=None): … … 235 177 sources = sources[rarr<p] 236 178 for src in sources: 237 nc = _single_connect(src, tgt, weight, delay, synapse_type)179 nc = simulator.single_connect(src, tgt, weight, delay, synapse_type) 238 180 connection_list.append(nc) 239 181 return connection_list … … 260 202 if not hasattr(source, '__len__'): 261 203 source = [source] 262 recorder = Recorder('spikes', file=filename)204 recorder = simulator.Recorder('spikes', file=filename) 263 205 recorder.record(source) 264 206 recorder_list.append(recorder) … … 272 214 if not hasattr(source, '__len__'): 273 215 source = [source] 274 recorder = Recorder('v', file=filename)216 recorder = simulator.Recorder('v', file=filename) 275 217 recorder.record(source) 276 218 recorder_list.append(recorder) … … 305 247 """ 306 248 common.Population.__init__(self, dims, cellclass, cellparams, label) 307 self.recorders = {'spikes': Recorder('spikes', population=self),308 'v': Recorder('v', population=self)}249 self.recorders = {'spikes': simulator.Recorder('spikes', population=self), 250 'v': simulator.Recorder('v', population=self)} 309 251 self.label = self.label or 'population%d' % Population.nPop 310 252 if isinstance(cellclass, type) and issubclass(cellclass, common.StandardCellType): … … 322 264 self._mask_local = self._mask_local.reshape(self.dim) 323 265 324 initializer.register(self)266 simulator.initializer.register(self) 325 267 Population.nPop += 1 326 268 logging.info(self.describe('Creating Population "%(label)s" of shape %(dim)s, '+ … … 456 398 # provided that the same rng with the same seed is used on each node. 457 399 if isinstance(rand_distr.rng, NativeRNG): 458 rng = h.Random(rand_distr.rng.seed or 0)400 rng = simulator.h.Random(rand_distr.rng.seed or 0) 459 401 native_rand_distr = getattr(rng, rand_distr.name) 460 402 rarr = [native_rand_distr(*rand_distr.parameters)] + [rng.repick() for i in range(self._all_ids.size-1)] … … 477 419 Private method called by record() and record_v(). 478 420 """ 479 global myid480 421 fixed_list=False 481 422 if isinstance(record_from, list): #record from the fixed list specified by user … … 666 607 connection_method(method_parameters) 667 608 elif isinstance(method, common.Connector): 668 print " gid_counter = ",gid_counter609 print "simulator.gid_counter = ", simulator.State.gid_counter 669 610 method.connect(self) 670 611 trunk/src/neuron2/cells.py
r376 r377 164 164 for name in 'start', 'interval', 'number': 165 165 setattr(self.source, name, locals()[name]) 166 self.spiketimes = neuron.Vector() 166 self.source.noise = 1 167 self.spiketimes = neuron.Vector(0) 167 168 self.do_not_record = False 168 169 … … 174 175 if not self.do_not_record: # for VecStims, etc, recording doesn't make sense as we already have the spike times 175 176 if active: 176 rec = neuron.NetCon(self.source, None) 177 rec.record(self.spiketimes.hoc_obj) 177 self.spiketimes.hoc_obj.printf() 178 self.rec = neuron.NetCon(self.source, None) 179 self.rec.record(self.spiketimes.hoc_obj) 178 180 179 181 trunk/src/neuron2/connectors.py
r376 r377 6 6 from pyNN import common 7 7 from pyNN.random import RandomDistribution, NativeRNG 8 from pyNN.neuron2 .__init__ import get_min_delay, _single_connect8 from pyNN.neuron2 import simulator 9 9 import numpy 10 10 from math import * 11 12 common.get_min_delay = get_min_delay13 11 14 12 # ============================================================================== … … 42 40 delays = d.__iter__() 43 41 else: 44 delays = ConstIter(max((d, get_min_delay())))42 delays = ConstIter(max((d, simulator.state.min_delay))) 45 43 else: 46 delays = ConstIter( get_min_delay())44 delays = ConstIter(simulator.state.min_delay) 47 45 return delays 48 46 … … 82 80 if create[j]: 83 81 projection.connections.append( 84 _single_connect(src, tgt,85 weights.next(), delays.next(),86 projection.synapse_type))82 simulator.single_connect(src, tgt, 83 weights.next(), delays.next(), 84 projection.synapse_type)) 87 85 88 86 … … 102 100 src = tgt - projection.post.first_id + projection.pre.first_id 103 101 projection.connections.append( 104 _single_connect(src, tgt, weights.next(), delays.next(), projection.synapse_type))102 simulator.single_connect(src, tgt, weights.next(), delays.next(), projection.synapse_type)) 105 103 else: 106 104 raise Exception("OneToOneConnector does not support presynaptic and postsynaptic Populations of different sizes.") trunk/src/neuron2/simulator.py
r376 r377 69 69 for id in self.recorded: 70 70 spikes = id._cell.spiketimes.toarray() 71 print "t = ", common.get_current_time() 72 spikes = spikes[spikes<=common.get_current_time()+1e-9] 71 spikes = spikes[spikes<=state.t+1e-9] 73 72 if len(spikes) > 0: 74 73 new_data = numpy.array([spikes, numpy.ones(spikes.shape)*id]).T … … 91 90 self.population, common.get_time_step()) 92 91 93 class Initializer(object):92 class _Initializer(object): 94 93 95 94 def __init__(self): 96 95 self.cell_list = [] 97 96 self.population_list = [] 98 neuron.h('objref initializer')97 h('objref initializer') 99 98 neuron.h.initializer = self 100 99 self.fih = h.FInitializeHandler("initializer.initialize()") 100 101 def __call__(self): 102 """This is to make the Initializer a Singleton.""" 103 return self 101 104 102 105 def register(self, *items): … … 118 121 cell._cell.memb_init() 119 122 120 121 load_mechanisms() 123 def h_property(name): 124 def _get(self): 125 return getattr(h,name) 126 def _set(self, val): 127 setattr(h, name, val) 128 return property(fget=_get, fset=_set) 129 130 class _State(object): 131 """Represent the simulator state.""" 132 133 def __init__(self): 134 self.gid_counter = 0 135 self.running = False 136 self.initialized = False 137 h('min_delay = 0') 138 h('tstop = 0') 139 self.parallel_context = neuron.ParallelContext() 140 self.parallel_context.spike_compress(1,0) 141 self.num_processes = int(self.parallel_context.nhost()) 142 self.mpi_rank = int(self.parallel_context.id()) 143 self.cvode = neuron.CVode() 144 145 t = h_property('t') 146 dt = h_property('dt') 147 tstop = h_property('tstop') # } do these really need to be stored in hoc? 148 min_delay = h_property('min_delay') # } 149 150 151 def __call__(self): 152 """This is to make the State a Singleton.""" 153 return self 154 155 def reset(): 156 state.running = False 157 state.t = 0 158 state.tstop = 0 159 160 def run(simtime): 161 if not state.running: 162 state.running = True 163 local_minimum_delay = state.parallel_context.set_maxstep(10) 164 h.finitialize() 165 state.tstop = 0 166 logging.debug("local_minimum_delay on host #%d = %g" % (state.mpi_rank, local_minimum_delay)) 167 if state.num_processes > 1: 168 assert local_minimum_delay >= state.min_delay,\ 169 "There are connections with delays (%g) shorter than the minimum delay (%g)" % (local_minimum_delay, state.min_delay) 170 state.tstop = simtime 171 logging.info("Running the simulation for %d ms" % simtime) 172 state.parallel_context.psolve(state.tstop) 173 return state.t 174 175 176 def finalize(quit=True): 177 state.parallel_context.runworker() 178 state.parallel_context.done() 179 if quit: 180 logging.info("Finishing up with NEURON.") 181 h.quit() 182 183 def register_gid(gid, source): 184 state.parallel_context.set_gid2node(gid, state.mpi_rank) # assign the gid to this node 185 nc = neuron.NetCon(source, None) # } associate the cell spike source 186 state.parallel_context.cell(gid, nc.hoc_obj) # } with the gid (using a temporary NetCon) 187 188 def single_connect(source, target, weight, delay, synapse_type): 189 """ 190 Private function to connect two neurons. 191 Used by `connect()` and the `Connector` classes. 192 """ 193 if not isinstance(source, int) or source > state.gid_counter or source < 0: 194 errmsg = "Invalid source ID: %s (gid_counter=%d)" % (source, state.gid_counter) 195 raise common.ConnectionError(errmsg) 196 if not isinstance(target, common.IDMixin): 197 raise common.ConnectionError("Invalid target ID: %s" % target) 198 if synapse_type is None: 199 synapse_type = weight>=0 and 'excitatory' or 'inhibitory' 200 if weight is None: 201 weight = common.DEFAULT_WEIGHT 202 if "cond" in target.cellclass.__name__: 203 weight = abs(weight) # weights must be positive for conductance-based synapses 204 elif synapse_type == 'inhibitory' and weight > 0: 205 weight *= -1 # and negative for inhibitory, current-based synapses 206 if delay is None: 207 delay = state.min_delay 208 elif delay < state.min_delay: 209 raise common.ConnectionError("delay (%s) is too small (< %s)" % (delay, state.min_delay)) 210 synapse_object = getattr(target._cell, synapse_type).hoc_obj 211 nc = state.parallel_context.gid_connect(int(source), synapse_object) 212 nc.weight[0] = weight 213 nc.delay = delay 214 return nc 215 216 # The following are executed every time the module is imported. 217 load_mechanisms() # maintains a list of mechanisms that have already been imported 218 state = _State() # a Singleton, so only a single instance ever exists 219 initializer = _Initializer() trunk/test/neuron2tests.py
r376 r377 23 23 24 24 def tearDown(self): 25 neuron. gid_counter = 025 neuron.simulator.state.gid_counter = 0 26 26 27 27 def testCreateStandardCell(self): … … 29 29 logging.info('=== CreationTest.testCreateStandardCell() ===') 30 30 ifcell = neuron.create(neuron.IF_curr_alpha) 31 assert ifcell == 0, 'Failed to create standard cell '31 assert ifcell == 0, 'Failed to create standard cell (cell=%s)' % ifcell 32 32 33 33 def testCreateStandardCells(self): … … 437 437 self.pop2 = neuron.Population((3,3), neuron.IF_curr_alpha) 438 438 439 def tearDown(self): 440 neuron.simulator.reset() 441 439 442 def testRecordAll(self): 440 443 """Population.record(): not a full test, just checking there are no Exceptions raised.""" … … 463 466 self.pop1.record() 464 467 simtime = 1000.0 465 neuron.running = False466 468 neuron.run(simtime) 467 self.pop1.printSpikes("temp_neuron.ras", gather=True)469 #self.pop1.printSpikes("temp_neuron.ras", gather=True) 468 470 rate = self.pop1.meanSpikeCount()*1000/simtime 469 471 if neuron.rank() == 0: # only on master node … … 493 495 spike_source = neuron.Population(1, neuron.SpikeSourceArray, {'spike_times': spike_times}) 494 496 spike_source.record() 495 neuron.running = False496 497 neuron.run(100.0) 497 spikes = spike_source.getSpikes()[:,0] 498 spikes = spike_source.getSpikes() 499 print spikes 500 spikes = spikes[:,0] 498 501 if neuron.rank() == 0: 499 502 self.assert_( max(spikes) == 100.0, str(spikes) )

