3D olfactory bulb: operators (Migliore et al, 2015)

 Download zip file   Auto-launch 
Help downloading and running models
"... Using a 3D model of mitral and granule cell interactions supported by experimental findings, combined with a matrix-based representation of glomerular operations, we identify the mechanisms for forming one or more glomerular units in response to a given odor, how and to what extent the glomerular units interfere or interact with each other during learning, their computational role within the olfactory bulb microcircuit, and how their actions can be formalized into a theoretical framework in which the olfactory bulb can be considered to contain "odor operators" unique to each individual. ..."
1 . Migliore M, Cavarretta F, Marasco A, Tulumello E, Hines ML, Shepherd GM (2015) Synaptic clusters function as odor operators in the olfactory bulb. Proc Natl Acad Sci U S A 112:8499-504 [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:
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): AMPA; NMDA; Gaba;
Transmitter(s): Gaba; Glutamate;
Simulation Environment: NEURON; Python;
Model Concept(s): Activity Patterns; Dendritic Action Potentials; Active Dendrites; Synaptic Plasticity; Action Potentials; Synaptic Integration; Unsupervised Learning; Sensory processing; Olfaction;
Implementer(s): 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; AMPA; NMDA; Gaba; I Na,t; I A; I K; Gaba; Glutamate;
ampanmda.mod *
distrt.mod *
fi.mod *
fi_stdp.mod *
kamt.mod *
kdrmt.mod *
naxn.mod *
ThreshDetect.mod *
all2all.py *
balance.py *
colors.py *
complexity.py *
custom_params.py *
destroy_model.py *
distribute.py *
fixnseg.hoc *
gidfunc.py *
Glom.py *
granule.hoc *
input-odors.txt *
loadbalutil.py *
lpt.py *
mitral.hoc *
modeldata.py *
multisplit_distrib.py *
odordisp.py *
odors.py *
realgloms.txt *
realSoma.py *
spike2file.hoc *
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()

  from loadbalutil import lb
except ImportError:
#dictionary for mgid, mcell (whats left of it)
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
    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:
  return isecden

def wholemitral(mgid, cell):
  ''' unsplit mitral 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)
      pc.multisplit(0.0, mgid, sec=cell.secden[i])
  # add to piece dictionary

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_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])
    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)
  splitmitral(gid, mcell, pieces)
  print "mgid2piece ", model.mgid2piece