Changeset 422 for branches

Show
Ignore:
Timestamp:
07/17/08 12:39:15 (4 years ago)
Author:
apdavison
Message:

Attempt at duplication reduction in pcsim module. Untested as I don't have PCSIM on this machine.

Location:
branches/harmonize/src/pcsim
Files:
2 modified

Legend:

Unmodified
Added
Removed
  • branches/harmonize/src/pcsim/__init__.py

    r420 r422  
    2424from pyNN.pcsim.synapses import * 
    2525 
    26 try: 
    27     import tables 
    28 except ImportError: 
    29     pass 
    3026import exceptions 
    3127from datetime import datetime 
    3228import operator 
    3329 
    34 from pyNN.pcsim.pcsim_globals import pcsim_globals 
    35  
    36 def checkParams(param, val=None): 
    37     """Check parameters are of valid types, normalise the different ways of 
    38        specifying parameters and values by putting everything in a dict. 
    39        Called by set() and Population.set().""" 
    40     if isinstance(param, str): 
    41         if isinstance(val, float) or isinstance(val, int): 
    42             param_dict = {param:float(val)} 
    43         elif isinstance(val, str): 
    44             param_dict = {param:val} 
    45         else: 
    46             raise common.InvalidParameterValueError 
    47     elif isinstance(param, dict): 
    48         param_dict = param 
    49     else: 
    50         raise common.InvalidParameterValueError 
    51     return param_dict 
     30import pyNN.pcsim.pcsim_globals as simulator 
     31pcsim_globals = simulator.pcsim_globals 
    5232 
    5333# ============================================================================== 
     
    7858        else: 
    7959            return values  
    80          
    81          
    82          
    83 class SpikesMultiChannelRecorder(object): 
    84      
    85     def __init__(self, source, filename=None, source_indices=None, gather=False, parent=None):         
    86         self.filename = filename 
    87         self.gather = gather 
    88         self.recordings = []         
    89         self.record(source, source_indices) 
    90         self.parent = parent 
    91                  
    92     def record(self, sources, src_indices = None): 
    93         """ 
    94             Add celllist list to the list of the cells for which spikes  
    95             are recorded by this spikes multi recorder 
    96         """ 
    97         if type(sources) != types.ListType: 
    98             sources = [sources] 
    99         if not src_indices: 
    100             src_indices = range(len(self.recordings), len(self.recordings) + len(sources)) 
    101         global pcsim_globals 
    102         if type(sources) != types.ListType: 
    103             sources = [sources]         
    104         for i, src in zip(src_indices, sources): 
    105             src_id = SimObject.ID(src)     
    106             rec = pcsim_globals.net.create(SpikeTimeRecorder(), SimEngine.ID(src_id.node, src_id.eng))             
    107             pcsim_globals.net.connect(src, rec, Time.sec(0))             
    108             if (src_id.node == pcsim_globals.net.mpi_rank()):                 
    109                 self.recordings += [ (i, rec, src) ] 
    110                              
    111     def saveSpikesH5(self, filename = None): 
    112         if filename: 
    113             self.filename = filename 
    114         if (pcsim_globals.net.mpi_rank() != 0): 
    115             self.filename += ".node." + net.mpi_rank() 
    116         try: 
    117             h5file = tables.openFile(self.filename, mode = "w", title = "spike recordings") 
    118         except NameError: 
    119             raise Exception("Use of this function requires PyTables.") 
    120         for rec_info in self.recordings: 
    121             spikes = array([rec_ids[1]] + pcsim_globals.net.object(rec_ids[0]).getSpikeTimes()) 
    122             h5file.createArray(h5file.root, "spikes_" + str(rec_ids[1]), spikes, "") 
    123             h5file.flush() 
    124         h5file.close() 
    125          
    126     def saveSpikesText(self, filename=None, compatible_output=True): 
    127         if filename: 
    128             self.filename = filename 
    129         if (pcsim_globals.net.mpi_rank() != 0):     
    130             self.filename += ".node." + net.mpi_rank() 
    131         f = file(self.filename, "w",10000) 
    132         all_spikes = [] 
    133         if compatible_output: 
    134             for i, rec, src in self.recordings:             
    135                 spikes =  1000.0*numpy.array(pcsim_globals.net.object(rec).getSpikeTimes()) 
    136                 all_spikes += zip(spikes, [ i for k in xrange(len(spikes)) ]) 
    137         else: 
    138             for i, rec, src in self.recordings:             
    139                 spikes =  pcsim_globals.net.object(rec).getSpikeTimes() 
    140                 all_spikes += zip( [ i for k in xrange(len(spikes)) ], spikes) 
    141         all_spikes = sorted(all_spikes, key=operator.itemgetter(1)) 
    142         f.write("# dt = %g\n" % pcsim_globals.dt) 
    143         if self.parent: 
    144             f.write("# first_id = %d\n# last_id = %d\n" % (self.parent.cell[0], self.parent.cell[-1])) 
    145         for spike in all_spikes: 
    146             f.write("%s\t%s\n" % spike )                 
    147         f.close()         
    148      
    149     def getSpikes(self): 
    150         all_spikes = numpy.zeros((0,2)) 
    151         for i, rec, src in self.recordings:             
    152             spikes =  1000.0*numpy.array(pcsim_globals.net.object(rec).getSpikeTimes()) 
    153             spikes = spikes.reshape((len(spikes),1)) 
    154             ids = i*numpy.ones(spikes.shape) 
    155             ids_spikes = numpy.concatenate((ids, spikes), axis=1) 
    156             all_spikes = numpy.concatenate((all_spikes, ids_spikes), axis=0) 
    157         return all_spikes 
    158      
    159     def meanSpikeCount(self): 
    160         count = 0 
    161         for i, rec, src in self.recordings: 
    162             count += pcsim_globals.net.object(rec).spikeCount() 
    163         return count / len(self.recordings) 
    164          
    165      
    166  
    167 class FieldMultiChannelRecorder: 
    168      
    169     def __init__(self, sources, filename = None, src_indices = None, gather = False, fieldname = "Vm"):         
    170         self.filename = filename 
    171         self.fieldname = fieldname 
    172         self.gather = gather 
    173         self.recordings = [] 
    174         self.record(sources, src_indices) 
    175                          
    176     def record(self, sources, src_indices = None): 
    177         """ 
    178             Add celllist to the list of the cells for which field values 
    179             are recorded by this field multi recorder 
    180         """ 
    181         if type(sources) != types.ListType: 
    182             sources = [sources] 
    183         if not src_indices: 
    184             src_indices = range(len(self.recordings), len(self.recordings) + len(sources)) 
    185         global pcsim_globals 
    186         for i, src in zip(src_indices, sources): 
    187             src_id = SimObject.ID(src) 
    188             rec = pcsim_globals.net.create(AnalogRecorder(), SimEngine.ID(src_id.node, src_id.eng)) 
    189             pcsim_globals.net.connect(src, self.fieldname, rec, 0, Time.sec(0)) 
    190             if (src_id.node == pcsim_globals.net.mpi_rank()): 
    191                 self.recordings += [ (i, rec, src) ] 
    192                  
    193     def saveValuesH5(self, filename = None): 
    194         if filename: 
    195             self.filename = filename 
    196         if (pcsim_globals.net.mpi_rank() != 0): 
    197             self.filename += ".node." + pcsim_globals.net.mpi_rank() 
    198         try: 
    199             h5file = tables.openFile(filename, mode = "w", title = self.filename + " recordings") 
    200         except NameError: 
    201             raise Exception("Use of this function requires PyTables.") 
    202         for i, rec, src in self.recordings: 
    203             analog_values = array([i] + pcsim_globals.net.object(rec).getRecordedValues()) 
    204             h5file.createArray(h5file.root, self.fieldname + "_" + str(src), analog_values, "") 
    205             h5file.flush() 
    206         h5file.close() 
    207          
    208     def saveValuesText(self, filename = None, compatible_output=True): 
    209         if filename: 
    210             self.filename = filename 
    211         if (pcsim_globals.net.mpi_rank() != 0): 
    212             self.filename += ".node." + pcsim_globals.net.net.mpi_rank() 
    213         f = file(self.filename, "w",10000) 
    214         all_spikes = [] 
    215         if compatible_output: 
    216             f.write("# dt = %g\n" % pcsim_globals.dt) 
    217             f.write("# n = %d\n" % len(pcsim_globals.net.object(self.recordings[0][1]).getRecordedValues())) 
    218             for i, rec, src in self.recordings: 
    219                 analog_values =  pcsim_globals.net.object(rec).getRecordedValues() 
    220                 for v in analog_values: 
    221                     f.write("%g\t%d\n" % (float(v)*1000.0, i)) # convert from mV to V 
    222              
    223         else: 
    224             for i, rec, src in self.recordings: 
    225                 analog_values =  [i] +  list(pcsim_globals.net.object(rec).getRecordedValues()) 
    226                 for v in analog_values: 
    227                     f.write("%s " % v)                 
    228                 f.write("\n") 
    229         f.close() 
    230  
     60 
     61 
     62# 
    23163class ID(long, common.IDMixin): 
    23264    """ 
     
    507339        raise common.ConnectionError(e) 
    508340     
    509  
    510 def set(cells, param, val=None): 
    511     """Set one or more parameters of an individual cell or list of cells. 
    512     param can be a dict, in which case val should not be supplied, or a string 
    513     giving the parameter name, in which case val is the parameter value. 
    514     """    
    515     param_dict = checkParams(param, val) 
    516     for cell in cells: 
    517         cell.set_parameters(**param_dict) 
    518      
     341set = common.set 
    519342 
    520343def record(source, filename): 
     
    526349    if filename in pcsim_globals.spikes_multi_rec: 
    527350        pcsim_globals.spikes_multi_rec[filename].record(source)     
    528     pcsim_globals.spikes_multi_rec[filename] = SpikesMultiChannelRecorder(source, filename) 
    529              
    530      
     351    pcsim_globals.spikes_multi_rec[filename] = simulator.SpikesMultiChannelRecorder(source, filename) 
    531352 
    532353def record_v(source, filename): 
     
    539360    if filename in pcsim_globals.vm_multi_rec: 
    540361        pcsim_globals.vm_multi_rec[filename].record(source) 
    541     pcsim_globals.vm_multi_rec[filename] = FieldMultiChannelRecorder(source, filename) 
    542  
    543              
     362    pcsim_globals.vm_multi_rec[filename] = simulator.FieldMultiChannelRecorder(source, filename) 
     363 
    544364 
    545365# ============================================================================== 
     
    588408        common.Population.__init__(self, dims, cellclass, cellparams, label) 
    589409         
    590          
    591                   
    592410        # set the steps list, used by the __getitem__() method. 
    593411        self.steps = [1]*self.ndim 
     
    619437        if not self.label: 
    620438            self.label = 'population%d' % Population.nPop          
    621         self.record_from = { 'spiketimes': [], 'vtrace': [] }         
     439         
     440        self.recorders = {} 
    622441        Population.nPop += 1 
    623442         
     
    706525        return self.pcsim_population.size() 
    707526         
    708     def set(self, param, val=None): 
    709         """ 
    710         Set one or more parameters for every cell in the population. param 
    711         can be a dict, in which case val should not be supplied, or a string 
    712         giving the parameter name, in which case val is the parameter value. 
    713         val can be a numeric value, or list of such (e.g. for setting spike times). 
    714         e.g. p.set("tau_m",20.0). 
    715              p.set({'tau_m':20,'v_rest':-65}) 
    716         """ 
    717         """PCSIM: iteration through all elements """ 
    718         param_dict = checkParams(param, val) 
    719         for cell in self: 
    720             cell.set_parameters(**param_dict) 
    721          
    722527    def tset(self, parametername, value_array): 
    723528        """ 
     
    745550        rarr = rarr.reshape(self.dim[0:self.actual_ndim])          
    746551        self.tset(parametername, rarr) 
    747          
    748     def record(self, record_from=None, rng=None): 
    749         """ 
    750         If record_from is not given, record spikes from all cells in the Population. 
    751         record_from can be an integer - the number of cells to record from, chosen 
    752         at random (in this case a random number generator can also be supplied) 
    753         - or a list containing the ids of the cells to record. 
    754         """ 
    755         """ 
    756           The current implementation allows only one invocation of this method per population 
    757         """ 
    758         """ PCSIM: IMPLEMENTED by an array of recorders at python level""" 
     552     
     553    def _record(self, variable, record_from=None, rng=None, to_file=True): 
    759554        if isinstance(record_from, int): 
    760             if not rng:   rng = pyNN.random.RandomDistribution(rng=NativeRNG(seed = datetime.today().microsecond), 
    761                                                                distribution='UniformInteger', 
    762                                                                parameters=(0, len(self)-1)) 
     555            if not rng: 
     556                rng = pyNN.random.RandomDistribution(rng=NativeRNG(seed = datetime.today().microsecond), 
     557                                                     distribution='UniformInteger', 
     558                                                     parameters=(0, len(self)-1)) 
    763559            src_indices = [ int(i) for i in rng.next(record_from) ]             
    764560        elif record_from: 
     
    767563            src_indices  = range(self.pcsim_population.size()) 
    768564        sources = [ self.pcsim_population[i] for i in src_indices ] 
    769         self.spike_rec = SpikesMultiChannelRecorder(sources, None, src_indices, parent=self) 
    770          
    771     def record_v(self, record_from=None, rng=None): 
    772         """ 
    773         If record_from is not given, record the membrane potential for all cells in 
    774         the Population. 
    775         record_from can be an integer - the number of cells to record from, chosen 
    776         at random (in this case a random number generator can also be supplied) 
    777         - or a list containing the ids of the cells to record.          
    778         """ 
    779         """ PCSIM: IMPLEMENTED by an array of recorders """ 
    780         if isinstance(record_from, int):              
    781             if not rng:   rng = pyNN.random.RandomDistribution(rng=NativeRNG(seed = datetime.today().microsecond), 
    782                                                                distribution='UniformInteger', 
    783                                                                parameters=(0, len(self)-1)) 
    784             src_indices = [ int(i) for i in rng.next(record_from) ]              
    785         elif record_from: 
    786             src_indices = record_from 
    787         else: 
    788             src_indices = range(self.pcsim_population.size()) 
    789         sources = [ self.pcsim_population[i] for i in src_indices ] 
    790         self.vm_rec = FieldMultiChannelRecorder(sources, None, src_indices) 
    791       
    792     def printSpikes(self, filename, gather=True, compatible_output=True): 
    793         """ 
    794         Write spike times to file. 
    795          
    796         If compatible_output is True, the format is "spiketime cell_id", 
    797         where cell_id is the index of the cell counting along rows and down 
    798         columns (and the extension of that for 3-D). 
    799         This allows easy plotting of a `raster' plot of spiketimes, with one 
    800         line for each cell. 
    801         The timestep, first id, last id, and number of data points per cell are 
    802         written in a header, indicated by a '#' at the beginning of the line. 
    803          
    804         If compatible_output is False, the raw format produced by the simulator 
    805         is used. This may be faster, since it avoids any post-processing of the 
    806         spike files. 
    807          
    808         For parallel simulators, if gather is True, all data will be gathered 
    809         to the master node and a single output file created there. Otherwise, a 
    810         file will be written on each node, containing only the cells simulated 
    811         on that node. 
    812         """         
    813         """PCSIM: implemented by corresponding recorders at python level """ 
    814         self.spike_rec.saveSpikesText(filename, compatible_output=compatible_output) 
    815          
    816          
    817     def print_v(self, filename, gather=True, compatible_output=True): 
    818         """ 
    819         Write membrane potential traces to file. 
    820          
    821         If compatible_output is True, the format is "v cell_id", 
    822         where cell_id is the index of the cell counting along rows and down 
    823         columns (and the extension of that for 3-D). 
    824         The timestep, first id, last id, and number of data points per cell are 
    825         written in a header, indicated by a '#' at the beginning of the line. 
    826          
    827         If compatible_output is False, the raw format produced by the simulator 
    828         is used. This may be faster, since it avoids any post-processing of the 
    829         voltage files. 
    830          
    831         For parallel simulators, if gather is True, all data will be gathered 
    832         to the master node and a single output file created there. Otherwise, a 
    833         file will be written on each node, containing only the cells simulated 
    834         on that node. 
    835         """ 
    836         """PCSIM: will be implemented by corresponding analog recorders at python level object  """ 
    837         self.vm_rec.saveValuesText(filename, compatible_output=compatible_output) 
    838      
    839     def getSpikes(self, gather=True): 
    840         """ 
    841         Return a 2-column numpy array containing cell ids and spike times for 
    842         recorded cells. 
    843  
    844         Useful for small populations, for example for single neuron Monte-Carlo. 
    845         """ 
    846         return self.spike_rec.getSpikes() 
    847      
     565        if variable == 'spikes': 
     566            self.recorders['spikes'] = simulator.SpikesMultiChannelRecorder(sources, None, src_indices, parent=self) 
     567        elif variable == 'v': 
     568            self.recorders['v'] = simulator.FieldMultiChannelRecorder(sources, None, src_indices) 
     569 
    848570    def meanSpikeCount(self, gather=True):          
    849571        """ 
     
    857579                  recorders.  
    858580        """ 
    859         if self.spike_rec: 
    860             return self.spike_rec.meanSpikeCount() 
     581        if self.recorders['spikes']: 
     582            return self.recorders['spikes'].meanSpikeCount() 
    861583        return 0; 
    862584 
  • branches/harmonize/src/pcsim/pcsim_globals.py

    r281 r422  
     1 
     2try: 
     3    import tables 
     4except ImportError: 
     5    pass 
     6 
    17# global pypcsim objects used throughout simulation 
    28class PyPCSIM_GLOBALS:     
     
    1218 
    1319pcsim_globals = PyPCSIM_GLOBALS() 
     20 
     21class SpikesMultiChannelRecorder(object): 
     22     
     23    def __init__(self, source, filename=None, source_indices=None, gather=False, parent=None):         
     24        self.filename = filename 
     25        self.gather = gather 
     26        self.recordings = []         
     27        self.record(source, source_indices) 
     28        self.parent = parent 
     29                 
     30    def record(self, sources, src_indices = None): 
     31        """ 
     32            Add celllist list to the list of the cells for which spikes  
     33            are recorded by this spikes multi recorder 
     34        """ 
     35        if type(sources) != types.ListType: 
     36            sources = [sources] 
     37        if not src_indices: 
     38            src_indices = range(len(self.recordings), len(self.recordings) + len(sources)) 
     39        global pcsim_globals 
     40        if type(sources) != types.ListType: 
     41            sources = [sources]         
     42        for i, src in zip(src_indices, sources): 
     43            src_id = SimObject.ID(src)     
     44            rec = pcsim_globals.net.create(SpikeTimeRecorder(), SimEngine.ID(src_id.node, src_id.eng))             
     45            pcsim_globals.net.connect(src, rec, Time.sec(0))             
     46            if (src_id.node == pcsim_globals.net.mpi_rank()):                 
     47                self.recordings += [ (i, rec, src) ] 
     48                             
     49    def saveSpikesH5(self, filename = None): 
     50        if filename: 
     51            self.filename = filename 
     52        if (pcsim_globals.net.mpi_rank() != 0): 
     53            self.filename += ".node." + net.mpi_rank() 
     54        try: 
     55            h5file = tables.openFile(self.filename, mode = "w", title = "spike recordings") 
     56        except NameError: 
     57            raise Exception("Use of this function requires PyTables.") 
     58        for rec_info in self.recordings: 
     59            spikes = array([rec_ids[1]] + pcsim_globals.net.object(rec_ids[0]).getSpikeTimes()) 
     60            h5file.createArray(h5file.root, "spikes_" + str(rec_ids[1]), spikes, "") 
     61            h5file.flush() 
     62        h5file.close() 
     63         
     64    def saveSpikesText(self, filename=None, compatible_output=True): 
     65        if filename: 
     66            self.filename = filename 
     67        if (pcsim_globals.net.mpi_rank() != 0):     
     68            self.filename += ".node." + net.mpi_rank() 
     69        f = file(self.filename, "w",10000) 
     70        all_spikes = [] 
     71        if compatible_output: 
     72            for i, rec, src in self.recordings:             
     73                spikes =  1000.0*numpy.array(pcsim_globals.net.object(rec).getSpikeTimes()) 
     74                all_spikes += zip(spikes, [ i for k in xrange(len(spikes)) ]) 
     75        else: 
     76            for i, rec, src in self.recordings:             
     77                spikes =  pcsim_globals.net.object(rec).getSpikeTimes() 
     78                all_spikes += zip( [ i for k in xrange(len(spikes)) ], spikes) 
     79        all_spikes = sorted(all_spikes, key=operator.itemgetter(1)) 
     80        f.write("# dt = %g\n" % pcsim_globals.dt) 
     81        if self.parent: 
     82            f.write("# first_id = %d\n# last_id = %d\n" % (self.parent.cell[0], self.parent.cell[-1])) 
     83        for spike in all_spikes: 
     84            f.write("%s\t%s\n" % spike )                 
     85        f.close()         
     86     
     87    def write(self, filename, gather, compatible_output): 
     88        return self.saveSpikesText(filename, compatible_output) 
     89     
     90    def getSpikes(self): 
     91        all_spikes = numpy.zeros((0,2)) 
     92        for i, rec, src in self.recordings:             
     93            spikes =  1000.0*numpy.array(pcsim_globals.net.object(rec).getSpikeTimes()) 
     94            spikes = spikes.reshape((len(spikes),1)) 
     95            ids = i*numpy.ones(spikes.shape) 
     96            ids_spikes = numpy.concatenate((ids, spikes), axis=1) 
     97            all_spikes = numpy.concatenate((all_spikes, ids_spikes), axis=0) 
     98        return all_spikes 
     99     
     100    def get(self, gather=False): 
     101        return self.getSpikes() 
     102     
     103    def meanSpikeCount(self): 
     104        count = 0 
     105        for i, rec, src in self.recordings: 
     106            count += pcsim_globals.net.object(rec).spikeCount() 
     107        return count / len(self.recordings) 
     108         
     109     
     110 
     111class FieldMultiChannelRecorder: 
     112     
     113    def __init__(self, sources, filename = None, src_indices = None, gather = False, fieldname = "Vm"):         
     114        self.filename = filename 
     115        self.fieldname = fieldname 
     116        self.gather = gather 
     117        self.recordings = [] 
     118        self.record(sources, src_indices) 
     119                         
     120    def record(self, sources, src_indices = None): 
     121        """ 
     122            Add celllist to the list of the cells for which field values 
     123            are recorded by this field multi recorder 
     124        """ 
     125        if type(sources) != types.ListType: 
     126            sources = [sources] 
     127        if not src_indices: 
     128            src_indices = range(len(self.recordings), len(self.recordings) + len(sources)) 
     129        global pcsim_globals 
     130        for i, src in zip(src_indices, sources): 
     131            src_id = SimObject.ID(src) 
     132            rec = pcsim_globals.net.create(AnalogRecorder(), SimEngine.ID(src_id.node, src_id.eng)) 
     133            pcsim_globals.net.connect(src, self.fieldname, rec, 0, Time.sec(0)) 
     134            if (src_id.node == pcsim_globals.net.mpi_rank()): 
     135                self.recordings += [ (i, rec, src) ] 
     136                 
     137    def saveValuesH5(self, filename = None): 
     138        if filename: 
     139            self.filename = filename 
     140        if (pcsim_globals.net.mpi_rank() != 0): 
     141            self.filename += ".node." + pcsim_globals.net.mpi_rank() 
     142        try: 
     143            h5file = tables.openFile(filename, mode = "w", title = self.filename + " recordings") 
     144        except NameError: 
     145            raise Exception("Use of this function requires PyTables.") 
     146        for i, rec, src in self.recordings: 
     147            analog_values = array([i] + pcsim_globals.net.object(rec).getRecordedValues()) 
     148            h5file.createArray(h5file.root, self.fieldname + "_" + str(src), analog_values, "") 
     149            h5file.flush() 
     150        h5file.close() 
     151         
     152    def saveValuesText(self, filename = None, compatible_output=True): 
     153        if filename: 
     154            self.filename = filename 
     155        if (pcsim_globals.net.mpi_rank() != 0): 
     156            self.filename += ".node." + pcsim_globals.net.net.mpi_rank() 
     157        f = file(self.filename, "w",10000) 
     158        all_spikes = [] 
     159        if compatible_output: 
     160            f.write("# dt = %g\n" % pcsim_globals.dt) 
     161            f.write("# n = %d\n" % len(pcsim_globals.net.object(self.recordings[0][1]).getRecordedValues())) 
     162            for i, rec, src in self.recordings: 
     163                analog_values =  pcsim_globals.net.object(rec).getRecordedValues() 
     164                for v in analog_values: 
     165                    f.write("%g\t%d\n" % (float(v)*1000.0, i)) # convert from mV to V 
     166             
     167        else: 
     168            for i, rec, src in self.recordings: 
     169                analog_values =  [i] +  list(pcsim_globals.net.object(rec).getRecordedValues()) 
     170                for v in analog_values: 
     171                    f.write("%s " % v)                 
     172                f.write("\n") 
     173        f.close() 
     174         
     175    def write(self, file=None, gather=False, compatible_output=True): 
     176        return self.saveValuesText(filename, compatible_output) 
     177 
     178    def get(self, gather=False): 
     179        raise Exception("Not implemented") 
     180     
     181