distributing mechanisms randomly

Anything that doesn't fit elsewhere.
Post Reply
adamimos
Posts: 45
Joined: Mon Jan 25, 2010 4:49 pm

distributing mechanisms randomly

Post by adamimos » Mon Apr 25, 2011 5:54 pm

Hello,

I was wondering if there was a built-in way to distribute let's say 1000 mechanisms uniformly randomly through a dendritic tree (let's say through a sectionList).

Otherwise I suppose the way to do it is to add up all the lengths, uniformly select 1000 numbers within the range of 0 to total length, and then go back and insert them according to the random numbers generated?

Thanks,
Adam

ted
Site Admin
Posts: 5628
Joined: Wed May 18, 2005 4:50 pm
Location: Yale University School of Medicine
Contact:

Re: distributing mechanisms randomly

Post by ted » Mon Apr 25, 2011 9:33 pm

What to do, and how to do it, depends on what kind of "mechanisms" you have in mind (density mechanisms vs. point processes), and your definition of "distribute randomly."

adamimos
Posts: 45
Joined: Mon Jan 25, 2010 4:49 pm

Re: distributing mechanisms randomly

Post by adamimos » Tue Apr 26, 2011 6:15 pm

ted wrote:What to do, and how to do it, depends on what kind of "mechanisms" you have in mind (density mechanisms vs. point processes), and your definition of "distribute randomly."
yes, sorry, should've been more precise. point processes (let's say simple alpha synapses), and distributed randomly means that i want the point processes to be uniformly distributed over the total length (ie. a section that is 9 times longer should have 9 times more probability of getting any one synapse), and then additionally it would be good to have the synapses temporally distributed (by that i mean the time at which the synapses fire) by some given distribution.

ted
Site Admin
Posts: 5628
Joined: Wed May 18, 2005 4:50 pm
Location: Yale University School of Medicine
Contact:

Re: distributing mechanisms randomly

Post by ted » Tue Apr 26, 2011 7:55 pm

adamimos wrote:i want the point processes to be uniformly distributed over the total length (ie. a section that is 9 times longer should have 9 times more probability of getting any one synapse)
The empirical basis for assuming constant density per unit length is what? The evidence with which I am familiar dates to anatomical studies in the early 1990s on neocortical and/or hippocampal pyramidal cells, and suggests that density per unit area is closer to being constant than is density per unit length.

For the sake of this discussion, assume a constant density per unit length which is called syndens, and that the synaptic mechanism class is called SynMech. Then you could proceed as follows:

1. Make a SectionList that contains all the neurites that you want to innervate. Call it "innervated".
2. Calculate the total length of all the neurites in that set.

Code: Select all

totalL = 0
forsec innervated totalL += L // iterate over all members of innervated
3. Attach the appropriate number of synapses to each segment of each neurite in the set.

Code: Select all

objref synlist, tobj
synlist = new List()
forsec innervated {
  seglength = L/nseg
  for (x,0) { // iterate over all segments of the currently accessed section
    calculate the number of synapses that should be attached to this segment
    create and attach them and append them to synlist
  }
  objref tobj // to prevent careless reuse of tobj from damaging the last synaptic mechanism
}
4. Set the parameters of the synaptic mechanisms.

Several devilish details are contained in these three lines:
calculate the number of synapses that should be attached to this segment
create and attach them
4. Set the parameters of the synaptic mechanisms.

Consider the first two:
calculate the number of synapses that should be attached to this segment
create and attach them and append them to synlist

Why "calculate the number of synapses that should be attached to this segment"? What's wrong with just calculating syndens*L/nseg, rounding to the nearest integer, and attaching that many synapses?

Because "synaptic density is syndens/um" does not mean that a compartment of length L/nseg is guaranteed to have syndens*L/nseg synapses. Ideally you should derive a discrete distribution that, given syndens and compartment length, tells you the probability that there will be 0, 1, 2 . . . synapses. The synaptic densities that I have seen are on the order of 1/um, and most compartments will be significantly longer than 10 um--indeed, probably 30 um or longer, for any reasonable spatial discretization strategy. Hint: you might be able to take advantage of the "law of large numbers" and the Gaussian distribution . . . (details left as an exercise to the reader)

So I will assume that you will have a function called numsyn that takes two arguments (synaptic density, and neurite length) and returns a whole number drawn from an appropriate distribution. The inner for loop then becomes

