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()
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
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
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
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
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
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
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
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]
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
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
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
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
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
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)
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))
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
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]
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]
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()
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
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
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]
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
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
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
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
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
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