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. [...]"
References:
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]
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
                            
# packages of various functions.
from copy import copy
from math import *

def mean(vec):
  mu = 0.
  for x in vec: mu += x
  return mu/len(vec)

def std(vec):
  mu = mean(vec)
  s = 0.
  for x in vec:
    s += (x - mu)**2
  return s/(len(vec)-1)

def distance(p, q):
    x = p[0] - q[0]
    y = p[1] - q[1]
    z = p[2] - q[2]
    return sqrt(x ** 2 + y ** 2 + z ** 2)

def plane_dist(p, w, o):
  a = 0.
  b = 0.
  for i in range(3):
    a += (p[i]-o[i])*w[i]
    b += w[i]**2
  return abs(a)/sqrt(b)
  

class Spherical:
    @staticmethod
    def to(p, center=[0,0,0]):
        rho = distance(p, center)
        
        p = copy(p); p[0] -= center[0]; p[1] -= center[1]; p[2] -= center[2]
        
        phi = atan2(p[1], p[0])
        try:
            theta = acos(p[2] / rho)
        except ZeroDivisionError:
            theta = acos(p[2] / 1e-8)
            
        return rho, phi, theta

    @staticmethod
    def xyz(rho, phi, theta, center=[0,0,0]):
        x = rho * cos(phi) * sin(theta) + center[0]
        y = rho * sin(phi) * sin(theta) + center[1]
        z = rho * cos(theta) + center[2]
        return [ x, y, z ]

def centroid(pts):
    x = 0.
    y = 0.
    z = 0.
    for p in pts:
        x += p[0]
        y += p[1]
        z += p[2]
    x /= len(pts)
    y /= len(pts)
    z /= len(pts)
    return [ x, y, z ]

# for elliptical coords
class Ellipsoid:
    
    def __init__(self, pos, axis):
      
        self.__pos = copy(pos)
        
        halfAxis = copy(axis)
        for i in range(3): halfAxis[i] /= 2.
        self.__inverse = halfAxis[0] < halfAxis[1]
        self.__halfAxis = halfAxis
        
        # eccentricity
        a = 0; b = 1;
        if halfAxis[a] < halfAxis[b]: b = 0; a = 1
        
        self.__eccen = sqrt(halfAxis[a] ** 2 - halfAxis[b] ** 2) / halfAxis[a]
        
    def intersect(self, p, u):
        A = 0.
        B = 0.
        C = -1
        v = []

        for i in range(3):
            A += (u[i]/self.__halfAxis[i])** 2
            B += 2*u[i]*(p[i]-self.__pos[i]) / (self.__halfAxis[i]**2)
            C += ((p[i]-self.__pos[i])/self.__halfAxis[i])**2

        delta = B ** 2 - 4 * A * C
        t0 = (-B+sqrt(delta)) / (2*A)
        t1 = (-B-sqrt(delta)) / (2*A)
        if abs(t0) < abs(t1):
            t = t0
        else:
            t = t1

        q = []
        for i in range(3):
            q.append(p[i] + t * u[i])
        return q
    
    def project(self, pos):
        return self.intersect(pos, versor(pos, self.__pos))


    def R(self, phi): return self.__halfAxis[0] / sqrt(1 - (self.__eccen * sin(phi)) ** 2)

    # from elliptical to cartesian
    def toXYZ(self, h, lamb, phi):
        N = self.R(phi)
        XYProj = (N + h) * cos(phi)
        p = [ XYProj * cos(lamb),
              XYProj * sin(lamb),
              ((1 - self.__eccen ** 2) * N + h) * sin(phi) ]
        if self.__inverse: aux = p[0]; p[0] = p[1]; p[1] = aux
        for i in range(3): p[i] += self.__pos[i]
        return p

    # from cartesian to elliptical
    def toElliptical(self, pt):
        x = pt[0] - self.__pos[0]
        y = pt[1] - self.__pos[1]
        z = pt[2] - self.__pos[2]
        
        if self.__inverse: aux = y; y = x; x = aux
            
        lamb = atan2(y, x)

        p = sqrt(x ** 2 + y ** 2)
        try:
            phi = atan(z / ((1 - self.__eccen ** 2) * p))
        except ZeroDivisionError:
            phi = atan(z / 1e-8)

        MAXIT = int(1e+4)
        for i in range(MAXIT):
            phi1 = phi
            N = self.R(phi)
            h = p / cos(phi) - N
            try:
                phi = atan(z /  ((1 - self.__eccen ** 2 * N / (N + h)) * p))
            except ZeroDivisionError:
                phi = atan(z / 1e-8)
            if abs(phi - phi1) < 1e-8: break
        return h, lamb, phi

    def getZ(self, pt):            
        x = pt[0]; y = pt[1]
        try:
            return self.__pos[2] + self.__halfAxis[2] * sqrt(1 - ((x - self.__pos[0]) / self.__halfAxis[0]) ** 2 - ((y - self.__pos[1]) / self.__halfAxis[1]) ** 2)
        except ValueError:
            return None

    def normalRadius(self, pt):
        r = 0.
        for i in range(3): r += ((pt[i] - self.__pos[i]) / self.__halfAxis[i]) ** 2
        return r

    def toElliptical2(self, phi, theta):
      p=Spherical.xyz(1, phi, theta)
      for i in range(3):
        p[i]*=self.__halfAxis[i]
        p[i]+=self.__pos[i]
      return p
      

# laplace rng
def rLaplace(r, mu, b):
    p = r.uniform(0, 1)
    if p > .5: return -log((1 - p) * 2) * b + mu
    return log(p * 2) * b + mu

# return versor between two points
def versor(p, q):
        d = distance(p, q)
        v = [ 0 ] * 3
        for i in range(3): v[i] = (p[i] - q[i]) / d
        return v

# return points on line
def getP(t, v, q):
            p = [ 0 ] * 3
            for i in range(3): p[i] = t * v[i] + q[i]
            return p
        
# stretch a section
def stretchSection(sec, p):
    dx = (sec[-1][0] - p[0]) / (len(sec) - 1)
    dy = (sec[-1][1] - p[1]) / (len(sec) - 1)
    dz = (sec[-1][2] - p[2]) / (len(sec) - 1)
    for k in range(1, len(sec)):
        sec[k][0] -= k * dx
        sec[k][1] -= k * dy
        sec[k][2] -= k * dz

class Matrix:
    @staticmethod
    def RZ(phi):
        return [[cos(phi),-sin(phi),0], [sin(phi),cos(phi),0], [0,0,1]]
    
    @staticmethod
    def RY(theta):
        return [[cos(theta),0,sin(theta)],[0,1,0],[-sin(theta),0,cos(theta)]]
    
    @staticmethod
    def prod(m, v):
        ret_v = [0]*len(v)
        for i in range(len(m)):
            for j in range(len(m[i])):
                ret_v[i] += v[j] * m[i][j]
        return ret_v
    
def convert_direction(phi, theta, phibase, thetabase, inv=False):
    u = Spherical.xyz(1, phi, theta)
    if inv:
        m1 = Matrix.RZ(-phibase)
        m2 = Matrix.RY(-thetabase)
    else:
        m2 = Matrix.RZ(phibase)
        m1 = Matrix.RY(thetabase)
    return Spherical.to(Matrix.prod(m2, Matrix.prod(m1, u)))[1:]
        
        
        


    
    

Loading data, please wait...