Page 1 of 1
object orientated gap juction
Posted: Sun Jun 28, 2009 1:18 am
by Bill Connelly
I'm trying to create a class for creating gap junctions, but I can't seem to get neuron to play nice.
The idea is that I can connect two cells by a gap junction by stating
objref gap[ngaps]
gap
= new gapjunction(cell1, cell2)
then I can access that gap junctions conductance with gap.g, and I could access methods for that gap junction with gap.proc, and recall the two cells that makes it up with gap.cell1 and gap.cell2
So this is what I have generate
Code: Select all
ncells = 2
begintemplate cell
public soma
create soma
proc init() {
soma {
nseg = 1
L = 30
diam = 30
insert hh
}
}
endtemplate cell
begintemplate gapjunction
public cell1, cell2, g
proc init() {
objref con1, con2
cell1 = $o1
cell2 = $o2
cell1 con1 = new Gap(0.5)
cell2 con2 = new Gap(0.5)
con1.g = 0.001
con2.g = 0.001
setpointer con1.vgap, cell2.v(0.5)
setpointer con2.vgap, cell1.v(0.5)
}
proc break {
con1.g = 0.000
con2.g = 0.000
}
endtemplate gapjunction
//============
//MAKE THE CELLS AND CONNECT THEM
//============
objectvar c[ncells]
for i=0, ncells-1 { c[i] = new cell() }
objectvar gaps[2]
gaps[0] = new gapjunction(c[i].soma, c[i+1].soma)
and the mod file that makes up the gap junction point process is
Code: Select all
NEURON {
POINT_PROCESS Gap
NONSPECIFIC_CURRENT i
RANGE g, i
POINTER vgap
}
PARAMETER {
g = 0.001 (microsiemens)
v (millivolt)
vgap (millivolt)
}
ASSIGNED {
i (nanoamp)
}
BREAKPOINT {
i = g * (v - vgap)
}
However I get an error
nrniv: syntax error
in C:/nrn71/ctxnet/cell.hoc near line 26
cell1 con1 = new Gap(0.5)
Any thoughts on what I've done wrong? Also I'm a bit confused about the "external" statement. It's just so that I could access functions or variables i'd defined, from inside the init() statement right? I also don't quite get the init() statement. I understand the code in the init() block is executed when you instantiate a new version of the template, but why would you have anything OUTSIDE the init block (apart from the public, external etc statements)?
Also, even if I insert a new Gap in a cell such that I don't get any errors; I still can't access g, which is declared in the parameters block of the mod file. That is I can not do the following
Code: Select all
create soma
objref gaps[1]
soma gaps[0] = new Gap(0.5)
setpointer gaps[0].vgap, soma.v(0.5)
print gaps[0].g
Error: g not a public member of Gap
I thought things in the parameters block could be accessed by neuron?
Re: object orientated gap juction
Posted: Sun Jun 28, 2009 2:03 am
by Bill Connelly
...and while I'm on OO, say I define a cell template with
Code: Select all
begintemplate cell
public soma, connections
objref connections
connections = new List()
create soma
proc init() {
soma {
nseg = 1
L = 30
diam = 30
insert hh
}
}
endtemplate cell
objref c[2]
c[0] = new cell()
However I get an error when I say
c[0].connections.append(someObjVar)
nrniv: append : object prefix is NULL
near line 31
c[0].connections.append(someObjVar)
What am I doing wrong?
Re: object orientated gap juction
Posted: Sun Jun 28, 2009 2:47 pm
by ted
Good questions, Bill. Here are some answers to your first post.
1. Sections cannot be passed as arguments, so anything that looks like
Code: Select all
gaps[0] = new gapjunction(c[i].soma, c[i+1].soma)
is doomed to fail. So you have a choice: either "hard wire" the sections that are to be connected into the definition of the gapjunction class, or create SectionRefs and pass those instead. Example:
Code: Select all
objref sr1, sr2
for i=0, ncells-2 {
c[i].soma sr1 = new SectionRef()
c[i+1].soma sr2 = new SectionRef()
gaps[i] = new gapjunction(sr1, sr2)
}
Of course, this forces revision of the gapjunction template.
2. In the gapjunction template, it no longer makes sense to have public objrefs called cell1 and cell2 (unless you build into the class a proc that determines the names of the cell classes from the SectionRefs that are passed to proc init()).
3. hoc uses a one-pass parser, so objrefs must be declared _outside_ of any proc or func before they can be used inside a proc or func. So right after the gapjunction template's public statement, declare con1 and con2 to be objrefs.
4. break is a reserved keyword--see
http://www.neuron.yale.edu/neuron/stati ... html#break
Even if declaring a proc break() worked, it would avoid user confusion to choose some other name. Or, if you were using a List instead of an array of objrefs to keep track of gap junctions, you can get rid of the ith one merely by saying
objref gjlist.o(i-1)
The revised template becomes
Code: Select all
begintemplate gapjunction
public g
objref con1, con2
proc init() {
objref con1, con2
$o1.sec con1 = new Gap(0.5)
$o2.sec con2 = new Gap(0.5)
con1.g = 0.001
con2.g = 0.001
setpointer con1.vgap, $o2.sec.v(0.5)
setpointer con2.vgap, $o1.sec.v(0.5)
}
proc breakgap() {
con1.g = 0.000
con2.g = 0.000
}
endtemplate gapjunction
Re: object orientated gap juction
Posted: Sun Jun 28, 2009 2:55 pm
by ted
To your second question, the answer is this:
In a template, statements outside of a proc or func are executed only when hoc first parses the code. Such statements are useful principally for telling hoc which names are public and which are objrefs. But before any objref can be used to refer to an instance of a particular class, it must appear in an
objrefname = new Classname
statement inside a proc or func. So create your List inside proc init(). Let me know if that takes care of the problem.
Re: object orientated gap juction
Posted: Sun Jun 28, 2009 7:13 pm
by Bill Connelly
Thanks Ted.
I'm still having trouble accessing the "g" parameter from HOC. This dot notation is correct isn't it?
$o1.sec con1 = new Gap(0.5)
$o2.sec con2 = new Gap(0.5)
con1.g = 0.001
con2.g = 0.001
but when I am refering to a section, I should say $o1.sec.g_Gap ? But nothing seems to work, apart from when I am accessing the defualt section, I can just type g_Gap and set and access the value, but I can't get it via sectionname.g_Gap or gapObjRef.g
Again, what am I doing wrong?
Re: object orientated gap juction
Posted: Mon Jun 29, 2009 12:48 pm
by ted
The g that is declared in the gapjunction template has nothing to do with the conductances assigned to the Gap objects' g parameter. Neither con1 nor con2 is public, so you can't access their g params. The Gap objects themselves are visible by calling them by their "actual" names, but that's exactly what you were trying to avoid having to do by wrapping them inside the gapjunction class.
If you want to change the junction's conductance from hoc, it's probably best to revise gapjunction like so:
Code: Select all
begintemplate gapjunction
public g, setg
objref con1, con2
proc init() {
objref con1, con2
$o1.sec con1 = new Gap(0.5)
$o2.sec con2 = new Gap(0.5)
// con1.g = 0.001
// con2.g = 0.001
if (numarg()==3) g = $3 // optional third argument is the conductance
if (numarg()==2) g = 0.001 // if omitted, set conductance to 0.001
setg(g)
setpointer con1.vgap, $o2.sec.v(0.5)
setpointer con2.vgap, $o1.sec.v(0.5)
}
proc setg() {
g = con1.g = con2.g = $1
}
proc breakgap() {
// con1.g = 0.000
// con2.g = 0.000
setg(0)
}
endtemplate gapjunction
Then after executing the original program with the new gapjunction class definition, a quick and dirty test:
Code: Select all
oc>gaps.g
0.001
oc>gaps.setg(0.3)
0
oc>gaps.g
0.3
oc>for i=0,1 print Gap[i].g
0.3
0.3
Note that the actual conductances are not directly accessible but instead are assigned by proc setg(), which ensures their equality and thereby preserves charge balance. Of course, one can subvert this by going directly to the underlying Gap objects. Maybe hoc needs a new keyword: perhaps a "no_perversity_or_stupid_tricks" switch to prevent deliberate abuse.
Re: object orientated gap juction
Posted: Mon Jun 29, 2009 11:48 pm
by Bill Connelly
Hmm, I am sure I copied you're code correctly, but I am still getting essentially the same error. Here is my code in full
Code: Select all
ncells = 2
begintemplate cell
public soma
create soma
proc init() {
soma {
nseg = 1
L = 30
diam = 30
insert hh
}
}
endtemplate cell
begintemplate gapjunction
public g, setg
objref con1, con2
proc init() {
objref con1, con2
$o1.soma con1 = new Gap(0.5)
$o2.soma con2 = new Gap(0.5)
// con1.g = 0.001
// con2.g = 0.001
if (numarg()==3) g = $3 // optional third argument is the conductance
if (numarg()==2) g = 0.001 // if omitted, set conductance to 0.001
setg(g)
setpointer con1.vgap, $o2.soma.v(0.5)
setpointer con2.vgap, $o1.soma.v(0.5)
}
proc setg() {
g = con1.g = con2.g = $1
}
proc breakgap() {
// con1.g = 0.000
// con2.g = 0.000
setg(0)
}
endtemplate gapjunction
objref cl
cl = new List()
objref tempcell
for i = 0, ncells-1 {
cl.append(new cell())
}
objref newgap
newgap = new gapjunction(cl.o(0), cl.o(1))
which returns
Code: Select all
g not a public member of Gap
nrniv: Gap g
in C:/nrn71/ctxnet/gaptest.hoc near line 60
newgap = new gapjunction(cl.o(0), cl.o(1))
^
gapjunction[0].setg(0.001 )
gapjunction[0].init(...... , )
initcode failed with 2 left
Re: object orientated gap juction
Posted: Tue Jun 30, 2009 11:23 am
by ted
Very strange. I simply copied the hoc from your most recent post, saved it to a file, and used nrngui to execute that file. No error messages, and the gapjunction class seems to work--
oc>newgap.g
0.001
oc>newgap.setg(0.01)
0
oc>newgap.g
0.01
Then I ran load_file("nrngui.hoc"), used the NEURON Main Menu toolbar to create a RunControl, IClamp attached to cell[0].soma(0.5) with del 1 ms, dur 0.1 ms, amp 3 nA, and a voltage axis graph that plots cell[0].soma.v(0.5) and cell[1].soma.v(0.5). Result: Init & Run shows that cell[0]'s soma fires a spike that crosses the time axis at about 3.05 ms, and cell[1] spikes a bit later (crosses t axis at ~ 3.825 ms).
Re: object orientated gap juction
Posted: Tue Jun 30, 2009 3:48 pm
by Bill Connelly
Hmmm... I recompilled nrnmech.dll and it still didn't work. Then I deleted nrnmech.dll and recompiled and it worked. Very strange. Thanks for all your help anyway.
Re: object orientated gap juction
Posted: Tue Jun 30, 2009 7:57 pm
by ted
Has all the earmarks of global climate change. Look out the window and see if the sea level isn't rising.