Source code for main

# -*- coding: utf-8 -*-
r"""
Run a parallel ring network of ball-and-stick cells and write the spike times
to a file.

To execute with MPI across 2 processors::
       
    $ mpiexec -n 2 python main.py
    
To modify any simulation parameters, specify individual variables encased in
a string to a sim_var dictionary variable::

    $ mpiexec -n 2 python main.py "sim_var['N']=6" \
       "sim_var['spike_out_file']='N6.spk'"
       
To visualize a few cells, playing back from a recorded spike file, specify
a list of cells in the ``playback`` variable and run from an interactive
python console::

    $ python -i main.py "sim_var['playback']=[0,3]"
    
.. Note::
    
    This code requires ``numpy`` and ``mpi4py`` and assumes NEURON is
    also installed in the Python environment.
    
.. seealso::
    
    Hines M.L. and Carnevale N.T, 
    Translating network models to parallel hardware in NEURON,
    Journal of Neuroscience Methods 169 (2008) 425-455).

AUTHORS:

- THOMAS MCTAVISH (2010-11-04): initial version.

"""
import sys, os

[docs]def process_args(in_argv): """Process additional arguments on command line. Any Python statement can be executed, but arguments need to be formatted as strings and each one in the form ``"sim_var['<var>']=x"`` will run the simulation with a modification of parameters.""" sim_var = {'N' : 5, # Number of cells 'stim_w' : 0.004, # Stimulus weight 'stim_spike_num' : 1, # Number of spikes in the stimulator 'syn_w' : 0.01, # Synaptic weights 'syn_delay' : 5, # Synaptic delay 'spike_out_file' : 'out.spk', # Spike output file 'playback' : [], # List of cells to playback in non-parallel mode } if in_argv is not None: global_dict = globals() local_dict = locals() for arg in in_argv: try: exec(arg, global_dict, local_dict) except: print "WARNING: Do not know how to process statement \ \'{0}\'".format(item) pass if 'sim_var' in local_dict: # Replace default values with those in the local_dict sim_var.update(local_dict['sim_var']) return sim_var
[docs]def plot_vecs(vecs, ids): """Plot time series data. :param vecs: Dict containing vectors. Assumes there is at least a 't' key. :param ids: Cell ids to plot. """ from matplotlib import pyplot fig = pyplot.figure() ax = fig.add_axes([.1,.1,.8,.8]) plts = [] legtext = [] for idx in ids: plts.extend(ax.plot(vecs['t'], vecs[idx])) legtext.append("cell %d" %(idx)) ax.legend(plts, legtext) pyplot.show()
[docs]def run(argv = None): """Run a ring network simulation. Additional arguments on command line can be any Python statement to execute, but strings in the form ``"sim_var['<var>']=x"`` will run the simulation with a modification of those parameters.""" sim_var = process_args(argv) if len(sim_var['playback']) == 0: try: from mpi4py import MPI # Must come before importing NEURON except ImportError as (strerror): print "*****\nWARNING: {0}:\n Running in serial mode.\n*****" \ .format(strerror) pass from neuron import h as nrn import ring nrn.load_file("stdrun.hoc") # For when we run simulations pc = nrn.ParallelContext() net = ring.Ring(sim_var['N'], \ sim_var['stim_w'], \ sim_var['stim_spike_num'], \ sim_var['syn_w'], \ sim_var['syn_delay'], \ sim_var['playback']) pc.set_maxstep(10) nrn.stdinit() nrn.dt = 0.025 # Fixed dt nrn.tstop = 100 if len(sim_var['playback']) > 0: import numpy from itertools import izip rec = {} for (cell, gid) in izip(net.cells, net.playlist): vec = nrn.Vector() vec.record(cell.soma(0.5)._ref_v) rec[gid] = vec vec = nrn.Vector() vec.record(nrn._ref_t) rec['t'] = vec npspikevec, npgidvec = numpy.loadtxt('sorted_' + sim_var['spike_out_file'], unpack=True) spikevec = nrn.Vector() gidvec = nrn.Vector() patternstim = nrn.PatternStim() patternstim.play(spikevec.from_python(npspikevec), gidvec.from_python(npgidvec)) nrn.run() plot_vecs(rec, sim_var['playback']) else: pc.psolve(100) net.write_spikes(sim_var['spike_out_file']) pc.runworker() pc.done() # After we are done, re-sort the file by spike times. exec_cmd = 'sort -k 1n,1n -k 2n,2n ' + sim_var['spike_out_file'] + \ ' > ' + 'sorted_' + sim_var['spike_out_file'] os.system(exec_cmd) nrn.quit()
if __name__ == '__main__': """ Runs when called from the command line. Optional arguments may specify different param files and Python commands. """ idx=1 for item in sys.argv: if item.startswith('main'): # Ignore everything leading up to ourselves break idx += 1 run(sys.argv[idx:])