object orientated gap juction

The basics of how to develop, test, and use models.
Post Reply
Bill Connelly
Posts: 86
Joined: Thu May 22, 2008 11:54 pm
Location: Australian National University

object orientated gap juction

Post 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?
Last edited by Bill Connelly on Sun Jun 28, 2009 2:47 am, edited 2 times in total.
Bill Connelly
Posts: 86
Joined: Thu May 22, 2008 11:54 pm
Location: Australian National University

Re: object orientated gap juction

Post 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?
ted
Site Admin
Posts: 5810
Joined: Wed May 18, 2005 4:50 pm
Location: Yale University School of Medicine
Contact:

Re: object orientated gap juction

Post 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
ted
Site Admin
Posts: 5810
Joined: Wed May 18, 2005 4:50 pm
Location: Yale University School of Medicine
Contact:

Re: object orientated gap juction

Post 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.
Bill Connelly
Posts: 86
Joined: Thu May 22, 2008 11:54 pm
Location: Australian National University

Re: object orientated gap juction

Post 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?
ted
Site Admin
Posts: 5810
Joined: Wed May 18, 2005 4:50 pm
Location: Yale University School of Medicine
Contact:

Re: object orientated gap juction

Post 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.
Bill Connelly
Posts: 86
Joined: Thu May 22, 2008 11:54 pm
Location: Australian National University

Re: object orientated gap juction

Post 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
ted
Site Admin
Posts: 5810
Joined: Wed May 18, 2005 4:50 pm
Location: Yale University School of Medicine
Contact:

Re: object orientated gap juction

Post 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).
Bill Connelly
Posts: 86
Joined: Thu May 22, 2008 11:54 pm
Location: Australian National University

Re: object orientated gap juction

Post 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.
ted
Site Admin
Posts: 5810
Joined: Wed May 18, 2005 4:50 pm
Location: Yale University School of Medicine
Contact:

Re: object orientated gap juction

Post by ted »

Has all the earmarks of global climate change. Look out the window and see if the sea level isn't rising.
Post Reply