Adding Synapses to Pre-existing model

The basics of how to develop, test, and use models.
Post Reply
nemomortus
Posts: 11
Joined: Fri Jan 08, 2016 11:05 pm

Adding Synapses to Pre-existing model

Post by nemomortus »

Dear Ted,

Thank you for all of our previous interactions. II have been working with NEURON for the past couple of weeks and I fainlly feel I am now somewhat competent after reading and testing my understanding of what NEURON can do. My current goal is to successfully add X number of excitatory synapses to a pre-existing cell model of L5B pyramidal cells (modelDB: 139653). I want to then stimulate each of these synapses with an independently-generated Poisson train.

What I have boiled it down to is to add X unique number of EXP2SYN / NETSTIM and connect the pair (source, target) with X NETCONs to stimulate each. I have run the simulation: (1) with adding the excitatory synapses I have created and (2) without (by taking the proc out). I have not changed any of the original cell parameters, and have just loaded the cell for my stated purpose. Both produce identical graphs show below, respectively.

(1) graph: Image
(2) graph: Image

I will attach my code at the end, but I would love some guidance on why the graphs are identitcal. My three questions:

1. How can I easily check the connection of the cell? I have gone through the source code and have played around to determine where the cells are connected, but I feel there should be an easier way than this.

2. How can I check if my NetCon is working properly and connecting the source and target? I am recording idvec and seeing if the parameters are matching for NetStim (particularly the .number) and it seems to be working as expected.

3. Sometimes when I run my code again after loading my cell and mod files (without quitting NEURON) i get the line:
"initcode failed with 1 left." What does this mean? This usually goes away if I quit the opened graph window before I run my simulation a second time.

Code: Select all


//=================== creating cell object ==========================
objref cvode
cvode = new CVode()
cvode.active(1)
load_file("import3d.hoc")

objref L5PC
strdef morphology_file
morphology_file = "../morphologies/cell1.asc"

load_file("../models/L5PCbiophys3.hoc")
load_file("../models/L5PCtemplate.hoc")
L5PC = new L5PCtemplate(morphology_file)

load_file("stdlib.hoc") 
load_file("nrngui.hoc")
load_file("ranstream.hoc")

//-------------------parameters-----------------------//
v_init = -80 
eNSNUM = 150       // how many NetStims to create
MAXSTREAM = 1000 
tstop = 300       // length of simulation
dendnseg = 1      // as determind by the original model

//-------------------parameters for NetStim-----------//
// this generates a presynaptic train of stimuli
spikeint = 10    // (ms) mean time between spikes, 1000(ms) to get 1 Hz 
nspikes = 50     // average number of spikes, that NetStim will produce. how do i choose this number?
spikeonset = 1    // start time of first spike
noise = 1         // set to 1 for poisson mode

//-------------------parameters for Exp2Syn-----------//
// S = 1 / Ohms. G is in microOhms
// TAU1 and TAU2 parameters for L5PC in a paper
TAU1 = 0.20     
TAU2 = 1.7
excite = 0

//-------------------parameters for NetCon------------//
// not sure what parameters to set for this setion. arbitrarily picked
THRESHOLD =  10
DELAY = 0.5
WEIGHT = 0.1

//-------------------MODEL SETUP-----------------------//
objref nslist, rslist, eslist, nclist
nslist = new List()   // NetStim list
rslist = new List()   // RandStream list
eslist = new List()   // Exp2Syn list

//----- make_stims create excitatory synapses, all firing randomly-----//
proc syn_excite() { local i  localobj ns, rs, es, r
  nslist = new List()   
  rslist = new List()   
  eslist = new List()   

  random_stream_offset_ = MAXSTREAM

  for i = 0, $1-1 {
    ns = new NetStim()
    nslist.append(ns)
    rs = new RandomStream(i)
    rslist.append(rs)
    ns.noiseFromRandom(rs.r)
    rs.r.negexp(1)              // must specify negexp distribution with mean = 1
    rs.start()                  // makes random noise and writes results in list
  }

  r = new Random()
  
  for i = 0, $1-1 {
    s1dend= 1                        //s1 dendrite, in our case, we only have 1 dend
    s1comp= r.uniform(0, dendnseg)  //s1 compartment --- choose a random (discunif = discrete uniform) compartment of dendrites
    s1coord= s1comp / dendnseg       //s1 coordinate, remember dendnseg is 1 by original cell model

    access L5PC.dend[s1dend] 
    es = new Exp2Syn(s1coord)         //places Exp2Syn on dend in compartment with coordinate s1
    eslist.append(es)
    access L5PC.soma                  //replace pointer back onto soma (default)
  }
}

