Beispiel #1
0
    def d_lambda(self):
        freq = 100
        d_lambda = 0.1
        for dendType in self.dendTypeList:
            for sec in self.dendTypeList[dendType]:
                sec.push()
                if h.n3d() < 2:
                    lambda_f = 1e5 * np.sqrt(
                        sec.diam / (4 * np.pi * freq * sec.Ra * sec.cm))
                else:
                    x1 = h.arc3d(0)
                    d1 = h.diam3d(0)
                    lam = 0
                    for ii in range(1, int(h.n3d())):
                        x2 = h.arc3d(ii)
                        d2 = h.diam3d(ii)
                        lam += (x2 - x1) / np.sqrt(d1 + d2)
                        x1 = x2
                        d1 = d2
                    lam *= np.sqrt(2) * 1e-5 * np.sqrt(
                        4 * np.pi * freq * sec.Ra * sec.cm)
                    lambda_f = sec.L / lam

                nseg = (int(
                    (sec.L / (d_lambda * lambda_f) + 0.9) / 2) * 2 + 1) / 2
                if nseg % 2 == 0:
                    nseg += 1

                sec.nseg = nseg
                h.pop_section()
Beispiel #2
0
def _volumes1d(sec):
    if not isinstance(sec, nrn.Section):
        sec = sec._sec
    arc3d = [h.arc3d(i, sec=sec) for i in xrange(int(h.n3d(sec=sec)))]
    diam3d = [h.diam3d(i, sec=sec) for i in xrange(int(h.n3d(sec=sec)))]
    vols = numpy.zeros(sec.nseg)
    dx = sec.L / sec.nseg
    for iseg in xrange(sec.nseg):
        # get a list of all pts in the segment, including end points
        lo = iseg * dx
        hi = (iseg + 1) * dx
        pts = [lo] + [x for x in arc3d if lo < x < hi] + [hi]

        diams = numpy.interp(pts, arc3d, diam3d)

        # sum the volume of the constituent frusta
        volume = 0
        for i in xrange(len(pts) - 1):
            diam0, diam1 = diams[i:i + 2]
            pt0, pt1 = pts[i:i + 2]
            volume += numpy.pi * (pt1 - pt0) / 12. * (diam0**2 +
                                                      diam0 * diam1 + diam1**2)
        vols[iseg] = volume

    return vols
def dend_connections(sec):
    sec.push()

    n = int(h.n3d())

    x = h.Vector(n)
    y = h.Vector(n)
    z = h.Vector(n)
    s = h.Vector(n)

    for i in range(n):
        x.x[i] = h.x3d(i)
        y.x[i] = h.y3d(i)
        z.x[i] = h.z3d(i)
        s.x[i] = h.arc3d(i)

    # find arc to interp
    s1 = h.Vector()
    arc = params.mean_synapse_invl / 2
    while arc < sec.L:
        s1.append(arc)
        arc += params.mean_synapse_invl

    h.pop_section()

    # interpolate
    x.interpolate(s1, s)
    y.interpolate(s1, s)
    z.interpolate(s1, s)
    s1.mul(1.0 / sec.L)

    return s1, x, y, z
Beispiel #4
0
    def result(sec):
        if not isinstance(sec, nrn.Section):
            sec = sec._sec
        arc3d = [h.arc3d(i, sec=sec) for i in xrange(int(h.n3d(sec=sec)))]
        diam3d = [h.diam3d(i, sec=sec) for i in xrange(int(h.n3d(sec=sec)))]
        sas = numpy.zeros(sec.nseg)
        dx = sec.L / sec.nseg
        for iseg in xrange(sec.nseg):
            # get a list of all pts in the segment, including end points
            lo = iseg * dx
            hi = (iseg + 1) * dx
            pts = [lo] + [x for x in arc3d if lo < x < hi] + [hi]

            diams = numpy.interp(pts, arc3d, diam3d)

            # sum the surface areas of the constituent frusta
            sa = 0
            for i in xrange(len(pts) - 1):
                diam0, diam1 = diams[i:i + 2]
                pt0, pt1 = pts[i:i + 2]
                sa += scale * 0.5 * (diam0 +
                                     diam1) * numpy.sqrt(0.25 *
                                                         (diam0 - diam1)**2 +
                                                         (pt1 - pt0)**2)
            sas[iseg] = sa
        return sas
Beispiel #5
0
    def volumes1d(self, sec):
        if not isinstance(sec, nrn.Section):
            sec = sec._sec
        arc3d = [h.arc3d(i, sec=sec) for i in xrange(int(h.n3d(sec=sec)))]
        diam3d = [h.diam3d(i, sec=sec) for i in xrange(int(h.n3d(sec=sec)))]
        vols = numpy.zeros(sec.nseg)
        dx = sec.L / sec.nseg
        for iseg in xrange(sec.nseg):
            # get a list of all pts in the segment, including end points
            lo = iseg * dx
            hi = (iseg + 1) * dx
            pts = [lo] + [x for x in arc3d if lo < x < hi] + [hi]

            diams = numpy.interp(pts, arc3d, diam3d)

            # sum the volume of the constituent frusta, hollowing out by the inside
            volume = 0
            for i in xrange(len(pts) - 1):
                diam0h, diam1h = self._hi * diams[i:i + 2]
                diam0l, diam1l = self._lo * diams[i:i + 2]
                pt0, pt1 = pts[i:i + 2]
                volume += numpy.pi * (pt1 - pt0) / 12. * (
                    (diam0h**2 + diam0h * diam1h + diam1h**2) -
                    (diam0l**2 + diam0l * diam1l + diam1l**2))
            vols[iseg] = volume

        return vols
