Changeset 76
- Timestamp:
- 05/24/07 11:49:19 (1 year ago)
- Files:
-
- branches/0.3/common.py (modified) (8 diffs)
- branches/0.3/doc/README (copied) (copied from trunk/doc/README)
- branches/0.3/doc/highlevelapi.txt (modified) (1 diff)
- branches/0.3/doc/lowlevelapi.txt (modified) (6 diffs)
- branches/0.3/doc/testdocs.py (copied) (copied from trunk/doc/testdocs.py)
- branches/0.3/doc/wikidoc.py (modified) (11 diffs)
- branches/0.3/nest.py (modified) (30 diffs)
- branches/0.3/nest2.py (copied) (copied from trunk/nest2.py)
- branches/0.3/neuron.py (modified) (55 diffs)
- branches/0.3/oldneuron.py (modified) (5 diffs)
- branches/0.3/pcsim.py (modified) (23 diffs)
- branches/0.3/test/IF_cond_alpha.py (modified) (1 diff)
- branches/0.3/test/VAbenchmark2.py (deleted)
- branches/0.3/test/VAbenchmark2_graphs.py (deleted)
- branches/0.3/test/VAbenchmark_graphs.py (modified) (5 diffs)
- branches/0.3/test/VAbenchmarks.py (modified) (10 diffs)
- branches/0.3/test/checkAPI.py (modified) (2 diffs)
- branches/0.3/test/nest_test.py (deleted)
- branches/0.3/test/nesttests.py (modified) (3 diffs)
- branches/0.3/test/neurontests.py (modified) (4 diffs)
- branches/0.3/test/pcsimtests_lowlevel.py (copied) (copied from trunk/test/pcsimtests_lowlevel.py)
- branches/0.3/test/pcsimtests_population.py (copied) (copied from trunk/test/pcsimtests_population.py)
- branches/0.3/test/pyNNPcsimLowLevelTest.py (deleted)
- branches/0.3/test/pyNNPcsimPopulationTest.py (deleted)
- branches/0.3/utility.py (copied) (copied from trunk/utility.py)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
branches/0.3/common.py
r54 r76 43 43 44 44 def set(self,param,val=None): 45 pass45 raise Exception("Not yet implemented") 46 46 47 47 def get(self,param): 48 pass48 raise Exception("Not yet implemented") 49 49 50 50 def setCellClass(self, cellclass): … … 97 97 raise InvalidParameterValueError, (type(supplied_parameters[k]), type(default_parameters[k])) 98 98 else: 99 raise NonExistentParameterError 99 raise NonExistentParameterError(k) 100 100 return parameters 101 101 … … 273 273 self.dim = dims 274 274 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" 276 276 self.dim = (self.dim,) 277 277 self.label = label … … 352 352 record_from can be an integer - the number of cells to record from, chosen 353 353 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. 356 355 """ 357 356 pass … … 367 366 pass 368 367 369 def printSpikes(self,filename,gather=True, compatible_output=True):368 def printSpikes(self,filename,gather=True,compatible_output=True): 370 369 """ 371 370 Writes spike times to file. … … 556 555 """ 557 556 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. 559 560 """ 560 561 # Need to implement parameter parsing here... … … 566 567 """ 567 568 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. 569 573 """ 570 574 pass … … 582 586 """ 583 587 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. 585 590 """ 586 591 pass branches/0.3/doc/highlevelapi.txt
r28 r76 2 2 Populations and Projections 3 3 =========================== 4 5 While 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... 6 This 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 8 For 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. 9 All 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 11 By 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. 12 Of 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 15 Creating ``Population``\s 16 ========================= 17 18 Some examples of creating a population of neurons (don't forget to call ``setup()`` first). 19 20 This creates a 10 x 10 array of ``IF_curr_exp`` neurons with default parameters:: 21 22 >>> p1 = Population((10,10), IF_curr_exp) 23 24 This creates a 1D array of 100 spike sources, and gives it a label:: 25 26 >>> p2 = Population(100, SpikeSourceArray, label="Input Population") 27 28 This illustrates all the possible arguments of the ``Population`` constructor, with argument names. 29 It 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 35 The 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 44 While 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 49 The 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 53 This example will work with NEST but not with NEURON or PCSIM. 54 55 Addressing individual neurons 56 ============================= 57 58 To 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 69 The actual return values depend on the simulator engine used, and may be integers, strings, or Python objects. 70 The n-tuple of values within the square brackets is referred to as a neurons's *address*, while the return value is its *id*. 71 Trying 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 80 as will giving the wrong number of dimensions in the address. 81 It 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 89 Neuron addresses are used in setting parameter values, and in specifying which neurons to record from. 90 They may also be used together with the low-level ``connect()``, ``set()``, and ``record()`` functions. 91 They 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 97 Setting parameter values 98 ======================== 99 100 Setting the same value for the entire population 101 ------------------------------------------------ 102 103 To 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 108 The first form can be used for setting a single parameter, the second form for setting multiple parameters at once. 109 110 Setting random values 111 --------------------- 112 113 To 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). 114 The 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 120 For the specific case of setting the initial membrane potential, there is a convenience method ``randomInit()``, e.g.:: 121 122 >>> p1.randomInit(vinit_distr) 123 124 Setting values according to an array 125 ------------------------------------ 126 127 The most efficient way to set different (but non-random) values for different neurons is to use the ``tset()`` (for *topographic* set) method. 128 The 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 135 Setting parameter values for individual neurons 136 ----------------------------------------------- 137 138 To 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 142 or 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 146 Recording 147 ========= 148 149 Recording spike times is done with the method ``record()``. 150 Recording membrane potential is done with the method ``record_v()``. 151 Both methods have identical argument lists. 152 Some 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 158 Writing 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 162 By 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. 163 This facilitates comparisons across simulators, but of course has some performace penalty. 164 To get output in the native format of the simulator, add ``compatible_output=False`` to the argument list. 165 166 When running a distributed simulation, each node records only those neurons that it simulates. 167 By 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. 168 Again, 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 170 Statistics 171 ========== 172 173 Often, the exact spike times and exact membrane potential traces are not required, only statistical measures. 174 PyNN currently only provides one such measure, the mean number of spikes per neuron, e.g.:: 175 176 >>> p1.meanSpikeCount() 177 0.0 178 179 More such statistical measures are planned for future releases. 180 181 182 Connecting two ``Population``\s with a ``Projection`` 183 ===================================================== 184 185 A ``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. 186 A ``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 190 This 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. 191 The currently available connection or 'wiring' methods are explained below. 192 193 All-to-all connections 194 ---------------------- 195 196 The ``'allToAll'`` method has one optional argument ``allow_self_connections``, for use when connecting a ``Population`` to itself. 197 By 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 201 One-to-one connections 202 ---------------------- 203 204 Use 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 208 Trying 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 220 Connecting neurons with a fixed probability 221 ------------------------------------------- 222 223 With 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 227 The ``methodParams`` dictionary can also contain the ``allow_self_connections`` parameter, as above. 228 229 Connecting neurons with a distance-dependent probability 230 -------------------------------------------------------- 231 232 For each pair of pre-post cells, the connection probability depends on distance. 233 If positions in space have been specified using the ``setPosition()`` method of the ID class, these positions are used to calculate distances. 234 If not, the neuron addresses, i.e., the array coordinates, are used. 235 236 The ``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 241 The first example connects neurons with an exponentially-decaying probability. 242 The 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 244 Currently 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 257 but it is planned to change this in the next release. 258 259 260 Divergent/fan-out connections 261 ----------------------------- 262 263 The ``'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 267 As 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 275 Convergent/fan-in connections 276 ----------------------------- 277 278 The ``'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 285 Writing and reading connection patterns to/from a file 286 ------------------------------------------------------ 287 288 Connection patterns can be written to a file using ``saveConnections()``, e.g.:: 289 290 >>> prj1_1a.saveConnections("prj1_1a.conn") 291 292 These 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 296 Specifying a list of connections 297 -------------------------------- 298 299 Specific 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 311 User-defined connection algorithms 312 ---------------------------------- 313 314 If 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. 315 In 316 317 Setting synaptic weights and delays 318 =================================== 319 320 To 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 326 To 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 332 To 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 337 Setting 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 346 Synaptic plasticity 347 =================== 348 349 The PyNN API supports setting parameters of spike-timing-dependent plasticity (STDP) models, but 350 this has currently only been implemented for NEURON. 351 352 Example 353 ======= 354 355 There are several examples of networks built with the high-level API in the ``test`` directory. branches/0.3/doc/lowlevelapi.txt
r48 r76 12 12 ``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.:: 13 13 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) 15 15 16 16 Debugging information is written to a log file in the working directory. … … 39 39 >>> create(IF_curr_alpha, n=10) 40 40 41 The neurons we have created so far have all had default parameter values. 42 [How can we find out what these defaults are?] 41 The neurons we have created so far have all had default parameter values, 42 stored 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 43 48 To use different parameter values, use the ``paramDict`` argument, e.g.:: 44 49 … … 48 53 49 54 >>> 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 51 66 >>> 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 53 78 54 79 If 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.:: … … 64 89 Any neuron that emits spikes can be connected to any neuron with at least one synapse using the ``connect()`` function, e.g.:: 65 90 66 >>> spike_source = create(SpikeSourceArray, paramDict={'spike times': [10.0, 20.0, 30.0]})67 >>> cell s = create(IF_curr_alpha, n=10)68 >>> connect(spike_source, cell s)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) 69 94 70 95 In 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. 71 96 For clarity, we could also have specified the argument names:: 72 97 73 >>> connect(source=spike_source, target=cell s)98 >>> connect(source=spike_source, target=cell_list2) 74 99 75 100 Either ``source``, or ``target``, or both may be individual cell ids or lists of ids. 76 101 In 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.:: 77 102 103 >>> source_list = cell_list 104 >>> target_list = cell_list2 78 105 >>> connect(source_list, target_list, p=0.5) 79 106 80 107 When specifying connections as above, default values are given to the synaptic weight and delay. 81 [These default values may be different for different simulators?]82 108 These values are seldom very useful, and it is better to specify the ``weight`` and ``delay`` arguments of ``connect()``, e.g.:: 83 109 … … 86 112 At 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. 87 113 88 Weights are specified in nA for 'current-based' synapses or µS for 'conductance-based' synapses.114 Weights are specified in nA for 'current-based' synapses or µS for 'conductance-based' synapses. 89 115 Delays are in ms. 90 116 For current-based synapses, weights should be negative for inhibitory synapses. … … 102 128 The parameters for individual neurons and post-synaptic mechanisms may be changed after creation of the neuron using the ``set()`` function, e.g.:: 103 129 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 113 137 It 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. 114 138 Individual 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.:: 115 139 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}) 117 141 118 142 An alternative way to set parameter values is to call the ``set()`` method of the cell ID objects, e.g.:: 119 143 120 144 >>> 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}) 122 146 123 147 Recording spikes and membrane potential branches/0.3/doc/wikidoc.py
r5 r76 24 24 #-- Define global data --------------------------------------------------------- 25 25 26 exclude = ['__module__','__doc__','__builtins__','__file__','__class__', 27 '__delattr__', '__dict__', '__getattribute__', '__hash__', 28 '__new__','__reduce__','__reduce_ex__','__repr__','__setattr__', 29 '__str__','__weakref__',] 26 exclude = set(['__module__','__doc__','__builtins__','__file__','__class__', 27 '__delattr__', '__dict__', '__getattribute__', '__hash__', 28 '__new__','__reduce__','__reduce_ex__','__repr__','__setattr__', 29 '__str__','__weakref__',] + dir(int) 30 ) 30 31 # 'time','types','copy',] 32 exclude.remove('__init__') 31 33 32 34 leftquote = re.compile(r"'\b") 33 35 leftdblquote = re.compile(r'"\b') 36 camelcase = re.compile(r'(\b([A-Z][a-z]+){2,99})') 34 37 35 38 classes = {} 36 39 functions = [] 37 40 data = [] 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' : "| || %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' : ''}67 41 68 42 #-- Process command line parameters -------------------------------------------- … … 72 46 output = 'wiki' 73 47 logging.info('Generating API documentation in %s format' % output) 48 49 #-- Define templates ----------------------------------------------------------- 50 if 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 = "| || %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' 65 elif 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' 80 elif 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 = '' 74 95 75 96 #-- Define functions ----------------------------------------------------------- … … 122 143 # anonymous arguments 123 144 arg = '(...)' 124 args[i] = default_arg_fmt [output]% (arg,r)145 args[i] = default_arg_fmt % (arg,r) 125 146 i = i + 1 126 147 if code.co_flags & 0x0004: # CO_VARARGS … … 130 151 args.append('**'+code.co_varnames[callargs]) 131 152 callargs = callargs + 1 132 return func_sig_fmt [output]% (fname,string.join(args,', '))153 return func_sig_fmt % (fname,string.join(args,', ')) 133 154 except AttributeError: 134 155 logging.warning("%s has no attribute 'func_code'" % func) … … 147 168 classes[entry] = { 'methods': [], 'data': [], 'staticmethods': [] } 148 169 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 150 171 classentry_type = type(eval('pyNN.common.%s.%s' % (entry,classentry))) 151 172 logging.info(' %-28s %s' % (classentry,classentry_type)) … … 175 196 176 197 logging.info("==== DATA ====") 177 outputStr += category_fmt [output]% "Data"198 outputStr += category_fmt % "Data" 178 199 for element in data: 179 200 instance = eval('pyNN.common.%s' % element) 180 201 if type(instance) == types.DictType: 181 outputStr += dict_fmt [output]% element182 outputStr += table_begin [output]202 outputStr += dict_fmt % element 203 outputStr += table_begin 183 204 for k,v in instance.items(): 184 205 if output == 'latex': 185 206 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 189 210 else: 190 outputStr += data_element_fmt [output]% (element, instance)211 outputStr += data_element_fmt % (element, instance) 191 212 192 213 logging.info("==== FUNCTIONS ====") 193 outputStr += category_fmt [output]% "Functions"214 outputStr += category_fmt % "Functions" 194 215 for funcname in functions: 195 216 funcinst = eval('pyNN.common.%s' % funcname) 196 outputStr += function_fmt [output]% func_sig(funcinst)217 outputStr += function_fmt % func_sig(funcinst) 197 218 if funcinst.__doc__: 198 219 outputStr += _(funcinst.__doc__.strip()) … … 217 238 218 239 # Now iterate through the classes 219 outputStr += category_fmt [output]% "Classes"240 outputStr += category_fmt % "Classes" 220 241 for classes in [celltype_classes, other_classes, error_classes]: 221 242 classlist = classes.keys() 222 243 classlist.sort() 223 244 for classname in classlist: 224 outputStr += class_fmt [output]% classname245 outputStr += class_fmt % classname 225 246 docstr = eval('pyNN.common.%s.__doc__' % classname) 226 247 if docstr: … … 230 251 fs = func_sig(methodinst) 231 252 if fs: 232 outputStr += method_fmt [output]% fs253 outputStr += method_fmt % fs 233 254 if methodinst.__doc__: 234 255 outputStr += _(methodinst.__doc__.strip()) … … 237 258 fs = func_sig(methodinst) 238 259 if fs: 239 outputStr += staticmethod_fmt [output]% fs260 outputStr += staticmethod_fmt % fs 240 261 if methodinst.__doc__: 241 262 outputStr += _(methodinst.__doc__.strip()) … … 243 264 instance = eval('pyNN.common.%s.%s' % (classname,element)) 244 265 if type(instance) == types.DictType: 245 outputStr += dict_fmt [output]% element266 outputStr += dict_fmt % element 246 267 if len(instance) > 0: 247 outputStr += table_begin [output]268 outputStr += table_begin 248 269 for k,v in instance.items(): 249 270 if output == 'latex': 250 271 v = str(v).replace('{',' $\\lbrace$').replace('}',' $\\rbrace$') 251 outputStr += table_row_fmt [output]% (k,v)272 outputStr += table_row_fmt % (k,v) 252 273 elif output == 'wiki': 253 outputStr += table_row_fmt[output] % ('"%s"' % k,v) 254 outputStr += table_end[output] 255 outputStr += dict_fmt_end[output] 274 outputStr += table_row_fmt % ('"%s"' % k,v) 275 elif output == 'trac': 276 outputStr += table_row_fmt % ("'%s'" % k,v) 277 outputStr += table_end 278 outputStr += dict_fmt_end 256 279 else: 257 outputStr += data_element_fmt [output]% (element, instance)280 outputStr += data_element_fmt % (element, instance) 258 281 259 outputStr += horiz_line [output]282 outputStr += horiz_line 260 283 261 284 if output == 'latex': … … 265 288 outputStr = leftquote.sub('`',outputStr) 266 289 outputStr = leftdblquote.sub('``',outputStr) 290 if output == 'trac': 291 outputStr = outputStr.replace('__','!__') 292 outputStr = camelcase.sub(r'!\1',outputStr) 267 293 268 294 print outputStr branches/0.3/nest.py
r54 r76 34 34 """ 35 35 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 36 41 def set(self,param,val=None): 37 42 # We perform a call to the low-level function set() of the API. … … 43 48 set(self,self._cellclass,param,val) 44 49 45 #def get(self,param):46 # pynest.getDict(self)[param]47 50 48 51 # ============================================================================== … … 230 233 celltype = cellclass(paramDict) 231 234 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] 233 236 pynest.setDict(cell_gids,celltype.parameters) 234 237 elif isinstance(cellclass, str): # celltype is not a standard cell 235 238 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] 237 240 if paramDict: 238 241 pynest.setDict(cell_gids,paramDict) 239 242 else: 240 243 raise "Invalid cell type" 244 for id in cell_gids: 245 id.setCellClass(cellclass) 241 246 if n == 1: 242 247 return cell_gids[0] … … 257 262 weight = weight*1000 # weights should be in nA or uS, but iaf_neuron uses pA and iaf_cond_neuron uses nS. 258 263 # 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 259 266 try: 260 267 if type(source) != types.ListType and type(target) != types.ListType: … … 289 296 if val: 290 297 param = {param:val} 291 if type(cells) != types.ListType: 298 try: 299 i = cells[0] 300 except TypeError: 292 301 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" 295 307 pynest.setDict(cells,param) 296 308 … … 335 347 writing process, which is not the case for the moment""" 336 348 tempfilename = "%s/%s" %(tempdir, filename) 337 pynest.sr('%s close' % tempfilename)349 pynest.sr('%s close' %filename) 338 350 if (compatible_output): 339 351 # Here we postprocess the file to have effectively the … … 343 355 result = open(filename,'w',100) 344 356 g = open(tempfilename,'r',100) 357 # Writing # such that Population.printSpikes and this have same output format 358 result.write("# "+"\n") 345 359 lines = g.readlines() 346 360 g.close() … … 462 476 return id 463 477 464 def __getitems__(self,addrs):465 """Returns the ids of neurons. Input should have format:466 n = number of synapses; nd = number of dimensions467 shape(addrs) == (n,nd)468