syn_excite(eNSNUM)

proc setparams() {local i, j
  for i = 0,nslist.count()-1 {
    nslist.o(i).interval = spikeint
    nslist.o(i).number = nspikes
    nslist.o(i).start = spikeonset
    nslist.o(i).noise = noise
  }

  for i = 0,eslist.count()-1 {                        
    eslist.o(i).tau1 = TAU1    //rise time (ms)
    eslist.o(i).tau2 = TAU2    //delay time (ms)
    eslist.o(i).e = excite     //reversal potential, change this to make it inhibitory
  }
}
setparams()             // default is deterministic spike times (NOISE = 0)

//-------------------instrumentation-----------------------//
// this is where NetCon is caled and connects the NetStim and EXP2SYN

objref tvec, idvec, i_tvec, i_idvec
idvec = new Vector()
tvec = new Vector()
i_idvec = new Vector()
i_tvec = new Vector() 

proc instrumentation() { local i  localobj nc, inc 
  for i = 0,nslist.count()-1 {
    nc = new NetCon(nslist.o(i), eslist.o(i), THRESHOLD, DELAY, WEIGHT)
    nc.record(tvec, idvec, i)
  }
}
instrumentation()

proc restart(){ local i
  for i = 0, rslist.count()-1{
  rslist.o(i).start()
  }
}

//check if nslist is being created and edited
proc check(){
  print nslist.count, ": this is how big nslist is"
  print nslist.o(23).number, ": this is .number of NetStim \n" //arbitrary i
  print "this is idvec, being generated by NetCon: "
  idvec.printf 
}

proc myrun(){
  finitialize(v_init)
  fcurrent()
  run()
  restart()             // restore each generator to the start of its stream
}

//======================= plot settings ============================
objref gV, tempVec

gV = new Graph()
gV.size(0,tstop,-80,40)
graphList[0].append(gV)
access L5PC.soma
gV.addvar("soma","v(0.5)",1,1)

//-------------------starting simulation-----------------------//
myrun()
check()
print "done!"
ted
Site Admin
Posts: 6286
Joined: Wed May 18, 2005 4:50 pm
Location: Yale University School of Medicine
Contact:

Re: Adding Synapses to Pre-existing model

Post by ted »

First, an important comment: those plots of membrane potential vs. time reveal that the model cell is not properly initialized. It's starting far from a steady state initial condition. Unless initialization is fixed, nothing else will matter. We can return to this in future posts.

Second, for several days now, technical problems have interfered with access to ModelDB (indeed, the entire SenseLab site). Until that is resolved, my comments can only be rather general; I won't be able to say anything that pertains specifically to any given ModelDB entry.
I want to then stimulate each of these synapses with an independently-generated Poisson train.
So you have associated each NetStim with its own pseudorandom number generator. Good!
How can I easily check the connection of the cell?
Think about the possible causes of problems. Is each NetStim generating events during the simulation? (you can check that by examining the contents of tvec and idvec). Are the events associated with nonzero weights? (use a for loop to iterate over all NetCons) Are the synaptic mechanism time constants > 0, and are the synaptic reversal potentials correct? (use another for loop to iterate over the synaptic mechanism instances) Does everything work together? (make a toy model that has just two or three NetStims, NetCons, and synaptic mechanisms, and plot the time courses of the individual synaptic conductances and currents)
3. Sometimes when I run my code again after loading my cell and mod files (without quitting NEURON) i get the line:
"initcode failed with 1 left." What does this mean?
Unfortunately that message doesn't provide any useful clues. Maybe the computational engine is complaining about an initialization problem. A lot of user-written NMODL code doesn't handle initialization correctly, and even when they're perfectly OK, models that have nonuniform membrane properties can be difficult to initialize because of the complexities of interactions between otherwise well-behaved mechanisms. Initialization with fixed step integration tends to be more robust. Does the problem go away when you don't activate cvode? Why use cvode at all?