Beispiel #6
0
    def volumes1d(self, sec):
        if not isinstance(sec, nrn.Section):
            sec = sec._sec
        arc3d = [h.arc3d(i, sec=sec)
                 for i in range(int(h.n3d(sec=sec)))]
        diam3d = [h.diam3d(i, sec=sec)
                  for i in range(int(h.n3d(sec=sec)))]
        vols = numpy.zeros(sec.nseg)
        dx = sec.L / sec.nseg
        for iseg in range(sec.nseg):
            # get a list of all pts in the segment, including end points
            lo = iseg * dx
            hi = (iseg + 1) * dx
            pts = [lo] + [x for x in arc3d if lo < x < hi] + [hi]
            
            diams = numpy.interp(pts, arc3d, diam3d)
            
            # sum the volume of the constituent frusta, hollowing out by the inside
            volume = 0
            for i in range(len(pts) - 1):
                diam0h, diam1h = self._hi * diams[i : i + 2]
                diam0l, diam1l = self._lo * diams[i : i + 2]
                pt0, pt1 = pts[i : i + 2]
                volume += numpy.pi * (pt1 - pt0) / 12. * ((diam0h ** 2 + diam0h * diam1h + diam1h ** 2) - (diam0l ** 2 + diam0l * diam1l + diam1l ** 2))
            vols[iseg] = volume

        return vols
Beispiel #7
0
 def result(sec):
     if not isinstance(sec, nrn.Section):
         sec = sec._sec
     arc3d = [h.arc3d(i, sec=sec)
             for i in range(int(h.n3d(sec=sec)))]
     diam3d = [h.diam3d(i, sec=sec)
             for i in range(int(h.n3d(sec=sec)))]
     sas = numpy.zeros(sec.nseg)
     dx = sec.L / sec.nseg
     for iseg in range(sec.nseg):
         # get a list of all pts in the segment, including end points
         lo = iseg * dx
         hi = (iseg + 1) * dx
         pts = [lo] + [x for x in arc3d if lo < x < hi] + [hi]
         
         diams = numpy.interp(pts, arc3d, diam3d)
         
         # sum the surface areas of the constituent frusta
         sa = 0
         for i in range(len(pts) - 1):
             diam0, diam1 = diams[i : i + 2]
             pt0, pt1 = pts[i : i + 2]
             sa += scale * 0.5 * (diam0 + diam1) * numpy.sqrt(0.25 * (diam0 - diam1) ** 2 + (pt1 - pt0) ** 2)
         sas[iseg] = sa
     return sas
def lambda_f(section, freq):
    if h.n3d() < 2:
        return 1e5*math.sqrt(section.diam/(math.pi*4*freq*section.Ra*section.cm))
    else:
        x1 = h.arc3d(0)
        d1 = h.diam3d(0)
        lam = 0
        for i in range(int(h.n3d())):
            x2 = h.arc3d(i)
            d2 = h.diam3d(i)
            lam += (x2 - x1)/math.sqrt(d1 + d2)
            x1 = x2
            d1 = d2
        lam *=  math.sqrt(2) * 1e-5*math.sqrt(4*math.pi*freq*section.Ra*section.cm)

    return section.L / lam
Beispiel #9
0
def _volumes1d(sec):
    if not isinstance(sec, nrn.Section):
        sec = sec._sec
    arc3d = [h.arc3d(i, sec=sec)
             for i in range(int(h.n3d(sec=sec)))]
    diam3d = [h.diam3d(i, sec=sec)
              for i in range(int(h.n3d(sec=sec)))]
    vols = numpy.zeros(sec.nseg)
    dx = sec.L / sec.nseg
    for iseg in range(sec.nseg):
        # get a list of all pts in the segment, including end points
        lo = iseg * dx
        hi = (iseg + 1) * dx
        pts = [lo] + [x for x in arc3d if lo < x < hi] + [hi]
        
        diams = numpy.interp(pts, arc3d, diam3d)
        
        # sum the volume of the constituent frusta
        volume = 0
        for i in range(len(pts) - 1):
            diam0, diam1 = diams[i : i + 2]
            pt0, pt1 = pts[i : i + 2]
            volume += numpy.pi * (pt1 - pt0) / 12. * (diam0 ** 2 + diam0 * diam1 + diam1 ** 2)
        vols[iseg] = volume

    return vols
Beispiel #10
0
def morph_per_root(root):
    morph = []
    h.define_shape()
    for sec in secs_with_root(root):
        n3d = int(h.n3d(sec=sec))
        x = [h.x3d(i, sec=sec) for i in xrange(n3d)]
        y = [h.y3d(i, sec=sec) for i in xrange(n3d)]
        z = [h.z3d(i, sec=sec) for i in xrange(n3d)]
        d = [h.diam3d(i, sec=sec) for i in xrange(n3d)]
        arc = [h.arc3d(i, sec=sec) for i in xrange(n3d)]
        length = sec.L
        half_dx = 0.5 / sec.nseg
        for seg in sec:
            morph.append(get_pts_between(x, y, z, d, arc, (seg.x - half_dx) * length, (seg.x + half_dx) * length))
    
    # add end points
    for end_pt in [0, 1]:
        for sec in secs_with_root(root):
            n3d = int(h.n3d(sec=sec))
            pt1 = [h.x3d(0, sec=sec), h.y3d(0, sec=sec), h.z3d(0, sec=sec), h.diam3d(0, sec=sec)]
            pt2 = [h.x3d(n3d - 1, sec=sec), h.y3d(n3d - 1, sec=sec), h.z3d(n3d - 1, sec=sec), h.diam3d(n3d - 1, sec=sec)]
            if h.section_orientation(sec=sec) == 0:
                morph_to_append = [pt1] if end_pt == 0 else [pt2]
            else:
                morph_to_append = [pt2] if end_pt == 0 else [pt1]
            round3(morph_to_append)
            morph.append(morph_to_append)
    return morph
