Wednesday, June 18, 2014

GSoC Open Source Brain: Retinal Filter I

LGN-Retinal filter

Treating the retina and the LGN together as a spatio-temporal filter is a common trait in the models that we are going to work with in this project. In this series of articles I am going to develop and explain the mechanism that I have developed to model this particular stage of processing.

Structure of the filter

In this particular example we are dealing with a separable spatio-temporal filter. That is, we can write our filter as a product of the spatial part and the temporal part. In the following sections, we will describe them in this given order.

Spatial filter

In order to calculate the spatial filter we need two things. First, how wide our filters are going to be and then the resolution level. So lx and ly will stand for the size of the receptive filters (in degrees) for the x and y direction respectively. The same will go for dx and dy with respect to the resolution. With this in our hands we then can proceed to create a 2 dimensional structure for our functions with the help of the mesh functions:

## Spatial parameters
x = np.arange(-lx/2, lx/2, dx)
y = np.arange(-ly/2, ly/2, dy)

X, Y = np.meshgrid(x, y) # Create the 2D dimensional coordinates

Now that we have the function it is just a matter of calculating the function with the appropiate formula:

R = np.sqrt(X**2 + Y**2) # Distance
center = (17.0 / sigma_center**2) * np.exp(-(R / sigma_center)**2)
surround = (16.0 / sigma_surround**2) * np.exp(-(R / sigma_surround)**2)
Z = surround - center

With the formula in our hands we can plot it as a countour line to have an idea of how it looks like in space:
# Plot countour map
plt.contourf(X, Y, Z, 50, alpha=0.75, cmap=plt.cm.hot)
plt.colorbar()

C = plt.contour(X, Y, Z, 10, colors='black', linewidth=.5)
plt.clabel(C, inline=10, fontsize=10)
plt.show()


We can also show a view when y=0 in order to offer a side view of the plot in order to gain further insight in the structure of it:

Temporal filter

The behaviour of the temporal filters in time is usually called bi-phasic response. This consists in a response that initially grows in time for the mean level but then it goes bellow to the mean level to finally return at it in time window of the order 200ms approximately. The particular function and parameters that we are going to use to illustrate this behaviour were taken from the paper by Cai et Al (Reference bellow). But first, we have to define our kernel size and resolution as in the code down here:

# First the kernel size and resolution
kernel_size = 200
dt_kernel = 1.0
t = np.arange(0, kernel_size * dt_kernel, dt_kernel) # Time vector

Now, we construct the function in the following way:
## Temporal parameters
K1 = 1.05
K2 = 0.7
c1 = 0.14
c2 = 0.12
n1 = 7.0
n2 = 8.0
t1 = -6.0
t2 = -6.0
td = 6.0

p1 = K1 * ((c1*(t - t1))**n1 * np.exp(-c1*(t - t1))) / ((n1**n1) * np.exp(-n1))
p2 = K2 * ((c2*(t - t2))**n2 * np.exp(-c2*(t - t2))) / ((n2**n2) * np.exp(-n2))
p3 = p1 - p2

We plot the function to have an idea of how it looks now:


Spatio-Temporal Filter

Finally, in order to have build the kernel, given that our filter is separable, we just have to multiply the temporal the temporal part by the spatial part at each point in space:
     # Initialize and fill the spatio-temporal kernel 
     kernel = np.zeros((kernel_size, int(lx/dx), int(ly/dy)))

     for k, p3 in enumerate(p3): 
          kernel[k,...] = p3 * Z 
    

Which we can show now in the following plot:

References

  • Cai, Daqing, Gregory C. Deangelis, and Ralph D. Freeman. "Spatiotemporal receptive field organization in the lateral geniculate nucleus of cats and kittens." Journal of Neurophysiology 78.2 (1997): 1045-1061.

Thursday, June 5, 2014

GSoC Open Source Brain: How to Create Connections, Two Neurons Example

Two Neurons

In this example we are going to define one of the most simple networks possible: one with three elements. This will allow us to introduce a couple of fundamental concepts in PyNN.

As in our past example we start by importing PyNN and the necessary libraries. Also we declare some initialization variables and we start the simulator:

