Changeset 419
- Timestamp:
- 07/16/08 17:25:05 (1 month ago)
- Files:
-
- branches/harmonize/src/common.py (modified) (2 diffs)
- branches/harmonize/src/nest2/__init__.py (modified) (5 diffs)
- branches/harmonize/src/nest2/connectors.py (modified) (1 diff)
- branches/harmonize/src/nest2/simulator.py (added)
- branches/harmonize/src/neuron2/__init__.py (modified) (4 diffs)
- branches/harmonize/src/neuron2/simulator.py (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
branches/harmonize/src/common.py
r418 r419 685 685 """Set one or more parameters of an individual cell or list of cells. 686 686 param can be a dict, in which case val should not be supplied, or a string 687 giving the parameter name, in which case val is the parameter value.""" 688 pass 687 giving the parameter name, in which case val is the parameter value. 688 """ 689 if val: 690 param = {param:val} 691 if not hasattr(cells, '__len__'): 692 cells = [cells] 693 # see comment in Population.set() below about the efficiency of the 694 # following 695 for cell in cells: 696 cell.set_parameters(**param) 689 697 690 698 def record(source, filename): … … 693 701 # would actually like to be able to record to an array and choose later 694 702 # whether to write to a file. 695 pass 703 if not hasattr(source, '__len__'): 704 source = [source] 705 recorder = simulator.Recorder('spikes', file=filename) 706 recorder.record(source) 707 simulator.recorder_list.append(recorder) 696 708 697 709 def record_v(source, filename): 698 """Record membrane potential to a file. source can be an individual cell or 710 """ 711 Record membrane potential to a file. source can be an individual cell or 699 712 a list of cells.""" 700 # would actually like to be able to record to an array and choose later 701 # whether to write to a file. 702 pass 713 # would actually like to be able to record to an array and 714 # choose later whether to write to a file. 715 if not hasattr(source, '__len__'): 716 source = [source] 717 recorder = simulator.Recorder('v', file=filename) 718 recorder.record(source) 719 simulator.recorder_list.append(recorder) 703 720 704 721 # ============================================================================== branches/harmonize/src/nest2/__init__.py
r418 r419 16 16 from pyNN.nest2.synapses import * 17 17 from pyNN.nest2.electrodes import * 18 from pyNN.nest2 import simulator 18 19 Set = set 19 20 recorder_list = [] 20 common.simulator = simulator 21 21 22 tempdirs = [] 22 RECORDING_DEVICE_NAMES = {'spikes': 'spike_detector', 23 'v': 'voltmeter', 24 'conductance': 'conductancemeter'} 23 25 24 DEFAULT_BUFFER_SIZE = 10000 26 25 NEST_SYNAPSE_TYPES = ["cont_delay_synapse" ,"static_synapse", "stdp_pl_synapse_hom", … … 96 95 delay = property(_get_delay, _set_delay) 97 96 98 99 class Recorder(object):100 """Encapsulates data and functions related to recording model variables."""101 102 formats = {'spikes': 'id t',103 'v': 'id t v'}104 105 def __init__(self, variable, population=None, file=None):106 """107 `file` should be one of:108 a file-name,109 `None` (write to a temporary file)110 `False` (write to memory).111 """112 assert variable in RECORDING_DEVICE_NAMES113 self.variable = variable114 self.filename = file or None115 self.population = population # needed for writing header information116 self.recorded = Set([])117 # create device118 device_name = RECORDING_DEVICE_NAMES[variable]119 self._device = nest.Create(device_name)120 device_parameters = {"withgid": True, "withtime": True,121 "to_file": True, "to_memory": False}122 if self.variable != 'spikes':123 device_parameters["interval"] = get_time_step()124 if file is False:125 device_parameters.update(to_file=False, to_memory=True)126 nest.SetStatus(self._device, device_parameters)127 128 def record(self, ids):129 """Add the cells in `ids` to the set of recorded cells."""130 ids = Set(ids)131 new_ids = list( ids.difference(self.recorded) )132 self.recorded = self.recorded.union(ids)133 134 device_name = nest.GetStatus(self._device, "model")[0]135 if device_name == "spike_detector":136 nest.ConvergentConnect(new_ids, self._device)137 elif device_name in ('voltmeter', 'conductancemeter'):138 nest.DivergentConnect(self._device, new_ids)139 else:140 raise Exception("%s is not a valid recording device" % device_name)141 142 def get(self, gather=False):143 """Returns the recorded data."""144 if nest.GetStatus(self._device, 'to_file')[0]:145 nest_filename = _merge_files(self._device, gather)146 data = recording.readArray(nest_filename, sepchar=None)147 #os.remove(nest_filename)148 if data.size > 0:149 # the following returns indices, not IDs. I'm not sure this is what we want.150 if self.population is not None:151 padding = self.population.cell.flatten()[0]152 else:153 padding = 0154 data[:,0] = data[:,0] - padding155 elif nest.GetStatus(self._device,'to_memory')[0]:156 data = nest.GetStatus(self._device,'events')[0]157 data = recording.convert_compatible_output(data, self.population, self.variable)158 return data159 160 def write(self, file=None, gather=False, compatible_output=True):161 user_filename = file or self.filename162 nest_filename = _merge_files(self._device, gather)163 if num_processes() > 1:164 user_filename += '.%d' % rank()165 if compatible_output:166 # We should do the post processing (i.e the compatible output) in a distributed167 # manner to speed up the thing. The only problem that will arise is the headers,168 # that should be taken into account to be really clean. Otherwise, if the # symbol169 # is escaped while reading the file, there is no problem170 recording.write_compatible_output(nest_filename, user_filename, Recorder.formats[self.variable],self.population, get_time_step())171 else:172 system_line = 'cat %s > %s' % (nest_filename, user_filename)173 os.system(system_line)174 if gather == True and num_processes() > 1:175 root_file = file or self.filename176 for node in xrange(num_processes()):177 if rank()==0:178 node_file = root_file + '.%d' % node179 if os.path.exists(node_file):180 system_line = 'cat %s >> %s' % (node_file, root_file)181 os.system(system_line)182 system_line = 'rm %s' % node_file183 os.system(system_line)184 # don't want to remove nest_filename at this point in case the user wants to access the data185 # a second time (e.g. with both getSpikes() and printSpikes()), but we should186 # maintain a list of temporary files to be deleted at the end of the simulation187 97 188 98 def list_standard_models(): … … 345 255 # And we postprocess the low level files opened by record() 346 256 # and record_v() method 347 for recorder in recorder_list:257 for recorder in simulator.recorder_list: 348 258 recorder.write(gather=False, compatible_output=compatible_output) 349 259 … … 454 364 return connect_id 455 365 456 def set(cells, param, val=None): 457 """Set one or more parameters of an individual cell or list of cells. 458 param can be a dict, in which case val should not be supplied, or a string 459 giving the parameter name, in which case val is the parameter value. 460 """ 461 if val: 462 param = {param:val} 463 if not hasattr(cells, '__len__'): 464 cells = [cells] 465 # see comment in Population.set() below about the efficiency of the 466 # following 467 for cell in cells: 468 cell.set_parameters(**param) 469 470 def record(source, filename): 471 """Record spikes to a file. source can be an individual cell or a list of 472 cells.""" 473 # would actually like to be able to record to an array and choose later 474 # whether to write to a file. 475 if not hasattr(source, '__len__'): 476 source = [source] 477 recorder = Recorder('spikes', file=filename) 478 recorder.record(source) 479 recorder_list.append(recorder) 480 481 def record_v(source, filename): 482 """ 483 Record membrane potential to a file. source can be an individual cell or 484 a list of cells.""" 485 # would actually like to be able to record to an array and 486 # choose later whether to write to a file. 487 if not hasattr(source, '__len__'): 488 source = [source] 489 recorder = Recorder('v', file=filename) 490 recorder.record(source) 491 recorder_list.append(recorder) 492 493 def _merge_files(recorder, gather): 494 """ 495 Combine data from multiple files (one per thread and per process) into a single file. 496 Returns the filename of the merged file. 497 """ 498 nest.FlushDevice(recorder) 499 status = nest.GetStatus([0])[0] 500 local_num_threads = status['local_num_threads'] 501 node_list = range(nest.GetStatus([0], "num_processes")[0]) 502 503 # Combine data from different threads to the zeroeth thread 504 nest.sps(recorder[0]) 505 nest.sr("%i GetAddress %i append" % (recorder[0], 0)) 506 nest.sr("GetStatus /filename get") 507 merged_filename = nest.spp() #nest.GetStatus(recorder, "filename") 508 509 if local_num_threads > 1: 510 for nest_thread in range(1, local_num_threads): 511 nest.sps(recorder[0]) 512 nest.sr("%i GetAddress %i append" % (recorder[0], nest_thread)) 513 nest.sr("GetStatus /filename get") 514 nest_filename = nest.spp() #nest.GetStatus(recorder, "filename") 515 system_line = 'cat %s >> %s' % (nest_filename, merged_filename) 516 os.system(system_line) 517 os.remove(nest_filename) 518 #if gather and len(node_list) > 1: 519 ##if rank() == 0: 520 #raise Exception("gather not yet implemented") 521 return merged_filename 522 366 set = common.set 367 record = common.record 368 record_v = common.record_v 523 369 524 370 # ============================================================================== … … 588 434 self.label = 'population%d' % Population.nPop 589 435 self.recorders = {} 590 for variable in RECORDING_DEVICE_NAMES:591 self.recorders[variable] = Recorder(variable, population=self)436 for variable in simulator.RECORDING_DEVICE_NAMES: 437 self.recorders[variable] = simulator.Recorder(variable, population=self) 592 438 Population.nPop += 1 593 439 branches/harmonize/src/nest2/connectors.py
r415 r419 7 7 from pyNN.nest2.__init__ import nest, is_number, get_max_delay, get_min_delay 8 8 import numpy 9 # note that WDManager is defined in __init__.py imported here, then imported10 # into __init__ through `from connectors import *`. This circularity can't be a11 # good thing. Better to define WDManager here?12 9 from pyNN.random import RandomDistribution, NativeRNG 13 10 from math import * branches/harmonize/src/neuron2/__init__.py
r418 r419 14 14 from pyNN.neuron2.synapses import * 15 15 from pyNN.neuron2.electrodes import * 16 common.simulator = simulator 16 17 17 18 from math import * … … 23 24 # Global variables 24 25 quit_on_end = True 25 recorder_list = []26 26 27 27 # ============================================================================== … … 51 51 def end(compatible_output=True): 52 52 """Do any necessary cleaning up before exiting.""" 53 for recorder in recorder_list:53 for recorder in simulator.recorder_list: 54 54 recorder.write(gather=False, compatible_output=compatible_output) 55 55 simulator.finalize(quit_on_end) … … 182 182 return connection_list 183 183 184 def set(cells, param, val=None): 185 """Set one or more parameters of an individual cell or list of cells. 186 param can be a dict, in which case val should not be supplied, or a string 187 giving the parameter name, in which case val is the parameter value. 188 """ 189 if val: 190 param = {param:val} 191 if not hasattr(cells, '__len__'): 192 cells = [cells] 193 # see comment in Population.set() below about the efficiency of the 194 # following 195 for cell in cells: 196 cell.set_parameters(**param) 197 198 def record(source, filename): 199 """Record spikes to a file. source can be an individual cell or a list of 200 cells.""" 201 # would actually like to be able to record to an array and choose later 202 # whether to write to a file. 203 if not hasattr(source, '__len__'): 204 source = [source] 205 recorder = simulator.Recorder('spikes', file=filename) 206 recorder.record(source) 207 recorder_list.append(recorder) 208 209 def record_v(source, filename): 210 """ 211 Record membrane potential to a file. source can be an individual cell or 212 a list of cells.""" 213 # would actually like to be able to record to an array and 214 # choose later whether to write to a file. 215 if not hasattr(source, '__len__'): 216 source = [source] 217 recorder = simulator.Recorder('v', file=filename) 218 recorder.record(source) 219 recorder_list.append(recorder) 184 set = common.set 185 record = common.record 186 record_v = common.record_v 220 187 221 188 # ============================================================================== branches/harmonize/src/neuron2/simulator.py
r403 r419 10 10 # Global variables 11 11 nrn_dll_loaded = [] 12 recorder_list = [] 12 13 13 14 def load_mechanisms(path=pyNN_path[0]):