Beispiel #11
0
    def interpxyz(self):
        """
        Equivalent methods interpxyz and setrx from the xtra mechanism available on the NEURON website from Ted Carnevale
        Setrx has been modified to integrate the use of multipolar electrodes

        interpolated data, spaced at regular intervals

        Returns:

        """

        # First, need to interpolate centers unto all compartments; from interpxyz.hoc
        for sec in self.allseclist:

            if h.ismembrane('xtra', sec=sec):

                nn = int(h.n3d(sec=sec))
                xx = h.Vector(nn)
                yy = h.Vector(nn)
                zz = h.Vector(nn)
                length = h.Vector(nn)

                # for ii in xrange(nn):
                for ii in range(nn):
                    xx.x[ii] = h.x3d(ii, sec=sec)
                    yy.x[ii] = h.y3d(ii, sec=sec)
                    zz.x[ii] = h.z3d(ii, sec=sec)
                    length.x[ii] = h.arc3d(ii, sec=sec)

                # to use Vector class's .interpolate() must first scale the independent variable i.e. normalize length along centroid
                length.div(length.x[nn - 1])
                # initialize the destination "independent" vector
                rr = h.Vector(sec.nseg + 2)
                rr.indgen(1. / sec.nseg)
                rr.sub(1. / (2. * sec.nseg))
                rr.x[0] = 0.
                rr.x[sec.nseg + 1] = 1.

                # length contains the normalized distances of the pt3d points along the centroid of the section.
                # These are spaced at irregular intervals.
                # range contains the normalized distances of the nodes along the centroid of the section.
                # These are spaced at regular intervals.

                # Ready to interpolate.
                xint = h.Vector(sec.nseg + 2)
                yint = h.Vector(sec.nseg + 2)
                zint = h.Vector(sec.nseg + 2)
                xint.interpolate(rr, length, xx)
                yint.interpolate(rr, length, yy)
                zint.interpolate(rr, length, zz)

                # for each node, assign the xyz values to x_xtra, y_xtra, z_xtra
                # don't bother computing coords of the 0 and 1 ends
                # also avoid writing coords of the 1 end into the last internal node's coords
                for ii in range(1, sec.nseg + 1):
                    xr = rr.x[ii]
                    sec(xr).x_xtra = xint.x[ii]
                    sec(xr).y_xtra = yint.x[ii]
                    sec(xr).z_xtra = zint.x[ii]
Beispiel #12
0
 def result(sec):
     if not isinstance(sec, nrn.Section):
         sec = sec._sec
         arc3d = [h.arc3d(i, sec=sec) for i in range(int(h.n3d(sec=sec)))]
         diam3d = [h.diam3d(i, sec=sec) for i in range(int(h.n3d(sec=sec)))]
         area_pos = numpy.linspace(0, sec.L, sec.nseg + 1)
         diams = numpy.interp(area_pos, arc3d, diam3d)
         return scale * diams
Beispiel #13
0
 def result(sec):
     if not isinstance(sec, nrn.Section):
         sec = sec._sec
         arc3d = [h.arc3d(i, sec=sec) for i in xrange(int(h.n3d(sec=sec)))]
         diam3d = [h.diam3d(i, sec=sec) for i in xrange(int(h.n3d(sec=sec)))]
         area_pos = numpy.linspace(0, sec.L, sec.nseg + 1)
         diams = numpy.interp(area_pos, arc3d, diam3d)
         return scale * diams
Beispiel #14
0
def _neighbor_areas1d(sec):
    if not isinstance(sec, nrn.Section):
        sec = sec._sec
    arc3d = [h.arc3d(i, sec=sec) for i in xrange(int(h.n3d(sec=sec)))]
    diam3d = [h.diam3d(i, sec=sec) for i in xrange(int(h.n3d(sec=sec)))]
    area_pos = numpy.linspace(0, sec.L, sec.nseg + 1)
    diams = numpy.interp(area_pos, arc3d, diam3d)
    return numpy.pi * 0.25 * diams**2
Beispiel #15
0
def _neighbor_areas1d(sec):
    arc3d = [h.arc3d(i, sec=sec._sec)
             for i in xrange(int(h.n3d(sec=sec._sec)))]
    diam3d = [h.diam3d(i, sec=sec._sec)
              for i in xrange(int(h.n3d(sec=sec._sec)))]
    area_pos = numpy.linspace(0, sec.L, sec.nseg + 1)
    diams = numpy.interp(area_pos, arc3d, diam3d)
    return numpy.pi * 0.25 * diams ** 2