Code: Select all

  for (x,0) { // iterate over all segments of the currently accessed section
    nsyn = numsyn(syndens, L/nseg)
    for i = 1,nsyn {
      tobj = new SynMech(x)
      synlist.append(tobj)
    }
  }
Why use a List to manage the synaptic mechanisms? Because Lists are far and away the most convenient way to deal with collections of things, and because you have no idea, in advance, of how many instances of SynMech you are going to create.

When you have created all of your synapses, you can specify their properties by iterating over the contents of synlist.

Code: Select all

for i=0, synlist.count()-1 {
  synlist.o(i).param1 = whatever1
  synlist.o(i).param2 = whatever2
  synlist.o(i).onset = some_function()
  . . . etc. . . .
}
where some_function() is a func that returns the time at which you want this particular SynMech to be activated.

davidsterratt
Posts: 26
Joined: Tue Jan 17, 2006 11:36 am

Re: distributing mechanisms randomly

Post by davidsterratt » Mon May 02, 2011 9:53 am

I have a somewhat complicated hoc object that allows you to place point processes with a probability that depends on the diameter and length of the segment within a section, and of the perpendicular distance of the segment to some plane, which could be the cell body layer.

Please let me know if you'd like me to post this.

David.

adamimos
Posts: 45
Joined: Mon Jan 25, 2010 4:49 pm

Re: distributing mechanisms randomly

Post by adamimos » Mon May 02, 2011 2:09 pm

davidsterratt wrote:I have a somewhat complicated hoc object that allows you to place point processes with a probability that depends on the diameter and length of the segment within a section, and of the perpendicular distance of the segment to some plane, which could be the cell body layer.

Please let me know if you'd like me to post this.

