Parallel odor processing by mitral and middle tufted cells in the OB (Cavarretta et al 2016, 2018)

 Download zip file   Auto-launch 
Help downloading and running models
Accession:240116
"[...] experimental findings suggest that MC and mTC may encode parallel and complementary odor representations. We have analyzed the functional roles of these pathways by using a morphologically and physiologically realistic three-dimensional model to explore the MC and mTC microcircuits in the glomerular layer and deeper plexiform layers. [...]"
Reference:
1 . Cavarretta F, Burton SD, Igarashi KM, Shepherd GM, Hines ML, Migliore M (2018) Parallel odor processing by mitral and middle tufted cells in the olfactory bulb. Sci Rep 8:7625 [PubMed]
2 . Cavarretta F, Marasco A, Hines ML, Shepherd GM, Migliore M (2016) Glomerular and Mitral-Granule Cell Microcircuits Coordinate Temporal and Spatial Information Processing in the Olfactory Bulb. Front Comput Neurosci 10:67 [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 tufted middle GLU cell; Olfactory bulb main interneuron granule MC GABA cell; Olfactory bulb main interneuron granule TC GABA cell; Olfactory bulb (accessory) mitral cell; Olfactory bulb main tufted cell external; Olfactory bulb short axon cell;
Channel(s): I A; I Na,t; I_Ks; I K;
Gap Junctions: Gap junctions;
Receptor(s): AMPA; GabaA; NMDA;
Gene(s):
Transmitter(s): Glutamate; Gaba;
Simulation Environment: NEURON;
Model Concept(s): Action Potentials; Action Potential Initiation; Active Dendrites; Long-term Synaptic Plasticity; Synaptic Integration; Synchronization; Pattern Recognition; Spatio-temporal Activity Patterns; Temporal Pattern Generation; Sensory coding; Sensory processing; Olfaction;
Implementer(s): Cavarretta, Francesco [francescocavarretta at hotmail.it]; Hines, Michael [Michael.Hines at Yale.edu];
Search NeuronDB for information about:  Olfactory bulb main interneuron granule MC GABA cell; Olfactory bulb main tufted middle GLU cell; Olfactory bulb main interneuron granule TC GABA cell; GabaA; AMPA; NMDA; I Na,t; I A; I K; I_Ks; Gaba; Glutamate;
/
modeldb-bulb3d
sim
ampanmda.mod
distrt.mod *
fi.mod
fi_stdp.mod *
gap.mod
Gfluct.mod
kamt.mod
kdrmt.mod
ks.mod
naxn.mod
orn.mod
ThreshDetect.mod *
all.py
all2all.py *
assembly.py
balance.py *
bindict.py
binsave.py
binspikes.py
blanes.hoc
blanes.py
blanes_exc_conn.txt
blanes6.dic
bulb3dtest.py
cancel.py
catfiles.sh
cellreader.py
cellwriter.py
cfg27.py
common.py
complexity.py *
convertdic.py
destroy_model.py
determine_connections.py
distribute.py *
dsac.py
Eta.txt *
fillgloms.py
fixnseg.hoc *
g_conn_stats.py
gapjunc.py
gen_weights.py
geodist.py
geodist.txt
getmitral.py
gidfunc.py
GJ.py
gj_nrn.hoc
Glom.py *
granule.hoc
granules.py
graphmeat.py
grow.py
growdef.py *
growout.py
job
Kod.txt *
lateral_connections.py
loadbalutil.py *
lpt.py *
mcgrow.py
MCrealSoma.py *
mgrs.py
misc.py
mitral.hoc
mkassembly.py
mkmitral.py
modeldata.py
mtgrow.py
MTrealSoma.py
MTrealSoma2.py
mtufted.hoc
multisplit_distrib.py
net_mitral_centric.py
Nod.txt *
odors.py
odorstim.py
odstim2.txt *
pad.txt *
params.py
parrun.py
pathdist.py
realgloms.txt *
runsim.py
spike2file.hoc *
spk2weight.py
split.py
subsetsim.py
test_complexity.py
txt2bin.py
util.py *
vrecord.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

def mgapjunc(mgid, i):
  ''' return secondary dendrite if it exists, otherwise None.'''
  c = mgid2pieces(mgid)
  if c and h.section_exists("gapjunc", i, c):
    return c.gapjunc[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 mpriden(mgid):
  c = mgid2pieces(mgid)
  if c and h.section_exists('priden', c):
    return c.priden
  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