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 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 get_pos_data_short(): """ Get positions of all segments currently loaded in Neuron in a simple matrix. Section position information is not available. :returns: Matrix (3 x nSegments) With x,y,z positions. :rtype: :class:`~numpy.ndarray` Example: .. code-block:: python data = get_pos_data_short() """ n = 0 for sec in h.allsec(): n += int(h.n3d()) data = np.zeros([4, n]) cnt = 0 for sec in h.allsec(): for i in xrange(int(h.n3d())): data[0, cnt] = h.x3d(i) data[1, cnt] = h.y3d(i) data[2, cnt] = h.z3d(i) data[3, cnt] = h.diam3d(i) cnt += 1 return data
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 _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 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 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 get_coords_and_radii(self): nrn_section = self.nrn_section # Count 3D points point_count = int(h.n3d(sec=nrn_section)) # Let NEURON create them if missing if point_count == 0: h.define_shape(sec=self.nrn_section) point_count = int(h.n3d(sec=self.nrn_section)) # Collect the coordinates coords = [None] * point_count * 3 # 3 for xy and z radii = [None] * point_count for c in range(point_count): ci = c * 3 coords[ci] = h.x3d(c, sec=nrn_section) coords[ci + 1] = h.y3d(c, sec=nrn_section) coords[ci + 2] = h.z3d(c, sec=nrn_section) radii[c] = h.diam3d(c, sec=nrn_section) / 2.0 self.nseg = int(nrn_section.nseg) self.point_count = point_count self.coords = coords self.radii = radii
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 modify_morphology(section_dict, cellname): for key, sec_list in section_dict.items(): for sec in sec_list: sec.nseg = 11 for sec in section_dict['basal']: for i in xrange(int(nrn.n3d())): nrn.pt3dchange(i, 0.76) for sec in section_dict['oblique_dendrites']: for i in xrange(int(nrn.n3d())): nrn.pt3dchange(i, 0.73) if cellname == 'n120': apic_root_segment = 'apic[9]' elif cellname == 'c12861': apic_root_segment = 'apic[92]' else: raise RuntimeError("Not known cellname!") nrn.distance() apic_tuft_root_diam = None apic_tuft_root_dist = None for sec in section_dict['apic_trunk']: npts = int(nrn.n3d()) cummulative_L = 0 for i in xrange(npts): if not i == 0: delta_x = (nrn.x3d(i) - nrn.x3d(i - 1))**2 delta_y = (nrn.y3d(i) - nrn.y3d(i - 1))**2 delta_z = (nrn.z3d(i) - nrn.z3d(i - 1))**2 cummulative_L += np.sqrt(delta_x + delta_y + delta_z) dist_from_soma = nrn.distance(0) + cummulative_L diam = 3.5 - 4.7e-3 * dist_from_soma # print diam, nrn.diam3d(i) nrn.pt3dchange(i, diam) if sec.name() == apic_root_segment: apic_tuft_root_diam = nrn.diam3d(npts - 1) apic_tuft_root_dist = nrn.distance(1.) longest_tuft_branch = find_longest_tuft_branch(section_dict, apic_tuft_root_dist) tuft_smallest_diam = 0.3 for sec in section_dict['apic_tuft']: npts = int(nrn.n3d()) cummulative_L = 0 start_dist_from_tuft_root = nrn.distance(0.0) - apic_tuft_root_dist for i in xrange(npts): if not i == 0: delta_x = (nrn.x3d(i) - nrn.x3d(i - 1))**2 delta_y = (nrn.y3d(i) - nrn.y3d(i - 1))**2 delta_z = (nrn.z3d(i) - nrn.z3d(i - 1))**2 cummulative_L += np.sqrt(delta_x + delta_y + delta_z) dist_from_root = start_dist_from_tuft_root + cummulative_L diam = apic_tuft_root_diam - dist_from_root/longest_tuft_branch * (apic_tuft_root_diam - tuft_smallest_diam) # print nrn.diam3d(i), diam nrn.pt3dchange(i, diam, sec=sec)
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 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 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 _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 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 get_axon_direction(hobj): for sec in hobj.somatic: n3d = int(h.n3d(sec=sec)) # get number of n3d points in each section soma_end = np.asarray([ h.x3d(n3d - 1, sec=sec), h.y3d(n3d - 1, sec=sec), h.z3d(n3d - 1, sec=sec) ]) mid_point = int(n3d / 2) soma_mid = np.asarray([ h.x3d(mid_point, sec=sec), h.y3d(mid_point, sec=sec), h.z3d(mid_point, sec=sec) ]) for sec in hobj.all: section_name = sec.name().split(".")[1][:4] if section_name == 'axon': n3d = int( h.n3d(sec=sec)) # get number of n3d points in each section axon_p3d = np.zeros( (n3d, 3) ) # to hold locations of 3D morphology for the current section for i in range(n3d): axon_p3d[i, 0] = h.x3d(i, sec=sec) axon_p3d[i, 1] = h.y3d( i, sec=sec ) # shift coordinates such to place soma at the origin. axon_p3d[i, 2] = h.z3d(i, sec=sec) # Add soma coordinates to the list p3d = np.concatenate(([soma_mid], axon_p3d), axis=0) # Compute PCA pca = PCA(n_components=3) pca.fit(p3d) unit_v = pca.components_[0] mag_v = np.sqrt(pow(unit_v[0], 2) + pow(unit_v[1], 2) + pow(unit_v[2], 2)) unit_v[0] = unit_v[0] / mag_v unit_v[1] = unit_v[1] / mag_v unit_v[2] = unit_v[2] / mag_v # Find the direction axon_end = axon_p3d[-1] - soma_mid if np.dot(unit_v, axon_end) < 0: unit_v *= -1 axon_seg_coor = np.zeros((4, 3)) # unit_v = np.asarray([0,1,0]) axon_seg_coor[0] = soma_end axon_seg_coor[1] = soma_end + (unit_v * 30.) axon_seg_coor[2] = soma_end + (unit_v * 30.) axon_seg_coor[3] = soma_end + (unit_v * 60.) return axon_seg_coor
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 get_axon_direction(hobj): for sec in hobj.somatic: n3d = int(h.n3d()) # get number of n3d points in each section soma_end = np.asarray([h.x3d(n3d - 1), h.y3d(n3d - 1), h.z3d(n3d - 1)]) mid_point = int(n3d / 2) soma_mid = np.asarray( [h.x3d(mid_point), h.y3d(mid_point), h.z3d(mid_point)]) axon_p3d_all = [] n_secs = 1 for i, sec in enumerate(hobj.axonal): if i < n_secs: n3d = int(h.n3d()) # get number of n3d points in each section axon_p3d = np.zeros( (n3d, 3) ) # to hold locations of 3D morphology for the current section for i in range(n3d): axon_p3d[i, 0] = h.x3d(i) axon_p3d[i, 1] = h.y3d(i) axon_p3d[i, 2] = h.z3d(i) axon_p3d_all.append(axon_p3d) axon_p3d_all = np.concatenate(axon_p3d_all) # Add soma coordinates to the list p3d = np.concatenate(([soma_mid], axon_p3d_all)) p3d = p3d - soma_mid # set the origin at soma # Compute PCA pca = PCA(n_components=3) pca.fit(p3d) unit_v = pca.components_[0] mag_v = np.sqrt(pow(unit_v[0], 2) + pow(unit_v[1], 2) + pow(unit_v[2], 2)) unit_v[0] = unit_v[0] / mag_v unit_v[1] = unit_v[1] / mag_v unit_v[2] = unit_v[2] / mag_v # Find the direction proj = p3d.dot(pca.components_[0]) unit_v = np.sign(proj.mean()) * pca.components_[0] axon_seg_coor = np.zeros((4, 3)) axon_seg_coor[0] = soma_end axon_seg_coor[1] = soma_end + (unit_v * 30.) axon_seg_coor[2] = soma_end + (unit_v * 30.) axon_seg_coor[3] = soma_end + (unit_v * 60.) return axon_seg_coor
def draw_mayavi(self, x, y, z, d, edges): "Draw the surface the first time" # rendering disabled self.mayavi.visualization.scene.disable_render = True points = mlab.pipeline.scalar_scatter(x, y, z, d / 2.0) dataset = points.mlab_source.dataset dataset.point_data.get_array(0).name = "diameter" dataset.lines = np.vstack(edges) dataset.point_data.update() self.dataset = dataset # The tube src = mlab.pipeline.set_active_attribute(points, point_scalars="diameter") stripper = mlab.pipeline.stripper(src) tube = mlab.pipeline.tube(stripper, tube_sides=6, tube_radius=1) tube.filter.capping = True # tube.filter.use_default_normal = False tube.filter.vary_radius = "vary_radius_by_absolute_scalar" self.tube = tube # Setting the voltage # Making room for the voltage v = [] for sec in h.allsec(): sec.push() v.extend(np.repeat(0.0, h.n3d())) h.pop_section() v = np.array(v) self.draw_surface(v, "v") # ReEnable the rendering self.mayavi.visualization.scene.disable_render = False
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 hoc2morph(hoc_file): """ Generate morph sectioning data from NEURON hoc file. """ sections = {} h.load_file(hoc_file) for sec in h.allsec(): sections[sec.name()] = {} sections[sec.name()]["name"] = sec.name() sr = h.SectionRef(sec=sec) if sr.has_parent(): parent = sr.parent.name() else: parent = None sections[sec.name()]["parent"] = parent children = [] for child in sr.child: children.append(child.name()) sections[sec.name()]["children"] = children x = [] y = [] z = [] d = [] n3d = int(h.n3d()) sections[sec.name()]["points"] = [] for i in range(n3d): sections[sec.name()]["points"].append( [h.x3d(i), h.y3d(i), h.z3d(i), h.diam3d(i)]) return sections
def coarse(hoc_filename,cube_length,save_filename): # INPUT: NEURON .hoc filename to import (str), voxel cube side length (fl/str for gcd), name of file to create for mesh output (str) # >> cube_length: 'gcd' (gcd of box dims) OR floating-point (must be common factor of all box dims) # This function reads in NEURON data and passes their info to # coarse_gen(), then associates the tets of the STEPS Tetmesh object returned # to the NEURON sections which exist inside of them. # Returns a tet_hoc dictionary -- tet_hoc[tet_index] = [encapsulated hoc section references] -- as well as the Tetmesh object ## GET HOC SECTION INFO ## h.load_file(hoc_filename) allp = [[],[],[]] for s in h.allsec(): for j in range(int(h.n3d())): allp[0].append(h.x3d(j)) allp[1].append(h.y3d(j)) allp[2].append(h.z3d(j)) maxl = [max(allp[0]),max(allp[1]),max(allp[2])] minl = [min(allp[0]),min(allp[1]),min(allp[2])] bdim = [ maxl[0] - minl[0], maxl[1] - minl[1], maxl[2] - minl[2] ] print "dims: ", bdim print "mins: ", minl ## CREATE COARSE MESH ## if (cube_length == 'gcd'): gcd = fractions.gcd(fractions.gcd(bdim[0],bdim[1]),fractions.gcd(bdim[2],bdim[1])) print "GCD: ", gcd cube_length = gcd sm = coarse_gen(cube_length,bdim,minl,save_filename) ## ASSOCIATE HOC SECTIONS WITH THEIR TETS ## tet_hoc = tet_associate(sm[0]) return tet_hoc, sm[0]
def retrieve_coordinate(self, sec): """Retrieve the coordinates of the section avoiding duplicates""" sec.push() x, y, z, d = [], [], [], [] tot_points = 0 connect_next = False for i in range(int(h.n3d())): present = False x_i = h.x3d(i) y_i = h.y3d(i) z_i = h.z3d(i) d_i = h.diam3d(i) # Avoiding duplicates in the sec if x_i in x: ind = len(x) - 1 - x[::-1].index( x_i) # Getting the index of last value if y_i == y[ind]: if z_i == z[ind]: present = True if not present: k = (x_i, y_i, z_i) x.append(x_i) y.append(y_i) z.append(z_i) d.append(d_i) h.pop_section() #adding num 3d points per section self.n3dpoints_per_sec[sec.name()] = len(d) return (np.array(x), np.array(y), np.array(z), np.array(d))
def get_pos_data(): """ Get positions x, y, z for all segments and their diameter. :returns: 4 lists: x,y,z,d. One element per section where each element is a :class:`~numpy.ndarray`. Example: .. code-block:: python x,y,z,d = get_pos_data() for sec in xrange(len(x)): for seg in xrange(len(x[sec]): print x[sec][seg], y[sec][seg], z[sec][seg] """ x = [] y = [] z = [] d = [] for sec in h.allsec(): n3d = int(h.n3d()) x_i, y_i, z_i = np.zeros(n3d), np.zeros(n3d), np.zeros(n3d), d_i = np.zeros(n3d) for i in xrange(n3d): x_i[i] = h.x3d(i) y_i[i] = h.y3d(i) z_i[i] = h.z3d(i) d_i[i] = h.diam3d(i) x.append(x_i) y.append(y_i) z.append(z_i) d.append(d_i) return x, y, z, d
def setup_pcmorphology(kk, x, y, z): print 'i value is:', kk cellpc = Purkinje() h.define_shape() sections = h.SectionList() sections.wholetree(cellpc.soma) cellpc.soma.push() n = h.n3d(sec=cellpc.soma) xs = [h.x3d(i) for i in range(int(n))] ys = [h.y3d(i) for i in range(int(n))] zs = [h.z3d(i) for i in range(int(n))] ds = [h.diam3d(i) for i in range(int(n))] j = 0 #sec.push() for a, b, c, d in zip(xs, ys, zs, ds): #print 'sec here is:', sec h.pt3dchange(j, a + x, b + y, c + z, d) j += 1 h.define_shape() h.pop_section() pulist.append(cellpc) #call another function to locate the local granule neurons cellpc.soma.push() getpurksecs = h.SectionList() getpurksecs.wholetree(cellpc.soma) func_local_grcneurons(kk, getpurksecs)
def position(self, x, y, z): for i in range(h.n3d()): h.pt3dchange(i, x+self.x+h.x3d(i), y+self.y+h.y3d(i), z+self.z+h.z3d(i), h.diam3d(i)) self.x = x self.y = y self.z = z
def get_nseg( mysec ): """ return the number of segments necesary to sample the smallest distance between 2 consequtive 3D coordinates in a segment according to the Nysquid criterum (in our case 2 times smaller than the smallest distance). """ ncoord = int( h.n3d( sec = mysec) ) # calculate distance between 0 and 1 coordinate x = h.x3d(0, sec = mysec) - h.x3d(1, sec = mysec) y = h.y3d(0, sec = mysec) - h.y3d(1, sec = mysec) z = h.z3d(0, sec = mysec) - h.z3d(1, sec = mysec) dist = sqrt(x*x + y*y + z*z) for i in range(1, ncoord-1): x = h.x3d(i, sec = mysec) - h.x3d(i+1, sec = mysec) y = h.y3d(i, sec = mysec) - h.y3d(i+1, sec = mysec) z = h.z3d(i, sec = mysec) - h.z3d(i+1, sec = mysec) value = sqrt(x*x + y*y + z*z) dist = value if value < dist else dist nseg = int((mysec.L/dist)*2.0) + 1 # odd number return( nseg )
def morphology_to_dict(sections, outfile=None): section_map = {sec: i for i, sec in enumerate(sections)} result = [] h.define_shape() for sec in sections: my_parent = parent(sec) my_parent_loc = -1 if my_parent is None else parent_loc(sec, my_parent) my_parent = -1 if my_parent is None else section_map[my_parent] n3d = int(h.n3d(sec=sec)) result.append({ 'section_orientation': h.section_orientation(sec=sec), 'parent': my_parent, 'parent_loc': my_parent_loc, '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)], 'diam': [h.diam3d(i, sec=sec) for i in xrange(n3d)], 'name': sec.hname() }) if outfile is not None: with open(outfile, 'w') as f: json.dump(result, f) return result
def get_section_path(h,sec): n3d = int(h.n3d(sec=sec)) xyz = [] for i in range(0,n3d): xyz.append([h.x3d(i,sec=sec),h.y3d(i,sec=sec),h.z3d(i,sec=sec)]) xyz = np.array(xyz) return xyz
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 get_section_path(h, sec): n3d = int(h.n3d(sec=sec)) xyz = [] for i in range(0, n3d): xyz.append([h.x3d(i, sec=sec), h.y3d(i, sec=sec), h.z3d(i, sec=sec)]) xyz = np.array(xyz) return xyz
def append_data(sec, xyzdv, parent_id, connections, func, segfunc): """ Append data to xyzdv """ if not segfunc: v = func(sec) n = int(h.n3d(sec=sec)) for ii in xrange(1, n): x = h.x3d(ii, sec=sec) y = h.y3d(ii, sec=sec) z = h.z3d(ii, sec=sec) d = h.diam3d(ii, sec=sec) if 'node' in sec.name() or 'MYSA' in sec.name(): v = 1.0 else: pass if segfunc: if n == 1: v = func(sec(0.5)) else: v = func(sec(ii / float(n - 1))) xyzdv.append([x, y, z, d, v]) child_id = len(xyzdv) - 1 if len(xyzdv) > 1: connections.append([child_id, parent_id]) parent_id = child_id return xyzdv, connections
def retrieve_coordinate(sec): sec.push() x, y, z, d = [],[],[],[] area = 0 tot_points = 0 connect_next = False for i in range(int(h.n3d())): present = False x_i = h.x3d(i) y_i = h.y3d(i) z_i = h.z3d(i) d_i = h.diam3d(i) a_i = h.area(0.5) if x_i in x: ind = len(x) - 1 - x[::-1].index(x_i) # Getting the index of last value if y_i == y[ind]: if z_i == z[ind]: present = True if not present: k =(x_i, y_i, z_i) x.append(x_i) y.append(y_i) z.append(z_i) d.append(d_i) area += np.sum(a_i) h.pop_section() #adding num 3d points per section n3dpoints[sec.name()] = [np.array(x),np.array(y),np.array(z),np.array(d)] return (np.array(x),np.array(y),np.array(z),np.array(d),area)
def retrieve_coordinate(sec): sec.push() x, y, z, d = [], [], [], [] area = 0 tot_points = 0 connect_next = False for i in range(int(h.n3d())): present = False x_i = h.x3d(i) y_i = h.y3d(i) z_i = h.z3d(i) d_i = h.diam3d(i) a_i = h.area(0.5) if x_i in x: ind = len(x) - 1 - x[::-1].index( x_i) # Getting the index of last value if y_i == y[ind]: if z_i == z[ind]: present = True if not present: k = (x_i, y_i, z_i) x.append(x_i) y.append(y_i) z.append(z_i) d.append(d_i) area += np.sum(a_i) h.pop_section() #adding num 3d points per section n3dpoints[sec.name()] = [ np.array(x), np.array(y), np.array(z), np.array(d) ] return (np.array(x), np.array(y), np.array(z), np.array(d), area)
def h2morph(h): """ Generate morph sectioning data from NEURON h interface with preloaded morphology. """ sections = {} for sec in h.allsec(): sections[sec.name()] = {} sections[sec.name()]["name"] = sec.name() sr = h.SectionRef(sec=sec) if sr.has_parent(): parent = sr.parent.name() else: parent = None sections[sec.name()]["parent"] = parent children = [] for child in sr.child: children.append(child.name()) sections[sec.name()]["children"] = children n3d = int(h.n3d()) sections[sec.name()]["points"] = [] for i in range(n3d): sections[sec.name()]["points"].append( [h.x3d(i), h.y3d(i), h.z3d(i), h.diam3d(i)]) return sections
def insert(self): h = self.h if not hasattr(h, 'cvode'): h.load_file('stdrun.hoc') if not h.cvode.use_fast_imem(): h.cvode.use_fast_imem(1) h.init() if self.method == 'Point': LfpClass = SectionLfpPointMethod elif self.method == 'Line': LfpClass = SectionLfpLineMethod else: # self.method == 'RC': LfpClass = SectionLfpRCMethod for sec in self.sec_list: # h.allsec(): if self.is_lfp_section(sec.name()): # Let NEURON create 3D points if missing if h.n3d(sec=sec) <= 0: h.define_shape(sec=sec) # Keep track of sections being monitored self.section_lfps[sec] = LfpClass(self, sec)
def get_coord(self, sec_ids, sec_xs, soma_center=(0.0, 0.0, 0.0), rotation_matrix=None): """Takes in a list of section_ids and section_x values and returns a list of coordinates, assuming the soma is at the center of the system. :param sec_ids: [float]: list of N section_ids :param sec_xs: [float]: list of N cooresponding section_x's :param soma_center: location of soma in respect to the coordinate system. (default (0, 0, 0)). :param rotation_matrix: List of rotations (not yet implemented) :return: [(float, float, float)]: for seach sec_ids/sec_xs returna the x,y,z coordinates as a tuple """ adjusted = self._morphology.get_soma_pos() - np.array(soma_center) absolute_coords = [] for sec_id, sec_x in zip(sec_ids, sec_xs): sec = self._secs[sec_id] n_coords = int(h.n3d(sec=sec)) coord_indx = int(sec_x * (n_coords - 1)) swc_coords = np.array([ h.x3d(coord_indx, sec=sec), h.y3d(coord_indx, sec=sec), h.x3d(coord_indx, sec=sec) ]) adjusted_coords = swc_coords - adjusted if rotation_matrix is not None: adjusted_coords = np.dot(rotation_matrix, adjusted_coords) absolute_coords.append(adjusted_coords) return absolute_coords
def rotateZ(self, theta): """Rotate the cell about the Z axis.""" rot_m = numpy.array([[sin(theta), cos(theta)], [cos(theta), -sin(theta)]]) for sec in self.all: for i in range(int(h.n3d())): xy = numpy.dot([h.x3d(i), h.y3d(i)], rot_m) h.pt3dchange(i, xy[0], xy[1], h.z3d(i), h.diam3d(i))
def retrieve_coordinate(self, sec): """Retrieve the coordinates of the section avoiding duplicates""" sec.push() x, y, z, d = [],[],[],[] tot_points = 0 connect_next = False for i in range(int(h.n3d())): present = False x_i = h.x3d(i) y_i = h.y3d(i) z_i = h.z3d(i) d_i = h.diam3d(i) # Avoiding duplicates in the sec if x_i in x: ind = len(x) - 1 - x[::-1].index(x_i) # Getting the index of last value if y_i == y[ind]: if z_i == z[ind]: present = True if not present: k =(x_i, y_i, z_i) x.append(x_i) y.append(y_i) z.append(z_i) d.append(d_i) h.pop_section() #adding num 3d points per section self.n3dpoints_per_sec[sec.name()] = len(d) return (np.array(x),np.array(y),np.array(z),np.array(d))
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 accumulate_density(sec, density, domain): sec.push() for i in range(int(h.n3d())): x,y = (h.x3d(i), h.y3d(i)) r = (round(x, domain[0]),round(y, domain[1])) if not False in r: density[r] += 1 h.pop_section()
def retrieve_coordinates(self, sec): xyzds = [] for ii in xrange(int(h.n3d(sec=sec))): xyzds.append([h.x3d(ii,sec=sec), h.y3d(ii,sec=sec), h.z3d(ii,sec=sec), h.diam3d(ii,sec=sec)]) return xyzds
def append_v(sec, v): """ Append data to v """ sec.push() for ii in xrange(1, int(nrn.n3d())): v.append(sec.v) nrn.pop_section() return v
def get_coordinates(sec): ptn = h.n3d(sec=sec) xc = [] yc = [] for i in range(int(ptn)): xc.append(h.x3d(i, sec=sec)) yc.append(h.y3d(i, sec=sec)) return np.array([xc, yc])
def modify_morphology(apic_trunk, basal, apic_tuft): for sec in basal: for i in xrange(int(nrn.n3d())): nrn.pt3dchange(i, 0.76) nrn.distance() apic_tuft_root_diam = None apic_tuft_root_dist = None for sec in apic_trunk: npts = int(nrn.n3d()) cummulative_L = 0 for i in xrange(npts - 1): delta_x = (nrn.x3d(i + 1) - nrn.x3d(i))**2 delta_y = (nrn.y3d(i + 1) - nrn.y3d(i))**2 delta_z = (nrn.z3d(i + 1) - nrn.z3d(i))**2 cummulative_L += np.sqrt(delta_x + delta_y + delta_z) diam = 3.5 - 4.7e-3 * cummulative_L nrn.pt3dchange(i, diam, sec=sec) apic_tuft_root_diam = nrn.diam3d(npts - 1) apic_tuft_root_dist = cummulative_L # THE FOLLOWING RETURNS NEGATIVE PARAMETERS! # for sec in nrn.somatic: # if sec.name() == 'soma[2]': # nrn.distance(0, 1) # for sec in apic_tuft: # # npts = int(nrn.n3d()) # cummulative_L = 0 # start_dist_from_soma = nrn.distance(0) # start_dist_from_tuft_root = start_dist_from_soma - apic_tuft_root_dist # for i in xrange(npts - 1): # delta_x = (nrn.x3d(i + 1) - nrn.x3d(i))**2 # delta_y = (nrn.y3d(i + 1) - nrn.y3d(i))**2 # delta_z = (nrn.z3d(i + 1) - nrn.z3d(i))**2 # cummulative_L += np.sqrt(delta_x + delta_y + delta_z) # dist_from_root = start_dist_from_tuft_root + cummulative_L # diam = apic_tuft_root_diam - 18e-3 * dist_from_root # print diam, nrn.diam3d(i) # # nrn.pt3dchange(i, diam, sec=sec) return apic_tuft_root_diam
def _indices_from_sec_x(self, sec, position): # TODO: the assert is here because the diameter is not computed correctly # unless it coincides with a 3d point, which we only know to exist at the # endpoints and because the section does not proceed linearly between # the endpoints (in general)... which affects the computation of the # normal vector as well assert(position in (0, 1)) # NOTE: some care is necessary in constructing normal vector... must be # based on end frusta, not on vector between end points if position == 0: x = h.x3d(0, sec=sec) y = h.y3d(0, sec=sec) z = h.z3d(0, sec=sec) nx = h.x3d(1, sec=sec) - x ny = h.y3d(1, sec=sec) - y nz = h.z3d(1, sec=sec) - z elif position == 1: n = int(h.n3d(sec=sec)) x = h.x3d(n - 1, sec=sec) y = h.y3d(n - 1, sec=sec) z = h.z3d(n - 1, sec=sec) # NOTE: sign of the normal is irrelevant nx = x - h.x3d(n - 2, sec=sec) ny = y - h.y3d(n - 2, sec=sec) nz = z - h.z3d(n - 2, sec=sec) else: raise RxDException('should never get here') # x, y, z = x * x1 + (1 - x) * x0, x * y1 + (1 - x) * y0, x * z1 + (1 - x) * z1 r = sec(position).diam * 0.5 plane_of_disc = geometry3d.graphicsPrimitives.Plane(x, y, z, nx, ny, nz) potential_coordinates = [] mesh = self._mesh xs, ys, zs = mesh._xs, mesh._ys, mesh._zs xlo, ylo, zlo = xs[0], ys[0], zs[0] # locate the indices of the cube containing the sphere containing the disc # TODO: write this more efficiently i_indices = [i for i, a in enumerate(xs) if abs(a - x) < r] j_indices = [i for i, a in enumerate(ys) if abs(a - y) < r] k_indices = [i for i, a in enumerate(zs) if abs(a - z) < r] sphere_indices = [(i, j, k) for i, j, k in itertools.product(i_indices, j_indices, k_indices) if (xs[i] - x) ** 2 + (ys[j] - y) ** 2 + (zs[k] - z) ** 2 < r ** 2] dx2 = self.dx * 0.5 dx = self.dx disc_indices = [] for i, j, k in sphere_indices: # a, b, c = xs[i], ys[j], zs[k] # TODO: no need to compute all; can stop when some True and some False # on_side1 = [plane_of_disc.distance(x, y, z) >= 0 for x, y, z in itertools.product([a - dx2, a + dx2], [b - dx2, b + dx2], [c - dx2, c + dx2])] # NOTE: the expression is structured this way to make sure it tests the exact same corner coordinates for corners shared by multiple voxels and that there are no round-off issues (an earlier attempt had round-off issues that resulted in double-thick discs when the frustum ended exactly on a grid plane) on_side1 = [plane_of_disc.distance(x, y, z) >= 0 for x, y, z in itertools.product([(xlo + (i - 1) * dx) + dx2, (xlo + i * dx) + dx2], [(ylo + (j - 1) * dx) + dx2, (ylo + j * dx) + dx2], [(zlo + (k - 1) * dx) + dx2, (zlo + k * dx) + dx2])] # need both sides to have at least one corner if any(on_side1) and not all(on_side1): # if we're here, then we've found a point on the disc. disc_indices.append((i, j, k)) return disc_indices
def retrieve_coordinates(self, sec): xyzds = [] sec.push() for ii in xrange(int(nrn.n3d())): xyzds.append([nrn.x3d(ii), nrn.y3d(ii), nrn.z3d(ii), nrn.diam3d(ii)]) nrn.pop_section() return xyzds
def set_position(self, x, y, z): """ Set the base location in 3D and move all other parts of the cell relative to that location. """ for sec in self.all: for i in range(int(h.n3d())): h.pt3dchange(i, x - self.x + h.x3d(i), y - self.y + h.y3d(i), z - self.z + h.z3d(i), h.diam3d(i)) self.x, self.y, self.z = x, y, z
def computeCenter(seg): """Compute the distance from soma Assuming soma is at (0,0,0) """ # n3d returns the number of 3d points in a segment. xpoints = ypoints = zpoints = np.zeros(h.n3d(seg)) for i in range(len(xpoints)): xpoints[i] = h.x3d(i, seg) ypoints[i] = h.y3d(i, seg) zpoints[i] = h.z3d(i, seg) center = np.array([xpoints.mean(), ypoints.mean(), zpoints.mean()]) r = np.sqrt(np.mean(center)) return r, center
def find_middle_coordinates(self) : cell_list = [] self.m_coordinates = [] for n in range(self.num_neurons) : cell = [] print "Neuron ", n for i in range(self.NSize[n]): exec "cell.append(h.neuron"+str(n)+"_tree["+str(i)+"])"; cell[i].push() middle = int(h.n3d()/2)# It has to be integer!! self.m_coordinates.append((h.x3d(middle),h.y3d(middle),h.z3d(middle))) #print "Yo(", i, ") Middle is ", middle, Coordinates[i] h.pop_section() cell_list.append(cell) self.m_coordinates
def set_position(self, x, y, z): """ Set the base location in 3D and move all other parts of the cell relative to that location. """ for sec in self.all: # note: iterating like this changes the context for all NEURON # functions that depend on a section, so no need to specify sec= for i in range(int(h.n3d())): h.pt3dchange(i, x - self.x + h.x3d(i), y - self.y + h.y3d(i), z - self.z + h.z3d(i), h.diam3d(i)) self.x, self.y, self.z = 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 set_position(self, x, y, z): """ Set the base location in 3D and move all other parts of the cell relative to that location. """ for sec in self.all: sec.push() #print('secname = %s, h.n3d = %d' % (h.secname(), h.n3d())) for i in range(int(h.n3d())): h.pt3dchange(i, x - self.x + h.x3d(i), y - self.y + h.y3d(i), z - self.z + h.z3d(i), h.diam3d(i), sec=sec) h.pop_section() #h.define_shape() self.x, self.y, self.z = x, y, z
def tet_associate(sm): # INPUT: Tetmesh object # This function associates .hoc sections to the tets which contain them, and returns the association dictionary. # It's packaged separately from the coarse() function so it can be used independently in scripts which load a Tetmesh from file # and don't need any Tetmesh to be generated from a .hoc file. tet_hoc = {} for s in h.allsec(): for j in range(int(h.n3d())): containing_tet = sm.findTetByPoint((h.x3d(j),h.y3d(j),h.z3d(j))) if (containing_tet) not in tet_hoc.keys(): tet_hoc[containing_tet] = [s] elif (containing_tet) in tet_hoc.keys(): if (s) not in tet_hoc[containing_tet]: tet_hoc[containing_tet].append(s) return tet_hoc
def retrieve_coordinate(sec): sec.push() x, y, z = [], [], [] connect_next = False for i in range(int(h.n3d())): present = False x_i = h.x3d(i) y_i = h.y3d(i) z_i = h.z3d(i) if x_i in x: ind = len(x) - 1 - x[::-1].index(x_i) if y_i == y[ind]: if z_i == z[ind]: present = True if not present: x.append(x_i) y.append(y_i) z.append(z_i) h.pop_section() return (np.array(x),np.array(y),np.array(z))