Computational Optogenetics: modelling ChR2 in NMODL

NMODL and the Channel Builder.
Post Reply
mgiugliano
Posts: 9
Joined: Fri Aug 18, 2006 12:08 pm
Location: Trieste, Italy
Contact:

Computational Optogenetics: modelling ChR2 in NMODL

Post by mgiugliano »

Dear All,

I implemented the channelrhodopsin model ChR2 (H134R mutant), described in a recent PLoS Comp Biology paper[1], as a nonspecific current mechanism. I have then shared this model on ModelDB (accession number 244414; to become public in the coming days).

Given my limited proficiency in NEURON and NMODL, I made possible for a user to specify the time course of the photo-stimulus by an a priori defined waveform (i.e. a pulse). I then expose the parameters of such a waveform (e.g. its intensity, duration, delay).

Is there a smarter way to feed in an arbitrary external waveform into the mechanism - without customising its code and recompiling it every time?

Say that I want to use ramps, sinusoids, or a repeated series of pulses: I am now forced to modify every time the NMODL source and come out with as many mechanisms as the waveforms of my choice. I have seen that other investigators (see the work by the group of Nikolic from Imperial College) have implemented the wild-type ChR2 as a point mechanism (not as a density) and they made use of "net_send" within their NMODL.

What is the best and most appropriate way to proceed?

Any feedback from you might be greatly appreciated.


Reference

1. Williams JC, Xu J, Lu Z, Klimas A, Chen X, Ambrosi CM, Cohen IS, Entcheva E (2013) Computational optogenetics: empirically-derived voltage- and light-sensitive channelrhodopsin-2 model. PLoS Comput Biol 9:e1003220
ramcdougal
Posts: 267
Joined: Fri Nov 28, 2008 3:38 pm
Location: Yale School of Public Health

Re: Computational Optogenetics: modelling ChR2 in NMODL

Post by ramcdougal »

You can probably do what you want by using Vector.play.

In brief, Vector.play allows you to use two Vectors (one listing time points and one with the values) to control an arbitrary memory location (e.g. a current, or in your case a variable in a MOD file).

Example that plays a stimulus into the ina variable:

Code: Select all

from neuron import h, gui
import numpy

# create a geometry
soma = h.Section(name='soma')

# insert variables for sodium ions
soma.insert('na_ion')

# driving stimulus
t = h.Vector(numpy.linspace(0, 2 * numpy.pi, 50))
y = h.Vector(numpy.sin(t))

# play the stimulus into soma(0.5)'s ina
# the last True means to interpolate; it's not the default, but unless
# you know what you're doing, you probably want to pass True there
y.play(soma(0.5)._ref_ina, t, True)

# setup a graph
g = h.Graph()
g.addvar("ina", soma(0.5)._ref_ina)
g.size(0, 6.28, -1, 1)
h.graphList[0].append(g)

# run the simulation
h.finitialize(-65)
h.continuerun(6.28)
ted
Site Admin
Posts: 6287
Joined: Wed May 18, 2005 4:50 pm
Location: Yale University School of Medicine
Contact:

Re: Computational Optogenetics: modelling ChR2 in NMODL

Post by ted »

A very efficient way to deal with functions that consist entirely of straight line segments is to store just the coordinates of the breakpoints in the vectors, and use the Vector class's play method with interpolation. Example:
This sequence of coordinates defines a ramp that begins at t = 0 and lasts for 10 ms, in which the function starts at 0 and ends at 5.

Code: Select all

tvec yvec
0    0
1    0
11   5
12    5
Note the point at (12, 5), which is needed to make the function remain constant after the end of the ramp. If you prefer to force it to fall back to 0 immediately after the end of the ramp and stay there, replace the (12, 5) with (11, 0) followed by (12, 0).

If your function can be expressed in analytical form, it may be more convenient to implement a POINT_PROCESS in NMODL and use that to calculate its value; for an example of a current clamp that generates a swept sine wave, see viewtopic.php?f=8&t=3676&p=15679.

cvode.event and an FInitializeHandler can be used to change the value of a parameter in the course of a simulation, but be sure to call cvode.re_init() after any such change if you're using adaptive integration (or suspect that your code might be reused by someone else who may want to use adaptive integration).
Post Reply