Changeset 419

Show
Ignore:
Timestamp:
07/16/08 17:25:05 (1 month ago)
Author:
apdavison
Message:

In harmonize branch, created a simulator module within nest2 and moved the Recorder class into it, which then allowed moving the definitions of the record() and record_v() functions to common, together with set(), which was more straightforward.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • branches/harmonize/src/common.py

    r418 r419  
    685685    """Set one or more parameters of an individual cell or list of cells. 
    686686    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) 
    689697 
    690698def record(source, filename): 
     
    693701    # would actually like to be able to record to an array and choose later 
    694702    # 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) 
    696708 
    697709def 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 
    699712    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) 
    703720 
    704721# ============================================================================== 
  • branches/harmonize/src/nest2/__init__.py

    r418 r419  
    1616from pyNN.nest2.synapses import * 
    1717from pyNN.nest2.electrodes import * 
     18from pyNN.nest2 import simulator 
    1819Set = set 
    19  
    20 recorder_list = [] 
     20common.simulator = simulator 
     21 
    2122tempdirs       = [] 
    22 RECORDING_DEVICE_NAMES = {'spikes': 'spike_detector', 
    23                           'v': 'voltmeter', 
    24                           'conductance': 'conductancemeter'} 
     23 
    2524DEFAULT_BUFFER_SIZE = 10000 
    2625NEST_SYNAPSE_TYPES = ["cont_delay_synapse" ,"static_synapse", "stdp_pl_synapse_hom", 
     
    9695    delay = property(_get_delay, _set_delay) 
    9796 
    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_NAMES 
    113         self.variable = variable 
    114         self.filename = file or None 
    115         self.population = population # needed for writing header information 
    116         self.recorded = Set([])         
    117         # create device 
    118         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 = 0 
    154                 data[:,0] = data[:,0] - padding 
    155         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 data 
    159      
    160     def write(self, file=None, gather=False, compatible_output=True): 
    161         user_filename = file or self.filename 
    162         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 distributed 
    167             # 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 # symbol 
    169             # is escaped while reading the file, there is no problem 
    170            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.filename 
    176             for node in xrange(num_processes()): 
    177                 if rank()==0: 
    178                     node_file = root_file + '.%d' % node  
    179                     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_file 
    183                         os.system(system_line) 
    184         # don't want to remove nest_filename at this point in case the user wants to access the data 
    185         # a second time (e.g. with both getSpikes() and printSpikes()), but we should 
    186         # maintain a list of temporary files to be deleted at the end of the simulation 
    18797 
    18898def list_standard_models(): 
     
    345255    # And we postprocess the low level files opened by record() 
    346256    # and record_v() method 
    347     for recorder in recorder_list: 
     257    for recorder in simulator.recorder_list: 
    348258        recorder.write(gather=False, compatible_output=compatible_output) 
    349259 
     
    454364    return connect_id 
    455365 
    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  
     366set = common.set 
     367record = common.record 
     368record_v = common.record_v 
    523369 
    524370# ============================================================================== 
     
    588434            self.label = 'population%d' % Population.nPop 
    589435        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) 
    592438        Population.nPop += 1 
    593439 
  • branches/harmonize/src/nest2/connectors.py

    r415 r419  
    77from pyNN.nest2.__init__ import nest, is_number, get_max_delay, get_min_delay 
    88import numpy 
    9 # note that WDManager is defined in __init__.py imported here, then imported 
    10 # into __init__ through `from connectors import *`. This circularity can't be a 
    11 # good thing. Better to define WDManager here? 
    129from pyNN.random import RandomDistribution, NativeRNG 
    1310from math import * 
  • branches/harmonize/src/neuron2/__init__.py

    r418 r419  
    1414from pyNN.neuron2.synapses import * 
    1515from pyNN.neuron2.electrodes import * 
     16common.simulator = simulator 
    1617 
    1718from math import * 
     
    2324# Global variables 
    2425quit_on_end = True 
    25 recorder_list = [] 
    2626 
    2727# ============================================================================== 
     
    5151def end(compatible_output=True): 
    5252    """Do any necessary cleaning up before exiting.""" 
    53     for recorder in recorder_list: 
     53    for recorder in simulator.recorder_list: 
    5454        recorder.write(gather=False, compatible_output=compatible_output) 
    5555    simulator.finalize(quit_on_end) 
     
    182182    return connection_list 
    183183 
    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) 
     184set = common.set 
     185record = common.record 
     186record_v = common.record_v 
    220187 
    221188# ============================================================================== 
  • branches/harmonize/src/neuron2/simulator.py

    r403 r419  
    1010# Global variables 
    1111nrn_dll_loaded = [] 
     12recorder_list = [] 
    1213 
    1314def load_mechanisms(path=pyNN_path[0]):