Beispiel #16
0
def lambda_f(section, freq):
    if h.n3d() < 2:
        return 1e5 * math.sqrt(section.diam /
                               (math.pi * 4 * freq * section.Ra * section.cm))
    else:
        x1 = h.arc3d(0)
        d1 = h.diam3d(0)
        lam = 0
        for i in range(int(h.n3d())):
            x2 = h.arc3d(i)
            d2 = h.diam3d(i)
            lam += (x2 - x1) / math.sqrt(d1 + d2)
            x1 = x2
            d1 = d2
        lam *= math.sqrt(2) * 1e-5 * math.sqrt(
            4 * math.pi * freq * section.Ra * section.cm)

    return section.L / lam
Beispiel #17
0
 def neighbor_areas1d(self, sec):
     arc3d = [h.arc3d(i, sec=sec._sec)
              for i in xrange(int(h.n3d(sec=sec._sec)))]
     diam3d = [h.diam3d(i, sec=sec._sec)
               for i in xrange(int(h.n3d(sec=sec._sec)))]
     area_pos = numpy.linspace(0, sec.L, sec.nseg + 1)
     diams = numpy.interp(area_pos, arc3d, diam3d)
     if self._type == _lo_hi_shell:
         return numpy.pi * .25 * ((diams * self._hi) ** 2 - (diams * self._lo) ** 2)
Beispiel #18
0
def pt_from_seg(seg):
    sec = seg.sec
    n = int(h.n3d(sec=sec))
    x = [h.x3d(i, sec=sec) for i in xrange(n)]
    y = [h.y3d(i, sec=sec) for i in xrange(n)]
    z = [h.z3d(i, sec=sec) for i in xrange(n)]
    arc = [h.arc3d(i, sec=sec) for i in xrange(n)]
    f = seg.x * sec.L
    return (numpy.interp(f, arc, x), numpy.interp(f, arc, y), numpy.interp(f, arc, z))
Beispiel #19
0
def _neighbor_areas1d(sec):
    if not isinstance(sec, nrn.Section):
        sec = sec._sec
    arc3d = [h.arc3d(i, sec=sec)
             for i in range(int(h.n3d(sec=sec)))]
    diam3d = [h.diam3d(i, sec=sec)
              for i in range(int(h.n3d(sec=sec)))]
    area_pos = numpy.linspace(0, sec.L, sec.nseg + 1)
    diams = numpy.interp(area_pos, arc3d, diam3d)
    return numpy.pi * 0.25 * diams ** 2
Beispiel #20
0
def _xyz(seg):
    """Return the (x, y, z) coordinate of the center of the segment."""
    # TODO: this is very inefficient, especially since we're calling this for each segment not for each section; fix
    sec = seg.sec
    n3d = int(h.n3d(sec=sec))
    x3d = [h.x3d(i, sec=sec) for i in xrange(n3d)]
    y3d = [h.y3d(i, sec=sec) for i in xrange(n3d)]
    z3d = [h.z3d(i, sec=sec) for i in xrange(n3d)]
    arc3d = [h.arc3d(i, sec=sec) for i in xrange(n3d)]
    return numpy.interp([seg.x * sec.L], arc3d, x3d)[0], numpy.interp([seg.x], arc3d, y3d)[0], numpy.interp([seg.x], arc3d, z3d)[0]
Beispiel #21
0
 def setdata(self):
     start_ends = []
     volts = []
     for dendType in self.dendTypeList:
         for sec in self.dendTypeList[dendType]:
             sec.push()
             seg_pos = np.linspace(0.5 / sec.nseg, 1 - 0.5 / sec.nseg,
                                   sec.nseg)
             boundary_pos = np.linspace(0, 1, sec.nseg + 1)
             for jj in range(len(seg_pos)):
                 pos = seg_pos[jj]
                 tmp_v = h.Vector()
                 tmp_v.record(sec(pos)._ref_v, 0.25)
                 start_pos = boundary_pos[jj]
                 end_pos = boundary_pos[jj + 1]
                 for ii in range(int(h.n3d()) - 1):
                     if (h.arc3d(ii) / sec.L) <= start_pos <= (
                             h.arc3d(ii + 1) / sec.L):
                         swc1 = np.array([h.x3d(ii), h.y3d(ii), h.z3d(ii)])
                         swc2 = np.array(
                             [h.x3d(ii + 1),
                              h.y3d(ii + 1),
                              h.z3d(ii + 1)])
                         f = (start_pos - h.arc3d(ii) / sec.L) / (
                             (h.arc3d(ii + 1) - h.arc3d(ii)) / sec.L)
                         break
                 start_point = tuple(f * (swc2 - swc1) + swc1)
                 for ii in range(int(h.n3d()) - 1):
                     if (h.arc3d(ii) /
                             sec.L) <= end_pos <= (h.arc3d(ii + 1) / sec.L):
                         swc1 = np.array([h.x3d(ii), h.y3d(ii), h.z3d(ii)])
                         swc2 = np.array(
                             [h.x3d(ii + 1),
                              h.y3d(ii + 1),
                              h.z3d(ii + 1)])
                         f = (end_pos - h.arc3d(ii) / sec.L) / (
                             (h.arc3d(ii + 1) - h.arc3d(ii)) / sec.L)
                         break
                 end_point = tuple(f * (swc2 - swc1) + swc1)
                 volts.append(tmp_v)
                 start_ends.append([start_point, end_point])
             h.pop_section()
     return [volts, start_ends]