Other comments on the code example:

Code: Select all

load_file("import3d.hoc")

objref L5PC
strdef morphology_file
morphology_file = "../morphologies/cell1.asc"
Why import data straight from morphometric data files? Is it necessary to reuse this code with many different morphometric data sources? Where is the code that handles spatial discretization? It isn't useful to try to control temporal error (by using adaptive integration) while ignoring spatial error. That alone could cause the error message you saw.

Code: Select all

nspikes = 50     // average number of spikes, that NetStim will produce. how do i choose this number?
With negexp ISI, nspikes merely sets an upper limit on the number of events that a NetStim can generate. The actual number for any given run can never be less than 0 or more than nspikes.

Code: Select all

    access L5PC.dend[s1dend] 
 . . .
    access L5PC.soma                  //replace pointer back onto soma (default)
An example of "access abuse"--you'll find comments about this in the Form. Use "access" only once in a program, and then only to tell NEURON which section is conceptually most important (usually the soma). Don't use "access" to specify the currently accessed section--use section stack notation instead, e.g.

Code: Select all

L5PC.dend[s1dend] statement
or

Code: Select all

L5PC.dend[s1dend] {
  compound statement
}
Otherwise you're setting traps for yourself and others who may try to reuse your code in the future.

proc restart() shouldn't be necessary--the standard run system default initialization should reset each random stream generator to the beginning of its sequence. Comment out the call to proc restart() and see for yourself whether each NetStim's event times are the same on each run.

proc myrun() is also not necessary, since run() automatically calls finitialize and fcurrent.

Oops, another (mis)use of access--
access L5PC.soma
gV.addvar("soma","v(0.5)",1,1)
Just do this
L5PC.soma gV.addvar("soma","v(0.5)",1,1)
or, if you prefer, this
gV.addvar("soma","L5PC.soma.v(0.5)",1,1)
nemomortus
Posts: 11
Joined: Fri Jan 08, 2016 11:05 pm

Re: Adding Synapses to Pre-existing model

Post by nemomortus »