David.
Hi David, that would be amazing (if it's not any work on your part, otherwise Ted gave me more than enough info)!

And thanks Ted, for your help!

Thanks.

adamimos
Posts: 45
Joined: Mon Jan 25, 2010 4:49 pm

Re: distributing mechanisms randomly

Post by adamimos » Mon May 02, 2011 8:13 pm

A related question: Now that I have a List with all the point processes, how do I mark them all on a ShapePlot?

Thanks again,
Adam

ted
Site Admin
Posts: 5628
Joined: Wed May 18, 2005 4:50 pm
Location: Yale University School of Medicine
Contact:

Re: distributing mechanisms randomly

Post by ted » Mon May 02, 2011 10:42 pm

In the Programmer's Reference read the documentation of the Shape class.

ted
Site Admin
Posts: 5628
Joined: Wed May 18, 2005 4:50 pm
Location: Yale University School of Medicine
Contact:

Re: distributing mechanisms randomly

Post by ted » Mon May 02, 2011 10:47 pm

davidsterratt wrote:I have a somewhat complicated hoc object that allows you to place point processes with a probability that depends on the diameter and length of the segment within a section, and of the perpendicular distance of the segment to some plane, which could be the cell body layer.
It would be very good of you to share that. Seeing code that others have found useful is indispensable for learning things that somehow don't get into books.

davidsterratt
Posts: 26
Joined: Tue Jan 17, 2006 11:36 am

Re: distributing mechanisms randomly

Post by davidsterratt » Wed May 04, 2011 10:41 am

OK, I will post the code on my website. I can't do it right now as the code is more involved than I recall - it requires three different types of object to work, and I need to produce a minimal example of its use rather than the gargantuan model I have at present.

However, I hope to have it early next week.

David.

adamimos
Posts: 45
Joined: Mon Jan 25, 2010 4:49 pm

Re: distributing mechanisms randomly

Post by adamimos » Wed May 04, 2011 5:04 pm

I can post up some very messy code, which I'm sure is not efficient at all, but just to give an example of how one might distribute some synapses:

Code: Select all

objref synList

////////use: aSynapseList = distSyns(numberOfSynapses,listOfSections,gMax,reversalPotential)
obfunc distSyns() { local totalSyns localobj lengthList, cumLList, tobj, toAdd, randomNum, r2, randomVec


   
   lengthList = new Vector(0)  // a vector that holds the lengths in order
   totalSyns = $1 // the number of point processes to add	 

   totalL = 0
   forsec $o2 {
       totalL += L  // this variable will hold the total length
       lengthList.append(L) 
   }

   cumLList = new Vector(lengthList.size()) //a cummulative sum of the lengths in order

   for i=0,lengthList.size()-1{
       cumLList.x[i]=lengthList.sum(0,i)
   }

   synList = new List() //this will be returned at the end of the code

   randomNum = new Random()
   randomNum.uniform(0,totalL)
   randomVec = new Vector(totalSyns)
   randomVec.setrand(randomNum)
   randomVec.sort()

   toAdd = new Vector(0)  // synapses to add in each iteration

   for i=0, lengthList.size()-1{ 
       //for each section check if random numbers were chosen within that length
        howManyToAdd=0
   	 while (randomVec.x[0]<cumLList.x[i]){
    	  howManyToAdd += 1
	  randomVec.remove(0)
	  if (randomVec.size()<1){randomVec.append(99999999999999)}
   	  }  //end while	  
 	  toAdd.append(howManyToAdd)
} // end for

ind = 0
r2 = new Random()

// add synapses to random locations within each section as appropriate
forsec $o2 {
       for i=1,toAdd.x[ind]{
       	   where = r2.uniform(0,1)
	   tobj = new AlphaSynapse(where)
	   synList.append(tobj)
       }
       ind+=1
}


for i=1,synList.count()-1{
    synList.object(i).onset = r2.normal(90,300)
    synList.object(i).tau = 1.5 
    synList.object(i).gmax = $3 
    synList.object(i).e = $4  
}



	return synList

} //end procedure

ted
Site Admin
Posts: 5628
Joined: Wed May 18, 2005 4:50 pm
Location: Yale University School of Medicine
Contact:

Re: distributing mechanisms randomly

Post by ted » Thu May 05, 2011 12:22 pm

You're on the right track.

It's a good idea to avoid code that has nested loops like this

Code: Select all

for i=0,n
  for j=0,i
because execution time will be proportional to i^2. Example:

Code: Select all

   for i=0,lengthList.size()-1{
       cumLList.x[i]=lengthList.sum(0,i)
   }
There really isn't any need to generate two random numbers for each synaptic mechanism that is to be placed. One number in the range [0, mmax], where mmax is total neurite length (or total surface area, if synaptic density is specified in number/area), specifies location unambiguously.

Here's what I'd suggest:

Code: Select all

/* assumes
1. sections to be innervated have been appended to a SectionList called seclist
2. synaptic density is in units of number/(length in um)
3. geometry specification has been completed, including spatial discretization
4. total number of synapses to distribute is called NUMSYN
*/
numsegs = 0 // will be total number of segments
forsec seclist numsegs+=nseg
objref mvec
mvec = new Vector(numsegs) // will hold cumulative sums of segment length
// each element in mvec corresponds to a segment in seclist

ii = 0 // to iterate over mvec
mtotal = 0 // will be total length in seclist
forsec seclist {
  for (x,0) { // iterate over internal nodes of current section
    mtotal += L/nseg // or area(x) if density is in (number)/area
    mvec.x[ii] = mtotal
    ii += 1
  }
}
/*
now mvec.x[ii] is the sum of segment lengths (or areas)
for all segments up to and including segment ii
*/

objref nvec
nvec = new Vector(numsegs, 0) // fill elements with 0
// each element in nvec corresponds to a segment in seclist
// when done, each element will hold the number of synaptic mechanisms
// that are to be attached to the corresponding segment
for ii=1,NUMSYN {
  x = a value drawn from uniform distribution over [0,mtotal]
  jj = mvec.indwhere(">=", x) // the first element in mvec that is >=x 
  // this is the index of the segment that should get the synapse
  nvec.x[jj] += 1
}

objref synlist
synlist = new List()
ii = 0
forsec seclist {
  for (x, 0) {
    num = nvec.x[ii]
    if (num>0) {
      for jj=1,num synlist.append(new SynMech(x))
      // to keep this entirely generic
      // defer param specification until later
    }
    ii += 1 // we're moving on to the next segment,
      // so move on to the next element of nvec
  }
}

davidsterratt
Posts: 26
Joined: Tue Jan 17, 2006 11:36 am

Re: distributing mechanisms randomly

Post by davidsterratt » Mon Jan 28, 2013 12:35 pm

As promised over a year ago, here is my PointProcessDistributor code:
http://homepages.inf.ed.ac.uk/sterratt/node/54

I've only just packaged it up, so please let me know if there are problems; it's not the most elegant of code and the documentation could be better!

Post Reply