Changeset 418

Show
Ignore:
Timestamp:
07/16/08 15:38:30 (1 month ago)
Author:
apdavison
Message:

In harmonize branch, moved common code from the definitions of the Population class in nest2 and neuron2 modules into common.

Files:

Legend:

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

    r415 r418  
    1212from pyNN import random 
    1313from string import Template 
     14import logging 
    1415 
    1516DEFAULT_WEIGHT = 0.0 
     
    747748             p[2,3] is equivalent to p.__getitem__((2,3)). 
    748749        """ 
    749         pass 
     750        if isinstance(addr, int): 
     751            addr = (addr,) 
     752        if len(addr) == self.ndim: 
     753            id = self._all_ids[addr] 
     754        else: 
     755            raise InvalidDimensionsError, "Population has %d dimensions. Address was %s" % (self.ndim, str(addr)) 
     756        if addr != self.locate(id): 
     757            raise IndexError, 'Invalid cell address %s' % str(addr) 
     758        return id 
    750759     
    751760    def __iter__(self): 
    752         """Iterator over cell ids.""" 
    753         return _abstract_method(self) 
    754          
     761        """Iterator over cell ids on the local node.""" 
     762        return iter(self._local_ids) 
     763 
     764    def __address_gen(self): 
     765        """ 
     766        Generator to produce an iterator over all cells on this node, 
     767        returning addresses. 
     768        """ 
     769        for i in self.__iter__(): 
     770            yield self.locate(i) 
     771 
    755772    def addresses(self): 
    756773        """Iterator over cell addresses.""" 
    757         return _abstract_method(self
    758      
     774        return self.__address_gen(
     775 
    759776    def ids(self): 
    760         """Iterator over cell ids.""" 
     777        """Iterator over cell ids on the local node.""" 
    761778        return self.__iter__() 
     779     
     780    def all(self): 
     781        """Iterator over cell ids on all nodes.""" 
     782        return self._all_ids.flat 
    762783     
    763784    def locate(self, id): 
     
    766787                         7 9 
    767788        """ 
    768         return _abstract_method(self) 
     789        id = id - self.first_id 
     790        if self.ndim == 3: 
     791            rows = self.dim[1]; cols = self.dim[2] 
     792            i = id/(rows*cols); remainder = id%(rows*cols) 
     793            j = remainder/cols; k = remainder%cols 
     794            coords = (i,j,k) 
     795        elif self.ndim == 2: 
     796            cols = self.dim[1] 
     797            i = id/cols; j = id%cols 
     798            coords = (i,j) 
     799        elif self.ndim == 1: 
     800            coords = (id,) 
     801        else: 
     802            raise common.InvalidDimensionsError 
     803        return coords 
    769804     
    770805    def __len__(self): 
     
    796831    def index(self, n): 
    797832        """Return the nth cell in the population (Indexing starts at 0).""" 
    798         return _abstract_method(self) 
     833        if hasattr(n, '__len__'): 
     834            n = numpy.array(n) 
     835        return self._all_ids.flatten()[n] 
    799836     
    800837    def nearest(self, position): 
     
    807844        nearest = distances.argmin() 
    808845        return self.index(nearest) 
    809              
     846     
     847    def get(self, parameter_name, as_array=False): 
     848        """ 
     849        Get the values of a parameter for every cell in the population. 
     850         
     851        If `as_array` is `True`, the values are returned in a numpy array with 
     852        the same shape as the `Population`. 
     853        """ 
     854        values = [getattr(cell, parameter_name) for cell in self] 
     855        if as_array: 
     856            values = numpy.array(values).reshape(self.dim) 
     857        return values 
     858         
    810859    def set(self, param, val=None): 
    811860        """ 
     
    817866             p.set({'tau_m':20,'v_rest':-65}) 
    818867        """ 
    819         return _abstract_method(self) 
     868        if isinstance(param, str): 
     869            if isinstance(val, (str, float, int)): 
     870                param_dict = {param: float(val)} 
     871            elif isinstance(val, (list, numpy.ndarray)): 
     872                param_dict = {param: val} 
     873            else: 
     874                raise common.InvalidParameterValueError 
     875        elif isinstance(param, dict): 
     876            param_dict = param 
     877        else: 
     878            raise common.InvalidParameterValueError 
     879        logging.info("%s.set(%s)", self.label, param_dict) 
     880        for cell in self: 
     881            cell.set_parameters(**param_dict) 
     882        # This loop is not very efficient for simple and scaled parameters for 
     883        # backends that can set parameters for multiple cells at once (e.g. nest) 
     884        # In `nest2`, for example, could call nest.SetStatus(self._local_ids,...) 
     885        # for the parameters in self.celltype.__class__.simple_parameters() and 
     886        # .scaled_parameters() and keep the loop below just for the computed 
     887        # parameters. Even in this case, it may be quicker to test whether the 
     888        # parameters participating in the computation vary between cells, since if 
     889        # this is not the case we can do the computation here and use nest.SetStatus. 
    820890 
    821891    def tset(self, parametername, value_array): 
     
    832902        """ 
    833903        return _abstract_method(self) 
    834      
    835     def _call(self, methodname, arguments): 
    836         """ 
    837         Call the method methodname(arguments) for every cell in the population. 
    838         e.g. p.call("set_background","0.1") if the cell class has a method 
    839         set_background(). 
    840         """ 
    841         return _abstract_method(self) 
    842      
    843     def _tcall(self, methodname, objarr): 
    844         """ 
    845         `Topographic' call. Call the method methodname() for every cell in the  
    846         population. The argument to the method depends on the coordinates of the 
    847         cell. objarr is an array with the same dimensions as the Population. 
    848         e.g. p.tcall("memb_init", vinitArray) calls 
    849         p.cell[i][j].memb_init(vInitArray[i][j]) for all i,j. 
    850         """ 
    851         return _abstract_method(self) 
    852904 
    853905    def randomInit(self, rand_distr): 
     
    856908        random values. 
    857909        """ 
    858         return _abstract_method(self
    859  
    860     def record(self, record_from=None, rng=None): 
     910        self.rset('v_init', rand_distr
     911 
     912    def record(self, record_from=None, rng=None, to_file=True): 
    861913        """ 
    862914        If record_from is not given, record spikes from all cells in the Population. 
     
    865917        - or a list containing the ids of the cells to record. 
    866918        """ 
    867         return _abstract_method(self
    868  
    869     def record_v(self, record_from=None, rng=None): 
     919        self._record('spikes', record_from, rng, to_file
     920 
     921    def record_v(self, record_from=None, rng=None, to_file=True): 
    870922        """ 
    871923        If record_from is not given, record the membrane potential for all cells in 
     
    875927        - or a list containing the ids of the cells to record. 
    876928        """ 
    877         return _abstract_method(self) 
     929        self._record('v', record_from, rng, to_file) 
     930 
     931    def record_c(self, record_from=None, rng=None, to_file=True): 
     932        """ 
     933        If record_from is not given, record the synaptic conductances for all cells in 
     934        the Population. 
     935        record_from can be an integer - the number of cells to record from, chosen 
     936        at random (in this case a random number generator can also be supplied) 
     937        - or a list containing the ids of the cells to record. 
     938        """ 
     939        self._record('conductance', record_from, rng, to_file) 
    878940 
    879941    def printSpikes(self, filename, gather=True, compatible_output=True): 
     
    898960        on that node. 
    899961        """         
    900         return _abstract_method(self) 
    901      
     962        self.recorders['spikes'].write(filename, gather, compatible_output) 
    902963 
    903964    def getSpikes(self, gather=True): 
     
    908969        Useful for small populations, for example for single neuron Monte-Carlo. 
    909970        """ 
    910         return _abstract_method(self
     971        return self.recorders['spikes'].get(gather
    911972 
    912973    def print_v(self, filename, gather=True, compatible_output=True): 
     
    929990        on that node. 
    930991        """ 
    931         return _abstract_method(self) 
     992        self.recorders['v'].write(filename, gather, compatible_output) 
     993     
     994    def get_v(self, gather=True): 
     995        """ 
     996        Return a 2-column numpy array containing cell ids and spike times for 
     997        recorded cells. 
     998 
     999        Useful for small populations, for example for single neuron Monte-Carlo. 
     1000        """ 
     1001        return self.recorders['v'].get(gather) 
     1002 
     1003    def print_c(self, filename, gather=True, compatible_output=True): 
     1004        """ 
     1005        Write conductance traces to file. 
     1006        If compatible_output is True, the format is "t g cell_id", 
     1007        where cell_id is the index of the cell counting along rows and down 
     1008        columns (and the extension of that for 3-D). 
     1009        The timestep, first id, last id, and number of data points per cell are 
     1010        written in a header, indicated by a '#' at the beginning of the line. 
     1011 
     1012        If compatible_output is False, the raw format produced by the simulator 
     1013        is used. This may be faster, since it avoids any post-processing of the 
     1014        voltage files. 
     1015        """ 
     1016        self.recorders['conductance'].write(filename, gather, compatible_output) 
     1017     
     1018    def get_c(self, gather=True): 
     1019        """ 
     1020        Return a 2-column numpy array containing cell ids and spike times for 
     1021        recorded cells. 
     1022 
     1023        Useful for small populations, for example for single neuron Monte-Carlo. 
     1024 
     1025        NOTE: getSpikes or printSpikes should be called only once per run, 
     1026        because they mangle simulator recorder files. 
     1027        """ 
     1028        return self.recorders['conductance'].get(gather) 
    9321029     
    9331030    def meanSpikeCount(self, gather=True): 
  • branches/harmonize/src/nest2/__init__.py

    r416 r418  
    583583                nest.SetStatus(self.cell_local, [self.cellparams]) 
    584584            self._local_ids = self.cell_local 
     585            self._all_ids = self.cell 
    585586 
    586587        if not self.label: 
     
    590591            self.recorders[variable] = Recorder(variable, population=self) 
    591592        Population.nPop += 1 
    592  
    593     def __getitem__(self, addr): 
    594         """Return a representation of the cell with coordinates given by addr, 
    595            suitable for being passed to other methods that require a cell id. 
    596            Note that __getitem__ is called when using [] access, e.g. 
    597              p = Population(...) 
    598              p[2,3] is equivalent to p.__getitem__((2,3)). 
    599         """ 
    600         if isinstance(addr, int): 
    601             addr = (addr,) 
    602         if len(addr) == self.ndim: 
    603             id = self.cell[addr] 
    604         else: 
    605             raise common.InvalidDimensionsError, "Population has %d dimensions. Address was %s" % (self.ndim, str(addr)) 
    606         if addr != self.locate(id): 
    607             raise IndexError, 'Invalid cell address %s' % str(addr) 
    608         return id 
    609  
    610     def __iter__(self): 
    611         """Iterator over cell ids.""" 
    612         return self.cell.flat 
    613  
    614     def __address_gen(self): 
    615         """ 
    616         Generator to produce an iterator over all cells on this node, 
    617         returning addresses. 
    618         """ 
    619         for i in self.__iter__(): 
    620             yield self.locate(i) 
    621  
    622     def addresses(self): 
    623         """Iterator over cell addresses.""" 
    624         return self.__address_gen() 
    625  
    626     def ids(self): 
    627         """Iterator over cell ids.""" 
    628         return self.__iter__() 
    629  
    630     def locate(self, id): 
    631         """Given an element id in a Population, return the coordinates. 
    632                e.g. for  4 6  , element 2 has coordinates (1,0) and value 7 
    633                          7 9 
    634         """ 
    635         # The top two lines (commented out) are the original implementation, 
    636         # which does not scale well when the population size gets large. 
    637         # The next lines are the neuron implementation of the same method. This 
    638         # assumes that the id values in self.cell are consecutive. This should 
    639         # always be the case, I think? A unit test is needed to check this. 
    640  
    641         ###assert isinstance(id,int) 
    642         ###return tuple([a.tolist()[0] for a in numpy.where(self.cell == id)]) 
    643  
    644         id -= self.first_id 
    645         if self.ndim == 3: 
    646             rows = self.dim[1]; cols = self.dim[2] 
    647             i = id/(rows*cols); remainder = id%(rows*cols) 
    648             j = remainder/cols; k = remainder%cols 
    649             coords = (i,j,k) 
    650         elif self.ndim == 2: 
    651             cols = self.dim[1] 
    652             i = id/cols; j = id%cols 
    653             coords = (i,j) 
    654         elif self.ndim == 1: 
    655             coords = (id,) 
    656         else: 
    657             raise common.InvalidDimensionsError 
    658         return coords 
    659  
    660     def index(self, n): 
    661         """Return the nth cell in the population (Indexing starts at 0).""" 
    662         if hasattr(n, '__len__'): 
    663             n = numpy.array(n) 
    664         return self.cell.flatten()[n] 
    665  
    666     def get(self, parameter_name, as_array=False): 
    667         """ 
    668         Get the values of a parameter for every cell in the population. 
    669         """ 
    670         values = [getattr(cell, parameter_name) for cell in self.cell_local] 
    671         if as_array: 
    672             values = numpy.array(values) 
    673         return values 
    674  
    675     def set(self, param, val=None): 
    676         """ 
    677         Set one or more parameters for every cell in the population. param 
    678         can be a dict, in which case val should not be supplied, or a string 
    679         giving the parameter name, in which case val is the parameter value. 
    680         val can be a numeric value, or list of such (e.g. for setting spike times). 
    681         e.g. p.set("tau_m",20.0). 
    682              p.set({'tau_m':20,'v_rest':-65}) 
    683         """ 
    684         if isinstance(param, str): 
    685             if isinstance(val, (str, float, int)): 
    686                 param_dict = {param: float(val)} 
    687             else: 
    688                 raise common.InvalidParameterValueError 
    689         elif isinstance(param,dict): 
    690             param_dict = param 
    691         else: 
    692             raise common.InvalidParameterValueError 
    693         # This is not very efficient for simple and scaled parameters. 
    694         # Should call nest.SetStatus(self.cell_local,...) for the parameters in 
    695         # self.celltype.__class__.simple_parameters() and .scaled_parameters() 
    696         # and keep the loop below just for the computed parameters. Even in this 
    697         # case, it may be quicker to test whether the parameters participating 
    698         # in the computation vary between cells, since if this is not the case 
    699         # we can do the computation here and use nest.SetStatus. 
    700         for cell in self.cell_local: 
    701             cell.set_parameters(**param_dict) 
    702593 
    703594    def tset(self, parametername, value_array): 
     
    743634                setattr(cell, parametername, val) 
    744635 
    745     def _record(self, variable, record_from=None, rng=None,to_file=True): 
     636    def _record(self, variable, record_from=None, rng=None, to_file=True): 
    746637        if to_file is False: 
    747638            nest.SetStatus(self.recorders[variable]._device, {'to_file': False, 'to_memory': True}) 
     
    774665 
    775666        self.recorders[variable].record(tmp_list) 
    776  
    777     def record(self, record_from=None, rng=None, to_file=True): 
    778         """ 
    779         If record_from is not given, record spikes from all cells in the Population. 
    780         record_from can be an integer - the number of cells to record from, chosen 
    781         at random (in this case a random number generator can also be supplied) 
    782         - or a list containing the ids 
    783         of the cells to record. 
    784         """ 
    785         self._record('spikes', record_from, rng, to_file) 
    786  
    787     def record_v(self, record_from=None, rng=None, to_file=True): 
    788         """ 
    789         If record_from is not given, record the membrane potential for all cells in 
    790         the Population. 
    791         record_from can be an integer - the number of cells to record from, chosen 
    792         at random (in this case a random number generator can also be supplied) 
    793         - or a list containing the ids of the cells to record. 
    794         """ 
    795         self._record('v', record_from, rng, to_file) 
    796  
    797     def record_c(self, record_from=None, rng=None, to_file=True): 
    798         """ 
    799         If record_from is not given, record the membrane potential for all cells in 
    800         the Population. 
    801         record_from can be an integer - the number of cells to record from, chosen 
    802         at random (in this case a random number generator can also be supplied) 
    803         - or a list containing the ids of the cells to record. 
    804         """ 
    805         self._record('conductance', record_from, rng, to_file) 
    806  
    807     def printSpikes(self, filename, gather=True, compatible_output=True): 
    808         """ 
    809         Write spike times to file. 
    810  
    811         If compatible_output is True, the format is "spiketime cell_id", 
    812         where cell_id is the index of the cell counting along rows and down 
    813         columns (and the extension of that for 3-D). 
    814         This allows easy plotting of a `raster' plot of spiketimes, with one 
    815         line for each cell. 
    816         The timestep, first id, last id, and number of data points per cell are 
    817         written in a header, indicated by a '#' at the beginning of the line. 
    818  
    819         If compatible_output is False, the raw format produced by the simulator 
    820         is used. This may be faster, since it avoids any post-processing of the 
    821         spike files. 
    822  
    823         For parallel simulators, if gather is True, all data will be gathered 
    824         to the master node and a single output file created there. Otherwise, a 
    825         file will be written on each node, containing only the cells simulated 
    826         on that node. 
    827         """ 
    828         self.recorders['spikes'].write(filename, gather, compatible_output) 
    829  
    830     def getSpikes(self, gather=True): 
    831         """ 
    832         Return a 2-column numpy array containing cell ids and spike times for 
    833         recorded cells. 
    834  
    835         Useful for small populations, for example for single neuron Monte-Carlo. 
    836  
    837         NOTE: getSpikes or printSpikes should be called only once per run, 
    838         because they mangle simulator recorder files. 
    839         """ 
    840         return self.recorders['spikes'].get(gather) 
    841  
    842     def get_v(self, gather=True): 
    843         """ 
    844         Return a 2-column numpy array containing cell ids and spike times for 
    845         recorded cells. 
    846  
    847         Useful for small populations, for example for single neuron Monte-Carlo. 
    848  
    849         NOTE: getSpikes or printSpikes should be called only once per run, 
    850         because they mangle simulator recorder files. 
    851         """ 
    852         return self.recorders['v'].get(gather) 
    853              
    854     def get_c(self, gather=True): 
    855         """ 
    856         Return a 2-column numpy array containing cell ids and spike times for 
    857         recorded cells. 
    858  
    859         Useful for small populations, for example for single neuron Monte-Carlo. 
    860  
    861         NOTE: getSpikes or printSpikes should be called only once per run, 
    862         because they mangle simulator recorder files. 
    863         """ 
    864         return self.recorders['conductance'].get(gather) 
    865667     
    866668    def meanSpikeCount(self, gather=True): 
     
    883685        return float(n_spikes)/n_rec 
    884686 
    885     def randomInit(self, rand_distr): 
    886         """ 
    887         Set initial membrane potentials for all the cells in the population to 
    888         random values. 
    889         """ 
    890         self.rset('v_init', rand_distr) 
    891  
    892     def print_v(self, filename, gather=True, compatible_output=True): 
    893         """ 
    894         Write membrane potential traces to file. 
    895  
    896         If compatible_output is True, the format is "v cell_id", 
    897         where cell_id is the index of the cell counting along rows and down 
    898         columns (and the extension of that for 3-D). 
    899         The timestep, first id, last id, and number of data points per cell are 
    900         written in a header, indicated by a '#' at the beginning of the line. 
    901  
    902         If compatible_output is False, the raw format produced by the simulator 
    903         is used. This may be faster, since it avoids any post-processing of the 
    904         voltage files. 
    905  
    906         For parallel simulators, if gather is True, all data will be gathered 
    907         to the master node and a single output file created there. Otherwise, a 
    908         file will be written on each node, containing only the cells simulated 
    909         on that node. 
    910         """ 
    911         self.recorders['v'].write(filename, gather, compatible_output) 
    912  
    913     def print_c(self, filename, gather=True, compatible_output=True): 
    914         """ 
    915         Write conductance traces to file. 
    916         If compatible_output is True, the format is "t g cell_id", 
    917         where cell_id is the index of the cell counting along rows and down 
    918         columns (and the extension of that for 3-D). 
    919         The timestep, first id, last id, and number of data points per cell are 
    920         written in a header, indicated by a '#' at the beginning of the line. 
    921  
    922         If compatible_output is False, the raw format produced by the simulator 
    923         is used. This may be faster, since it avoids any post-processing of the 
    924         voltage files. 
    925         """ 
    926         self.recorders['conductance'].write(filename, gather, compatible_output) 
    927  
    928687    def getSubPopulation(self, cell_list, label=None): 
    929688         
     
    940699        pop.positions   = pop.parent.positions[:,idx] 
    941700        return pop 
    942  
     701     
    943702 
    944703class Projection(common.Projection): 
  • branches/harmonize/src/neuron2/__init__.py

    r416 r418  
    272272        logging.debug(self.describe()) 
    273273     
    274     def __getitem__(self, addr): 
    275         """Return a representation of the cell with coordinates given by addr, 
    276            suitable for being passed to other methods that require a cell id. 
    277            Note that __getitem__ is called when using [] access, e.g. 
    278              p = Population(...) 
    279              p[2,3] is equivalent to p.__getitem__((2,3)). 
    280         """ 
    281         if isinstance(addr, int): 
    282             addr = (addr,) 
    283         if len(addr) == self.ndim: 
    284             id = self._all_ids[addr] 
    285         else: 
    286             raise common.InvalidDimensionsError, "Population has %d dimensions. Address was %s" % (self.ndim, str(addr)) 
    287         if addr != self.locate(id): 
    288             raise IndexError, 'Invalid cell address %s' % str(addr) 
    289         return id 
    290      
    291     def __iter__(self): 
    292         """Iterator over cell ids on the local node.""" 
    293         return iter(self._local_ids) 
    294  
    295     def __address_gen(self): 
    296         """ 
    297         Generator to produce an iterator over all cells on this node, 
    298         returning addresses. 
    299         """ 
    300         for i in self.__iter__(): 
    301             yield self.locate(i) 
    302  
    303     def addresses(self): 
    304         """Iterator over cell addresses.""" 
    305         return self.__address_gen() 
    306  
    307     def ids(self): 
    308         """Iterator over cell ids on the local node.""" 
    309         return self.__iter__() 
    310      
    311     def all(self): 
    312         """Iterator over cell ids on all nodes.""" 
    313         return self._all_ids.flat 
    314      
    315     def locate(self, id): 
    316         """Given an element id in a Population, return the coordinates. 
    317                e.g. for  4 6  , element 2 has coordinates (1,0) and value 7 
    318                          7 9 
    319         """ 
    320         id = id - self.first_id 
    321         if self.ndim == 3: 
    322             rows = self.dim[1]; cols = self.dim[2] 
    323             i = id/(rows*cols); remainder = id%(rows*cols) 
    324             j = remainder/cols; k = remainder%cols 
    325             coords = (i,j,k) 
    326         elif self.ndim == 2: 
    327             cols = self.dim[1] 
    328             i = id/cols; j = id%cols 
    329             coords = (i,j) 
    330         elif self.ndim == 1: 
    331             coords = (id,) 
    332         else: 
    333             raise common.InvalidDimensionsError 
    334         return coords 
    335  
    336     def index(self, n): 
    337         """Return the nth cell in the population (Indexing starts at 0).""" 
    338         if hasattr(n, '__len__'): 
    339             n = numpy.array(n) 
    340         return self._all_ids.flatten()[n] 
    341  
    342     def get(self, parameter_name, as_array=False): 
    343         """ 
    344         Get the values of a parameter for every cell in the population. 
    345         """ 
    346         values = [getattr(cell, parameter_name) for cell in self] 
    347         if as_array: 
    348             values = numpy.array(values).reshape(self.dim) 
    349         return values 
    350  
    351     def set(self, param, val=None): 
    352         """ 
    353         Set one or more parameters for every cell in the population. param 
    354         can be a dict, in which case val should not be supplied, or a string 
    355         giving the parameter name, in which case val is the parameter value. 
    356         val can be a numeric value, or list of such (e.g. for setting spike times). 
    357         e.g. p.set("tau_m",20.0). 
    358              p.set({'tau_m':20,'v_rest':-65}) 
    359         """ 
    360         if isinstance(param, str): 
    361             if isinstance(val, (str, float, int)): 
    362                 param_dict = {param: float(val)} 
    363             elif isinstance(val, (list, numpy.ndarray)): 
    364                 param_dict = {param: val} 
    365             else: 
    366                 raise common.InvalidParameterValueError 
    367         elif isinstance(param, dict): 
    368             param_dict = param 
    369         else: 
    370             raise common.InvalidParameterValueError 
    371         logging.info("%s.set(%s)", self.label, param_dict) 
    372         for cell in self: 
    373             cell.set_parameters(**param_dict) 
    374      
    375274    def tset(self, parametername, value_array): 
    376275        """ 
     
    420319            setattr(cell, parametername, val) 
    421320 
    422     def randomInit(self, rand_distr): 
    423         """ 
    424         Set initial membrane potentials for all the cells in the population to 
    425         random values. 
    426         """ 
    427         self.rset('v_init', rand_distr) 
    428  
    429     def __record(self, record_what, record_from=None, rng=None): 
     321    def _record(self, record_what, record_from=None, rng=None, to_file=False): 
    430322        """ 
    431323        Private method called by record() and record_v(). 
    432324        """ 
     325        # `to_file` is not used, but is there for compatibility with other modules 
    433326        fixed_list=False 
    434327        if isinstance(record_from, list): #record from the fixed list specified by user 
     
    450343        logging.info("%s.record('%s', %s)", self.label, record_what, record_from[:5]) 
    451344        self.recorders[record_what].record(record_from) 
    452  
    453     def record(self, record_from=None, rng=None): 
    454         """ 
    455         If record_from is not given, record spikes from all cells in the Population. 
    456         record_from can be an integer - the number of cells to record from, chosen 
    457         at random (in this case a random number generator can also be supplied) 
    458         - or a list containing the ids of the cells to record. 
    459         """ 
    460         self.__record('spikes', record_from, rng) 
    461  
    462     def record_v(self, record_from=None, rng=None): 
    463         """ 
    464         If record_from is not given, record the membrane potential for all cells in 
    465         the Population. 
    466         record_from can be an integer - the number of cells to record from, chosen 
    467         at random (in this case a random number generator can also be supplied) 
    468         - or a list containing the ids of the cells to record. 
    469         """ 
    470         self.__record('v', record_from, rng) 
    471  
    472     def printSpikes(self, filename, gather=True, compatible_output=True): 
    473         """ 
    474         Write spike times to file. 
    475  
    476         If compatible_output is True, the format is "spiketime cell_id", 
    477         where cell_id is the index of the cell counting along rows and down 
    478         columns (and the extension of that for 3-D). 
    479         This allows easy plotting of a `raster' plot of spiketimes, with one 
    480         line for each cell. 
    481         The timestep, first id, last id, and number of data points per cell are 
    482         written in a header, indicated by a '#' at the beginning of the line. 
    483  
    484         If compatible_output is False, the raw format produced by the simulator 
    485         is used. This may be faster, since it avoids any post-processing of the 
    486         spike files. 
    487  
    488         For parallel simulators, if gather is True, all data will be gathered 
    489         to the master node and a single output file created there. Otherwise, a 
    490         file will be written on each node, containing only the cells simulated 
    491         on that node. 
    492         """ 
    493         self.recorders['spikes'].write(filename, gather, compatible_output) 
    494  
    495     def print_v(self, filename, gather=True, compatible_output=True): 
    496         """ 
    497         Write membrane potential traces to file. 
    498  
    499         If compatible_output is True, the format is "v cell_id", 
    500         where cell_id is the index of the cell counting along rows and down 
    501         columns (and the extension of that for 3-D). 
    502         The timestep, first id, last id, and number of data points per cell are 
    503         written in a header, indicated by a '#' at the beginning of the line. 
    504  
    505         If compatible_output is False, the raw format produced by the simulator 
    506         is used. This may be faster, since it avoids any post-processing of the 
    507         voltage files. 
    508  
    509         For parallel simulators, if gather is True, all data will be gathered 
    510         to the master node and a single output file created there. Otherwise, a 
    511         file will be written on each node, containing only the cells simulated 
    512         on that node. 
    513         """ 
    514         self.recorders['v'].write(filename, gather, compatible_output) 
    515  
    516     def getSpikes(self, gather=True): 
    517         """ 
    518         Return a 2-column numpy array containing cell ids and spike times for 
    519         recorded cells. 
    520         """ 
    521         return self.recorders['spikes'].get(gather) 
    522  
    523     def get_v(self, gather=True): 
    524         """ 
    525         Return a 2-column numpy array containing cell ids and spike times for 
    526         recorded cells. 
    527         """ 
    528         return self.recorders['v'].get(gather) 
    529345 
    530346    def meanSpikeCount(self, gather=True): 
  • branches/harmonize/test/unittests/nest2tests.py

    r410 r418  
    2626 
    2727def arrays_almost_equal(a, b, threshold): 
     28    assert a.shape == b.shape, 'Shape mismatch: %s, %s' % (a.shape, b.shape) 
    2829    return (abs(a-b) < threshold).all() 
    2930 
     
    343344        self.net.rset('cm',rd1) 
    344345        output_values = self.net.get('cm', as_array=True) 
    345         input_values = rd2.next(9) 
     346        input_values = rd2.next(9).reshape(self.net.dim) 
    346347        self.assert_( arrays_almost_equal(input_values, output_values, 1e-6), 
    347348                     "%s != %s" % (input_values, output_values) ) 
     
    541542            for src,tgt in prj.connections(): 
    542543                weights_out.append(0.001*get_weight(src, tgt)) # units conversion 
    543             self.assert_(arrays_almost_equal(weights_in, weights_out, 1e-8), "%s != %s" % (weights_in, weights_out)) 
     544            self.assert_(arrays_almost_equal(numpy.array(weights_in), numpy.array(weights_out), 1e-8), "%s != %s" % (weights_in, weights_out)) 
    544545             
    545546    def testRandomizeWeights(self):