import pyNN.nest as simulator
import pyNN.nest.standardmodels.electrodes as elect
import matplotlib.pyplot as plt
import numpy as np

N = 3 # Number of neurons
t = 150.0 # Simulation time

# Has to be called at the beginning of the simulation
simulator.setup(timestep=0.1, min_delay=0.1, max_delay=10)

Now we have to declare our cell modell. But before to so, let's check which parameters of it we can play with. In order to do so we can consult the available parameters for each model class with the method default_parameters. In our case of example we are interested in the integrate and fire model with current based synapses. We can call the following code to see the parameters available:

simulator.IF_curr_exp.default_parameters

After this we are going to get a list of the available parameters, we set them and the declare our model with the following instructions:

# Neuron Model's parameters
i_offset = 0
R = 20
tau_m = 20.0
tau_refractory = 50
v_thresh = 0
v_rest = -60
tau_syn_E = 5.0
tau_syn_I = 5.0
cm = tau_m / R

# Declare our cell model
model = simulator.IF_curr_exp(cm=cm, i_offset=i_offset, tau_m=tau_m, tau_refrac=tau_refractory, tau_syn_E=tau_syn_E, tau_syn_I=tau_syn_I, v_reset=v_rest, v_thresh=v_thresh)

# Declare a population
neurons = simulator.Population(N, model)

In order to modify a specific subset of a given population in PyNN we use the concept of View. Views allow us to use Python array notation to access a given subset of a population and modify it for our purposes. In this particular case we are going select two sub-populations (neurons 1 and 2) to modify the parameters and a create a connection to them from the reminder neuron. In order to modify parameters from a given population we use the method set_parameters that each population posses:

# Create views
neuron1 = neurons[[0]]
neuron2 = neurons[1, 2]

# Modify second neuron
tau_m2 = 10.0
cm2 = tau_m2 / R
neurons[1].set_parameters(cm=cm2, tau_m=tau_m2)

tau_m3 = 5.0
cm3 = tau_m3 / R
neurons[2].set_parameters(cm=cm3, tau_m=tau_m3)

Now, in order to create connections in PyNN we need the concept of projection. As stated in the tutorial of PyNN a project needs the following elements to be declared:

  • The pre-synaptic population
  • The post-synaptic population
  • A connection algorithm
  • A synapse type

The general form of the Projection method is given by

Projection(presynaptic population, posynaptic population, connection algorithm, synapase type)

In our example the pre-synaptic population is going to be the neuron 0 and the post-synaptic population is going to be composed of the neurons 1 and 2 as declared in the views above. As a connection algorithm we are going to use the AllToAllConnector method which connects every member of the presynaptic population to the post-synaptic population. Finally we can define a static syanpse with the method StaticSynapse, it requires two attributes a value that determines the size (weight) and a delay that determines how long after the spike in the pre-synaptic neuron the pos-synaptic neuron elicits a response. Our code bellow is:

# Synapses
syn = simulator.StaticSynapse(weight=10, delay=0.5)
# Projections
connections = simulator.Projection(neuron1, neuron2, simulator.AllToAllConnector(),
syn, receptor_type='excitatory')

Finally we set the current for the neuron 1 and the recorder as in the previous example:

# DC source
current = elect.DCSource(amplitude=3.5, start=20.0, stop=100.0)
current.inject_into(neuron1)
#neurons.inject(current)

# Record the voltage
neurons.record('v')

simulator.run(t) # Run the simulations for t ms
simulator.end()

Finally we extract the data and plot the function

# Extracts the data
data = neurons.get_data() # Creates a Neo Block
segment = data.segments[0] # Takes the first segment
vm = segment.analogsignalarrays[0] # Take the arrays

# Extract the data for neuron 1
vm1 = vm[:, 0]
vm2 = vm[:, 1]
vm3 = vm[:, 2]

# Plot the data
plt.plot(vm.times, vm1, label='pre-neuron')
plt.hold('on')
plt.plot(vm.times, vm2, label='post-neuron 1')
plt.plot(vm.times, vm3, label= 'post-neuron 2')

plt.xlabel('time')
plt.ylabel('Voltage')
plt.legend()

plt.show()

A particular example of the simulation running is attached next. Playing with the parameters in this example can provide a clear idea of how the models and synapsis' parameters work:

GSoC Open Source Brain: First Example, Integrate and Fire neuron

First Example

In this entry I am going to describe a very basic example with PyNN. Our aim is to build a system with a simple Integrate and Fire neuron under the influence of a direct current. The first thing that we need to do is to import the simulator that we are going to use with the instruction:

import pyNN.nest as simulator

Note that this could also be Neuron or Brian instead of Nest

Now, we need to define our model but before that we need to do some presettings. So we set first the number of neurons that our simulations is going to run and also the total time it will take.

N = 1 # Number of neurons
t = 100.0 #Simulation time

# Has to be called at the beginning of the simulation
simulator.setup(timestep=0.1, min_delay=0.1, max_delay=10)

Now we can define a neuron model for our neuron. For this example we are going to chose a leaky integrate and fire with exponentially decaying pos-synpatic current.

model = simulator.IF_curr_exp()
neurons = simulator.Population(N, model)

Note that once we have defined our model and our number of neurons we can define a population with this.

As a next step we define the current and inject it into the neurons

# DC source
current = simulator.DCSource(amplitude=0.5, start=20.0, stop=80.0)
#current = elect.DCSource(amplitude=0.5, start=20.0, stop=80.0)
current.inject_into(neurons)
#neurons.inject(current)

And finally we can indicate our simulator to run with the instruction

simulator.run(t) # Run the simulations for t ms

With this we have already simulated our neuron. However, as the things stand right now it we are unable to visualize the trajectory in time of the voltage in our system. In order to extract the membrane potential from our data we have to declare a recorder for the voltage.

neurons.record('v') # Record voltage
simulator.run(t) # Run the simulations for t ms

Now in ourder to extract our simulations from the recorder we use:

data = neurons.get_data()

This returns a Neo bloc. A Neo blocked is a container of segments which in turn contain the data recorded in a given experiment. In order to extract our data from the block above we use the following code:

data = neurons.get_data() # Crates a Neo Block
segment = data.segments[0] # Takes the first
vm = segment.analogsignalarrays[0]

Finally in order to plot our data:

import matplotlib.pyplot as plt
plt.plot(vm.times, vm)
plt.xlabel('time')
plt.ylabel('Vm')
plt.show()

Which produces the next plot:

GSoC Open Source Brain: Google Summer of Code 2014 Presentation

Presentation

Introduction

My name is Ramon Heberto Martinez and I am student in the Erasmus Mundus Master in Complex Systems Science. I will use the coming series of entries in this blog to describe and report my progress in the project for Google Summer of Code 2014 (GSoC 2014). I have been lucky enough to have my proposal entitled Open source, cross simulator, large scale cortical models with the International Neuroinformatics Coordinating Facility (INCF). This project will be co- mentored by Andrew Davison at the INCF's French branch and Padraig Gleeson from the INCF branch in the UK.

The Project

As we advance the study of the brain we have required more powerful tools to study it. In particular more powerful computational tools have become available as well as more elaborated simulation environments. An example of these efforts is the Open Source Brain Project (OSB) project that provides a space where the computational models can be built collaboratively and shared with open standards such as PyNN [Davison et al., 2008] and NeuroML [Gleeson et al., 2010].

On the other hand there is a lack of well tested open models that can serve as benchmarks to test and reliably compare the capabilities of the different environments. It is the spirit of this project to try to reduce the lack of such models. In particular this project will consist on developing models of the visual system which, at the date that I write, is an area not very well covered by the OSB project so far

The work specifically will consist on developing the code of the models below in PyNN and release them as free code in the platform of the Open Source Brain Project
. Papers:

  • Different roles for simple-cell and complex-cell inhibition in v1 [Lauritzen and Miller, 2003].
  • Inhibitory stabilization of the cortical network underlies visual surround suppression [Ozeki et al., 2009]
  • Feedforward origins of response variability underlying contrast invari- ant orientation tuning in cat visual cortex [Sadagopan and Ferster, 2012]
The theme of the papers is to have a thorough set of properties of the visual system (V1) and in particular of the orientation invariance property.

References and Links

