Source code for LFPy.pointprocess

#!/usr/bin/env python
'''Copyright (C) 2012 Computational Neuroscience Group, NMBU.

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.'''

import numpy
import neuron

[docs]class PointProcess: ''' Superclass on top of Synapse, StimIntElectrode, just to import and set some shared variables. Arguments: :: cell : LFPy.Cell object idx : index of segment color : color in plot (optional) marker : marker in plot (optional) record_current : Must be set True for recording of pointprocess currents kwargs : pointprocess specific variables passed on to cell/neuron ''' def __init__(self, cell, idx, color='k', marker='o', record_current=False, **kwargs): ''' cell is an LFPy.Cell object, idx index of segment. This class sets some variables and extracts Cartesian coordinates of a segment ''' self.idx = idx self.color = color self.marker = marker self.record_current = record_current self.kwargs = kwargs self.update_pos(cell)
[docs] def update_pos(self, cell): ''' Extract coordinates of point-process ''' self.x = cell.xmid[self.idx] self.y = cell.ymid[self.idx] self.z = cell.zmid[self.idx]
[docs]class Synapse(PointProcess): ''' The synapse class, pointprocesses that spawn membrane currents. See http://www.neuron.yale.edu/neuron/static/docs/help/neuron/neuron/mech.html#pointprocesses for details, or corresponding mod-files. This class is meant to be used with synaptic mechanisms, giving rise to currents that will be part of the membrane currents. Usage: :: #!/usr/bin/env python import LFPy import pylab as pl pl.interactive(1) cellParameters = { 'morphology' : 'morphologies/L5_Mainen96_LFPy.hoc', 'tstopms' : 50, } cell = LFPy.Cell(**cellParameters) synapseParameters = { 'idx' : cell.get_closest_idx(x=0, y=0, z=800), 'e' : 0, # reversal potential 'syntype' : 'ExpSyn', # synapse type 'tau' : 2, # syn. time constant 'weight' : 0.01, # syn. weight 'record_current' : True # syn. current record } synapse = LFPy.Synapse(cell, **synapseParameters) synapse.set_spike_times(pl.array([10, 15, 20, 25])) cell.simulate(rec_isyn=True) pl.subplot(211) pl.plot(cell.tvec, synapse.i) pl.title('Synapse current (nA)') pl.subplot(212) pl.plot(cell.tvec, cell.somav) pl.title('Somatic potential (mV)') ''' def __init__(self, cell, idx, syntype, color='r', marker='o', record_current=False, **kwargs): ''' Initialization of class Synapse ''' PointProcess.__init__(self, cell, idx, color, marker, record_current, **kwargs) self.syntype = syntype self.cell = cell self.hocidx = int(cell.set_synapse(idx, syntype, record_current, **kwargs)) cell.synapses.append(self) cell.synidx.append(idx)
[docs] def set_spike_times(self, sptimes=numpy.zeros(0)): '''Set the spike times explicitly using numpy arrays''' self.sptimes = sptimes self.cell.sptimeslist.append(sptimes)
[docs] def set_spike_times_w_netstim(self, noise=1., start=0., number=1E3, interval=10., seed=1234.): ''' Generate a train of pre-synaptic stimulus times by setting up the neuron NetStim object associated with this synapse kwargs: :: noise : float in [0, 1] Fractional randomness, from deterministic to intervals that drawn from negexp distribution (Poisson spiketimes). start : float ms, (most likely) start time of first spike number : int (average) number of spikes interval : float ms, (mean) time between spikes seed : float random seed value ''' self.cell.netstimlist[-1].noise = noise self.cell.netstimlist[-1].start = start self.cell.netstimlist[-1].number = number self.cell.netstimlist[-1].interval = interval self.cell.netstimlist[-1].seed(seed)
[docs] def collect_current(self, cell): '''Collect synapse current''' try: self.i = numpy.array(cell.synireclist.o(self.hocidx)) except: raise Exception('cell.synireclist deleted from consequtive runs')
[docs] def collect_potential(self, cell): '''Collect membrane potential of segment with synapse''' try: self.v = numpy.array(cell.synvreclist.o(self.hocidx)) except: raise Exception('cell.synvreclist deleted from consequtive runs')
[docs]class StimIntElectrode(PointProcess): ''' Class for NEURON point processes, ie VClamp, SEClamp and ICLamp, SinIClamp, ChirpIClamp with arguments. Electrode currents go here. Membrane currents will no longer sum to zero if these mechanisms are used. Refer to NEURON documentation @ neuron.yale.edu for kwargs Usage example: :: #/usr/bin/python import LFPy import pylab as pl pl.interactive(1) #define a list of different electrode implementations from NEURON pointprocesses = [ { 'idx' : 0, 'record_current' : True, 'pptype' : 'IClamp', 'amp' : 1, 'dur' : 20, 'delay' : 10, }, { 'idx' : 0, 'record_current' : True, 'pptype' : 'VClamp', 'amp[0]' : -65, 'dur[0]' : 10, 'amp[1]' : 0, 'dur[1]' : 20, 'amp[2]' : -65, 'dur[2]' : 10, }, { 'idx' : 0, 'record_current' : True, 'pptype' : 'SEClamp', 'dur1' : 10, 'amp1' : -65, 'dur2' : 20, 'amp2' : 0, 'dur3' : 10, 'amp3' : -65, }, ] #create a cell instance for each electrode for pointprocess in pointprocesses: cell = LFPy.Cell(morphology='morphologies/L5_Mainen96_LFPy.hoc') stimulus = LFPy.StimIntElectrode(cell, **pointprocess) cell.simulate(rec_istim=True) pl.subplot(211) pl.plot(cell.tvec, stimulus.i, label=pointprocess['pptype']) pl.legend(loc='best') pl.title('Stimulus currents (nA)') pl.subplot(212) pl.plot(cell.tvec, cell.somav, label=pointprocess['pptype']) pl.legend(loc='best') pl.title('Somatic potential (mV)') ''' def __init__(self, cell, idx, pptype='SEClamp', color='p', marker='*', record_current=False, **kwargs): ''' Will insert pptype on cell-instance, pass the corresponding kwargs onto cell.set_point_process. ''' PointProcess.__init__(self, cell, idx, color, marker, record_current) self.pptype = pptype self.hocidx = int(cell.set_point_process(idx, pptype, record_current, **kwargs)) cell.pointprocesses.append(self) cell.pointprocess_idx.append(idx)
[docs] def collect_current(self, cell): ''' Fetch electrode current from recorder list ''' self.i = numpy.array(cell.stimireclist.o(self.hocidx))
[docs] def collect_potential(self, cell): ''' Collect membrane potential of segment with PointProcess ''' self.v = numpy.array(cell.synvreclist.o(self.hocidx))
class PointProcessPlayInSoma: ''' Class implementation of Eivind's playback alghorithm ''' def __init__(self, soma_trace): ''' Class for playing back somatic trace at specific time points into soma as boundary condition for the membrane voltage ''' self.soma_trace = soma_trace def set_play_in_soma(self, cell, t_on=numpy.array([0])): ''' Set mechanisms for playing soma trace at time(s) t_on, where t_on is a numpy.array ''' if type(t_on) != numpy.ndarray: t_on = numpy.array(t_on) f = file(self.soma_trace) x = [] for line in f.readlines(): x.append(list(map(float, line.split()))) x = numpy.array(x) X = x.T f.close() #time and values for trace, shifting tTrace = X[0, ] tTrace -= tTrace[0] trace = X[1, ] trace -= trace[0] trace += cell.e_pas #creating trace somaTvec0 = tTrace somaTvec0 += t_on[0] somaTvec = somaTvec0 somaTrace = trace for i in range(1, t_on.size): numpy.concatenate((somaTvec, somaTvec0 + t_on[i])) numpy.concatenate((somaTrace, trace)) somaTvec1 = numpy.interp(numpy.arange(somaTvec[0], somaTvec[-1], cell.timeres_NEURON), somaTvec, somaTvec) somaTrace1 = numpy.interp(numpy.arange(somaTvec[0], somaTvec[-1], cell.timeres_NEURON), somaTvec, somaTrace) somaTvecVec = neuron.h.Vector(somaTvec1) somaTraceVec = neuron.h.Vector(somaTrace1) for sec in neuron.h.somalist: #cell.somalist #ensure that soma is perfect capacitor sec.cm = 1E9 #Why the fuck doesnt this work: #for seg in sec: # somaTraceVec.play(seg._ref_v, somaTvecVec) #call function that insert trace on soma self._play_in_soma(somaTvecVec, somaTraceVec) def _play_in_soma(self, somaTvecVec, somaTraceVec): ''' Replacement of LFPy.hoc "proc play_in_soma()", seems necessary that this function lives in hoc ''' neuron.h('objref soma_tvec, soma_trace') neuron.h('soma_tvec = new Vector()') neuron.h('soma_trace = new Vector()') neuron.h.soma_tvec.from_python(somaTvecVec) neuron.h.soma_trace.from_python(somaTraceVec) neuron.h('soma_trace.play(&soma.v(0.5), soma_tvec)')