Beispiel #22
0
 def find_segloc(self, sec, reg, loclist):
     sec.push()
     if len(reg[sec]) > 0:
         for seg in reg[sec]:
             for ii in range(int(h.n3d()) - 1):
                 if (h.arc3d(ii) / sec.L) <= seg < (h.arc3d(ii + 1) /
                                                    sec.L):
                     swc1 = np.array([h.x3d(ii), h.y3d(ii), h.z3d(ii)])
                     swc2 = np.array(
                         [h.x3d(ii + 1),
                          h.y3d(ii + 1),
                          h.z3d(ii + 1)])
                     f = (seg - h.arc3d(ii) / sec.L) / (
                         (h.arc3d(ii + 1) - h.arc3d(ii)) / sec.L)
                     break
             point = f * (swc2 - swc1) + swc1
             loclist[0].append(point[0])
             loclist[1].append(point[1])
             loclist[2].append(point[2])
     h.pop_section()
Beispiel #23
0
def _posFromLoc(self, sec, x):
    sec.push()
    s = x * sec.L
    numpts = int(h.n3d())
    b = -1
    for ii in range(numpts):
        if h.arc3d(ii) >= s:
            b = ii
            break
    if b == -1: print("an error occurred in pointFromLoc, SOMETHING IS NOT RIGHT")

    if h.arc3d(b) == s:  # shortcut
        x, y, z = h.x3d(b), h.y3d(b), h.z3d(b)
    else:               # need to interpolate
        a = b-1
        t = (s - h.arc3d(a)) / (h.arc3d(b) - h.arc3d(a))
        x = h.x3d(a) + t * (h.x3d(b) - h.x3d(a))
        y = h.y3d(a) + t * (h.y3d(b) - h.y3d(a))
        z = h.z3d(a) + t * (h.z3d(b) - h.z3d(a))    

    h.pop_section()
    return x, y, z
Beispiel #24
0
def objects_by_segment(sec):
    """
    given a section, returns a dictionary whose entries are lists of objects
    that should be used for distance calculations, keyed by section
    
    .. warning::
    
        Does not currently support non-frustum based sections (i.e. no support
        for new 3d styles, like soma outlines)
    
    .. warning::
    
        This assumes a 3d style exists. The safest way to call this is to call
        h.define_shape() first
    """
    # TODO: fix the issue described in the warning
    #       (when this was written, these objects were only under development)

    n3d = int(h.n3d(sec=sec))
    length = sec.L

    arc3d = [h.arc3d(i, sec=sec) for i in xrange(n3d)]
    x3d = numpy.array([h.x3d(i, sec=sec) for i in xrange(n3d)])
    y3d = numpy.array([h.y3d(i, sec=sec) for i in xrange(n3d)])
    z3d = numpy.array([h.z3d(i, sec=sec) for i in xrange(n3d)])
    diam3d = numpy.array([h.diam3d(i, sec=sec) for i in xrange(n3d)])

    dx = length / sec.nseg
    objs = {}
    for i in xrange(sec.nseg):
        x_lo = i * dx
        x_hi = (i + 1) * dx
        pts = [x_lo] + _values_strictly_between(x_lo, x_hi, arc3d) + [x_hi]
        local_x3d = numpy.interp(pts, arc3d, x3d)
        local_y3d = numpy.interp(pts, arc3d, y3d)
        local_z3d = numpy.interp(pts, arc3d, z3d)
        local_diam3d = numpy.interp(pts, arc3d, diam3d)
        local_objs = []
        for j in xrange(len(pts) - 1):
            x0, y0, z0, r0 = local_x3d[j], local_y3d[j], local_z3d[
                j], local_diam3d[j] / 2.
            x1, y1, z1, r1 = local_x3d[j + 1], local_y3d[j + 1], local_z3d[
                j + 1], local_diam3d[j + 1] / 2.
            if r0 == r1:
                local_objs.append(Cylinder(x0, y0, z0, x1, y1, z1, r0))
            else:
                local_objs.append(Cone(x0, y0, z0, r0, x1, y1, z1, r1))
        objs[sec((i + 0.5) / sec.nseg)] = local_objs
    return objs
Beispiel #25
0
 def interpxyz(self):
     """ interpolated data, spaced at regular intervals
     """
             # First, need to interpolate centers unto all compartments; from interpxyz.hoc
     for sec in h.allsec():
         #if h.ismembrane('chanrhod',sec=sec):
         if h.ismembrane('chanrhod',sec=sec):
             nn = h.n3d(sec=sec).__int__()
             xx = h.Vector(nn)
             yy = h.Vector(nn)
             zz = h.Vector(nn)
             length = h.Vector(nn)
             for ii in range(nn):
                 xx.x[ii] = h.x3d(ii,sec=sec)
                 yy.x[ii] = h.y3d(ii,sec=sec)
                 zz.x[ii] = h.z3d(ii,sec=sec)
                 length.x[ii] = h.arc3d(ii,sec=sec)
             # to use Vector class's .interpolate() must first scale the
             # independent variable i.e. normalize length along centroid
             length.div(length.x[nn-1])
             # initialize the destination "independent" vector
             rr = h.Vector(sec.nseg+2)
             rr.indgen(1./sec.nseg)
             rr.sub(1./(2.*sec.nseg))
             rr.x[0]=0.
             rr.x[sec.nseg+1]=1.
             # length contains the normalized distances of the pt3d points
             # along the centroid of the section.  These are spaced at
             # irregular intervals.
             # range contains the normalized distances of the nodes along the
             # centroid of the section.  These are spaced at regular intervals.
             # Ready to interpolate.
             xint = h.Vector(sec.nseg+2)
             yint = h.Vector(sec.nseg+2)
             zint = h.Vector(sec.nseg+2)
             xint.interpolate(rr, length, xx)
             yint.interpolate(rr, length, yy)
             zint.interpolate(rr, length, zz)
             # for each node, assign the xyz values to x_xtra, y_xtra, z_xtra
             # don't bother computing coords of the 0 and 1 ends
             # also avoid writing coords of the 1 end into the last internal node's coords
             for ii in range(1,sec.nseg+1):
                 xr = rr.x[ii]
                 #sec(xr).x_chanrhod = xint.x[ii]
                 #sec(xr).y_chanrhod = yint.x[ii]
                 #sec(xr).z_chanrhod = zint.x[ii]
                 sec(xr).x_chanrhod = xint.x[ii]
                 sec(xr).y_chanrhod = yint.x[ii]
                 sec(xr).z_chanrhod = zint.x[ii]