References

  • Andrew P Davison, Daniel Br ̈derle, Jochen Eppler, Jens Kremkow, Eilif Muller, Dejan Pecevski, Laurent Perrinet, and Pierre Yger. Pynn: a common interface for neuronal network simulators. Frontiers in neuroinformatics, 2, 2008.
  • Padraig Gleeson, Sharon Crook, Robert C Cannon, Michael L Hines, Guy O Billings, Matteo Farinella, Thomas M Morse, Andrew P Davison, Subhasis Ray, Upinder S Bhalla, et al. Neuroml: a language for describing datadriven models of neurons and networks with a high degree of biological detail. PLoS computational biology,(6):e1000815, 2010.
  • Thomas Z Lauritzen and Kenneth D Miller. Different roles for simple-cell and complex-cell inhibition in v1. The Journal of neuroscience, 23(32):10201–10213, 2003.
  • Hirofumi Ozeki, Ian M Finn, Evan S Schaffer, Kenneth D Miller, and David Ferster. Inhibitory stabilization of the cortical network underlies visual surround suppression. Neuron, 62(4):578–592, 2009.
  • Roger D Peng. Reproducible research in computational science. Science (New York, Ny), 334(6060):1226, 2011.
  • Srivatsun Sadagopan and David Ferster. Feedforward origins of response variability underlying contrast invariant orientation tuning in cat visual cortex. Neuron, 74(5):911–923, 2012.

Links

Project Page at INCF
PyNN
NeuroML
Open Source Brain Project
Neural Ensemblet
International Neuroinformatics Coordinating Facility
Google Summer of Code 2014

Friday, April 18, 2014

Sumatra 0.6 released

We would like to announce the release of version 0.6.0 of Sumatra, a tool for automated tracking of simulations and computational analyses so as to be able to easily replicate them at a later date.

This version of Sumatra sees many new features, improvements to existing ones, and bug fixes:

New export formats: LaTeX and bash script

You can now export your project history as a LaTeX document, allowing you to easily generate a PDF listing details of all the simulations or data analyses you've run.

    $ smt list -l -f latex > myproject.tex

Using tags, you can also restrict the output to only a subset of the history.

You can also generate a shell script, which can be executed to repeat the sequence of computations captured by Sumatra, or saved as an executable record of your work. The shell script includes all version control commands needed to ensure the correct version of the code is used at each step.

    $ smt list -l -f shell > myproject.sh

Working with multiple VCS branches

Previous versions of Sumatra would always update to the latest version of the code in your version control repository before running the computation.

Now, "smt run" will never change the working copy, which makes it much easier to work with multiple version control branches and to go back to running earlier versions of your code.

Programs that read from stdin or write to stdout

Programs that read from standard input or write to standard output can now be run with "smt run". For example, if the program is normally run using:

    $ myprog < input > output

You can run it with Sumatra using:

    $ smt run -e myprog -i input -o output

Improvements to the Web browser interface

There have been a number of small improvements to the browser interface:

  • a slightly more compact and easier-to-read (table-like) layout for parameters;
  • the working directory is now displayed in the record detail view;
  • the interface now works if record label contain spaces or forward slashes.

The minimal Django version needed is now 1.4.

Support for PostgreSQL

The default record store for Sumatra is based on the Django ORM, using SQLite as the backend. It is now possible to use PostgreSQL instead of SQLite, which gives better performance and allows the Sumatra record store to be placed on a separate server.

To set up a new Sumatra project using PostgreSQL, you will first have to create a database using the PostgreSQL tools ("psql", etc.). You then configure Sumatra as follows:

    $ smt init --store=postgres://username:password@hostname/databasename MyProject

Note that the database tables will not be created until after the first "smt run".

Integration with the SLURM resource manager

Preliminary support for launching MPI computations via SLURM has been added.

  $ smt configure --launch_mode=slurm-mpi
  $ smt run -n 256 input_file1 input_file2

This will launch 256 tasks using "salloc" and "mpiexec".

Command-line options for SLURM can also be set using "smt configure"

  $ smt configure --launch_mode_options=" --tasks-per-node=1"

If you are using "mpiexec" on its own, without a resource manager, you can set MPI command-line options in the same way.

Improvements to the @capture decorator

