Electrostimulation to reduce synaptic scaling driven progression of Alzheimers (Rowan et al. 2014)

 Download zip file   Auto-launch 
Help downloading and running models
"... As cells die and synapses lose their drive, remaining cells suffer an initial decrease in activity. Neuronal homeostatic synaptic scaling then provides a feedback mechanism to restore activity. ... The scaling mechanism increases the firing rates of remaining cells in the network to compensate for decreases in network activity. However, this effect can itself become a pathology, ... Here, we present a mechanistic explanation of how directed brain stimulation might be expected to slow AD progression based on computational simulations in a 470-neuron biomimetic model of a neocortical column. ... "
1 . Rowan MS, Neymotin SA, Lytton WW (2014) Electrostimulation to reduce synaptic scaling driven progression of Alzheimer's disease. Front Comput Neurosci 8:39 [PubMed]
Citations  Citation Browser
Model Information (Click on a link to find other models with that property)
Model Type: Realistic Network;
Brain Region(s)/Organism: Neocortex;
Cell Type(s): Neocortex L5/6 pyramidal GLU cell; Neocortex L2/3 pyramidal GLU cell; Neocortex V1 interneuron basket PV GABA cell; Neocortex fast spiking (FS) interneuron; Neocortex spiny stellate cell; Neocortex spiking regular (RS) neuron; Neocortex spiking low threshold (LTS) neuron;
Gap Junctions:
Receptor(s): GabaA; AMPA; NMDA;
Transmitter(s): Gaba; Glutamate;
Simulation Environment: NEURON; Python;
Model Concept(s): Long-term Synaptic Plasticity; Aging/Alzheimer`s; Deep brain stimulation; Homeostasis;
Implementer(s): Lytton, William [bill.lytton at downstate.edu]; Neymotin, Sam [Samuel.Neymotin at nki.rfmh.org]; Rowan, Mark [m.s.rowan at cs.bham.ac.uk];
Search NeuronDB for information about:  Neocortex L5/6 pyramidal GLU cell; Neocortex L2/3 pyramidal GLU cell; Neocortex V1 interneuron basket PV GABA cell; GabaA; AMPA; NMDA; Gaba; Glutamate;
autotune.hoc *
basestdp.hoc *
batch.hoc *
batch2.hoc *
checkirreg.hoc *
col.dot *
col.hoc *
comppowspec.hoc *
condisconcellfig.hoc *
condisconpowfig.hoc *
declist.hoc *
decmat.hoc *
decnqs.hoc *
decvec.hoc *
default.hoc *
drline.hoc *
e2hubsdisconpow.hoc *
e2incconpow.hoc *
filtutils.hoc *
geom.hoc *
graphplug.hoc *
grvec.hoc *
infot.hoc *
init.hoc *
labels.hoc *
load.hoc *
local.hoc *
makepopspikenq.hoc *
matfftpowplug.hoc *
matpmtmplug.hoc *
matpmtmsubpopplug.hoc *
matspecplug.hoc *
network.hoc *
nload.hoc *
nqpplug.hoc *
nqs.hoc *
nqsnet.hoc *
nrnoc.hoc *
powchgtest.hoc *
python.hoc *
pywrap.hoc *
ratlfp.dat *
redE2.hoc *
setup.hoc *
shufmua.hoc *
simctrl.hoc *
spkts.hoc *
stats.hoc *
syncode.hoc *
vsampenplug.hoc *
xgetargs.hoc *
// This is a collection of scripts for adding flexible input to
// intfcol. It uses the lfpstim function that Bill
// wrote, plus an adaptation of "sgrcells" from col.hoc.
// Version: 2012nov21 by cliffk and markr

// This function adds an arbitrary Poisson input to a particular
// population or populations of cells. It calls poistim followed
// by stimadd.
// Usage:
//   poisadd(signal,timei,timef,freq,cellpop,cellprct,cellwt,whichsy[,seed][,stim_membrane])
// where
//   signal describes the probability of a spike at a given time (e.g. a 10K-element sine wave)
//   timei is the start time of the stimulus (in ms, e.g. 2e3)
//   timef is the end time of the stimulus (in ms, e.g. 5e3)
//   freq is the number of spikes (in Hz, e.g. 10) (note: signal.size() must be greater than (timef-timei)*freq!)
//   pop is a vector of cell populations (e.g. [E2,E4,E5])
//   cellwt is the weight given to each spike, in a vector  (e.g. 1e9)
//   whichsy is the synapse used (e.g. AM2)
//   seed is (optionally) the random seed to use for generating the spikes
//   stim_membrane bypasses the cell's attempts to scale AMPA synapses up/down, by multiplying
//     the cellwt by 1/scalefactor. This allows modelling of direct stimulation of the cell
//     membrane (e.g. by a prosthesis), rather than the stimulation being scaled up/down
// Version: 2012nov21

proc poisadd () { local timei,timef,freq,cellprct,whichsy,npops,cellstart,cellfinish,pickthiscell localobj pickcell,signal,cellpop,spkoutput,cellwt
  signal=$o1 // Signal to base the Poisson spike train on
  timei=$2 // Start time of signal
  timef=$3 // End time of signal
  freq=$4 // Frequency/rate of the signal
  cellpop=$o5 // Cell populations to add signal to
  cellprct=$6 // Percent of cells to stimulate in each population
  cellwt=$o7 // Weight of each synapse, one value per population in cellpop
  whichsy=$8 // Type of each synapse
  fixedseed=0 // 0 by default
  stim_membrane=0 // Off by default
  if(numarg()>8) {
    fixedseed=$9 // Random seed to use for generating spikes
  if(numarg()>9) {
    stim_membrane=$10 // Whether to ignore scaling for direct stimulation of cell membrane

  pickcell=new Random(fixedseed) // Random number generator
  pickcell.uniform(0,1) // Require uniform-distributed random numbers from 0->1
  npops=cellpop.size() // Number of cell populations

  for h=0,numcols-1 { // Loop over columns
    for i=0,npops-1 { // Loop over each cell population
	   	cellstart=col[h].ix[cellpop.x[i]] // Starting cell index
	  	cellfinish=col[h].ixe[cellpop.x[i]] // Finishing cell index
	  	for cellid=cellstart,cellfinish { // Loop over each cell in the population
	  		pickthiscell=100*pickcell.repick() // Whether or not to pick this cell
	  		if(cellprct>pickthiscell) { // Pick out cellprct percent of cells
	  			//thisseed=7829*cellid+24091*i+251 // Create a pseudorandom seed
                //printf("cellprct %d, pickthiscell %f, cell %d\n", cellprct, pickthiscell, cellid)
                if(fixedseed>0) {
                    thisseed = cellid+fixedseed // Each cell has its own fixed seed
                    // So the seed for each cell remains the same on every call, but each cell does not
                    // get exactly the same spike train (which would lead to over-synchronized firing).
                    //printf("Using fixed seed %df\n", thisseed)
                } else {
                    thisseed = cellid+t // Pseudorandom seed (new for each cell every time t increments)
                    //printf("Using variable seed %d\n", thisseed)
	  			spkoutput=poistim(signal,timei,timef,freq,thisseed) // Calculate Poisson train

                if(stim_membrane) {
                    scalefactor=col[h].ce.o(cellid).get_scale_factor() // Obtain scalefactor.
                    // For info trials, scalefactor == 1 for every cell anyway, so this doesn't matter.
                    // But for AD + prosthesis trials, prosthesis shouldn't be scaled as it's supposed to
                    // act on cell membranes (which are not scaled), rather than the AM2 synapses (which
                    // are scaled) that we're forced to use due to the model limitations.
                    // So we should multiply the prosthesis weight by 1/scalefactor
                    stimwt = cellwt.x[i] * 1/scalefactor
                } else {
                    stimwt = cellwt.x[i]
                //printf("cellID = %d, stimwt = %f\n", cellid, stimwt)
/*  col[h].cstim.pushspks() // Test -- stim wasn't having any effect before*/

// POISTIM -- arbitrary Poisson generator
//** spktimevec = poistim(signal,timei,timef,freq)
// signal is vector giving the input signal - eg LFP
// timei gives the initial time time of the signal
// timef gives the final time of the signal, thus timespan is timef-timei
// freq gives the target freq for the spike train -- this is approximate
// Example: 
// objref signal, spktimevec
// signal=new Vector()
// signal.indgen(0.1,0.9,0.001)
// spktimevec=poistim(signal,10,5)
// spktimevec.size() = 50
// Note: the number of points in "signal" must be equal to or greater than the number of spikes!
// Version: 2011may20
obfunc poistim () { local a,timei,timef,thisseed localobj signal,v1,v2,vt
  signal=$o1 timei=$2 timef=$3 freq=$4 thisseed=$5 // Handle input arguments: signal
  a=allocvecs(v1,v2) // Allocate vectors
  vt=new Vector(signal.size) // but ((timef-timei)*freq) is number of spikes desired in period
  vt.setrnd(4,thisseed) // seed for 0-1
  v1.copy(signal) v1.inv()
  vt.mul(v1) // scale the intervals by the signal
  vt.integral() // turn intervals into times
  v1.resize((timef-timei)*freq/1e3) // deletes trailing elements
  v1.setrnd(6,0,vt.size-1,thisseed) // rand unique indices; to cull to get only (maxt*freq/1e3)
  v2.index(vt,v1) // pick the times randomly
  vt.add(timei) // Add start time
  return vt

// STIMADD -- add stimulus to the input list for a single cell
// This function, based on sgrcells, adds an arbitrary
// stimulus to the rest of the input NQS table vq.
// Usage:
//	 stimadd(times,cellid,cellwt,whichsy)
// where
//	 times is a length-N vector of spike times (e.g. 0, 1.34, 2.53, 7.34, 7.45)
//	 cellid is the cell ID (e.g. 142)
//   cellwt is the synaptic weight (e.g. 1e9)
//   whichsy is the synapse type (e.g. AMPA)
// Version: 2011may20
proc stimadd () { local cellid,cellwt,whichsy,npts,ii,foo,i localobj times,vqtmp
   for i=0,numcols-1 {
     if (col[i].cstim.vq==nil) col[i].cstim.vq=new NQS("ind","time","cellwt","whichsy") // Initialize NQS to store spikes
   vqtmp=new NQS("ind","time","cellwt","whichsy")
   times=$o1 // Incoming spike times (e.g. 0, 1.34, 2.53, 7.34, 7.45)
   cellid=$2 // Cell ID (e.g. 142)
   cellwt=$3 // Synaptic weights (e.g. 1e9)
   whichsy=$4 // Synapse type (e.g. AMPA)
   npts=times.size() // Find the number of points
   for ii=0,3 vqtmp.v[ii]=new Vector(npts) // Initialize vectors
   vqtmp.v[0].fill(cellid) // Assign the cell ID
   vqtmp.v[1]=times // Assign the times to the second column
   vqtmp.v[2].fill(cellwt) // Assign weights
   vqtmp.v[3].fill(whichsy) // Assign synapse type
   vqtmp.pad() // Shouldn't be necessary, but it is -- make sure all columns are the same size
   for i=0,numcols-1 {
     col[i].cstim.vq.append(vqtmp) // Append to original array -- won't take effect until pushspks() call, however
   nqsdel(vqtmp) // Garbage collection