Beispiel #26
0
def objects_by_segment(sec):
    """
    given a section, returns a dictionary whose entries are lists of objects
    that should be used for distance calculations, keyed by section
    
    .. warning::
    
        Does not currently support non-frustum based sections (i.e. no support
        for new 3d styles, like soma outlines)
    
    .. warning::
    
        This assumes a 3d style exists. The safest way to call this is to call
        h.define_shape() first
    """
    # TODO: fix the issue described in the warning
    #       (when this was written, these objects were only under development)
    
    n3d = int(h.n3d(sec=sec))
    length = sec.L
    
    arc3d = [h.arc3d(i, sec=sec) for i in xrange(n3d)]
    x3d = numpy.array([h.x3d(i, sec=sec) for i in xrange(n3d)])
    y3d = numpy.array([h.y3d(i, sec=sec) for i in xrange(n3d)])
    z3d = numpy.array([h.z3d(i, sec=sec) for i in xrange(n3d)])
    diam3d = numpy.array([h.diam3d(i, sec=sec) for i in xrange(n3d)])
    
    dx = length / sec.nseg
    objs = {}
    for i in xrange(sec.nseg):
        x_lo = i * dx
        x_hi = (i + 1) * dx
        pts = [x_lo] + _values_strictly_between(x_lo, x_hi, arc3d) + [x_hi]
        local_x3d = numpy.interp(pts, arc3d, x3d)
        local_y3d = numpy.interp(pts, arc3d, y3d)
        local_z3d = numpy.interp(pts, arc3d, z3d)
        local_diam3d = numpy.interp(pts, arc3d, diam3d)
        local_objs = []
        for j in xrange(len(pts) - 1):
            x0, y0, z0, r0 = local_x3d[j], local_y3d[j], local_z3d[j], local_diam3d[j] / 2.
            x1, y1, z1, r1 = local_x3d[j + 1], local_y3d[j + 1], local_z3d[j + 1], local_diam3d[j + 1] / 2.
            if r0 == r1:
                local_objs.append(Cylinder(x0, y0, z0, x1, y1, z1, r0))
            else:
                local_objs.append(Cone(x0, y0, z0, r0, x1, y1, z1, r1))
        objs[sec((i + 0.5) / sec.nseg)] = local_objs
    return objs
Beispiel #27
0
def get_alen_pos3d(sec):
    """Get the arclength and 3D position of the poinst in section sec.
    Inspired by
    http://www.neuron.yale.edu/ftp/ted/neuron/extracellular_stim_and_rec.zip:
    interpxyz.hoc

    Returns: length, pos where length is the list of arc3d lengths and
    pos the list of 3D positions (x, y, z), of the 3D points in
    section `sec`.

    """
    npts = int(h.n3d(sec=sec))
    pos = []
    length = []
    for ii in range(npts):
        pos.append((h.x3d(ii, sec=sec), h.y3d(ii, sec=sec), h.z3d(ii,
                                                                  sec=sec)))
        length.append(h.arc3d(ii, sec=sec))
    return length, pos