The "@capture" decorator, which makes it easy to add Sumatra support to Python scripts (as an alternative to using the "smt" command), now captures stdout and stderr.

Improvements to parameter file handling

Where a parameter file has a standard mime type (like json, yaml), Sumatra uses the appropriate extension if rewriting the file (e.g. to add parameters specified on the command line), rather than the generic ".param".

Migrating data files

If you move your input and/or output data files, either within the filesystem on your current computer or to a new computer, you need to tell Sumatra about it so that it can still find your files. For this there is a new command, "smt migrate". This command also handles changes to the location of the data archive, if you are using one, and changes to the base URL of any mirrored data stores. For usage information, run:

    $ smt help migrate

Miscellaneous improvements

  • "smt run" now passes unknown keyword args on to the user program. There is also a new option '--plain' which prevents arguments of the form "x=y" being interpreted by Sumatra; instead they are passed straight through to the program command line.
  • When repeating a computation, the label of the original is now stored in the 'repeats' attribute of 'Record', rather than appending "_repeat" to the original label. The new record will get a new unique label, or a label specified by the user. This means a record can be repeated more than once, and is a more reliable method of indicating a repeat.
  • A Sumatra project now knows the version of Sumatra with which it was created.
  • "smt list" now has an option '-r'/'--reverse' which lists records oldest to newest.

Bug fixes

A fair number of bugs have been fixed.

Download, support and documentation

The easiest way to get the latest version of Sumatra is

  $ pip install sumatra

Alternatively, Sumatra 0.6.0 may be downloaded from PyPI or from the INCF Software Center. Support is available from the sumatra-users Google Group. Full documentation is available on pythonhosted.org.

Monday, March 3, 2014

Docker image to run the software neural simulators used in BrainScaleS

Docker is like a virtual machine (Virtualbox, VMware,...) but with one huge advantage for everyone wanting to run a neural simulator on his own computer: being based on Linux containers, a Docker image can use all the resources (CPUs, RAMs) of your host computer.
That's why we have decided to put all the tools needed to run the software neural simulators used in the European project BrainScaleS into an openly accessible docker image. To use it, please follow the official step-by-step guide.
This Docker image (brainscales/neural-networks:software) contains the following neural simulators and the associated tools (openmpi, visualization,...):
  • NEST (version 2.2.2)
  • NEURON (version 7.3)
  • Brian (latest version from PyPI, currently 1.4.1)
  • PyNN (latest version from PyPI, currently 0.7.5), the language-independent simulator (it uses as backend either NEST, Brian or NEURON),
  • MUSIC, the multi-simulation coordinator (multiconn branch). Note that, in this image, only NEURON has been compiled with MUSIC.
To use this image, you need to install Docker on your host computer. On an Ubuntu computer, this means installing lxc-docker:
  $ sudo apt-get install lxc-docker
Then, you download the image from the Docker index repository:
  $ sudo docker pull brainscales/neural-networks:software
You can now follow this step-by-step guide to run the examples from all these neural simulators using all the resources from your host computer, without having to install other software than Docker itself and a ssh client. Enjoy!

Joël Chavas and Andrew Davison.

Wednesday, January 22, 2014

Tools for cortical modelling from the Bednar Lab

Jim Bednar writes:

"We are pleased to announce the availability of a comprehensive new example of modelling topographic maps in the visual cortex, suitable as a ready-to-run starting point for future research. This example consists of:

1. A new J. Neuroscience paper (Stevens et al. 2013a) describing the GCAL model and showing that is is stable, robust, and adaptive, developing orientation maps like those observed in ferret V1.

2. A new open-source Python software package, Lancet, for launching simulations and collating the results into publishable figures.

3. A new Frontiers in Neuroinformatics paper (Stevens et al. 2013b) describing a lightweight and practical workflow for doing reproducible research using Lancet and IPython.

4. An IPython notebook showing the precise steps necessary to reproduce the 842 simulation runs required to reproduce the complete set of figures and text of Stevens et al. (2013a),  using the Topographica simulator.

5. A family of Python packages that were once part of Topographica but are now usable by a broader audience. These packages include 'param' for specifying parameters declaratively, 'imagen' for defining 0D, 1D, and 2D distributions (such as visual stimuli), and  'featuremapper' for analyzing the activity of neural populations  (e.g. to estimate receptive fields, feature maps, or tuning curves).