Dear Ted, thank you for your quick and detailed response! It has been very helpful into guiding me in the right direction. It is unfortunate that modelDB is not working, so would you like me to send you the zip file that contains my code as well as the original code for the modelDB file I am using? Perhaps this would help somewhat. If not, I appreciate the general feedback as I am already learning a lot discussing ideas and asking questions! I apologize in advance for asking any stupid questions as I am still trying to grasp the hang of this.
First, an important comment: those plots of membrane potential vs. time reveal that the model cell is not properly initialized.
I am basing my cell initialization off of Etay Hay’s “Step_current_firing.hoc” file inside his modelDB file, I was under the impression that the “//=====CREATING THE CELL OBJECT======” section of the code at the start, imports all of the necessary initialization for the cell to work properly. I know realize that this may be an erroneous assumption. My question now is how do I know how to properly initialized the cell?
Is each NetStim generating events during the simulation? (you can check that by examining the contents of tvec and idvec.
Yes! I have done this and this was the first thing I checked if it was working. tvec and idvec vectors has the expected values.
Are the events associated with nonzero weights? (use a for loop to iterate over all NetCons)
How do you check for nonzero weights? I see my nc.weight has been changed to the variable at the start of the program, but I’m not sure what you mean by “events associated with these nonzero weights."
Are the synaptic mechanism time constants > 0, and are the synaptic reversal potentials correct? (use another for loop to iterate over the synaptic mechanism instances)

I am unsure what you mean by "iterating over the synaptic mechanism instances." Do you mean to follow a certain ion in the cell throughout the simulation (like Na or K)?
Does everything work together? (make a toy model that has just two or three NetStims, NetCons, and synaptic mechanisms, and plot the time courses of the individual synaptic conductances and currents)
I will finish making a toy model after I understand the above questions.
Does the problem go away when you don't activate cvode? Why use cvode at all?
The problem seems to persist even if cvode is taken away. The main reason I used cvode because I was modeling initialization of the L5PC based on Etay Hay’s previous “Step_current_firing.hoc” model (I have attached it at the end of this post). Hay added it into his code, and I thought it was necessary for the model to work (after reading some literature about what CVODE does). But like you said, it may be a problem associated with initialization, so I will worry about it more in the future.
Why import data straight from morphometric data files? Is it necessary to reuse this code with many different morphometric data sources? Where is the code that handles spatial discretization? It isn't useful to try to control temporal error (by using adaptive integration) while ignoring spatial error. That alone could cause the error message you saw.
Like my previous response, I am under the impression this import of data is necessary to initialize the cell. It is not necessary to reuse this code with many different morphometric data sources. I am unaware that there needs to be code that handles spatial discretization... I will read up on that now, but do you have any good sources I should read up on?

As for access abuse, I understand now my errors and have changed my code accordingly. Thanks for pointing it out!

Code: Select all

//Author: Etay Hay, 2011
//  Models of Neocortical Layer 5b Pyramidal Cells Capturing a Wide Range of
//  Dendritic and Perisomatic Active Properties
//  (Hay et al., PLoS Computational Biology, 2011) 
//
// A simulation of L5 Pyramidal Cell under a prolonged step current

load_file("nrngui.hoc")

objref cvode
cvode = new CVode()
cvode.active(1)

//======================== settings ===================================

v_init = -80

//step 1: 0.619
//step 2: 0.793
//step 3: 1.507
	
step_amp = 0.793		
tstop = 2000

//=================== creating cell object ===========================
load_file("import3d.hoc")
objref L5PC

strdef morphology_file
morphology_file = "../morphologies/cell1.asc"

load_file("../models/L5PCbiophys3.hoc")
load_file("../models/L5PCtemplate.hoc")
L5PC = new L5PCtemplate(morphology_file)

//==================== stimulus settings ===========================

objref st1

st1 = new IClamp(0.5)  	// change where it is positioned
st1.del = 500			//	delay until onset of simulation (ms)
st1.dur = 1000			//  duration of simulation (ms)
st1.amp = step_amp		// delay amplitude (in nA)

L5PC.soma st1

//==================== recording settings ==========================

objref vvec, tvec

vvec = new Vector()
tvec = new Vector()

access L5PC.soma
cvode.record(&v(0.5),vvec,tvec)

objref apcvec, apc
apcvec = new Vector()
apc = new APCount(0.5)
apc.thresh= -10
apc.record(apcvec)

//======================= plot settings ============================

objref gV, cS

gV = new Graph()
gV.size(0,tstop,-80,40)
graphList[0].append(gV)
access L5PC.soma
gV.addvar("soma","v(0.5)",1,1)

//============================= simulation ================================
init()
run()

print "spike count = ", apcvec.size()
ted
Site Admin
Posts: 6286
Joined: Wed May 18, 2005 4:50 pm
Location: Yale University School of Medicine
Contact:

Re: Adding Synapses to Pre-existing model

Post by ted »

nemomortus wrote:unfortunate that modelDB is not working
I was able to get the zip file of the original model. Some comments about that below.

Hay's source code does not initialize the model to steady state. The model has spatially nonuniform membrane properties, and includes a calcium accumulation mechanism--attributes that make initialization to steady state nontrivial. Hay's solution was to let the simulation execute until things settle down, then apply stimuli (injected current or whatever). I suspect that adaptive integration was used to try to speed up convergence to steady state. That said, it was a naive attempt, because the wide range of state scales (e.g. membrane potential vs. calcium concentration) really requires use of different absolute tolerance scale factors--otherwise the states with the largest numerical values will completely dominate the integrator's choice of dt and integration order; see https://www.neuron.yale.edu/neuron/stat ... .atolscale. Selection of appropriate scale factors can be a tedious manual task that requires judgement, or it can be automated with the GUI's VariableStepControl tool. For whatever reason--blind reliance on one's raw programming prowess, disdain for learning anything about GUI tools, failure to RTFM--too many users just plow ahead with the attitude of "I wrote it, it runs, the results must be correct."
Is each NetStim generating events during the simulation? (you can check that by examining the contents of tvec and idvec.
Yes! I have done this and this was the first thing I checked if it was working. tvec and idvec vectors has the expected values.
Good. Then the question is whether the NetCon weights are large enough to produce significant synaptic currents.
Are the events associated with nonzero weights? (use a for loop to iterate over all NetCons)
How do you check for nonzero weights?
Presumably you have a list that refers to all the NetCon instances that connect your NetStims to the synaptic mechanisms. If it's called netconlist, then
for i=0,netconlist.count()-1 print i, " ", netconlist.o(i).weight
will report all of their weights.
Are the synaptic mechanism time constants > 0, and are the synaptic reversal potentials correct? (use another for loop to iterate over the synaptic mechanism instances)
I am unsure what you mean by "iterating over the synaptic mechanism instances."
If the List that refers to all the synaptic mechanism instances is called synlist, and the time constants are called tau1 and tau2, then
for i=0,synlist.count()-1 print i, " ", synlist.o(i).tau1, " ", synlist.o(i).tau2
will tell you what you need to know about the time constants. Only minor revision needed to report the synaptic reversal potentials.
Does the problem go away when you don't activate cvode? Why use cvode at all?
The problem seems to persist even if cvode is taken away. The main reason I used cvode because I was modeling initialization of the L5PC based on Etay Hay’s previous “Step_current_firing.hoc” model (I have attached it at the end of this post). Hay added it into his code, and I thought it was necessary for the model to work
Hay used it to dodge the performance penalty of having to wait for hundreds of ms while the model settled down. Adaptive integration is more finicky about stability of ODEs, especially those that are in user-written mod files. That might be why you're getting "initcode failed" messages.

By the way, about half of the mod files contain formulas that have singularities--expressions in which numerator and denominator both become 0 at a given membrane potential. Most of them use very kludgy, naive workarounds, instead of applying a principled approach like one based on Taylor's series expansion or L'hospital's rule. That might account for "initcode failed" messages too.
Why import data straight from morphometric data files? Is it necessary to reuse this code with many different morphometric data sources? Where is the code that handles spatial discretization? It isn't useful to try to control temporal error (by using adaptive integration) while ignoring spatial error. That alone could cause the error message you saw.
Like my previous response, I am under the impression this import of data is necessary to initialize the cell. It is not necessary to reuse this code with many different morphometric data sources. I am unaware that there needs to be code that handles spatial discretization... I will read up on that now, but do you have any good sources I should read up on?
You might find it useful to read about the d_lambda rule
Hines, M.L. and Carnevale, N.T.
NEURON: a tool for neuroscientists.
The Neuroscientist 7:123-135, 2001.
Preprint available from a link at http://www.neuron.yale.edu/neuron/nrnpubs
The model source code apparently uses a fixed dL rule (tries to keep segment lengths < 40 um), but that isn't adequate with a model like this in which many neurites have very small diameters.

Fixing adaptive integration scale factors and the spatial discretization strategy may make the model better behaved during initialization, and will help it generate results that more accurately reflect its anatomical and biophysical properties; it remains to be seen whether those results will be qualitatively similar to those published by the model's authors.
nemomortus
Posts: 11
Joined: Fri Jan 08, 2016 11:05 pm

Re: Adding Synapses to Pre-existing model

Post by nemomortus »

Thanks for the great insight Ted. For the initialization I think I will try to use GUI's VariableStepControl tool to initialize the model to steady state at the beginning! I have been reading up on the GUI and I believe by loading the parameters the GUI outputs from the ses file, it should be sufficient.
Hay used it to dodge the performance penalty of having to wait for hundreds of ms while the model settled down. Adaptive integration is more finicky about stability of ODEs, especially those that are in user-written mod files. That might be why you're getting "initcode failed" messages.
Thank you for pointing this out. I think once I get a better understanding of NEURON I can better fix this problem.
The model source code apparently uses a fixed dL rule (tries to keep segment lengths < 40 um), but that isn't adequate with a model like this in which many neurites have very small diameters....
I have also seen the source code that uses a fixed dL rule, but since this model has very small diameters as you've mentioned. I thought the source code actually uses the spacial discretion strategy of (d_lambda rule). In that same regards, what would you suggest what spacial discretion strategy should I use?
Why import data straight from morphometric data files? Is it necessary to reuse this code with many different morphometric data sources?
Could you clarify further why loading the morphological code is not necessarily good? Maybe I'm not understanding what the morphological code does... please correct me if I'm wrong. The morphological code loads up the certain type of cell and creates it in 3D space in NEURON.

Other issues you've answered:
As for the weights and time constant checks, thank you for your clarification! I have checked everything and it seems to be in place. In fact, for those following I realized what was 'wrong' with my code. I did not make a list for the NetCons. Once I made an objref nc and nc = new List, and used nc.append to append the created NetCon into the new list, the simulation immediately began to "work" (figure + code revision below). Ted, could you explain why this would happen? I thought just from my original code the NetCons would work but apparently it didn't when the NetCons failed to be appended onto a list.

Code: Select all

 //-------------------instrumentation-----------------------//
// this is where NetCon is caled and connects the NetStim and EXP2SYN

objref nclist, tvec, idvec
idvec = new Vector()
tvec = new Vector()
nclist = new List()

proc instrumentation() { local i  localobj nc, inc 
  for i = 0,nslist.count()-1 {
    nc = new NetCon(nslist.o(i), eslist.o(i), THRESHOLD, DELAY, WEIGHT)
    nclist.append(nc)
    nc.record(tvec, idvec, i)
  }
}
instrumentation()
Image
nemomortus
Posts: 11
Joined: Fri Jan 08, 2016 11:05 pm

Re: Adding Synapses to Pre-existing model

Post by nemomortus »

Sorry, but another quick question... I would like the excitatory synapses to have excitatory quantal conductances of 1 nS. Is there a parameter I could easily change in Exp2Syn to achieve this? I thought about changing the synaptic current (syn.i) to 1 nA, but I know this is insufficient in changing the quantal conductance (G) as i = G (v - e) and G = weight * factor * (exp(-t/tau2) - exp(-t/tau1))...
ted
Site Admin
Posts: 6286
Joined: Wed May 18, 2005 4:50 pm
Location: Yale University School of Medicine
Contact:

Re: Adding Synapses to Pre-existing model

Post by ted »

nemomortus wrote:For the initialization I think I will try to use GUI's VariableStepControl tool to initialize the model to steady state at the beginning!
The important thing is to use its Atol Scale Tool to perform an "Analysis Run," then click on the latter's Rescale button. Click on the AtolScale Tool's "Help" button to find out more.
I thought the source code actually uses the spacial discretion strategy of (d_lambda rule). In that same regards, what would you suggest what spacial discretion strategy should I use?
The d_lambda rule with d_lambda set to 0.1 length constant at 100 Hz generally produces results that are "good enough" (fine enough spatial grid for good accuracy, not so fine as to needlessly prolong simulations). It's always a good idea to run a couple of tests--do one run using the d_lambda rule, then triple the number of compartments
forall nseg*=3
and run another test, and compare results. If there isn't a significant qualitative or quantitative change, then the first discretization was adequate.
Could you clarify further why loading the morphological code is not necessarily good?
First, it adds an unnecessary complication to the program. Keep programs short and simple, and they'll be easier to debug and maintain.

Second, there isn't any "morphometric data files inspection authority" that goes around checking them, like FDA's meat inspectors. It's never a good idea to assume that anybody else's data file is free of errors--and morphometric data files often have problems like orphan sections or trees, or other problems that are only discovered when the file is read by the Import3D tool. The Import3D tool reports those errors and suggests fixes or workarounds.

"Oh, but I'm sure these files are good, because the original authors are geniuses and never make mistakes."

Yes, and I know there are very smart people who work in big teams, where some players generate clean morphometric data and others reuse that data. If you're in one of those labs, fine, do what you have to do. But in general it's not a good idea to trust morphometric data files without verifying by going through the step of using the Import3D tool--if they aren't good, it's only your time, effort, and reputation that are at stake. A safer workflow is
1. use Import3D to get the data into a CellBuilder
2. save that CellBuilder to a ses file
3. use that CellBuilder to export a hoc file, either of a "top level" cell or a cell class, depending on what you want. Be sure to specify that spatial discretization is to use the d_lambda rule (unless you have a very good reason not to). The exported hoc file will contain a proc geom_nseg() that you can call after your model's Ra and cm have been specified in all sections. That will apply the d_lambda rule to each branch in your model.
Once I made an objref nc and nc = new List, and used nc.append to append the created NetCon into the new list, the simulation immediately began to "work"
I'm glad you figured that out for yourself.
could you explain why this would happen?
In your original code, each time you created a new NetCon you killed the one that was created previously. NEURON keeps track of the "reference count" for every object instance that is created. When an object instance's reference count falls to 0, the object is deleted--this is called garbage collection, which is a standard feature of many programming languages. To see it in action, start NEURON and execute the following commands, one after another.

objref g
g = new Graph()

Now there is an objref called g, and g points to an instance of the Graph class.
Confirm this by executing the next command:

print g

Note that g points to Graph[0]. What happens if you do this?

g = new Graph()
print g

Does Graph[0] still exist? Find out by

print Graph[0]

What did hoc tell you?

Now exit and restart NEURON. This time execute these commands:

objref g
g = new List()
g.append(new Graph())
g.append(new Graph())
for i=0,g.count()-1 print g.o(i)

Both Graph instances persist because they are referenced by the elements in g.
nemomortus
Posts: 11
Joined: Fri Jan 08, 2016 11:05 pm

Re: Adding Synapses to Pre-existing model

Post by nemomortus »

Thanks for all of the clarification of the initialization, spacial discretion, and checking the morphological data! I understand better now and have made the appropriate changes. In particular, you explanation for the NetCon list makes a lot of sense. I was dumb to assume that NEURON would just keep count arbitrarily and not actually overwrite the previous one.

I do have a new question though, that I think may have a simple answer, but I am having a hard time doing it. I would like my excitatory synapses to have excitatory quantal conductances of 1 nS. Is there a parameter I could easily change in Exp2Syn to achieve this? I thought about changing the synaptic current (syn.i) to 1 nA, but I know this is insufficient in changing the quantal conductance (G) as i = G (v - e) and G = weight * factor * (exp(-t/tau2) - exp(-t/tau1))...
ted
Site Admin
Posts: 6286
Joined: Wed May 18, 2005 4:50 pm
Location: Yale University School of Medicine
Contact:

Re: Adding Synapses to Pre-existing model

Post by ted »

nemomortus wrote:I was dumb to assume that NEURON would just keep count arbitrarily and not actually overwrite the previous one.
Not really. In the absence of any other information, you had a 50-50 chance of guessing correctly. Somehow, every time I make a guess and the odds seem about 50-50, I usually turn out to have guessed incorrectly.
I would like my excitatory synapses to have excitatory quantal conductances of 1 nS. Is there a parameter I could easily change in Exp2Syn to achieve this?
No. ExpSyn and Exp2Syn are described by linear ODEs that are perturbed by the weight associated with an input event, and the weight can be any floating point value. If you really need a model of quantal synaptic transmission, use something like Example 10.6: Saturating synapses in chapter 10 of The NEURON Book, or pick up
https://www.neuron.yale.edu/ftp/ted/neuron/chance.zip
and see if anything in that does what you want. Note that those old mod files would have to be modified to allow each synaptic instance to be paired with its own pseudorandom number generator (so that the pattern of quantal release by each synapse point process is statistically independent of the pattern of release by any other synapse point process).
Post Reply