Beispiel #28
0
    def calc_seg_coords(self):
        """Calculate segment coordinates from 3d point coordinates"""
        ix = 0  # segment index

        p3dsoma = self.get_soma_pos()
        self.psoma = p3dsoma

        p0 = np.zeros(
            (3, self.nseg))  # hold the coordinates of segment starting points
        p1 = np.zeros(
            (3, self.nseg))  # hold the coordinates of segment end points
        p05 = np.zeros((3, self.nseg))
        d0 = np.zeros(self.nseg)
        d1 = np.zeros(self.nseg)

        for sec in self.hobj.all:
            n3d = int(h.n3d())  # get number of n3d points in each section
            p3d = np.zeros(
                (3, n3d)
            )  # to hold locations of 3D morphology for the current section
            l3d = np.zeros(
                n3d
            )  # to hold locations of 3D morphology for the current section
            diam3d = np.zeros(n3d)  # to diameters

            for i in range(n3d):
                p3d[0, i] = h.x3d(i) - p3dsoma[0]
                p3d[1, i] = h.y3d(i) - p3dsoma[
                    1]  # shift coordinates such to place soma at the origin.
                p3d[2, i] = h.z3d(i) - p3dsoma[2]
                diam3d[i] = h.diam3d(i)
                l3d[i] = h.arc3d(i)

            l3d /= sec.L  # normalize
            nseg = sec.nseg

            l0 = np.zeros(nseg)  # keep range of segment starting point
            l1 = np.zeros(nseg)  # keep range of segment ending point
            l05 = np.zeros(nseg)

            for iseg, seg in enumerate(sec):
                l0[iseg] = seg.x - 0.5 * 1 / nseg  # x (normalized distance along the section) for the beginning of the segment
                l1[iseg] = seg.x + 0.5 * 1 / nseg  # x for the end of the segment
                l05[iseg] = seg.x

            if n3d != 0:
                p0[0, ix:ix + nseg] = np.interp(l0, l3d, p3d[0, :])
                p0[1, ix:ix + nseg] = np.interp(l0, l3d, p3d[1, :])
                p0[2, ix:ix + nseg] = np.interp(l0, l3d, p3d[2, :])
                d0[ix:ix + nseg] = np.interp(l0, l3d, diam3d[:])

                p1[0, ix:ix + nseg] = np.interp(l1, l3d, p3d[0, :])
                p1[1, ix:ix + nseg] = np.interp(l1, l3d, p3d[1, :])
                p1[2, ix:ix + nseg] = np.interp(l1, l3d, p3d[2, :])
                d1[ix:ix + nseg] = np.interp(l1, l3d, diam3d[:])

                p05[0, ix:ix + nseg] = np.interp(l05, l3d, p3d[0, :])
                p05[1, ix:ix + nseg] = np.interp(l05, l3d, p3d[1, :])
                p05[2, ix:ix + nseg] = np.interp(l05, l3d, p3d[2, :])
            else:
                # If we are dealing with a stub axon, this compartment
                # will be zero'd out in the calculation of transfer
                # resistance in modules/ecp.py

                if sec not in self.hobj.axonal:
                    raise Exception(
                        "Non-axonal section with 0 3d points (stub)")

                if nseg != 1:
                    raise Exception(
                        "in calc_seg_coords(), n3d = 0, but nseg != 1")

            ix += nseg

        self.seg_coords = {}

        self.seg_coords['p0'] = p0
        self.seg_coords['p1'] = p1
        self.seg_coords['p05'] = p05

        self.seg_coords['d0'] = d0
        self.seg_coords['d1'] = d1

        return self.seg_coords
Beispiel #29
0
    def calc_seg_coords(self):
        """Calculate segment coordinates from 3d point coordinates"""
        ix = 0  # segment index

        p3dsoma = self.get_soma_pos()
        self.psoma = p3dsoma

        p0 = np.zeros(
            (3, self.nseg))  # hold the coordinates of segment starting points
        p1 = np.zeros(
            (3, self.nseg))  # hold the coordinates of segment end points
        d0 = np.zeros(self.nseg)
        d1 = np.zeros(self.nseg)

        for sec in self.hobj.all:
            n3d = int(h.n3d())  # get number of n3d points in each section
            p3d = np.zeros(
                (3, n3d)
            )  # to hold locations of 3D morphology for the current section
            l3d = np.zeros(
                n3d
            )  # to hold locations of 3D morphology for the current section
            diam3d = np.zeros(n3d)  # to diameters

            for i in range(n3d):
                p3d[0, i] = h.x3d(i) - p3dsoma[0]
                p3d[1, i] = h.y3d(i) - p3dsoma[
                    1]  # shift coordinates such to place soma at the origin.
                p3d[2, i] = h.z3d(i) - p3dsoma[2]
                diam3d[i] = h.diam3d(i)
                l3d[i] = h.arc3d(i)

            l3d /= sec.L  # normalize
            nseg = sec.nseg

            l0 = np.zeros(nseg)  # keep range of segment starting point
            l1 = np.zeros(nseg)  # keep range of segment ending point

            for iseg, seg in enumerate(sec):
                l0[iseg] = seg.x - 0.5 * 1 / nseg  # x (normalized distance along the section) for the beginning of the segment
                l1[iseg] = seg.x + 0.5 * 1 / nseg  # x for the end of the segment

            p0[0, ix:ix + nseg] = np.interp(l0, l3d, p3d[0, :])
            p0[1, ix:ix + nseg] = np.interp(l0, l3d, p3d[1, :])
            p0[2, ix:ix + nseg] = np.interp(l0, l3d, p3d[2, :])
            d0[ix:ix + nseg] = np.interp(l0, l3d, diam3d[:])

            p1[0, ix:ix + nseg] = np.interp(l1, l3d, p3d[0, :])
            p1[1, ix:ix + nseg] = np.interp(l1, l3d, p3d[1, :])
            p1[2, ix:ix + nseg] = np.interp(l1, l3d, p3d[2, :])
            d1[ix:ix + nseg] = np.interp(l1, l3d, diam3d[:])
            ix += nseg

        self.seg_coords = {}

        self.seg_coords['p0'] = p0
        self.seg_coords['p1'] = p1

        self.seg_coords['d0'] = d0
        self.seg_coords['d1'] = d1

        return self.seg_coords