The resulting recipe for building mechanistic models of cortical map development should be an excellent way for new researchers to start doing work in this area.

Jean-Luc R. Stevens, Judith S. Law, Jan Antolik, Philipp Rudiger, Chris Ball, and James A. Bednar

Computational Systems Neuroscience Group
The University of Edinburgh


_______________________________________________________________________________


1. STEVENS et. al. 2013a: GCAL model

Our recent paper:

Jean-Luc R. Stevens, Judith S. Law, Jan Antolik, and James A. Bednar. Mechanisms for stable, robust, and adaptive  development of orientation maps in the primary visual cortex. Journal of Neuroscience, 33:15747-15766, 2013.  http://dx.doi.org/10.1523/JNEUROSCI.1037-13.2013

shows how the GCAL model was designed to replace previous models of V1development that were unstable and not robust.  The model in this paper accurately reproduces the process of orientation map development in ferrets, as illustrated in this animation comparing GCAL, a simpler model, and chronic optical imaging data from ferrets.


2. LANCET

Lancet is a lightweight Python package that offers a set of flexible components to allow researchers to declare their intentions succinctly and reproducibly. Lancet makes it easy to specify a parameter space,
run jobs, and collate the output from an external simulator or analysis tool. The approach is fully general, to allow the researcher to switch between different software tools and platforms as necessary.


3. STEVENS et. al. 2013b: LANCET/IPYTHON workflow

Jean-Luc R. Stevens, Marco I. Elver, and James A. Bednar.  An Automated and Reproducible Workflow for Running and Analyzing  Neural Simulations Using Lancet and IPython Notebook. Frontiers in Neuroinformatics, in press, 2013. http://www.frontiersin.org/Journal/10.3389/fninf.2013.00044/abstract

Lancet is designed to integrate well into an exploratory workflow within the Notebook environment offered by the IPython project. In an IPython notebook, you can generate data, carry out analyses, and plot the results interactively, with a complete record of all the code used.
Together with Lancet, it becomes practical to automate every step needed to generate a publication within IPython Notebook, concisely and reproducibly.  This new paper describes the reproducible workflow and shows how to use it in your own projects.


4. NOTEBOOKS for Stevens et al. 2013a

As an extended example of how to use Lancet with IPython to do reproducible research, the complete recipe for reproducing Stevens et al. 2013a is available in models/stevens.jn13 of Topographica's GitHub repository.  The first of two notebooks defines the model, alternating between code specification, a textual description of the key model properties with figures, and interactive visualization of the model's initial weights and training stimuli. The second notebook can be run to quickly generate the last three published figures (at half resolution) but can also launch all 842, high-quality simulations
needed to reproduce all the published figures in the paper.  Static copies of these notebooks, along with instructions for downloading runnable versions, can be viewed here:

  http://topographica.org/_static/gcal.html
  http://topographica.org/_static/stevens_jn13.html

5. PARAM, IMAGEN, and FEATUREMAPPER

The Topographica simulator has been refactored into several fully independent Python projects available on GitHub (http://ioam.github.io). These projects are intended to be useful to a wide audience of both computational and experimental neuroscientists:

  param: The parameters offered by param allow scientific Python programs to be written declaratively, with type and range checking,  optional documentation strings, dynamically generated values,  default values and many other features.

  imagen: Imagen offers a set of 0D,1D and 2D pattern distributions. These patterns may be procedurally generated or  loaded from files. They can be used to generate simple scalar values, such as values drawn from a specific random distribution,  or for generating complex, resolution-independent composite image pattern distributions typically used as visual stimuli (e.g. Gabor and Gaussian patches or masked sinusoidal gratings).


  featuremapper: Featuremapper allows the response properties of a neural population to be measured from any simulator or experimental setup that can give estimates of the neural activity values in  response to an input pattern. Featuremapper may be used to measure preference and selectivity maps for various stimulus features (e.g  orientation and direction of visual stimuli, or frequency for  auditory stimuli), to compute tuning curves for these features, or  to measure receptive fields, regardless of the underlying implementation of the model or experimental setup."