3D model of the olfactory bulb (Migliore et al. 2014)

 Download zip file 
Help downloading and running models
Accession:151681
This entry contains a link to a full HD version of movie 1 and the NEURON code of the paper: "Distributed organization of a brain microcircuit analysed by three-dimensional modeling: the olfactory bulb" by M Migliore, F Cavarretta, ML Hines, and GM Shepherd.
Reference:
1 . Migliore M, Cavarretta F, Hines ML, Shepherd GM (2014) Distributed organization of a brain microcircuit analyzed by three-dimensional modeling: the olfactory bulb. Front Comput Neurosci 8:50 [PubMed]
Citations  Citation Browser
Model Information (Click on a link to find other models with that property)
Model Type: Realistic Network; Channel/Receptor; Dendrite;
Brain Region(s)/Organism: Olfactory bulb;
Cell Type(s): Olfactory bulb main mitral GLU cell; Olfactory bulb main interneuron granule MC GABA cell;
Channel(s): I Na,t; I A; I K;
Gap Junctions:
Receptor(s): NMDA; Glutamate; Gaba;
Gene(s):
Transmitter(s):
Simulation Environment: NEURON;
Model Concept(s): Pattern Recognition; Activity Patterns; Bursting; Temporal Pattern Generation; Oscillations; Synchronization; Active Dendrites; Detailed Neuronal Models; Synaptic Plasticity; Action Potentials; Synaptic Integration; Unsupervised Learning; Olfaction;
Implementer(s): Hines, Michael [Michael.Hines at Yale.edu]; Migliore, Michele [Michele.Migliore at Yale.edu]; Cavarretta, Francesco [francescocavarretta at hotmail.it];
Search NeuronDB for information about:  Olfactory bulb main mitral GLU cell; Olfactory bulb main interneuron granule MC GABA cell; NMDA; Glutamate; Gaba; I Na,t; I A; I K;
/
bulb3d
readme.html
ampanmda.mod *
distrt.mod *
fi.mod *
kamt.mod *
kdrmt.mod *
naxn.mod *
ThreshDetect.mod *
all2all.py *
balance.py *
bindict.py
BulbSurf.py
colors.py *
common.py
complexity.py *
custom_params.py *
customsim.py
destroy_model.py *
determine_connections.py
distribute.py *
fig7.py
fixnseg.hoc *
getmitral.py
gidfunc.py *
glom.py
granule.hoc *
granules.py
input-odors.txt *
loadbalutil.py *
lpt.py *
mayasyn.py
mgrs.py
misc.py
mitral.hoc *
mitral_dend_density.py
mkmitral.py
modeldata.py *
multisplit_distrib.py *
net_mitral_centric.py
odordisp.py *
odors.py *
odorstim.py
params.py
parrun.py
realgloms.txt *
runsim.py
split.py *
util.py *
weightsave.py *
                            
'''
The concept of gid has two uses. One is administrative so that, given a
gid, one can determine the (pieces that exist) on this machine. The other
is for purposes of spike exchange and is associated with the spike output.
The overall design is to have the necessary ParallelContext.gid_exist(mgid)
associated the mitral cell spike detector and, anytime some piece of the
mitral cell exists on a process, there is a {mgid:cell} entry in mgid2piece.

Because of reciprocal synapses, a pair of spike gids must be reserved
for each synapse and it must be easy to determine from a synapse gid, the
appropriate mitral/granule, and vice versa. Furthermore, splitting consists
of splitting all of a variable number of secondary dendrites from the
soma,primary,tuft,axon region. So we need a single sid for each mitral
which can be the same as the mitral gid.  Python nicely allows us to
have a dict, independent of that supplied by ParallelContext, that says
that one or more pieces exist on this machine.
'''
'''
pc.gid_exists(mgid) returns a positive number only if the soma-priden-tuft-axon
piece exists on this cpu. For other existence questions, use
mpiece_exists, mgid2pieces, and msecden.
Although granules are not currently split, we have their equivalents:
  gpiece_exists, ggid2pieces, and gpriden.
'''
from neuron import h
pc = h.ParallelContext()

try:
  from loadbalutil import lb
except ImportError:
  pass
#dictionary for mgid, mcell (whats left of it)
#model.mgid2piece
from modeldata import getmodel
model = getmodel()

def mpiece_exists(mgid):
  return model.mgid2piece.has_key(mgid)

