.. currentmodule:: brian

Recording
=========

The activity of the network can be recorded by defining *monitors*.

Recording spikes
----------------
To record the spikes from a given group, define a :class:`SpikeMonitor` object::

  M=SpikeMonitor(group)
  
At the end of the simulation, the spike times are stored in the variable ``spikes`` as
a list of pairs (i,t) where neuron i fired at time t. For example, the following code extracts
the list of spike times for neuron 3::

  spikes3=[t for i,t in M.spikes if i==3]

but this operation can be done directly as follows::

  spikes3=M[3]

The total number of spikes is ``M.nspikes``.

Custom monitoring
^^^^^^^^^^^^^^^^^
To process the spikes in a specific way, one can pass a function at initialisation of the
:class:`SpikeMonitor` object::

  def f(spikes):
    print spikes
    
  M=SpikeMonitor(group,function=f)

The function ``f`` is called every time step with the argument ``spikes`` being the list of
indexes of neurons that just spiked.

.. TODO: docs: recording directly to a file
	Recording directly to a file
	^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Recording state variables
-------------------------
State variables can be recorded continuously by defining a :class:`StateMonitor` object, as follows::

  M=StateMonitor(group,'v')

Here the state variables ``v`` of the defined group are monitored. By default, only the statistics
are recorded. The list of time averages for all neurons is ``M.mean``; the standard deviations are stored
in ``M.std`` and the variances in ``M.var``. Note that these are averages over time, not over the neurons.

To record the values of the state variables over the whole simulation, use the keyword ``record``::

  M1=StateMonitor(group,'v',record=True)
  M2=StateMonitor(group,'v',record=[3,5,9])

The first monitor records the value of ``v`` for all neurons while the second one records ``v`` for
neurons 3, 5 and 9 only. The list of times is stored in ``M1.times`` and the lists of values are stored in
``M1[i]``, where i the index of the neuron. Means and variances are no longer recorded if you
record traces.

By default, the values of the state variables are recorded every timestep, but one may record every n timesteps
by setting the keyword ``timestep``::

  M=StateMonitor(group,'v',record=True,timestep=n)

Recording spike triggered state values
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

You can record the value of a state variable at each spike using :class:`StateSpikeMonitor`::

  M = StateSpikeMonitor(group, 'V')

The ``spikes`` attribute of ``M`` consists of a series of tuples ``(i,t,V)`` where ``V`` is the
value at the time of the spike.

Recording multiple state variables
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

You can either use multiple :class:`StateMonitor` objects or use the :class:`MultiStateMonitor`
object::

	M = MultiStateMonitor(group, record=True)
	...
	run(...)
	...
	plot(M['V'].times, M['V'][0])
	figure()
	for name, m in M.iteritems():
	    plot(m.times, m[0], label=name)
	legend()
	show()  

Recording only recent values
^^^^^^^^^^^^^^^^^^^^^^^^^^^^

You can use the :class:`RecentStateMonitor` object, e.g.::

    G = NeuronGroup(1, 'dV/dt = xi/(10*ms)**0.5 : 1')
    MR = RecentStateMonitor(G, 'V', duration=5*ms)
    run(7*ms)
    MR.plot()
    show()

Counting spikes
---------------
To count the total number of spikes produced by a group, use a :class:`PopulationSpikeCounter` object::

  M=PopulationSpikeCounter(group)

Then the number of spikes after the simulation is ``M.nspikes``. If you need to count the spikes
separately for each neuron, use a :class:`SpikeCounter` object::

  M=SpikeCounter(group)
  
Then ``M[i]`` is the number of spikes produced by neuron i.

Counting coincidences
---------------------
To count the number of coincident spikes between the neurons of a group
and given target spike trains, use a :class:`CoincidenceCounter` object::

  C=CoincidenceCounter(source=group, data=data, delta=delta)
  
``data`` is a list of pairs (neuron_index, spike time), and delta is the time window
in second. To get the number of coincidences for each neuron of the group, use ::

  coincidences = C.coincidences

The gamma precision factor can be obtained with ::

  gamma = C.gamma

Recording population rates
--------------------------
The population rate can be monitored with a :class:`PopulationRateMonitor` object::

  M=PopulationRateMonitor(group)

After the simulation, ``M.times`` contains the list of recording times and
``M.rate`` is the list of rate values (where the rate is meant in the spatial sense: average rate over
the whole group at some given time). The bin size is set with the ``bin`` keyword (in seconds)::

  M=PopulationRateMonitor(group,bin=1*ms)
  
Here the averages are calculated over 1 ms time windows. Alternatively, one can use the
:meth:`~PopulationRateMonitor.smooth_rate` method to smooth the rates::

  rates=M.smooth_rate(width=1*ms,filter='gaussian')

The rates are convolved with a linear filter, which is either a Gaussian function
(``gaussian``, default) or a box function ('flat').

Van Rossum Metric
-----------------

The Van Rossum metric can be computed by monitoring a group with a
:class:`VanRossumMetric` object::

	M = VanRossumMetric(G, tau=4*ms)
	...
	imshow(M.distance)