Beispiel #30
0
    def collect_geometry_neuron(self):
        """
        Loop over allseclist to determine area, diam, xyz-start- and
        endpoints, embed geometry to self object

        Returns:

        """

        areavec = np.zeros(self.totnsegs)
        diamvec = np.zeros(self.totnsegs)
        lengthvec = np.zeros(self.totnsegs)
        xstartvec = np.zeros(self.totnsegs)
        xendvec = np.zeros(self.totnsegs)
        ystartvec = np.zeros(self.totnsegs)
        yendvec = np.zeros(self.totnsegs)
        zstartvec = np.zeros(self.totnsegs)
        zendvec = np.zeros(self.totnsegs)

        counter = 0

        #loop over all segments
        for sec in self.allseclist:
            n3d = int(h.n3d())
            nseg = sec.nseg
            gsen2 = 1. / 2 / nseg
            if n3d > 0:
                #create interpolation objects for the xyz pt3d info:
                L = np.zeros(n3d)
                x = np.zeros(n3d)
                y = np.zeros(n3d)
                z = np.zeros(n3d)
                for i in range(n3d):
                    L[i] = h.arc3d(i)
                    x[i] = h.x3d(i)
                    y[i] = h.y3d(i)
                    z[i] = h.z3d(i)
                #normalize as seg.x [0, 1]
                L /= sec.L

                #temporary store position of segment midpoints
                segx = np.zeros(nseg)
                for i, seg in enumerate(sec):
                    segx[i] = seg.x

                #can't be >0 which may happen due to NEURON->Python float transfer:
                segx0 = (segx - gsen2).round(decimals=6)
                segx1 = (segx + gsen2).round(decimals=6)

                #fill vectors with interpolated coordinates of start and end points
                xstartvec[counter:counter + nseg] = np.interp(segx0, L, x)
                xendvec[counter:counter + nseg] = np.interp(segx1, L, x)

                ystartvec[counter:counter + nseg] = np.interp(segx0, L, y)
                yendvec[counter:counter + nseg] = np.interp(segx1, L, y)

                zstartvec[counter:counter + nseg] = np.interp(segx0, L, z)
                zendvec[counter:counter + nseg] = np.interp(segx1, L, z)

                #fill in values area, diam, length
                for i, seg in enumerate(sec):
                    areavec[counter] = h.area(seg.x)
                    diamvec[counter] = seg.diam
                    lengthvec[counter] = sec.L / nseg
                    counter += 1

        #set self attributes
        self.xstart = xstartvec
        self.ystart = ystartvec
        self.zstart = zstartvec
        self.xend = xendvec
        self.yend = yendvec
        self.zend = zendvec
        self.area = areavec
        self.diam = diamvec
        self.length = lengthvec
Beispiel #31
0
    def calcRelativeSegCoords(self):
        """Calculate segment coordinates from 3d point coordinates
        Used for LFP calc (one per population cell; assumes same morphology)"""

        from .. import sim

        localPopGids = list(
            set(sim.net.gid2lid.keys()).intersection(set(self.cellGids)))
        if localPopGids:
            cell = sim.net.cells[sim.net.gid2lid[localPopGids[0]]]
        else:
            return -1

        ix = 0  # segment index

        p3dsoma = cell.getSomaPos()
        nseg = sum([sec['hObj'].nseg for sec in list(cell.secs.values())])

        p0 = np.zeros(
            (3, nseg))  # hold the coordinates of segment starting points
        p1 = np.zeros((3, nseg))  # hold the coordinates of segment end points
        d0 = np.zeros(nseg)
        d1 = np.zeros(nseg)

        for sec in list(cell.secs.values()):
            hSec = sec['hObj']
            hSec.push()
            n3d = int(h.n3d())  # get number of n3d points in each section
            p3d = np.zeros(
                (3, n3d)
            )  # to hold locations of 3D morphology for the current section
            l3d = np.zeros(
                n3d
            )  # to hold locations of 3D morphology for the current section
            diam3d = np.zeros(n3d)  # to diameters

            for i in range(n3d):
                p3d[0, i] = h.x3d(i) - p3dsoma[0]
                p3d[1, i] = h.y3d(i) - p3dsoma[
                    1]  # shift coordinates such to place soma at the origin.
                p3d[2, i] = h.z3d(i) - p3dsoma[2]
                diam3d[i] = h.diam3d(i)
                l3d[i] = h.arc3d(i)

            l3d /= hSec.L  # normalize
            nseg = hSec.nseg

            l0 = np.zeros(nseg)  # keep range of segment starting point
            l1 = np.zeros(nseg)  # keep range of segment ending point

            for iseg, seg in enumerate(hSec):
                l0[iseg] = seg.x - 0.5 * 1 / nseg  # x (normalized distance along the section) for the beginning of the segment
                l1[iseg] = seg.x + 0.5 * 1 / nseg  # x for the end of the segment

            p0[0, ix:ix + nseg] = np.interp(l0, l3d, p3d[0, :])
            p0[1, ix:ix + nseg] = np.interp(l0, l3d, p3d[1, :])
            p0[2, ix:ix + nseg] = np.interp(l0, l3d, p3d[2, :])
            d0[ix:ix + nseg] = np.interp(l0, l3d, diam3d[:])

            p1[0, ix:ix + nseg] = np.interp(l1, l3d, p3d[0, :])
            p1[1, ix:ix + nseg] = np.interp(l1, l3d, p3d[1, :])
            p1[2, ix:ix + nseg] = np.interp(l1, l3d, p3d[2, :])
            d1[ix:ix + nseg] = np.interp(l1, l3d, diam3d[:])
            ix += nseg
            h.pop_section()

        self._morphSegCoords = {}

        self._morphSegCoords['p0'] = p0
        self._morphSegCoords['p1'] = p1

        self._morphSegCoords['d0'] = d0
        self._morphSegCoords['d1'] = d1

        return self._morphSegCoords