def mgid2pieces(mgid):
  ''' return cell with existing pieces for mgid; None if does not exist.'''
  if mpiece_exists(mgid):
    return model.mgid2piece[mgid]
  return None

def msecden(mgid, i):
  ''' return secondary dendrite if it exists, otherwise None.'''
  c = mgid2pieces(mgid)
  if c and h.section_exists("secden", i, c):
    return c.secden[i]
  return None

#granules are presently not split but we provide equivalents to the above
def gpiece_exists(ggid):
  return pc.gid_exists(ggid) > 0.0
def ggid2pieces(ggid):
  if gpiece_exists(ggid):
    return pc.gid2cell(ggid)
  return None  
def gpriden(ggid, i):
  c = ggid2pieces(ggid)
  if c and h.section_exists("priden2", i, c):
    return c.priden2[i]
  return None

def secparent(sec):
  sr = h.SectionRef(sec = sec)
  if sr.has_parent():
    return sr.parent
  else:
    return None

def secden_indices_connected_to_soma(cell):
  #list of secden indices connected to soma
  isecden = []
  for i, s in enumerate(cell.secdens):
    if secparent(s) == cell.soma:
      isecden.append(i)
  return isecden

def wholemitral(mgid, cell):
  ''' unsplit mitral cell '''
  model.mgid2piece.update({mgid:cell})

def splitmitral(mgid, cell, piecelist):
  ''' split a mitral cell into secondary dendrites and the soma/priden/axon
      and destroy pieces not on this cpu and connect pieces with multisplit.
      Note that -1 is the piece that includes the soma.
      Also note that secondary dendrites have branches and the piecelist is
      for the indices of secondary dentrites that connect to the soma.
      The {mgid:cell} is added to mgid2piece so the assumption is that
      piecelist is not empty.
  '''
  isecden = secden_indices_connected_to_soma(cell)
  #disconnect all secden and destroy what is not supposed to exist
  for i in isecden:
    s = cell.secden[i]
    h.disconnect(sec = s)
    if i not in piecelist:
      subtree = h.SectionList()
      subtree.wholetree(sec = s)
      for ss in subtree:
        h.delete_section(sec = ss)
  rest = h.SectionList()
  rest.wholetree(sec = cell.soma)
  if -1 not in piecelist:
    for s in rest:
      h.delete_section(sec = s)
  #multisplit connect using mgid
  for i in piecelist:
    if i == -1:
      pc.multisplit(0.5, mgid, sec = cell.soma)
    else:
      pc.multisplit(0.0, mgid, sec=cell.secden[i])
  # add to piece dictionary
  model.mgid2piece.update({mgid:cell})

def subset_complexity(subset):
  cx = 0.
  for sec in subset:
    cx += lb.sec_complexity(sec = sec)
  return cx

def mitral_complexity(cell):
  '''For a full mitral cell return a three-tuple. Total complexity,
     complexity of soma, priden, tuft, axon, and finally a list of
     secondary dendrite subtree complexities.
  '''

  total_cx = 0.

  soma_etc = h.SectionList()
  soma_etc.wholetree(sec = cell.soma)
  soma_etc.remove(cell.secdens)
  soma_etc_cx = subset_complexity(soma_etc)
  total_cx += soma_etc_cx

  isecden = secden_indices_connected_to_soma(cell)
  secden_cx = []
  for i in isecden:
    subtree = h.SectionList()
    subtree.subtree(sec = cell.secden[i])
    secden_cx.append(subset_complexity(subtree))
    total_cx += secden_cx[-1]

  return (total_cx, soma_etc_cx, secden_cx)

def msoma(mgid):
  c = mgid2pieces(mgid)
  if c and h.section_exists('soma', c):
    return c.soma
  return None

def gsoma(ggid):
  c = ggid2pieces(ggid)
  if c and h.section_exists('soma', c):
    return c.soma
  return None

if __name__ == "__main__":
  from mkmitral import mkmitral
  gid = 259
  mcell = mkmitral(gid) # according to mkmitral.py this has tertiary branches
  print "mitral_complexity ", mitral_complexity(mcell)
  print "cell_complexity = ", lb.cell_complexity(mcell)
  pieces = secden_indices_connected_to_soma(mcell)
  pieces.append(-1)
  splitmitral(gid, mcell, pieces)
  h.topology()
  print "mgid2piece ", model.mgid2piece