Olfactory Bulb Network (Davison et al 2003)

 Download zip file   Auto-launch 
Help downloading and running models
Accession:2730
A biologically-detailed model of the mammalian olfactory bulb, incorporating the mitral and granule cells and the dendrodendritic synapses between them. The results of simulation experiments with electrical stimulation agree closely in most details with published experimental data. The model predicts that the time course of dendrodendritic inhibition is dependent on the network connectivity as well as on the intrinsic parameters of the synapses. In response to simulated odor stimulation, strongly activated mitral cells tend to suppress neighboring cells, the mitral cells readily synchronize their firing, and increasing the stimulus intensity increases the degree of synchronization. For more details, see the reference below.
Reference:
1 . Davison AP, Feng J, Brown D (2003) Dendrodendritic inhibition and simulated odor responses in a detailed olfactory bulb network model. J Neurophysiol 90:1921-35 [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: Olfactory bulb;
Cell Type(s): Olfactory bulb main mitral cell; Olfactory bulb main interneuron granule MC cell;
Channel(s): I Na,t; I L high threshold; I A; I K; I K,leak; I M; I K,Ca; I Sodium; I Calcium; I Potassium;
Gap Junctions:
Receptor(s): GabaA; AMPA; NMDA;
Gene(s):
Transmitter(s): Gaba; Glutamate;
Simulation Environment: NEURON;
Model Concept(s): Oscillations; Synchronization; Spatio-temporal Activity Patterns; Olfaction;
Implementer(s): Davison, Andrew [Andrew.Davison at iaf.cnrs-gif.fr];
Search NeuronDB for information about:  Olfactory bulb main mitral cell; Olfactory bulb main interneuron granule MC cell; GabaA; AMPA; NMDA; I Na,t; I L high threshold; I A; I K; I K,leak; I M; I K,Ca; I Sodium; I Calcium; I Potassium; Gaba; Glutamate;
/
bulbNet
README *
cadecay.mod *
flushf.mod *
kA.mod *
kca.mod *
kfasttab.mod *
kM.mod *
kslowtab.mod *
lcafixed.mod *
nafast.mod *
nagran.mod *
nmdanet.mod *
bulb.hoc
calcisilag.hoc *
ddi_baseline.gnu *
ddi_baseline.ses *
experiment_ddi_baseline.hoc *
experiment_odour_baseline.hoc *
granule.tem *
init.hoc *
input.hoc *
input1 *
mathslib.hoc *
mitral.tem *
mosinit.hoc *
odour_baseline.connect
odour_baseline.gnu *
odour_baseline.ses *
parameters_ddi_baseline.hoc *
parameters_odour_baseline.hoc *
screenshot.png *
tabchannels.dat *
tabchannels.hoc *
                            
// calcisilag.hoc
// Olfactory bulb network model: calculate inter-spike interval
//                             : and lag time statistics
// Andrew Davison, The Babraham Institute, 2000.

/* The following procedures are defined for writing results to file
 * fileroot is the filename root. A suffix will be added to
 * this, e.g. fileroot.synch for print_si().
 * i,j are the mitral cell indices
 *
 * print_smooth_hist(variance,fileroot)
 * print_gran_smooth_hist(variance,fileroot)
 * print_spiketimes(i,j,fileroot)
 * print_raster(fileroot)
 * print_gran_raster(fileroot)
 * print_isis(i,j,fileroot)
 * print_isi_stats(fileroot)
 * print_lags(i,j,fileroot) 	
 * print_si(fileroot)
 */

// Variables used in this file
objref work, work2, outputarray, isi, lags, hist
work 	= new Vector()
work2 	= new Vector()
outputarray = new Matrix(nmitx,nmity)
isi 	= new Vector()
lags 	= new Vector()

// Procedures for processing spike times -------------------------------

proc calc_isis() { local i,j,k,n // 3 args - indices of mitral cell, transient time
  if ($1 > nmitx || $2 > nmity) {
    print "Sorry - index out of range. Please try again."
    return
  }
  i = int($1)
  j = int($2)
  isi.resize(0)
  n = mit[i][j].spiketimes.size()
  if (n > 1) {
    for k = 1,n-1 {
      if (mit[i][j].spiketimes.x[k-1] > $3) {
        isi.append(mit[i][j].spiketimes.x[k]-mit[i][j].spiketimes.x[k-1])
      }
    }
  }
}

proc calc_gran_isis() { local i,j,k,n // 3 args - indices of granule cell, transient time
  if ($1 > ngranx || $2 > ngrany) {
    print "Sorry - index out of range. Please try again."
    return
  }
  i = int($1)
  j = int($2)
  isi.resize(0)
  n = gran[i][j].spiketimes.size()
  if (n > 1) {
    for k = 1,n-1 {
      if (gran[i][j].spiketimes.x[k-1] > $3) {
        isi.append(gran[i][j].spiketimes.x[k]-gran[i][j].spiketimes.x[k-1])
      }
    }
  }
}

func minisi() { local i,j,min	// find shortest mean ISI
  min = 1e6
  for i = 0, nmitx-1 {
    for j = 0, nmity-1 {
      calc_isis(i,j,ttrans)
      if (isi.size() > 0) {
        if (isi.mean() < min) { min = isi.mean() }
      }
    }
  }
  return min
}
      
  
proc rate_array() { local i,j
  for i = 0,nmitx-1 {
    for j = 0, nmity-1 {
      calc_isis(i,j,ttrans)
      if (isi.size() > 0) {
        outputarray.x[i][j] = 1000/isi.mean()
      } else {
        outputarray.x[i][j] = 0
      }
    }
  }  
  print "Max: ",arraymax(outputarray)
  outputarray.muls(1/arraymax(outputarray))
} 

proc calc_lags() { local i1,j1,i2,j2,k,minidx,min // 5 args - indices of mitral cells, transient time
    if ($1 > nmitx || $2 > nmity || $3 > nmitx || $4 > nmity) {
    print "Sorry - index out of range. Please try again."
    return
  }
  i1 = int($1)
  j1 = int($2)
  i2 = int($3)
  j2 = int($4)
  lags.resize(0)
  // for each spiketime in cell 1, find closest spike in cell 2
  // Note: first and last spikes ignored since can't calculate previous ISI
  if (mit[i2][j2].spiketimes.size > 0) {
    for k = 1,mit[i1][j1].spiketimes.size()-2 {
      if (mit[i1][j1].spiketimes.x[k] > $5) {
        work = mit[i2][j2].spiketimes.c.add(-mit[i1][j1].spiketimes.x[k])
        minidx = work.c.abs.min_ind()
        min = work.x[minidx]
        isiprev = mit[i1][j1].spiketimes.x[k-1]-mit[i1][j1].spiketimes.x[k]
        isinext = mit[i1][j1].spiketimes.x[k+1]-mit[i1][j1].spiketimes.x[k]
        if (min > isiprev/2 && min < isinext/2) {
          lags.append(min)
        }
      }
    }
  }
}

proc calc_phase_lags() { local i1,j1,i2,j2,k,minidx,min // 5 args - indices of mitral cells, transient time
    if ($1 > nmitx || $2 > nmity || $3 > nmitx || $4 > nmity) {
    print "Sorry - index out of range. Please try again."
    return
  }
  i1 = int($1)
  j1 = int($2)
  i2 = int($3)
  j2 = int($4)
  lags.resize(0)
  // for each spiketime in cell 1, find closest spike in cell 2
  // Note: first and last spikes ignored since can't calculate previous ISI
  if (mit[i2][j2].spiketimes.size > 0) {
    for k = 1,mit[i1][j1].spiketimes.size()-2 {
      if (mit[i1][j1].spiketimes.x[k] > $5) {
        work = mit[i2][j2].spiketimes.c.add(-mit[i1][j1].spiketimes.x[k])
        minidx = work.c.abs.min_ind()
        min = work.x[minidx]
        isiprev = mit[i1][j1].spiketimes.x[k-1]-mit[i1][j1].spiketimes.x[k]
        isinext = mit[i1][j1].spiketimes.x[k+1]-mit[i1][j1].spiketimes.x[k]
        if (min > isiprev/2 && min < isinext/2) {
          if (min < 0) {
            lags.append(min/isiprev)
          } else {
            lags.append(min/isinext)
          }
        }
      }
    }
  }
}

proc calc_gran_lags() { local i1,j1,i2,j2,k,minidx,min // 5 args - indices of granule cells, transient time
    if ($1 > ngranx || $2 > ngrany || $3 > ngranx || $4 > ngrany) {
    print "Sorry - index out of range. Please try again."
    return
  }
  i1 = int($1)
  j1 = int($2)
  i2 = int($3)
  j2 = int($4)
  lags.resize(0)
  // for each spiketime in cell 1, find closest spike in cell 2
  // Note: first and last spikes ignored since can't calculate previous ISI
  if (gran[i2][j2].spiketimes.size > 0) {
    for k = 1,gran[i1][j1].spiketimes.size()-2 {
      if (gran[i1][j1].spiketimes.x[k] > $5) {
        work = gran[i2][j2].spiketimes.c.add(-gran[i1][j1].spiketimes.x[k])
        minidx = work.c.abs.min_ind()
        min = work.x[minidx]
        isiprev = gran[i1][j1].spiketimes.x[k]-gran[i1][j1].spiketimes.x[k-1]
        isinext = gran[i1][j1].spiketimes.x[k]-gran[i1][j1].spiketimes.x[k+1]
        if (min < isiprev/2 && min > isinext/2) {
          lags.append(min)
        }
      }
    }
  }
}

proc time_hist() { // 1 arg - time step
  work.resize(0)
  for i = 0, nmitx-1 {
    for j = 0, nmity-1 {
      work.append(mit[i][j].spiketimes)
    }
  }
  hist = work.histogram(0,tstop,$1)
  hist.printf("%d\n")
}

func synch_index() { local i1,j1,i2,j2,n
  synchindex = 0
  n = 0
  for i1 = 0, nmitx-1 {
    for j1 = 0, nmity-1 {
      if (mit[i1][j1].spiketimes.size() > 0) {
        for i2 = 0, nmitx-1 {
          for j2 = 0, nmity-1 {
            if (i1 != i2 || j1 != j2) {
              calc_phase_lags(i1,j1,i2,j2,ttrans)
              n += lags.size()
              synchindex += lags.reduce("abs",0)
            }
          }
        }
      }
    }
  }
  if (n > 0) {
    return synchindex/n
  } else {
    return 1e6
  }
}


func phaselock_index() { local n,i1,j1,i2,j2
  synchindex = 0
  n = 0
  for i1 = 0, nmitx-1 {
    for j1 = 0, nmity-1 {
      if (mit[i1][j1].spiketimes.size() > 0) {
        for i2 = 0, nmitx-1 {
          for j2 = 0, nmity-1 {
            if (i1 != i2 || j1 != j2) {
              calc_phase_lags(i1,j1,i2,j2,ttrans)
              if (lags.size() > 1) {
                synchindex += lags.var()
                n += 1
              }
            }
          }
        }
      }
    }
  }
  if (n > 0) {
    synchindex = sqrt(synchindex/n)
    return synchindex
  } else {
    return 1e6
  }
}

// Procedures for writing out data --------------------------------

proc calc_smooth_hist() { // 1 arg - variance
  work.resize(0)
  for i = 0, nmitx-1 {
    for j = 0, nmity-1 {
      work.append(mit[i][j].spiketimes)
    }
  }
  hist = work.sumgauss(0,tstop,1,$1)
}

proc print_smooth_hist() { // 2 args - variance, filename root
  calc_smooth_hist($1)
  sprint(filename,"%s.smhist",$s2)
  outfile.wopen(filename)
  outfile.printf("# Mitral cell smoothed histogram\n")
  hist.printf(outfile,"%8.3f\n")
  outfile.close()
/*
  work.resize(0)
  hist.remove(0,ttrans)
  work.spctrm(hist)
  sprint(filename,"%s.pow",$s2)
  outfile.wopen(filename)
  outfile.printf("# Power spectrum of Mitral cell smoothed histogram\n")
  work.printf(outfile,"%9.5f\n")
  outfile.close()
  */
}

proc calc_gran_smooth_hist() { // 1 arg - variance
  work.resize(0)
  for i = 0, ngranx-1 {
    for j = 0, ngrany-1 {
      work.append(gran[i][j].spiketimes)
    }
  }
  hist = work.sumgauss(0,tstop,1,$1)
}

proc print_gran_smooth_hist() { // 2 args - variance, filename root
  calc_gran_smooth_hist($1)
  sprint(filename,"%s.gran.smhist",$s2)
  outfile.wopen(filename)
  outfile.printf("# Granule cell smoothed histogram\n")
  hist.printf(outfile,"%8.3f\n")
  outfile.close()
  //work.resize(0)
  //hist.remove(0,ttrans)
  //work.spctrm(hist)
  //sprint(filename,"%s.gran.pow",$s2)
  //outfile.wopen(filename)
  //outfile.printf("# Power spectrum of Granule cell smoothed histogram\n")
  //work.printf(outfile,"%9.5f\n")
  //outfile.close()
}

proc print_gran_hist() { // 2 args - binsize, filename root
  work.resize(0)
  for i = 0, ngranx-1 {
    for j = 0, ngrany-1 {
      work.append(gran[i][j].spiketimes)
    }
  }
  hist = work.histogram(0,tstop,$1)
  sprint(filename,"%s.gran.hist",$s2)
  outfile.wopen(filename)
  outfile.printf("# Granule cell unsmoothed histogram\n")
  hist.printf(outfile,"%8.3f\n")
  outfile.close()
}

proc print_spiketimes() { // 3 args - indices of mitral cell plus filename root
  if (numarg() == 3) {
    sprint(filename,"%s_%d_%d.isi",$s3,$1,$2)
    outfile.wopen(filename)
    outfile.printf("# Spiketimes for mitral cell [%d][%d]",$1,$2)
    mit[$1][$2].spiketimes.printf(outfile,"%10.3f")
  }
  if (numarg() == 1) {
    sprint(filename,"%s.isi",$s1)
    outfile.wopen(filename)
    for i = 0, nmitx-1 {
      for j = 0, nmity-1 {
        outfile.printf("[%d][%d]",i,j)
        mit[i][j].spiketimes.printf(outfile,"%10.3f")
      }
    }
  }
  outfile.close()
}

proc print_raster() { // 1 arg - filename root
  sprint(filename,"%s.ras",$s1)
  outfile.wopen(filename)
  outfile.printf("# Mitral cell raster plot\n")
  for i = 0, nmitx-1 {
    for j = 0, nmity-1 {
      for k = 0, mit[i][j].spiketimes.size()-1 {
        outfile.printf("%d %d %d %10.3f\n",i,j,i*nmity+j,mit[i][j].spiketimes.x[k])
      }
    }
  }
  outfile.close()
}

proc print_gran_raster() { // 1 arg - filename root
  sprint(filename,"%s.gran.ras",$s1)
  outfile.wopen(filename)
  outfile.printf("# Granule cell raster plot\n")
  for i = 0, ngranx-1 {
    for j = 0, ngrany-1 {
      for k = 0, gran[i][j].spiketimes.size()-1 {
        outfile.printf("%d %d %d %10.3f\n",i,j,i*ngrany+j,gran[i][j].spiketimes.x[k])
      }
    }
  }
  outfile.close()
}

proc print_isis() { // 3 args - indices of mitral cell plus filename root
  calc_isis($1,$2,ttrans)
  sprint(filename,"%s_%d_%d.isi",$s3,$1,$2)
  outfile.wopen(filename)
  outfile.printf("# Interspike intervals for mitral cell [%d][%d]",$1,$2)
  isi.printf(outfile,"%10.3f")
  outfile.close()
}

proc print_isi_stats() { // 1 arg - filename root
  sprint(filename,"%s.stats",$s1)
  outfile.wopen(filename)
  outfile.printf("#Interspike interval statistics for mitral cells\n")
  outfile.printf("# i  j   n   mean   median   stdev  \n")
  for i = 0, nmitx-1 {
    for j = 0, nmity-1 {
      calc_isis(i,j,ttrans)
      outfile.printf("%3d%3d%4d",i,j,isi.size())
      if (isi.size() > 0) {
        outfile.printf("%8.2f%8.2f",isi.mean(),isi.median())
        if (isi.size() > 1) {
          outfile.printf("%8.2f\n",isi.stdev())
        } else {
          printf("\n")
        }
      } else { outfile.printf("\n") }
    }
  }
  outfile.printf("#Interspike interval statistics for granule cells\n")
  outfile.printf("# i  j   n   mean   median   stdev  \n")
  for i = 0, ngranx-1 {
    for j = 0, ngrany-1 {
      calc_gran_isis(i,j,ttrans)
      outfile.printf("%3d%3d%4d",i,j,isi.size())
      if (isi.size() > 0) {
        outfile.printf("%8.2f%8.2f",isi.mean(),isi.median())
        if (isi.size() > 1) {
          outfile.printf("%8.2f\n",isi.stdev())
        }
      } else { outfile.printf("\n") }
    }
  }
  outfile.close()
}

proc print_lags() { local i,j // 3 args - indices of mitral cell + filename root
  sprint(filename,"%s_%d_%d.lags",$s3,$1,$2)
  outfile.wopen(filename)
  outfile.printf("# Lag times for mitral cell [%d][%d]\n",$1,$2)
  for i = 0, nmitx-1 {
    for j = 0, nmity-1 {
      calc_lags($1,$2,i,j,ttrans)
      outfile.printf("[%d,%d]",i,j)
      lags.printf(outfile,"%10.3f")
    }
  }
  outfile.close()
}

proc print_si() { // 1 arg - fileroot
  print "Calculating synchronization indices"
  sprint(filename,"%s.synch",$s1)
  outfile.wopen(filename)
  outfile.printf("Synchronization index: %10.3f\n",synch_index())
  outfile.printf("Phase-locking index:   %10.3f\n",phaselock_index())
  outfile.close()
}