Changeset 321

Show
Ignore:
Timestamp:
06/04/08 15:17:28 (6 months ago)
Author:
apdavison
Message:

Started filling out lectures - mostly a copy and paste from users guide, so far

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • doc/Freiburg2008/backends.tex

    r320 r321  
    1 % ==================================================================== 
     1% ================================================================================== 
    22\section{PyNN backends} 
    33 
     4% .................................................................................. 
     5\subsection{NEST}  
     6 
    47\begin{frame} % -------------------------------------------------------------------- 
    5 \frametitle 
     8\frametitle{NEST} 
    69 
    710\end{frame} 
     11 
     12 
     13\begin{frame} % -------------------------------------------------------------------- 
     14\frametitle{NEST} 
     15\framesubtitle{Installation} 
     16 
     17\end{frame} 
     18 
     19\begin{frame} % -------------------------------------------------------------------- 
     20\frametitle{NEST} 
     21\framesubtitle{Documentation and resources} 
     22 
     23\end{frame} 
     24 
     25\begin{frame} % -------------------------------------------------------------------- 
     26\frametitle{NEST} 
     27\framesubtitle{PyNEST} 
     28 
     29\end{frame} 
     30 
     31% .................................................................................. 
     32\subsection{NEURON} 
     33 
     34\begin{frame} % -------------------------------------------------------------------- 
     35\frametitle{NEURON} 
     36 
     37\end{frame} 
     38 
     39 
     40\begin{frame} % -------------------------------------------------------------------- 
     41\frametitle{NEURON} 
     42\framesubtitle{Installation} 
     43 
     44\end{frame} 
     45 
     46\begin{frame} % -------------------------------------------------------------------- 
     47\frametitle{NEURON} 
     48\framesubtitle{Documentation and resources} 
     49 
     50\end{frame} 
     51 
     52\begin{frame} % -------------------------------------------------------------------- 
     53\frametitle{NEURON} 
     54\framesubtitle{nrnpython} 
     55 
     56\end{frame} 
     57 
     58 
     59% .................................................................................. 
     60\subsection{PCSIM} 
     61 
     62\begin{frame} % -------------------------------------------------------------------- 
     63\frametitle{PCSIM} 
     64 
     65\end{frame} 
     66 
     67 
     68\begin{frame} % -------------------------------------------------------------------- 
     69\frametitle{PCSIM} 
     70\framesubtitle{Installation} 
     71 
     72\end{frame} 
     73 
     74\begin{frame} % -------------------------------------------------------------------- 
     75\frametitle{PCSIM} 
     76\framesubtitle{Documentation and resources} 
     77 
     78\end{frame} 
     79 
     80\begin{frame} % -------------------------------------------------------------------- 
     81\frametitle{PCSIM} 
     82\framesubtitle{PyPCSIM} 
     83 
     84\end{frame} 
     85 
     86 
     87% .................................................................................. 
     88\subsection{Brian} 
     89 
     90 
     91\begin{frame} % -------------------------------------------------------------------- 
     92\frametitle{Brian} 
     93 
     94\end{frame} 
     95 
     96 
     97\begin{frame} % -------------------------------------------------------------------- 
     98\frametitle{Brian} 
     99\framesubtitle{Installation} 
     100 
     101\end{frame} 
     102 
     103\begin{frame} % -------------------------------------------------------------------- 
     104\frametitle{Brian} 
     105\framesubtitle{Documentation and resources} 
     106 
     107\end{frame} 
     108 
     109\begin{frame} % -------------------------------------------------------------------- 
     110\frametitle{Brian} 
     111\framesubtitle{Examples} 
     112 
     113\end{frame} 
     114 
  • doc/Freiburg2008/contributing.tex

    r320 r321  
    33 
    44\begin{frame} % -------------------------------------------------------------------- 
    5 \frametitle 
     5\frametitle{Reporting a bug} 
     6 
     7screenshot of homepage with arrow pointing to New Ticket button 
    68 
    79\end{frame} 
     10 
     11\begin{frame} % -------------------------------------------------------------------- 
     12\frametitle{Reporting a bug} 
     13 
     14screenshot of New Ticket page 
     15 
     16\end{frame} 
     17 
     18\begin{frame} % -------------------------------------------------------------------- 
     19\frametitle{Asking a question} 
     20 
     21screenshot of Google groups 
     22 
     23\end{frame} 
     24 
     25\begin{frame} % -------------------------------------------------------------------- 
     26\frametitle{svn commit} 
     27 
     28STOP! First, run the test suite. 
     29 
     30Show how to do this. 
     31 
     32STOP! Now write an informative commit message (using Trac syntax if possible) 
     33 
     34 
     35\end{frame} 
  • doc/Freiburg2008/freiburg_PyNN_lectures.tex

    r320 r321  
    11% $Id:  $ 
    2 \documentclass{beamer} 
     2\documentclass[utf8]{beamer} 
    33 
    44\mode<presentation> 
  • doc/Freiburg2008/installation.tex

    r320 r321  
    33 
    44\begin{frame} % -------------------------------------------------------------------- 
    5 \frametitle 
     5\frametitle{Installing PyNN} 
     6 
    67 
    78\end{frame} 
     9 
     10 
     11\begin{frame} % -------------------------------------------------------------------- 
     12\frametitle{Running a PyNN simulation} 
     13 
     14% mention the sys.argv trick 
     15 
     16\end{frame} 
  • doc/Freiburg2008/larger_networks.tex

    r320 r321  
    1 % ==================================================================== 
     1% ================================================================================== 
    22\section{Larger networks} 
    33 
    4 \begin{frame} % -------------------------------------------------------------------- 
    5 \frametitle 
    6  
    7 \end{frame} 
     4\begin{frame}[fragile] % -------------------------------------------------------------------- 
     5\frametitle{Populations and Projections} 
     6 
     7While it is entirely possible to create very large networks using only the \verb|create()|, \verb|connect()|, \verb|set()| and \verb|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... 
     8This 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. 
     9 
     10For these reasons, PyNN provides the \verb|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 \verb|Projection| object, repesenting the set of connections between two \verb|Population|s. 
     11All 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. 
     12 
     13By using the \verb|Population| and \verb|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. 
     14Of particular importance is that 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. 
     15 
     16\end{frame} 
     17 
     18 
     19\begin{frame}[fragile] % -------------------------------------------------------------------- 
     20\frametitle{Creating \texttt{Population}s} 
     21 
     22Some examples of creating a population of neurons (don't forget to call \verb|setup()| first). 
     23 
     24This creates a 10 x 10 array of \verb|IF_curr_exp| neurons with default parameters: 
     25    \begin{verbatim} 
     26    >>> p1 = Population((10,10), IF_curr_exp) 
     27    \end{verbatim} 
     28This creates a 1D array of 100 spike sources, and gives it a label: 
     29    \begin{verbatim} 
     30    >>> p2 = Population(100, SpikeSourceArray, label="Input Population") 
     31    \end{verbatim} 
     32This illustrates all the possible arguments of the \verb|Population| constructor, with argument names. 
     33It creates a 3D array of \verb|IF_cond_alpha| neurons, all with a spike threshold set to -55 mV and membrane time constant set to 10 ms: 
     34    \begin{verbatim} 
     35    >>> p3 = Population(dims=(3,4,5), cellclass=IF_cond_alpha, 
     36    ...                 cellparams={'v_thresh': -55.0, 'tau_m': 10.0}, 
     37    ...                 label="Column 1") 
     38    \end{verbatim}                     
     39The population dimensions can be retrieved using the \verb|dim| attribute, e.g.: 
     40    \begin{verbatim} 
     41    >>> p1.dim 
     42    (10, 10) 
     43    >>> p2.dim 
     44    (100,) 
     45    >>> p3.dim 
     46    (3, 4, 5) 
     47    \end{verbatim}     
     48while the total number of neurons in a population can be obtained with the Python \verb|len()| function: 
     49    \begin{verbatim} 
     50    >>> print len(p1), len(p2), len(p3) 
     51    100 100 60 
     52    \end{verbatim}     
     53The above examples all use PyNN standard cell models. It is also possible to use simulator-specific models, but in this case the \verb|cellclass| should be given as a string, e.g.: 
     54    \begin{verbatim} 
     55    >>> p4 = Population(20, 'iaf_neuron', cellparams={'Tau': 15.0, 'C': 0.001}) 
     56    \end{verbatim}     
     57This example will work with NEST but not with NEURON or PCSIM. 
     58                         
     59\end{frame} 
     60 
     61 
     62\begin{frame}[fragile] % -------------------------------------------------------------------- 
     63\frametitle{Addressing individual neurons} 
     64 
     65 
     66To address individual neurons in a population, use \verb|[]| notation, e.g.,: 
     67    \begin{verbatim} 
     68    >>> p1[0,0] 
     69    1 
     70    >>> p1[9,9] 
     71    100 
     72    >>> p2[67] 
     73    168 
     74    >>> p3[2,1,0] 
     75    246 
     76    \end{verbatim}     
     77The return values are \verb|ID| objects, which behave in most cases as integers, but also 
     78allow accessing the values of the cell parameters (see below). 
     79The n-tuple of values within the square brackets is referred to as a neurons's *address*, while the return value is its *id*. 
     80Trying to address a non-existent neuron will raise an Exception: 
     81    \begin{verbatim} 
     82    >>> p1[999,0] 
     83    Traceback (most recent call last): 
     84      File "<stdin>", line 1, in ? 
     85      File "/usr/lib/python/site-packages/pyNN/nest1.py", line 457, in __getitem__ 
     86        id = self.cell[addr] 
     87    IndexError: index (999) out of range (0<=index<=10) in dimension 0 
     88    \end{verbatim} 
     89as will giving the wrong number of dimensions in the address. 
     90It is equally possible to define the address as a tuple, and then pass the tuple within the square brackets, e.g.: 
     91    \begin{verbatim} 
     92    >>> p1[5,5] 
     93    56 
     94    >>> address = (5,5) 
     95    >>> p1[address] 
     96    56 
     97    \end{verbatim}     
     98Neuron addresses are used in setting parameter values, and in specifying which neurons to record from. 
     99They may also be used together with the low-level \verb|connect()|, \verb|set()|, and \verb|record()| functions. 
     100 
     101To obtain an address given the id, use \verb|locate()|, e.g.: 
     102    \begin{verbatim} 
     103    >>> print p3[2,2,0] 
     104    250 
     105    >>> p3.locate(250) 
     106    (2, 2, 0) 
     107    \end{verbatim} 
     108To access the 'i'th neuron in a Population, use the \verb|index()| method, e.g.,: 
     109    \begin{verbatim} 
     110    >>> p3.index(0) 
     111    200 
     112    >>> p3.index(59) 
     113    259 
     114    >>> p3.index(60) 
     115    Traceback (most recent call last): 
     116      File "<stdin>", line 1, in <module> 
     117      File "/home/andrew/dev/pyNN/neuron/__init__.py", line 759, in index 
     118        return self.fullgidlist[n] 
     119    IndexError: index out of bounds 
     120    \end{verbatim} 
     121\end{frame} 
     122 
     123 
     124\begin{frame}[fragile] % -------------------------------------------------------------------- 
     125\frametitle{Setting parameter values} 
     126 
     127 
     128Setting the same value for the entire population 
     129------------------------------------------------ 
     130 
     131To set a parameter for all neurons in the population to the same value, use the \verb|set()| method, e.g.: 
     132    \begin{verbatim} 
     133    >>> p1.set("tau_m", 20.0) 
     134    >>> p1.set({'tau_m':20, 'v_rest':-65}) 
     135    \end{verbatim}     
     136The first form can be used for setting a single parameter, the second form for setting multiple parameters at once. 
     137 
     138Setting random values 
     139--------------------- 
     140 
     141To set a parameter to values drawn from a random distribution, use the \verb|rset()| method with a \verb|RandomDistribution| object from the \verb|pyNN.random| module (see the chapter on random numbers for more details). 
     142The following example sets the initial membrane potential of each neuron to a value drawn from a uniform distribution between -70 mV and -55 mV: 
     143    \begin{verbatim} 
     144    >>> from pyNN.random import RandomDistribution 
     145    >>> vinit_distr = RandomDistribution(distribution='uniform',parameters=[-70,-55]) 
     146    >>> p1.rset('v_init', vinit_distr) 
     147    \end{verbatim} 
     148Note that positional arguments can also be used. The following produces the same result as the above: 
     149    \begin{verbatim} 
     150    >>> vinit_distr = RandomDistribution('uniform', [-70,-55]) 
     151    \end{verbatim}For the specific case of setting the initial membrane potential, there is a convenience method \verb|randomInit()|, e.g.: 
     152    \begin{verbatim} 
     153    >>> p1.randomInit(vinit_distr) 
     154    \end{verbatim} 
     155\end{frame} 
     156 
     157 
     158\begin{frame}[fragile] % -------------------------------------------------------------------- 
     159\frametitle{Setting values according to an array} 
     160 
     161 
     162The most efficient way to set different (but non-random) values for different neurons is to use the \verb|tset()| (for *topographic* set) method. 
     163The following example injects a current of 0.1 nA into the first column of neurons in the population: 
     164    \begin{verbatim} 
     165    >>> import numpy 
     166    >>> current_input = numpy.zeros(p1.dim) 
     167    >>> current_input[:,0] = 0.1 
     168    >>> p1.tset('i_offset', current_input) 
     169    \end{verbatim} 
     170Setting parameter values for individual neurons 
     171----------------------------------------------- 
     172 
     173To set the parameters of an individual neuron, you can use the low-level \verb|set()| function,: 
     174    \begin{verbatim} 
     175    >>> set(p1[0,3], 'tau_m', 12.0) 
     176    \end{verbatim}     
     177or you can just set the relevant attribute of the \verb|ID| object: 
     178    \begin{verbatim} 
     179    >>> p1[0,4].tau_m = 12.0 
     180    \end{verbatim} 
     181\end{frame} 
     182 
     183 
     184\begin{frame}[fragile] % -------------------------------------------------------------------- 
     185\frametitle{Iterating over all the neurons in a population} 
     186 
     187 
     188To iterate over all the cells in a population, returning the neuron ids, use: 
     189    \begin{verbatim} 
     190    >>> for id in p1: #doctest: +ELLIPSIS 
     191    ...   print id, id.tau_m 
     192    ... 
     193    0 20.0 
     194    1 20.0 
     195    2 20.0 
     196    3 12.0 
     197    4 12.0 
     198    5 20.0 
     199    ... 
     200    \end{verbatim} 
     201The \verb|Population.ids()| method produces the same result. To iterate over cells but return neuron addresses, use the \verb|addresses()| method: 
     202    \begin{verbatim} 
     203    >>> for addr in p1.addresses(): #doctest: +ELLIPSIS 
     204    ...   print addr 
     205    ... 
     206    (0, 0) 
     207    (0, 1) 
     208    (0, 2) 
     209    ... 
     210    (0, 9) 
     211    (1, 0) 
     212    (1, 1) 
     213    (1, 2) 
     214    ... 
     215    \end{verbatim}     
     216\end{frame} 
     217 
     218 
     219\begin{frame}[fragile] % -------------------------------------------------------------------- 
     220\frametitle{Recording} 
     221 
     222 
     223Recording spike times is done with the method \verb|record()|. 
     224Recording membrane potential is done with the method \verb|record_v()|. 
     225Both methods have identical argument lists. 
     226Some examples: 
     227    \begin{verbatim} 
     228    >>> p1.record()                            # record from all neurons in the population 
     229    >>> p1.record(10)                          # record from 10 neurons chosen at random 
     230    >>> p1.record([p1[0,0], p1[0,1], p1[0,2]]) # record from specific neurons 
     231    \end{verbatim} 
     232Writing the recorded values to file is done with a second pair of methods, \verb|printSpikes()| and \verb|print_v()|, e.g.: 
     233    \begin{verbatim} 
     234    >>> p1.printSpikes("spikefile.dat") 
     235    \end{verbatim} 
     236By 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. 
     237This facilitates comparisons across simulators, but of course has some performace penalty. 
     238To get output in the native format of the simulator, add \verb|compatible_output=False| to the argument list. 
     239 
     240When running a distributed simulation, each node records only those neurons that it simulates. 
     241By 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. [Note that this does not work yet for nest2, not sure about pcsim]. 
     242Again, there is a performance penalty for this, so if you wish each node to write its own file, add \verb|gather=False| to the argument list. 
     243 
     244\end{frame} 
     245 
     246 
     247\begin{frame}[fragile] % -------------------------------------------------------------------- 
     248\frametitle{Position in space} 
     249 
     250 
     251The positions of individual neurons in a population can be accessed using their \verb|position| attribute, e.g.: 
     252    \begin{verbatim} 
     253    >>> p1[1,0].position = (0.0, 0.1, 0.2) 
     254    >>> p1[1,0].position 
     255    array([ 0. ,  0.1,  0.2]) 
     256    \end{verbatim}     
     257To obtain the positions of all neurons at once (as a numpy array), use the \verb|positions| attribute of the \verb|Population| object, e.g.: 
     258    \begin{verbatim} 
     259    >>> p1.positions #doctest: +ELLIPSIS,+NORMALIZE_WHITESPACE 
     260    array([[...]]) 
     261    \end{verbatim}          
     262To find the neuron that is closest to a particular point in space, use the \verb|nearest()| attribute: 
     263    \begin{verbatim} 
     264    >>> p1.nearest((4.5, 7.8, 3.3)) 
     265    48 
     266    >>> p1[p1.locate(48)].position 
     267    array([ 4.,  8.,  0.]) 
     268    \end{verbatim} 
     269\end{frame} 
     270 
     271 
     272\begin{frame}[fragile] % -------------------------------------------------------------------- 
     273\frametitle{Statistics} 
     274 
     275 
     276Often, the exact spike times and exact membrane potential traces are not required, only statistical measures. 
     277PyNN currently only provides one such measure, the mean number of spikes per neuron, e.g.: 
     278    \begin{verbatim} 
     279    >>> p1.meanSpikeCount() 
     280    0.0 
     281    \end{verbatim}     
     282More such statistical measures are planned for future releases. 
     283 
     284 
     285\end{frame} 
     286 
     287 
     288\begin{frame}[fragile] % -------------------------------------------------------------------- 
     289\frametitle{Connecting two \texttt{Population}s with a \texttt{Projection}} 
     290 
     291 
     292A \verb|Projection| object is a container for all the synaptic connections between neurons in two \verb|Population|s, together with methods for setting synaptic weights and delays. 
     293A \verb|Projection| is created by specifying a pre-synaptic \verb|Population|, a post-synaptic \verb|Population| and a \verb|Connector| object, which determines 
     294the algorithm used to wire up the neurons, e.g.: 
     295    \begin{verbatim} 
     296    >>> prj2_1 = Projection(p2, p1, method=AllToAllConnector()) 
     297    \end{verbatim}     
     298This connects \verb|p2| (pre-synaptic) to \verb|p1| (post-synaptic), using an '\verb|AllToAllConnector|' object, which connects every neuron in the pre-synaptic population to every neuron in the post-synaptic population. 
     299The currently available \verb|Connector| classes are explained below. It is fairly straightforward for a user to write a new \verb|Connector| class if they 
     300wish to use a connection algorithm not already available in PyNN. 
     301 
     302\end{frame} 
     303 
     304 
     305\begin{frame}[fragile] % -------------------------------------------------------------------- 
     306\frametitle{All-to-all connections} 
     307 
     308 
     309The \verb|AllToAllConnector'| constructor has one optional argument \verb|allow_self_connections|, for use when connecting a \verb|Population| to itself. 
     310By default it is \verb|True|, but if a neuron should not connect to itself, set it to \verb|False|, e.g.: 
     311    \begin{verbatim} 
     312    >>> prj1_1 = Projection(p1, p1, AllToAllConnector(allow_self_connections=False)) 
     313    \end{verbatim} 
     314\end{frame} 
     315 
     316 
     317\begin{frame}[fragile] % -------------------------------------------------------------------- 
     318\frametitle{One-to-one connections} 
     319 
     320 
     321Use of the \verb|OneToOneConnector| requires that the pre- and post-synaptic populations have the same dimensions, e.g.: 
     322    \begin{verbatim} 
     323    >>> prj1_1a = Projection(p1, p1, OneToOneConnector()) 
     324    \end{verbatim}     
     325Trying to connect two \verb|Population|s with different dimensions will raise an Exception, e.g.: 
     326    \begin{verbatim} 
     327    >>> invalid_prj = Projection(p2, p3, OneToOneConnector()) #doctest: +IGNORE_EXCEPTION_DETAIL 
     328    Traceback (most recent call last): 
     329      File "doctest.py", line 1212, in __run 
     330        compileflags, 1) in test.globs 
     331      File "<doctest highlevelapi.txt[49]>", line 1, in <module> 
     332        invalid_prj = Projection(p2, p3, OneToOneConnector()) 
     333      File "/home/andrew/dev/pyNN/neuron/__init__.py", line 1199, in __init__ 
     334        hoc_commands += method.connect(self) 
     335      File "/home/andrew/dev/pyNN/neuron/connectors.py", line 95, in connect 
     336        raise Exception("OneToOneConnector does not support presynaptic and postsynaptic Populations of different sizes.") 
     337    Exception: OneToOneConnector does not support presynaptic and postsynaptic Populations of different sizes. 
     338    \end{verbatim}     
     339     
     340\end{frame} 
     341 
     342 
     343\begin{frame}[fragile] % -------------------------------------------------------------------- 
     344\frametitle{Connecting neurons with a fixed probability} 
     345 
     346 
     347With the \verb|FixedProbabilityConnector| method, each possible connection between all pre-synaptic neurons and all post-synaptic neurons is created with probability \verb|p_connect|, e.g.: 
     348    \begin{verbatim} 
     349    >>> prj2_3 = Projection(p2, p3, FixedProbabilityConnector(p_connect=0.2)) 
     350    \end{verbatim}     
     351The constructor also accepts an \verb|allow_self_connections| parameter, as above. 
     352 
     353\end{frame} 
     354 
     355 
     356\begin{frame}[fragile] % -------------------------------------------------------------------- 
     357\frametitle{Connecting neurons with a distance-dependent probability} 
     358 
     359 
     360For each pair of pre-post cells, the connection probability depends on distance. 
     361If positions in space have been specified using the \verb|positions()| method of the \verb|Population| class or the \verb|position| attributes of individual 
     362neurons, these positions are used to calculate distances. 
     363If not, the neuron addresses, i.e., the array coordinates, are used. 
     364 
     365The constructor requires a string \verb|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 '\verb|d|', e.g.: 
     366    \begin{verbatim} 
     367    >>> prj1_1b = Projection(p1, p1, DistanceDependentProbabilityConnector("exp(-abs(d))")) 
     368    >>> prj3_3  = Projection(p3, p3, DistanceDependentProbabilityConnector("float(d<3)")) 
     369    \end{verbatim} 
     370The first example connects neurons with an exponentially-decaying probability. 
     371The second example connects each neuron to all its neighbours within a range of 3 units (distance is in $\mu$m if positions have been specified, in array coordinate distance otherwise). 
     372 
     373The calculation of distance may be controlled by a number of further arguments. 
     374 
     375By default, the 3D distance between cell positions is used, but the \verb|axes| argument may be used to change this, e.g.: 
     376    \begin{verbatim} 
     377    >>> connector = DistanceDependentProbabilityConnector("exp(-abs(d))", axes='xy') 
     378    \end{verbatim}     
     379will ignore the z-coordinate when calculating distance. 
     380 
     381Similarly, the origins of the coordinate systems of the two Populations and the relative scale of the two coordinate systems may be controlled using the \verb|offset| and \verb|scale_factor| arguments. This is useful when connecting brain regions that have very different sizes but that have a topographic mapping between them, e.g. retina to LGN to V1. 
     382 
     383In more abstract models, it is often useful to be able to avoid edge effects by specifying periodic boundary conditions, e.g.: 
     384    \begin{verbatim} 
     385    >>> connector = DistanceDependentProbabilityConnector("exp(-abs(d))", periodic_boundaries=(500, 500, 0)) 
     386    \end{verbatim}     
     387calculates distance on the surface of a torus of circumference 500 $\mu$m (wrap-around in the x- and y-dimensions but not z) 
     388[really need to test this, and improve the docstrings] 
     389 
     390 
     391\end{frame} 
     392 
     393 
     394\begin{frame}[fragile] % -------------------------------------------------------------------- 
     395\frametitle{Divergent/fan-out connections} 
     396 
     397 
     398The \verb|FixedNumberPostConnector| connects each pre-synaptic neuron to exactly \verb|n| post-synaptic neurons chosen at random: 
     399    \begin{verbatim} 
     400    >>> prj2_1a = Projection(p2, p1, FixedNumberPostConnector(n=30)) 
     401    \end{verbatim}     
     402As a refinement to this, the number of post-synaptic neurons can be chosen at random from a \verb|RandomDistribution| object, e.g.: 
     403    \begin{verbatim} 
     404    >>> distr_npost = RandomDistribution(distribution='binomial', parameters=[100,0.3]) 
     405    >>> prj2_1b = Projection(p2, p1, FixedNumberPostConector(n=distr_npost)) 
     406    \end{verbatim}     
     407 
     408\end{frame} 
     409 
     410 
     411\begin{frame}[fragile] % -------------------------------------------------------------------- 
     412\frametitle{Convergent/fan-in connections} 
     413 
     414 
     415The \verb|FixedNumberPreConnector| has the same arguments as \verb|FixedNumberPostConnector|, but of course it connects each *post*-synaptic neuron to \verb|n| *pre*-synaptic neurons, e.g.: 
     416    \begin{verbatim} 
     417    >>> prj2_1c = Projection(p2, p1, FixedNumberPreConnector(5)) 
     418    >>> distr_npre = RandomDistribution(distribution='poisson', parameters=[5]) 
     419    >>> prj2_1d = Projection(p2, p1, FixedNumberPreConnector(distr_npre)) 
     420    \end{verbatim} 
     421 
     422\end{frame} 
     423 
     424 
     425\begin{frame}[fragile] % -------------------------------------------------------------------- 
     426\frametitle{Writing and reading connection patterns to/from a file} 
     427 
     428 
     429Connection patterns can be written to a file using \verb|saveConnections()|, e.g.: 
     430    \begin{verbatim} 
     431    >>> prj1_1a.saveConnections("prj1_1a.conn") 
     432    \end{verbatim}     
     433These files can then be read back in to create a new \verb|Projection| object using a \verb|FromFileConnector| object, e.g.: 
     434    \begin{verbatim} 
     435    >>> prj1_1c = Projection(p1, p1, FromFileConnector("prj1_1a.conn")) 
     436    \end{verbatim} 
     437\end{frame} 
     438 
     439 
     440\begin{frame}[fragile] % -------------------------------------------------------------------- 
     441\frametitle{Specifying a list of connections} 
     442 
     443 
     444Specific 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. 
     445(Note that the weights and delays should be optional, but currently are not). Example: 
     446    \begin{verbatim} 
     447    >>> conn_list = [ 
     448    ...   ((0,0), (0,0,0), 0.0, 0.1), 
     449    ...   ((0,0), (0,0,1), 0.0, 0.1), 
     450    ...   ((0,0), (0,0,2), 0.0, 0.1), 
     451    ...   ((0,1), (1,3,0), 0.0, 0.1) 
     452    ... ] 
     453    >>> prj1_3d = Projection(p1, p3, FromListConnector(conn_list)) 
     454    \end{verbatim} 
     455 
     456\end{frame} 
     457 
     458 
     459\begin{frame}[fragile] % -------------------------------------------------------------------- 
     460\frametitle{User-defined connection algorithms} 
     461 
     462 
     463If you wish to use a specific connection/wiring algorithm not covered by the PyNN built-in ones, the simplest option is to construct a list of connections and use the \verb|FromListConnector| class. By looking at the code for the built-in \verb|Connector|s, it should also be quite straightforward to write your own \verb|Connector| class, although this must be done separately for each simulator you wish to use. In a future release, we plan to make writing new simulator-independent \verb|Connector|s much simpler. 
     464 
     465 
     466\end{frame} 
     467 
     468 
     469\begin{frame}[fragile] % -------------------------------------------------------------------- 
     470\frametitle{Setting synaptic weights and delays} 
     471 
     472 
     473Synaptic weights and delays may be set either when creating the \verb|Projection|, as arguments to the \verb|Connector| object, or afterwards using the \verb|setWeights()| and \verb|setDelays()| methods \verb|Projection|. 
     474 
     475All \verb|Connector| objects accept \verb|weights| and \verb|delays| arguments to their constructors. Some examples: 
     476 
     477To set all weights to the same value: 
     478    \begin{verbatim} 
     479    >>> connector = AllToAllConnector(weights=0.7) 
     480    >>> prj1_3e = Projection(p1, p3, connector) 
     481    \end{verbatim}     
     482To set delays to random values taken from a specific distribution: 
     483    \begin{verbatim} 
     484    >>> delay_distr = RandomDistribution(distribution='gamma',parameters=[1,0.1]) 
     485    >>> connector = FixedNumberPostConnector(n=20, delays=delay_distr) 
     486    >>> prj2_1e = Projection(p2, p1, connector) 
     487    \end{verbatim} 
     488To set individual weights and delays to specific values: 
     489    \begin{verbatim} 
     490    >>> weights = numpy.arange(1.1, 2.0, 0.9/60) 
     491    >>> delays = 2*weights 
     492    >>> connector = OneToOneConnector(weights=weights, delays=delays) 
     493    >>> prj1_1d = Projection(p1, p1, connector) 
     494    \end{verbatim} 
     495After creating the \verb|Projection|, to set the weights of all synaptic connections in a \verb|Projection| to a single value, use the \verb|setWeights()| method: 
     496    \begin{verbatim} 
     497    >>> prj1_1.setWeights(0.2) 
     498    \end{verbatim}     
     499[Note: synaptic weights in PyNN are in nA for current-based synapses and µS for conductance-based synapses)]. 
     500 
     501To set different weights to different values, use \verb|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.: 
     502    \begin{verbatim} 
     503    >>> weight_list = 0.1*numpy.ones(len(prj2_1)) 
     504    >>> weight_list[0:5] = 0.2 
     505    >>> prj2_1.setWeights(weight_list) 
     506    \end{verbatim}     
     507To set weights to random values, use the \verb|randomizeWeights()| method: 
     508    \begin{verbatim} 
     509    >>> weight_distr = RandomDistribution(distribution='gamma',parameters=[1,0.1]) 
     510    >>> prj1_1.randomizeWeights(weight_distr) 
     511    \end{verbatim}     
     512Setting delays works similarly: 
     513    \begin{verbatim} 
     514    >>> prj1_1.setDelays(0.6) 
     515    >>> delay_list = 0.3*numpy.ones(len(prj2_1)) 
     516    >>> delay_list[0:5] = 0.4 
     517    >>> prj2_1.setDelays(delay_list) 
     518    >>> delay_distr = RandomDistribution(distribution='gamma',parameters=[2,0.2]) 
     519    >>> prj1_1.randomizeDelays(delay_distr) 
     520    \end{verbatim} 
     521 
     522\end{frame} 
     523 
     524 
     525\begin{frame}[fragile] % -------------------------------------------------------------------- 
     526\frametitle{Accessing weights and delays} 
     527 
     528 
     529To get the weights of all connections in the \verb|Projection|, use the \verb|getWeights()| method. 
     530Two formats are available. \verb|'list'| returns a list of length equal to the number of connections 
     531in the projection, \verb|'array'| returns a 2D weight array (with zero or None for non-existent 
     532connections): 
     533    \begin{verbatim} 
     534    >>> prj2_1e.getWeights(format='list') 
     535    fsgs 
     536    >>> prj2_1e.getWeights(format='array') 
     537    fdsg 
     538    \end{verbatim} 
     539\verb|getDelays()| is analogous. \verb|printWeights()| writes the weights to a file. 
     540 
     541The \verb|weightHistogram()| method returns a histogram of the synaptic weights, with bins 
     542determined by the \verb|min|, \verb|max| and \verb|nbins| arguments passed to the method. 
     543 
     544\end{frame} 
     545 
  • doc/Freiburg2008/native_celltypes.tex

    r320 r321  
    1 % ==================================================================== 
     1% ================================================================================== 
    22\section{Native cell types} 
    33 
    44\begin{frame} % -------------------------------------------------------------------- 
    5 \frametitle 
     5\frametitle{Native cell types} 
     6 
     7a few slides showing how to use native cell models in PyNN 
     8 
     9Easy for NEST 
     10 
     11Don't really know for PCSIM - look at ModelDB for Vogels-Abbott, perhaps 
     12 
     13For NEURON, give a full example of wrapping a multi-compartment neuron 
    614 
    715\end{frame} 
  • doc/Freiburg2008/plasticity.tex

    r320 r321  
    22\section{Plasticity} 
    33 
    4 \begin{frame} % -------------------------------------------------------------------- 
    5 \frametitle 
     4\begin{frame}[fragile] % -------------------------------------------------------------------- 
     5\frametitle{Dynamic synapses} 
     6 
     7The default type of synaptic connection in PyNN is static, with fixed synaptic 
     8weights. To model dynamic synapses, for which the synaptic weight (and possibly 
     9other properties, such as rise-time) varies depending on the recent history of 
     10post- and/or pre-synaptic activity, we use the same idea as for neurons, of 
     11standardized, named models that have the same interface and behaviour across 
     12simulators, even if the underlying implementation may be very different. 
     13[note: does the approach of using strings for native models also work, as for 
     14neurons?] 
     15 
     16Where the approach for dynamic synapses differs from that for neurons is that 
     17we attempt a greater degree of compositionality, i.e. we decompose models into 
     18a number of components, for example for short-term and long-term dynamics, or 
     19for the timing-dependence and the weight-dependence of STDP rules, that can 
     20then be composed in different ways. 
     21 
     22The advantage of this is that if we have \verb|n| differerent models for  component 
     23''A'' and \verb|m| models for component ''B'', then we require only \verb|n + m| models 
     24rather than \verb|n x m|, which had advantages in terms of code-simplicity and in 
     25shorter model names. The disadvantage is that not all combinations may exist, if 
     26the underlying simulator implements composite models rather than using 
     27components itself: in this situation, PyNN checks whether a given composite model 
     28\verb|AB| exists for a given simulator and raises an Exception if it does not. 
     29 
     30The composite approach may be extended to neuron models in future versions of the 
     31PyNN interface depending on the experience with composite synapse models. 
    632 
    733\end{frame} 
     34 
     35\begin{frame}[fragile] % -------------------------------------------------------------------- 
     36\frametitle{SynapseDynamics objects} 
     37 
     38To set the model of synapse dynamics to use for the connections of a given 
     39\verb|Projection|, we pass a \verb|SynapseDynamics| object as the \verb|synapse_dynamics| 
     40keyword argument to the \verb|Projection|constructor. 
     41 
     42The \verb|SynapseDynamics| object is simply a container that has attributes \verb|fast|, 
     43which, if set, is an instance of a subclass of the abstract class 
     44\verb|ShortTermPlasticityMechanism|, and \verb|slow|, which is an instance of a 
     45subclass of the abstract class \verb|STDPMechanism|. 
     46 
     47Only a single subclass of \verb|ShortTermPlasticityMechanism| is currently available in 
     48PyNN: \verb|TsodkysMarkramMechanism|. 
     49 
     50\verb|STDPMechanism| objects are further decomposed into components for the 
     51timing-dependence, weight-dependence and post-synaptic voltage-dependence of 
     52the mechanism. 
     53 
     54\end{frame} 
     55 
     56\begin{frame}[fragile] % -------------------------------------------------------------------- 
     57\frametitle{Example} 
     58 
     59An example of defining a \verb|Projection| with facilitating/depressing synapses, 
     60but no long-term plasticity: 
     61        \begin{verbatim} 
     62    >>> depressing_syn = SynapseDynamics(fast=TsodyksMarkramMechanism(**params)) 
     63    >>> prj = Projection(pre, post, AllToAllConnector(), 
     64    ...                  synapse_dynamics = depressing_syn) 
     65    \end{verbatim}                      
     66and one with long-term plasticity, using a spike-pair rule and with additive 
     67weight updates (i.e. the weight change is independent of the current weight 
     68value): 
     69        \begin{verbatim} 
     70    >>> stdp_model = STDPMechanism( 
     71           timing_dependence=SpikePairRule(tau_plus=20.0, tau_minus=20.0), 
     72           weight_dependence=AdditiveWeightDependence(w_min=0, w_max=0.02, 
     73                                                      A_plus=0.01, A_minus=0.012) 
     74        ) 
     75    >>> prj2 = Projection(pre, post, FixedProbabilityConnector(p=0.1), 
     76    ...                   synapse_dynamics=SynapseDynamics(slow=stdp_model)) 
     77        \end{verbatim} 
     78 
     79\end{frame} 
  • doc/Freiburg2008/porting.tex

    r320 r321  
    33 
    44\begin{frame} % -------------------------------------------------------------------- 
    5 \frametitle 
     5\frametitle{Example of porting a NEURON model to PyNN} 
    66 
    77\end{frame} 
     8 
     9\begin{frame} % -------------------------------------------------------------------- 
     10\frametitle{Example of porting a NEST model to PyNN} 
     11 
     12\end{frame} 
  • doc/Freiburg2008/small_networks.tex

    r320 r321  
    1 % ==================================================================== 
     1% ================================================================================== 
    22\section{Small networks} 
    33 
    4 \begin{frame} % -------------------------------------------------------------------- 
    5 \frametitle 
    6  
    7 \end{frame} 
     4\begin{frame}[fragile] % -------------------------------------------------------------------- 
     5\frametitle{Initialising the simulator} 
     6 
     7Before using any other functions or classes from PyNN, the user must call the \verb|setup()| function: 
     8    \begin{verbatim} 
     9    >>> setup() 
     10    \end{verbatim} 
     11\verb|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.: 
     12    \begin{verbatim} 
     13    >>> setup(timestep=0.1, min_delay=0.1, max_delay=0.5, debug=False) 
     14    \end{verbatim}     
     15Debugging information is written to a log file in the working directory. 
     16 
     17\end{frame} 
     18 
     19 
     20\begin{frame}[fragile] % ------------------------------------------------------------ 
     21\frametitle{Creating neurons} 
     22 
     23Neurons are created with the \verb|create()| function. To create a single integrate-and-fire neuron, type: 
     24    \begin{verbatim} 
     25    >>> create(IF_curr_alpha) 
     26    \end{verbatim} 
     27Here, \verb|IF_curr_alpha| is a particular class of IF neuron with alpha-function shaped synaptic currents, that will work with any PyNN simulation engine, whether NEURON, NEST or PCSIM. 
     28\verb|IF_curr_alpha| is a so-called 'standard cell', implemented as a Python class. 
     29For more information, see the section StandardCells. 
     30 
     31You don't have to use standard cells. 
     32You can also use any neuron model that is available in an individual simulator, although of course your simulation will then only run with that simulator, for example: 
     33    \begin{verbatim} 
     34    >>> create('iaf_neuron') 
     35    \end{verbatim}     
     36\verb|iaf_neuron| is a neuron model available in the NEST simulator. 
     37Note that the model name has to be given as a string for simulator-specific models. 
     38 
     39To create many neurons at once, add the \verb|n| argument, e.g.     
     40    \begin{verbatim} 
     41    >>> create(IF_curr_alpha, n=10) 
     42    \end{verbatim}     
     43The neurons we have created so far have all had default parameter values,  
     44stored in the \verb|default_values| of the standard cell class, e.g.: 
     45    \begin{verbatim} 
     46    >>> IF_curr_alpha.default_parameters #doctest" +NORMALIZE_WHITESPACE 
     47    {'tau_refrac': 0.0, 'tau_m': 20.0, 'i_offset': 0.0, 'cm': 1.0, 'v_init': -65.0, 
     48     'v_thresh': -50.0, 'tau_syn_E': 0.5, 'v_rest': -65.0, 'tau_syn_I': 0.5, 
     49     'v_reset': -65.0} 
     50    \end{verbatim} 
     51To use different parameter values, use the \verb|param_dict| argument, e.g.: 
     52    \begin{verbatim} 
     53    >>> create(IF_curr_alpha, param_dict={'tau_m': 15.0, 'cm': 0.9}, n=10) 
     54    \end{verbatim} 
     55If you try to set a non-existent parameter, or pass an invalid value, PyNN will raise an Exception, e.g.: 
     56    \begin{verbatim} 
     57    >>> create(IF_curr_alpha, param_dict={'foo': 15.0}) 
     58    Traceback (most recent call last): 
     59      File "<stdin>", line 1, in ? 
     60      File "/usr/lib/python/site-packages/pyNN/nest1.py", line 228, in create 
     61        celltype = cellclass(param_dict) 
     62      File "/usr/lib/python/site-packages/pyNN/nest1.py", line 68, in __init__ 
     63        common.IF_curr_alpha.__init__(self,parameters) # checks supplied parameters and adds default 
     64      File "/usr/lib/python/site-packages/pyNN/common.py", line 113, in __init__ 
     65        self.parameters = self.checkParameters(parameters, with_defaults=True) 
     66      File "/usr/lib/python/site-packages/pyNN/common.py", line 99, in checkParameters 
     67        raise NonExistentParameterError(k) 
     68    NonExistentParameterError: foo 
     69    >>> create(IF_curr_alpha, param_dict={'tau_m': 'bar'}) 
     70    Traceback (most recent call last): 
     71      File "/usr/lib/python/site-packages/pyNN/nest1.py", line 228, in create 
     72        celltype = cellclass(param_dict) 
     73      File "/usr/lib/python/site-packages/pyNN/nest1.py", line 68, in __init__ 
     74        common.IF_curr_alpha.__init__(self,parameters) # checks supplied parameters and adds default 
     75      File "/usr/lib/python/site-packages/pyNN/common.py", line 113, in __init__ 
     76        self.parameters = self.checkParameters(parameters, with_defaults=True) 
     77      File "/usr/lib/python/site-packages/pyNN/common.py", line 90, in checkParameters 
     78        raise InvalidParameterValueError, (type(supplied_parameters[k]), type(default_parameters[k])) 
     79    InvalidParameterValueError: (<type 'str'>, <type 'float'>) 
     80    \end{verbatim} 
     81     
     82If 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.: 
     83    \begin{verbatim} 
     84    >>> cell = create(IF_curr_alpha) 
     85    >>> cell_list = create(IF_curr_alpha, n=10) 
     86    \end{verbatim} 
     87The \verb|create()| function returns either a cell id object or a list of id objects. 
     88 
     89\end{frame} 
     90 
     91 
     92\begin{frame}[fragile] % -------------------------------------------------------------------- 
     93\frametitle{Connecting neurons} 
     94 
     95Any neuron that emits spikes can be connected to any neuron with at least one synapse using the \verb|connect()| function, e.g.: 
     96    \begin{verbatim} 
     97    >>> spike_source = create(SpikeSourceArray, param_dict={'spike_times': [10.0, 20.0, 30.0]}) 
     98    >>> cell_list2 = create(IF_curr_exp, n=10) 
     99    >>> connect(spike_source, cell_list2) 
     100    \end{verbatim}     
     101In this case we connect a spike-generating mechanism (\verb|SpikeSourceArray| is a 'standard cell' model that emits spikes at times specified by the \verb|spike_times| parameter) to each cell in the list \verb|cells|, i.e. we create 10 connections at once. 
     102For clarity, we could also have specified the argument names: 
     103    \begin{verbatim} 
     104    >>> connect(source=spike_source, target=cell_list2) 
     105    \end{verbatim}     
     106Either \verb|source| or \verb|target| or both may be individual cell ids or lists of ids. 
     107In 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.: 
     108    \begin{verbatim} 
     109    >>> source_list = cell_list 
     110    >>> target_list = cell_list2 
     111    >>> connect(source_list, target_list, p=0.5) 
     112    \end{verbatim}     
     113When specifying connections as above, default values are given to the synaptic weight and delay. 
     114These values are seldom very useful, and it is better to specify the \verb|weight| and \verb|delay| arguments of \verb|connect()|, e.g.: 
     115    \begin{verbatim} 
     116    >>> connect(source_list, target_list, weight=1.5, delay=0.5) 
     117    \end{verbatim}     
     118Weights are specified in nA for 'current-based' synapses or $\mu$S for 'conductance-based' synapses. 
     119Delays are in ms. 
     120For current-based synapses, weights should be negative for inhibitory synapses. 
     121For conductance-based synapses, weights should always be positive, since the effect of a synapse is determined by its reversal potential. 
     122 
     123If the neuron model has more than one synapse mechanism, or more than one synaptic location, the particular synapse to which the connection should be made is specified with the \verb|synapse_type| argument, e.g.: 
     124    \begin{verbatim} 
     125    >>> connect(source_list, target_list, weight=1.5, delay=0.5, synapse_type='inhibitory') 
     126    \end{verbatim} 
     127[How to find out what synapse types a standard cell has?] 
     128 
     129\end{frame} 
     130 
     131 
     132\begin{frame}[fragile] % -------------------------------------------------------------------- 
     133\frametitle{Setting neuron parameters} 
     134 
     135There are many ways to change the parameters for individual neurons and post-synaptic mechanisms after creation of the neuron. 
     136To change a single parameter of a single neuron, just set the relevant attribute of the neuron ID object, e.g.: 
     137    \begin{verbatim} 
     138    >>> cells = create(IF_curr_exp, param_dict={'v_init': -70.0}, n=10) 
     139    >>> cells[0].tau_m 
     140    20.0 
     141    >>> cells[0].tau_m = 15 
     142    >>> cells[0].tau_m 
     143    15.0 
     144    \end{verbatim}     
     145To change several parameters at once for a single neuron, use the \verb|set_parameters()| method of the neuron ID, e.g.: 
     146    \begin{verbatim} 
     147    >>> cells[1].set_parameters(tau_m=10.0, cm=0.5) 
     148    >>> cells[1].tau_m 
     149    10.0 
     150    >>> cells[1].cm 
     151    0.5 
     152    \end{verbatim} 
     153To change parameters for several cells at once, use the \verb|set()| function, e.g.: 
     154    \begin{verbatim} 
     155    >>> set(cells[0:5], param='v_init', val=-65.0) 
     156    >>> print cells[0].v_init 
     157    -65.0 
     158    >>> print cells[5].v_init 
     159    -70.0 
     160    \end{verbatim}     
     161Individual parameters can be set using the \verb|param| and \verb|val| arguments, as above, or multiple parameters can be set at once by passing a dictionary of name:value pairs as the \verb|param| argument, with \verb|val| empty, e.g.: 
     162    \begin{verbatim} 
     163    >>> set(cells, param={'tau_refrac': 2.0, 'tau_syn_E': 5.0}) 
     164    \end{verbatim} 
     165\end{frame} 
     166 
     167 
     168\begin{frame}[fragile] % -------------------------------------------------------------------- 
     169\frametitle{Setting position in space} 
     170 
     171 
     172In some cases it is important to know the position of a neuron in space. This information 
     173can be set and retrieved using the `position` attribute of the neuron ID: 
     174    \begin{verbatim} 
     175    >>> cells[0].position = (75, 456, 56) 
     176    >>> cells[0].position 
     177    (75, 456, 56) 
     178    \end{verbatim}     
     179Positions must always be in 3D, and may be given as integers or floating-point values, and as tuples or as numpy arrays. 
     180No specific scale of units is assumed, although many parts of PyNN do assume a Euclidean coordinate system. 
     181 
     182\end{frame} 
     183 
     184 
     185\begin{frame}[fragile] % -------------------------------------------------------------------- 
     186\frametitle{Recording spikes and membrane potential} 
     187 
     188 
     189To record action potentials use the \verb|record()| function and to record membrane potential use the \verb|record_v()| funct