Changeset 76

Show
Ignore:
Timestamp:
05/24/07 11:49:19 (1 year ago)
Author:
apdavison
Message:

Merged trunk changes r54:75 into pyNN-0.3 branch

Files:

Legend:

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

    r54 r76  
    4343 
    4444    def set(self,param,val=None): 
    45         pass 
     45        raise Exception("Not yet implemented") 
    4646     
    4747    def get(self,param): 
    48         pass 
     48        raise Exception("Not yet implemented") 
    4949 
    5050    def setCellClass(self, cellclass): 
     
    9797                        raise InvalidParameterValueError, (type(supplied_parameters[k]), type(default_parameters[k])) 
    9898                else: 
    99                     raise NonExistentParameterError 
     99                    raise NonExistentParameterError(k) 
    100100        return parameters 
    101101 
     
    273273        self.dim      = dims 
    274274        if isinstance(dims, int): # also allow a single integer, for a 1D population 
    275             print "Converting integer dims to tuple" 
     275            #print "Converting integer dims to tuple" 
    276276            self.dim = (self.dim,) 
    277277        self.label    = label 
     
    352352        record_from can be an integer - the number of cells to record from, chosen 
    353353        at random (in this case a random number generator can also be supplied) 
    354         - or a list containing the ids (e.g., (i,j,k) tuple for a 3D population) 
    355         of the cells to record. 
     354        - or a list containing the ids of the cells to record. 
    356355        """ 
    357356        pass 
     
    367366        pass 
    368367 
    369     def printSpikes(self,filename,gather=True, compatible_output=True): 
     368    def printSpikes(self,filename,gather=True,compatible_output=True): 
    370369        """ 
    371370        Writes spike times to file. 
     
    556555        """ 
    557556        Read connections from a list of tuples, 
    558         containing ['src[x,y]', 'tgt[x,y]', 'weight', 'delay'] 
     557        containing [pre_addr, post_addr, weight, delay] 
     558        where pre_addr and post_addr are both neuron addresses, i.e. tuples or 
     559        lists containing the neuron array coordinates. 
    559560        """ 
    560561        # Need to implement parameter parsing here... 
     
    566567        """ 
    567568        w can be a single number, in which case all weights are set to this 
    568         value, or an array with the same dimensions as the Projection array. 
     569        value, or a list/1D array of length equal to the number of connections 
     570        in the population. 
     571        Weights should be in nA for current-based and µS for conductance-based 
     572        synapses. 
    569573        """ 
    570574        pass 
     
    582586        """ 
    583587        d can be a single number, in which case all delays are set to this 
    584         value, or an array with the same dimensions as the Projection array. 
     588        value, or a list/1D array of length equal to the number of connections 
     589        in the population. 
    585590        """ 
    586591        pass 
  • branches/0.3/doc/highlevelapi.txt

    r28 r76  
    22Populations and Projections 
    33=========================== 
     4 
     5While it is entirely possible to create very large networks using only the ``create()``, ``connect()``, ``set()`` and ``record()`` functions, this involves writing a lot of repetitive code, which is the same or similar for every model: iterating over lists of cells and connections, creating common projection patterns, recording from all or a subset of neurons... 
     6This sort of 'book-keeping' code takes time to write, obscures the essential principles of the simulation script with details, and, of course, the more code that has to be written, the more bugs and errors will be introduced, and, if the code is only used for a single project, not all the bugs may be found. 
     7 
     8For these reasons, PyNN provides the ``Population`` object, representing a group of neurons all of the same type (although possibly with cell-to-cell variations in the values of parameters), and the ``Projection`` object, repesenting the set of connections between two ``Population``\s. 
     9All the book-keeping code is contained within the object classes, which also provide functions ('methods') to perform commonly-used tasks, such as recording from a fixed number of cells within the population, chosen at random. 
     10 
     11By using the ``Population`` and ``Projection`` classes, less code needs to be written to create a given simulation, which means fewer-bugs and easier-to-understand scripts, plus because the code for the classes is used in many different projects, bugs will be found more reliably, and the internal implementation of the classes optimized for performance. 
     12Of particular importance is iterations over large numbers of cells or connections can be done in fast compiled code (within the simulator engines) rather than in comparatively slow Python code. 
     13 
     14 
     15Creating ``Population``\s 
     16========================= 
     17 
     18Some examples of creating a population of neurons (don't forget to call ``setup()`` first). 
     19 
     20This creates a 10 x 10 array of ``IF_curr_exp`` neurons with default parameters:: 
     21 
     22    >>> p1 = Population((10,10), IF_curr_exp) 
     23 
     24This creates a 1D array of 100 spike sources, and gives it a label:: 
     25 
     26    >>> p2 = Population(100, SpikeSourceArray, label="Input Population") 
     27 
     28This illustrates all the possible arguments of the ``Population`` constructor, with argument names. 
     29It creates a 3D array of ``IF_cond_alpha`` neurons, all with a spike threshold set to -55 mV and membrane time constant set to 10 ms:: 
     30 
     31    >>> p3 = Population(dims=(3,4,5), cellclass=IF_cond_alpha, 
     32    ...                 cellparams={'v_thresh': -55.0, 'tau_m': 10.0}, 
     33    ...                 label="Column 1") 
     34                         
     35The population dimensions can be retrieved using the ``dim`` attribute, e.g.:: 
     36 
     37    >>> p1.dim 
     38    (10, 10) 
     39    >>> p2.dim 
     40    (100,) 
     41    >>> p3.dim 
     42    (3, 4, 5) 
     43     
     44While the total number of neurons in a population can be obtained with the Python ``len()`` function:: 
     45 
     46    >>> print len(p1), len(p2), len(p3) 
     47    100 100 60 
     48     
     49The above examples all use PyNN standard cell models. It is also possible to use simulator-specific models, but in this case the ``cellclass`` should be given as a string, e.g.:: 
     50 
     51    >>> p4 = Population(20, 'iaf_neuron', cellparams={'Tau': 15.0, 'C': 0.001}) 
     52     
     53This example will work with NEST but not with NEURON or PCSIM. 
     54                         
     55Addressing individual neurons 
     56============================= 
     57 
     58To address individual neurons in a population, use ``[]`` notation, e.g.,:: 
     59 
     60    >>> p1[0,0] 
     61    1 
     62    >>> p1[9,9] 
     63    100 
     64    >>> p2[67] 
     65    168 
     66    >>> p3[2,1,0] 
     67    246 
     68     
     69The actual return values depend on the simulator engine used, and may be integers, strings, or Python objects. 
     70The n-tuple of values within the square brackets is referred to as a neurons's *address*, while the return value is its *id*. 
     71Trying to address a non-existent neuron will raise an Exception:: 
     72 
     73    >>> p1[999,0] 
     74    Traceback (most recent call last): 
     75      File "<stdin>", line 1, in ? 
     76      File "/usr/lib/python/site-packages/pyNN/nest.py", line 457, in __getitem__ 
     77        id = self.cell[addr] 
     78    IndexError: index (999) out of range (0<=index<=10) in dimension 0 
     79 
     80as will giving the wrong number of dimensions in the address. 
     81It is equally possible to define the address as a tuple, and then pass the tuple within the square brackets, e.g.:: 
     82 
     83    >>> p1[5,5] 
     84    56 
     85    >>> address = (5,5) 
     86    >>> p1[address] 
     87    56 
     88     
     89Neuron addresses are used in setting parameter values, and in specifying which neurons to record from. 
     90They may also be used together with the low-level ``connect()``, ``set()``, and ``record()`` functions. 
     91They may also be used to specify a position in space, e.g.:: 
     92 
     93    >>> p1[5,5].setPosition((0.0, 0.1)) 
     94    >>> p1[5,5].getPosition() 
     95    (0.0, 0.10000000000000001) 
     96 
     97Setting parameter values 
     98======================== 
     99 
     100Setting the same value for the entire population 
     101------------------------------------------------ 
     102 
     103To set a parameter for all neurons in the population to the same value, use the ``set()`` method, e.g.:: 
     104 
     105    >>> p1.set("tau_m", 20.0) 
     106    >>> p1.set({'tau_m':20, 'v_rest':-65}) 
     107     
     108The first form can be used for setting a single parameter, the second form for setting multiple parameters at once. 
     109 
     110Setting random values 
     111--------------------- 
     112 
     113To set a parameter to values drawn from a random distribution, use the ``rset()`` method with a ``RandomDistribution`` object from the ``pyNN.random`` module (see the chapter on random numbers for more details). 
     114The following example sets the initial membrane potential of each neuron to a value drawn from a uniform distribution between -70 mV and -55 mV:: 
     115 
     116    >>> from pyNN.random import RandomDistribution 
     117    >>> vinit_distr = RandomDistribution(distribution='uniform',parameters=[-70,-55]) 
     118    >>> p1.rset('v_init', vinit_distr) 
     119 
     120For the specific case of setting the initial membrane potential, there is a convenience method ``randomInit()``, e.g.:: 
     121 
     122    >>> p1.randomInit(vinit_distr) 
     123 
     124Setting values according to an array 
     125------------------------------------ 
     126 
     127The most efficient way to set different (but non-random) values for different neurons is to use the ``tset()`` (for *topographic* set) method. 
     128The following example injects a current of 0.1 nA into the first column of neurons in the population:: 
     129 
     130    >>> import numpy 
     131    >>> current_input = numpy.zeros(p1.dim) 
     132    >>> current_input[:,0] = 0.1 
     133    >>> p1.tset('i_offset', current_input) 
     134 
     135Setting parameter values for individual neurons 
     136----------------------------------------------- 
     137 
     138To set the parameters of an individual neuron, you can use the low-level ``set()`` function,:: 
     139 
     140    >>> set(p1[3,3], IF_curr_exp, 'tau_m', 12.0) 
     141     
     142or you can use the set method of the ''ID'' object that the ``neuron``, ``nest`` and ``pcsim`` (but not ``oldneuron``) modules return as neuron ids:: 
     143 
     144    >>> p1[3,3].set('tau_m', 12.0) 
     145     
     146Recording 
     147========= 
     148 
     149Recording spike times is done with the method ``record()``. 
     150Recording membrane potential is done with the method ``record_v()``. 
     151Both methods have identical argument lists. 
     152Some examples:: 
     153 
     154    >>> p1.record()                            # record from all neurons in the population 
     155    >>> p1.record(10)                          # record from 10 neurons chosen at random 
     156    >>> p1.record([p1[0,0], p1[0,1], p1[0,2]]) # record from specific neurons 
     157 
     158Writing the recorded values to file is done with a second pair of methods, ``printSpikes()`` and ``print_v()``, e.g.:: 
     159 
     160    >>> p1.printSpikes("spikefile.dat") 
     161 
     162By default, the output files are post-processed to reformat them from the native simulator format to a common format that is the same for all simulator engines. 
     163This facilitates comparisons across simulators, but of course has some performace penalty. 
     164To get output in the native format of the simulator, add ``compatible_output=False`` to the argument list. 
     165 
     166When running a distributed simulation, each node records only those neurons that it simulates. 
     167By default, at the end of the simulation all nodes send their recorded data to the master node so that all values are written to a single output file. 
     168Again, there is a performance penalty for this, so if you wish each node to write its own file, add ``gather=False`` to the argument list. 
     169 
     170Statistics 
     171========== 
     172 
     173Often, the exact spike times and exact membrane potential traces are not required, only statistical measures. 
     174PyNN currently only provides one such measure, the mean number of spikes per neuron, e.g.:: 
     175 
     176    >>> p1.meanSpikeCount() 
     177    0.0 
     178     
     179More such statistical measures are planned for future releases. 
     180 
     181 
     182Connecting two ``Population``\s with a ``Projection`` 
     183===================================================== 
     184 
     185A ``Projection`` object is a container for all the synaptic connections between neurons in two ``Population``\s, together with methods for setting synaptic weights and delays. 
     186A ``Projection`` is created by specifying a pre-synaptic ``Population``, a post-synaptic ``Population`` and a 'wiring' method, e.g.:: 
     187 
     188    >>> prj2_1 = Projection(p2, p1, method='allToAll') 
     189     
     190This connects ``p2`` (pre-synaptic) to ``p1`` (post-synaptic), using the '``allToAll``' connection method, which connects every neuron in the pre-synaptic population to every neuron in the post-synaptic population. 
     191The currently available connection or 'wiring' methods are explained below. 
     192 
     193All-to-all connections 
     194---------------------- 
     195 
     196The ``'allToAll'`` method has one optional argument ``allow_self_connections``, for use when connecting a ``Population`` to itself. 
     197By default it is ``True``, but if a neuron should not connect to itself, set it to ``False``, e.g.:: 
     198 
     199    >>> prj1_1 = Projection(p1, p1, method='allToAll', methodParameters={'allow_self_connections': False}) 
     200 
     201One-to-one connections 
     202---------------------- 
     203 
     204Use of the ``'oneToOne'`` method requires that the pre- and post-synaptic populations have the same dimensions, e.g.:: 
     205     
     206    >>> prj1_1a = Projection(p1, p1, method='oneToOne') 
     207     
     208Trying to connect two ``Population``\s with different dimensions will raise an Exception, e.g.:: 
     209 
     210    >>> invalid_prj = Projection(p2, p3, method='oneToOne') 
     211    Traceback (most recent call last): 
     212      File "<stdin>", line 1, in ? 
     213      File "/usr/lib/python/site-packages/pyNN/nest.py", line 839, in __init__ 
     214        self.nconn = connection_method(methodParameters) 
     215      File "/usr/lib/python/site-packages/pyNN/nest.py", line 920, in _oneToOne 
     216        raise "Method 'oneToOne' not yet implemented for the case where presynaptic and postsynaptic Populations have different sizes." 
     217    Exception: Method 'oneToOne' not yet implemented for the case where presynaptic and postsynaptic Populations have different sizes. 
     218     
     219     
     220Connecting neurons with a fixed probability 
     221------------------------------------------- 
     222 
     223With the ``'fixedProbability'`` method, each possible connection between all pre-synaptic neurons and all post-synaptic neurons is created with probability ``p_connect``, e.g.:: 
     224 
     225    >>> prj2_3 = Projection(p2, p3, 'fixedProbability', {'p_connect': 0.2}) 
     226     
     227The ``methodParams`` dictionary can also contain the ``allow_self_connections`` parameter, as above. 
     228 
     229Connecting neurons with a distance-dependent probability 
     230-------------------------------------------------------- 
     231 
     232For each pair of pre-post cells, the connection probability depends on distance. 
     233If positions in space have been specified using the ``setPosition()`` method of the ID class, these positions are used to calculate distances. 
     234If not, the neuron addresses, i.e., the array coordinates, are used. 
     235 
     236The ``methodParams`` dictionary should contain a string ``d_expression``, which should be the right-hand side of a valid python expression for probability (i.e. returning a value between 0 and 1), involving '``d``', e.g.:: 
     237 
     238    >>> prj1_1b = Projection(p1, p1, 'distanceDependentProbability', "exp(-abs(d))") 
     239    >>> prj3_3  = Projection(p3, p3, 'distanceDependentProbability', "float(d<3)") 
     240 
     241The first example connects neurons with an exponentially-decaying probability. 
     242The second example connects each neuron to all its neighbours within a range of 3 units (distance is in µm if positions have been specified, in array coordinate distance otherwise). 
     243 
     244Currently it is not possible to connect ``Population``\s which have different dimensionality. Trying to do this will raise an Exception:: 
     245 
     246    >>> prj3_1 = Projection(p3, p1, 'distanceDependentProbability', "exp(-(d*d)/4.0)") 
     247    Traceback (most recent call last): 
     248      File "<stdin>", line 1, in ? 
     249      File "/usr/lib/python/site-packages/pyNN/nest.py", line 839, in __init__ 
     250        self.nconn = connection_method(methodParameters) 
     251      File "/usr/lib/python/site-packages/pyNN/nest.py", line 988, in _distanceDependentProbability 
     252        dist = self._distance(self.pre, self.post, pre, post) 
     253      File "/usr/lib/python/site-packages/pyNN/nest.py", line 875, in _distance 
     254        raise Exception("Method _distance() not yet implemented for Populations with different sizes.") 
     255    Exception: Method _distance() not yet implemented for Populations with different sizes. 
     256 
     257but it is planned to change this in the next release. 
     258 
     259 
     260Divergent/fan-out connections 
     261----------------------------- 
     262 
     263The ``'fixedNumberPost'`` method connects each pre-synaptic neuron to exactly ``n`` post-synaptic neurons chosen at random, where ``n`` is an integer supplied in the ``methodParams`` dictionary, e.g.:: 
     264 
     265    >>> prj2_1a = Projection(p2, p1, 'fixedNumberPost', {'n': 30}) 
     266     
     267As a refinement to this, the number of post-synaptic neurons can be chosen at random from a ``RandomDistribution`` object, e.g.:: 
     268 
     269    >>> distr_npost = RandomDistribution(distribution='binomial', parameters=[100,0.3]) 
     270    >>> prj2_1b = Projection(p2, p1, 'fixedNumberPost', {'rand_distr': distr_npost}) 
     271     
     272(of course, the number of post-synaptic synapses is no longer exactly fixed, but it didn't seem worth defining a whole new method for it). 
     273 
     274 
     275Convergent/fan-in connections 
     276----------------------------- 
     277 
     278The ``'fixedNumberPre'`` method has the same arguments as ``'fixedNumberPost'``, but of course it connects each *post*-synaptic neuron to ``n`` *pre*-synaptic neurons, e.g.:: 
     279 
     280    >>> prj2_1c = Projection(p2, p1, 'fixedNumberPre', {'n': 5}) 
     281    >>> distr_npre = RandomDistribution(distribution='poisson', parameters=[5]) 
     282    >>> prj2_1d = Projection(p2, p1, 'fixedNumberPre', {'rand_distr': distr_npre}) 
     283 
     284 
     285Writing and reading connection patterns to/from a file 
     286------------------------------------------------------ 
     287 
     288Connection patterns can be written to a file using ``saveConnections()``, e.g.:: 
     289 
     290    >>> prj1_1a.saveConnections("prj1_1a.conn") 
     291     
     292These files can then be read back in to create a new ``Projection`` object by specifying the ``fromFile`` connection method, e.g.:: 
     293 
     294    >>> prj1_1c = Projection(p1, p1, 'fromFile', "prj1_1a.conn") 
     295 
     296Specifying a list of connections 
     297-------------------------------- 
     298 
     299Specific connection patterns not covered by the methods above can be obtained by specifying an explicit list of pre-synaptic and post-synaptic neuron addresses, with weights and delays. 
     300(Note that the weights and delays should be optional, but currently are not). Example:: 
     301 
     302    >>> conn_list = [ 
     303    ...   ((0,0), (0,0,0), 0.0, 0.1), 
     304    ...   ((0,0), (0,0,1), 0.0, 0.1), 
     305    ...   ((0,0), (0,0,2), 0.0, 0.1), 
     306    ...   ((0,1), (1,3,0), 0.0, 0.1) 
     307    ... ] 
     308    >>> prj1_3d = Projection(p1, p3, 'fromList', conn_list) 
     309 
     310 
     311User-defined connection algorithms 
     312---------------------------------- 
     313 
     314If you wish to use a specific connection/wiring algorithm not covered by the PyNN built-in ones, the only option currently is to construct a list of connections and use the ``'fromList'`` method. 
     315In  
     316 
     317Setting synaptic weights and delays 
     318=================================== 
     319 
     320To set the weights of all synaptic connections in a ``Projection`` to a single value, use the ``setWeights()`` method:: 
     321 
     322    >>> prj1_1.setWeights(0.2) 
     323     
     324[Note: synaptic weights in PyNN are in nA for current-based synapses and µS for conductance-based synapses)]. 
     325 
     326To set different weights to different values, use ``setWeights()`` with a list or 1D numpy array argument, where the length of the list/array is equal to the number of synapses, e.g.:: 
     327 
     328    >>> weight_list = 0.1*numpy.ones(len(prj2_1)) 
     329    >>> weight_list[0:5] = 0.2 
     330    >>> prj2_1.setWeights(weight_list) 
     331     
     332To set weights to random values, use the ``randomizeWeights()`` method:: 
     333 
     334    >>> weight_distr = RandomDistribution(distribution='gamma',parameters=[1,0.1]) 
     335    >>> prj1_1.randomizeWeights(weight_distr) 
     336     
     337Setting delays works similarly:: 
     338 
     339    >>> prj1_1.setDelays(0.6) 
     340    >>> delay_list = 0.3*numpy.ones(len(prj2_1)) 
     341    >>> delay_list[0:5] = 0.4 
     342    >>> prj2_1.setDelays(delay_list) 
     343    >>> delay_distr = RandomDistribution(distribution='gamma',parameters=[2,0.2]) 
     344    >>> prj1_1.randomizeDelays(delay_distr) 
     345 
     346Synaptic plasticity 
     347=================== 
     348 
     349The PyNN API supports setting parameters of spike-timing-dependent plasticity (STDP) models, but 
     350this has currently only been implemented for NEURON. 
     351 
     352Example 
     353======= 
     354 
     355There are several examples of networks built with the high-level API in the ``test`` directory. 
  • branches/0.3/doc/lowlevelapi.txt

    r48 r76  
    1212``setup()`` takes various optional arguments: setting the simulation timestep (there is currently no support in the API for variable timestep methods although native simulator code can be used to select this option where the simulator supports it), setting the minimum and maximum synaptic delays, and turning debugging output on and off, e.g.:: 
    1313 
    14     >>> setup(timestep=0.1, min_delay=0.1, max_delay=0.1, debug=False) 
     14    >>> setup(timestep=0.1, min_delay=0.1, max_delay=0.5, debug=False) 
    1515     
    1616Debugging information is written to a log file in the working directory. 
     
    3939    >>> create(IF_curr_alpha, n=10) 
    4040     
    41 The neurons we have created so far have all had default parameter values. 
    42 [How can we find out what these defaults are?] 
     41The neurons we have created so far have all had default parameter values,  
     42stored in the ``default_values`` of the standard cell class, e.g.:: 
     43 
     44    >>> IF_curr_alpha.default_parameters 
     45    {'tau_refrac': 0.0, 'tau_m': 20.0, 'i_offset': 0.0, 'cm': 1.0, 'v_init': -65.0, 
     46     'v_thresh': -50.0, 'v_rest': -65.0, 'tau_syn': 5.0, 'v_reset': -65.0} 
     47 
    4348To use different parameter values, use the ``paramDict`` argument, e.g.:: 
    4449 
     
    4853 
    4954    >>> create(IF_curr_alpha, paramDict={'foo': 15.0}) 
    50     [output to go here] 
     55    Traceback (most recent call last): 
     56      File "<stdin>", line 1, in ? 
     57      File "/usr/lib/python/site-packages/pyNN/nest.py", line 228, in create 
     58        celltype = cellclass(paramDict) 
     59      File "/usr/lib/python/site-packages/pyNN/nest.py", line 68, in __init__ 
     60        common.IF_curr_alpha.__init__(self,parameters) # checks supplied parameters and adds default 
     61      File "/usr/lib/python/site-packages/pyNN/common.py", line 113, in __init__ 
     62        self.parameters = self.checkParameters(parameters, with_defaults=True) 
     63      File "/usr/lib/python/site-packages/pyNN/common.py", line 99, in checkParameters 
     64        raise NonExistentParameterError(k) 
     65    NonExistentParameterError: foo 
    5166    >>> create(IF_curr_alpha, paramDict={'tau_m': 'bar'}) 
    52     [output to go here]. 
     67    Traceback (most recent call last): 
     68      File "/usr/lib/python/site-packages/pyNN/nest.py", line 228, in create 
     69        celltype = cellclass(paramDict) 
     70      File "/usr/lib/python/site-packages/pyNN/nest.py", line 68, in __init__ 
     71        common.IF_curr_alpha.__init__(self,parameters) # checks supplied parameters and adds default 
     72      File "/usr/lib/python/site-packages/pyNN/common.py", line 113, in __init__ 
     73        self.parameters = self.checkParameters(parameters, with_defaults=True) 
     74      File "/usr/lib/python/site-packages/pyNN/common.py", line 90, in checkParameters 
     75        raise InvalidParameterValueError, (type(supplied_parameters[k]), type(default_parameters[k])) 
     76    InvalidParameterValueError: (<type 'str'>, <type 'float'>) 
     77 
    5378     
    5479If you wish to do something with the cell after creating it: record from it, change a parameter, connect it to another cell, you should assign the return value of the function to a variable, e.g.:: 
     
    6489Any neuron that emits spikes can be connected to any neuron with at least one synapse using the ``connect()`` function, e.g.:: 
    6590 
    66     >>> spike_source = create(SpikeSourceArray, paramDict={'spiketimes': [10.0, 20.0, 30.0]}) 
    67     >>> cells = create(IF_curr_alpha, n=10) 
    68     >>> connect(spike_source, cells
     91    >>> spike_source = create(SpikeSourceArray, paramDict={'spike_times': [10.0, 20.0, 30.0]}) 
     92    >>> cell_list2 = create(IF_curr_exp, n=10) 
     93    >>> connect(spike_source, cell_list2
    6994     
    7095In this case we connect a spike-generating mechanism (``SpikeSourceArray`` is a 'standard cell' model that emits spikes at times specified by the ``spiketimes`` parameter) to each cell in the list ``cells``, i.e. we create 10 connections at once. 
    7196For clarity, we could also have specified the argument names:: 
    7297 
    73     >>> connect(source=spike_source, target=cells
     98    >>> connect(source=spike_source, target=cell_list2
    7499     
    75100Either ``source``, or ``target``, or both may be individual cell ids or lists of ids. 
    76101In the latter case, each source (presynaptic) cell is connected to every target (postsynaptic) cell with probability given by the optional argument `p`, which defaults to 1, e.g.:: 
    77102 
     103    >>> source_list = cell_list 
     104    >>> target_list = cell_list2 
    78105    >>> connect(source_list, target_list, p=0.5) 
    79106     
    80107When specifying connections as above, default values are given to the synaptic weight and delay. 
    81 [These default values may be different for different simulators?] 
    82108These values are seldom very useful, and it is better to specify the ``weight`` and ``delay`` arguments of ``connect()``, e.g.:: 
    83109 
     
    86112At the moment, in fact, this is the only way to specify synaptic weights and connections in PyNN without using simulator-specific code. This deficiency will be addressed in a future release. 
    87113 
    88 Weights are specified in nA for 'current-based' synapses or µS for 'conductance-based' synapses. 
     114Weights are specified in nA for 'current-based' synapses or µS for 'conductance-based' synapses. 
    89115Delays are in ms. 
    90116For current-based synapses, weights should be negative for inhibitory synapses. 
     
    102128The parameters for individual neurons and post-synaptic mechanisms may be changed after creation of the neuron using the ``set()`` function, e.g.:: 
    103129 
    104     >>> cells = create(IF_curr_exp, cellParams={'i_offset': 0.0}, n=10) 
    105     >>> set(cells[0:5], IF_curr_exp, param='i_offset', val=0.1) 
    106     >>> print cells[0].i_offset 
    107     0.1 
    108     >>> print cells[5].i_offset 
    109     0.0 
    110      
    111 [actually, the above print statements don't work. More work on ID class needed].     
    112  
     130    >>> cells = create(IF_curr_exp, paramDict={'v_init': -70.0}, n=10) 
     131    >>> set(cells[0:5], IF_curr_exp, param='v_init', val=-65.0) 
     132    >>> print cells[0].v_init 
     133    -65.0 
     134    >>> print cells[5].v_init 
     135    -70.0 
     136     
    113137It is unfortunately necessary to specify the neuron type as the second argument, since cell ids do not (currently, at least) hold information about the neuron type. 
    114138Individual parameters can be set using the ``param`` and ``val`` arguments, as above, or multiple parameters can be set at once by passing a dictionary of name:value pairs as the ``param`` argument, with ``val`` empty, e.g.:: 
    115139 
    116     >>> set(cells, IF_curr_exp, param={'tau_refrac': 2.0, 'tau_syn': 5.0}) 
     140    >>> set(cells, IF_curr_exp, param={'tau_refrac': 2.0, 'tau_syn_E': 5.0}) 
    117141     
    118142An alternative way to set parameter values is to call the ``set()`` method of the cell ID objects, e.g.:: 
    119143 
    120144    >>> cells[0].set('v_reset', -70.0) 
    121     >>> cells[1].set({'tau_refrac': 2.0, 'tau_syn': 5.0}) 
     145    >>> cells[1].set({'tau_refrac': 2.0, 'tau_syn_E': 5.0}) 
    122146 
    123147Recording spikes and membrane potential 
  • branches/0.3/doc/wikidoc.py

    r5 r76  
    2424#-- Define global data --------------------------------------------------------- 
    2525 
    26 exclude = ['__module__','__doc__','__builtins__','__file__','__class__', 
    27                 '__delattr__', '__dict__', '__getattribute__', '__hash__', 
    28                 '__new__','__reduce__','__reduce_ex__','__repr__','__setattr__', 
    29                 '__str__','__weakref__',] 
     26exclude = set(['__module__','__doc__','__builtins__','__file__','__class__', 
     27               '__delattr__', '__dict__', '__getattribute__', '__hash__', 
     28               '__new__','__reduce__','__reduce_ex__','__repr__','__setattr__', 
     29               '__str__','__weakref__',] + dir(int) 
     30             ) 
    3031#               'time','types','copy',] 
     32exclude.remove('__init__') 
    3133 
    3234leftquote = re.compile(r"'\b") 
    3335leftdblquote = re.compile(r'"\b') 
     36camelcase = re.compile(r'(\b([A-Z][a-z]+){2,99})') 
    3437 
    3538classes = {} 
    3639functions = [] 
    3740data = [] 
    38  
    39 default_arg_fmt  = {'wiki'  : '%s<span style="color:grey;">=%s</span>', 
    40                     'latex' : '%s{\\color{grey}=%s}'} 
    41 func_sig_fmt     = {'wiki'  : '%s(<span style="font-weight:normal;">%s</span>)', 
    42                     'latex' : '%s(\\mdseries %s)'} 
    43 function_fmt     = {'wiki'  : '\n====<span style="color:#0066ff;">%s</span>====\n', 
    44                     'latex' : '\n\\paragraph*{\\color{brightblue}{%s}}\n'} 
    45 method_fmt       = {'wiki'  : '\n====<span style="color:#8888ff;">%s</span>====\n', 
    46                     'latex' : '\n\\paragraph*{\\color{brightblue}{%s}}\n'} 
    47 staticmethod_fmt = {'wiki'  : '\n====<span style="color:#0066ff;">%s</span> (static)====\n', 
    48                     'latex' : '\n\\paragraph*{\\color{brightblue}{%s} (static)}\n'} 
    49 dict_fmt         = {'wiki'  : "\n\n'''%s''' = {\n", 
    50                     'latex' : '\n\\textbf{%s} = $\\lbrace$\n\n'} 
    51 dict_fmt_end     = {'wiki'  : '}\n', 
    52                     'latex' : '$\\rbrace$\n'} 
    53 data_element_fmt = {'wiki'  : "\n'''%s''' = %s\n", 
    54                     'latex' : "\n\\textbf{%s} = %s\n"} 
    55 table_begin      = {'wiki'  : "{|\n", 
    56                     'latex' : "\\begin{tabular}{lll}\n"} 
    57 table_end        = {'wiki'  : "|}\n", 
    58                     'latex' : "\\end{tabular}\n"} 
    59 table_row_fmt    = {'wiki'  : "| &nbsp;&nbsp;&nbsp; || %s ||: %s\n|-\n", 
    60                     'latex' : '& %s & :%s\\\\\n'} 
    61 category_fmt     = {'wiki'  : '\n==%s==\n', 
    62                     'latex' : '\n\\subsection{%s}\n'} 
    63 class_fmt        = {'wiki'  : '\n===<span style="color:green">%s</span>===\n', 
    64                     'latex' : '\n\\subsubsection*{%s}\n'} 
    65 horiz_line       = {'wiki'  : '\n----\n', 
    66                     'latex' : ''} 
    6741 
    6842#-- Process command line parameters -------------------------------------------- 
     
    7246    output = 'wiki' 
    7347logging.info('Generating API documentation in %s format' % output) 
     48 
     49#-- Define templates ----------------------------------------------------------- 
     50if output == 'wiki': 
     51    default_arg_fmt  = '%s<span style="color:grey;">=%s</span>' 
     52    func_sig_fmt     = '%s(<span style="font-weight:normal;">%s</span>)' 
     53    function_fmt     = '\n====<span style="color:#0066ff;">%s</span>====\n' 
     54    method_fmt       = '\n====<span style="color:#8888ff;">%s</span>====\n' 
     55    staticmethod_fmt = '\n====<span style="color:#0066ff;">%s</span> (static)====\n' 
     56    dict_fmt         = "\n\n'''%s''' = {\n" 
     57    dict_fmt_end     = '}\n' 
     58    data_element_fmt = "\n'''%s''' = %s\n" 
     59    table_begin      = "{|\n" 
     60    table_end        = "|}\n" 
     61    table_row_fmt    = "| &nbsp;&nbsp;&nbsp; || %s ||: %s\n|-\n" 
     62    category_fmt     = '\n==%s==\n' 
     63    class_fmt        = '\n===<span style="color:green">%s</span>===\n' 
     64    horiz_line       = '\n----\n' 
     65elif output == 'trac': 
     66    default_arg_fmt  = '%s=%s' 
     67    func_sig_fmt     = '%s(%s)' 
     68    function_fmt     = '\n=== %s ===\n' 
     69    method_fmt       = '\n=== %s ===\n' 
     70    staticmethod_fmt = '\n=== %s ===\n' 
     71    dict_fmt         = "\n\n'''%s''' = {\n" 
     72    dict_fmt_end     = '}\n' 
     73    data_element_fmt = "\n'''%s''' = %s\n" 
     74    table_begin      = "\n" 
     75    table_end        = "\n" 
     76    table_row_fmt    = "|| %s ||: %s ||\n" 
     77    category_fmt     = '\n= %s =\n' 
     78    class_fmt        = '\n== %s ==\n' 
     79    horiz_line       = '\n----\n' 
     80elif output == 'latex': 
     81    default_arg_fmt  = '%s{\\color{grey}=%s}' 
     82    func_sig_fmt     = '%s(\\mdseries %s)' 
     83    function_fmt     = '\n\\paragraph*{\\color{brightblue}{%s}}\n' 
     84    method_fmt       = '\n\\paragraph*{\\color{brightblue}{%s}}\n' 
     85    staticmethod_fmt = '\n\\paragraph*{\\color{brightblue}{%s} (static)}\n' 
     86    dict_fmt         = '\n\\textbf{%s} = $\\lbrace$\n\n' 
     87    dict_fmt_end     = '$\\rbrace$\n' 
     88    data_element_fmt = "\n\\textbf{%s} = %s\n" 
     89    table_begin      = "\\begin{tabular}{lll}\n" 
     90    table_end        = "\\end{tabular}\n" 
     91    table_row_fmt    = '& %s & :%s\\\\\n' 
     92    category_fmt     = '\n\\subsection{%s}\n' 
     93    class_fmt        = '\n\\subsubsection*{%s}\n' 
     94    horiz_line       = '' 
    7495              
    7596#-- Define functions ----------------------------------------------------------- 
     
    122143                    # anonymous arguments 
    123144                    arg = '(...)' 
    124                 args[i] = default_arg_fmt[output] % (arg,r) 
     145                args[i] = default_arg_fmt % (arg,r) 
    125146                i = i + 1 
    126147        if code.co_flags & 0x0004: # CO_VARARGS 
     
    130151            args.append('**'+code.co_varnames[callargs]) 
    131152            callargs = callargs + 1 
    132         return func_sig_fmt[output] % (fname,string.join(args,', ')) 
     153        return func_sig_fmt % (fname,string.join(args,', ')) 
    133154    except AttributeError: 
    134155        logging.warning("%s has no attribute 'func_code'" % func) 
     
    147168            classes[entry] = { 'methods': [], 'data': [], 'staticmethods': [] } 
    148169            for classentry in dir(instance): 
    149                 if classentry not in exclude: 
     170                if classentry not in exclude and (classentry[0] != '_' or classentry[0:2] == '__'): # don't include private methods 
    150171                    classentry_type = type(eval('pyNN.common.%s.%s' % (entry,classentry))) 
    151172                    logging.info('    %-28s %s' % (classentry,classentry_type)) 
     
    175196 
    176197logging.info("==== DATA ====") 
    177 outputStr += category_fmt[output] % "Data" 
     198outputStr += category_fmt % "Data" 
    178199for element in data: 
    179200    instance = eval('pyNN.common.%s' % element) 
    180201    if type(instance) == types.DictType: 
    181         outputStr += dict_fmt[output] % element 
    182         outputStr += table_begin[output] 
     202        outputStr += dict_fmt % element 
     203        outputStr += table_begin 
    183204        for k,v in instance.items(): 
    184205            if output == 'latex': 
    185206                v = str(v).replace('{',' $\\lbrace$').replace('}',' $\\rbrace$') 
    186             outputStr += table_row_fmt[output] % (k,v) 
    187         outputStr += table_end[output] 
    188         outputStr += dict_fmt_end[output] 
     207            outputStr += table_row_fmt % (k,v) 
     208        outputStr += table_end 
     209        outputStr += dict_fmt_end 
    189210    else: 
    190         outputStr +=  data_element_fmt[output] % (element, instance) 
     211        outputStr +=  data_element_fmt % (element, instance) 
    191212     
    192213logging.info("==== FUNCTIONS ====") 
    193 outputStr += category_fmt[output] % "Functions" 
     214outputStr += category_fmt % "Functions" 
    194215for funcname in functions: 
    195216    funcinst = eval('pyNN.common.%s' % funcname) 
    196     outputStr += function_fmt[output] % func_sig(funcinst) 
     217    outputStr += function_fmt % func_sig(funcinst) 
    197218    if funcinst.__doc__: 
    198219        outputStr += _(funcinst.__doc__.strip()) 
     
    217238 
    218239# Now iterate through the classes 
    219 outputStr += category_fmt[output] % "Classes" 
     240outputStr += category_fmt % "Classes" 
    220241for classes in [celltype_classes, other_classes, error_classes]: 
    221242    classlist = classes.keys() 
    222243    classlist.sort() 
    223244    for classname in classlist: 
    224         outputStr += class_fmt[output] % classname 
     245        outputStr += class_fmt % classname 
    225246        docstr = eval('pyNN.common.%s.__doc__' % classname) 
    226247        if docstr: 
     
    230251            fs = func_sig(methodinst) 
    231252            if fs: 
    232                 outputStr += method_fmt[output] % fs 
     253                outputStr += method_fmt % fs 
    233254                if methodinst.__doc__: 
    234255                    outputStr += _(methodinst.__doc__.strip()) 
     
    237258            fs = func_sig(methodinst) 
    238259            if fs: 
    239                 outputStr += staticmethod_fmt[output] % fs 
     260                outputStr += staticmethod_fmt % fs 
    240261                if methodinst.__doc__: 
    241262                    outputStr += _(methodinst.__doc__.strip()) 
     
    243264            instance = eval('pyNN.common.%s.%s' % (classname,element)) 
    244265            if type(instance) == types.DictType: 
    245                 outputStr += dict_fmt[output] % element 
     266                outputStr += dict_fmt % element 
    246267                if len(instance) > 0: 
    247                     outputStr += table_begin[output] 
     268                    outputStr += table_begin 
    248269                    for k,v in instance.items(): 
    249270                        if output == 'latex': 
    250271                            v = str(v).replace('{',' $\\lbrace$').replace('}',' $\\rbrace$') 
    251                             outputStr += table_row_fmt[output] % (k,v) 
     272                            outputStr += table_row_fmt % (k,v) 
    252273                        elif output == 'wiki': 
    253                             outputStr += table_row_fmt[output] % ('&quot;%s&quot;' % k,v) 
    254                     outputStr += table_end[output] 
    255                 outputStr += dict_fmt_end[output] 
     274                            outputStr += table_row_fmt % ('&quot;%s&quot;' % k,v) 
     275                        elif output == 'trac': 
     276                            outputStr += table_row_fmt % ("'%s'" % k,v) 
     277                    outputStr += table_end 
     278                outputStr += dict_fmt_end 
    256279            else: 
    257                 outputStr +=  data_element_fmt[output] % (element, instance) 
     280                outputStr +=  data_element_fmt % (element, instance) 
    258281                 
    259         outputStr += horiz_line[output] 
     282        outputStr += horiz_line 
    260283     
    261284if output == 'latex': 
     
    265288    outputStr = leftquote.sub('`',outputStr) 
    266289    outputStr = leftdblquote.sub('``',outputStr) 
     290if output == 'trac': 
     291    outputStr = outputStr.replace('__','!__') 
     292    outputStr = camelcase.sub(r'!\1',outputStr) 
    267293 
    268294print outputStr 
  • branches/0.3/nest.py

    r54 r76  
    3434    """ 
    3535     
     36    def __getattr__(self,name): 
     37        """Note that this currently does not translate units.""" 
     38        translated_name = self._cellclass.translations[name][0] 
     39        return pynest.getDict([int(self)])[0][translated_name] 
     40     
    3641    def set(self,param,val=None): 
    3742        # We perform a call to the low-level function set() of the API. 
     
    4348            set(self,self._cellclass,param,val) 
    4449 
    45     #def get(self,param): 
    46     #    pynest.getDict(self)[param] 
    4750 
    4851# ============================================================================== 
     
    230233        celltype = cellclass(paramDict) 
    231234        cell_gids = pynest.create(celltype.nest_name,n) 
    232         cell_gids = [pynest.getGID(gid) for gid in cell_gids] 
     235        cell_gids = [ID(pynest.getGID(gid)) for gid in cell_gids] 
    233236        pynest.setDict(cell_gids,celltype.parameters) 
    234237    elif isinstance(cellclass, str):  # celltype is not a standard cell 
    235238        cell_gids = pynest.create(cellclass,n) 
    236         cell_gids = [pynest.getGID(gid) for gid in cell_gids] 
     239        cell_gids = [ID(pynest.getGID(gid)) for gid in cell_gids] 
    237240        if paramDict: 
    238241            pynest.setDict(cell_gids,paramDict) 
    239242    else: 
    240243        raise "Invalid cell type" 
     244    for id in cell_gids: 
     245        id.setCellClass(cellclass) 
    241246    if n == 1: 
    242247        return cell_gids[0] 
     
    257262    weight = weight*1000 # weights should be in nA or uS, but iaf_neuron uses pA and iaf_cond_neuron uses nS. 
    258263                         # Using convention in this way is not ideal. We should be able to look up the units used by each model somewhere. 
     264    if synapse_type == 'inhibitory' and weight > 0: 
     265        weight *= -1 
    259266    try: 
    260267        if type(source) != types.ListType and type(target) != types.ListType: 
     
    289296    if val: 
    290297        param = {param:val} 
    291     if type(cells) != types.ListType: 
     298    try: 
     299        i = cells[0] 
     300    except TypeError: 
    292301        cells = [cells] 
    293     if issubclass(cellclass, common.StandardCellType): 
    294         param = cellclass({}).translate(param) 
     302    if not isinstance(cellclass,str): 
     303        if issubclass(cellclass, common.StandardCellType): 
     304            param = cellclass({}).translate(param) 
     305        else: 
     306            raise TypeError, "cellclass must be a string or derived from commonStandardCellType" 
    295307    pynest.setDict(cells,param) 
    296308 
     
    335347    writing process, which is not the case for the moment""" 
    336348    tempfilename = "%s/%s" %(tempdir, filename) 
    337     pynest.sr('%s close' %tempfilename)  
     349    pynest.sr('%s close' %filename)  
    338350    if (compatible_output): 
    339351        # Here we postprocess the file to have effectively the 
     
    343355        result = open(filename,'w',100) 
    344356        g = open(tempfilename,'r',100) 
     357        # Writing # such that Population.printSpikes and this have same output format 
     358        result.write("# "+"\n") 
    345359        lines = g.readlines() 
    346360        g.close() 
     
    462476        return id 
    463477     
    464     def __getitems__(self,addrs): 
    465         """Returns the ids of neurons. Input should have format: 
    466         n = number of synapses; nd = number of dimensions 
    467         shape(addrs) == (n,nd) 
    468