def check_cloned_neuron(nrn1, nrn2): # check if two neurons are identical # soma nt.ok_(isinstance(nrn2.soma, type(nrn1.soma))) nt.eq_(nrn1.soma.radius, nrn2.soma.radius) for v1, v2 in zip(nrn1.soma.iter(), nrn2.soma.iter()): nt.ok_(np.allclose(v1, v2)) # neurites for v1, v2 in zip(iter_segments(nrn1), iter_segments(nrn2)): (v1_start, v1_end), (v2_start, v2_end) = v1, v2 nt.ok_(np.allclose(v1_start, v2_start)) nt.ok_(np.allclose(v1_end, v2_end)) # check if the ids are different # somata nt.ok_(nrn1.soma is not nrn2.soma) # neurites for neu1, neu2 in zip(nrn1.neurites, nrn2.neurites): nt.ok_(neu1 is not neu2) # check if changes are propagated between neurons nrn2.soma.radius = 10. nt.ok_(nrn1.soma.radius != nrn2.soma.radius) nrn2._data.data_block[0, :] = np.zeros_like(nrn2._data.data_block[0, :]) nt.ok_(not np.allclose(nrn1._data.data_block[0, :], nrn2._data.data_block[ 0, :]))
def check_cloned_neuron(nrn1, nrn2): # check if two neurons are identical # soma nt.ok_(isinstance(nrn2.soma, type(nrn1.soma))) nt.eq_(nrn1.soma.radius, nrn2.soma.radius) for v1, v2 in zip(nrn1.soma.iter(), nrn2.soma.iter()): nt.ok_(np.allclose(v1, v2)) # neurites for v1, v2 in zip(iter_segments(nrn1), iter_segments(nrn2)): (v1_start, v1_end), (v2_start, v2_end) = v1, v2 nt.ok_(np.allclose(v1_start, v2_start)) nt.ok_(np.allclose(v1_end, v2_end)) # check if the ids are different # somata nt.ok_(nrn1.soma is not nrn2.soma) # neurites for neu1, neu2 in zip(nrn1.neurites, nrn2.neurites): nt.ok_(neu1 is not neu2) # check if changes are propagated between neurons nrn2.soma.radius = 10. nt.ok_(nrn1.soma.radius != nrn2.soma.radius) nrn2._data.data_block[0, :] = np.zeros_like(nrn2._data.data_block[0, :]) nt.ok_(not np.allclose(nrn1._data.data_block[0, :], nrn2._data.data_block[0, :]))
def test_iter_segments_nrn(): ref = list(core.iter_segments(NRN1)) nt.eq_(len(ref), 840) ref = list(core.iter_segments(NRN1, neurite_filter=lambda n: n.type == nm.AXON)) nt.eq_(len(ref), 210) ref = list(core.iter_segments(NRN1, neurite_filter=lambda n: n.type == nm.BASAL_DENDRITE)) nt.eq_(len(ref), 420) ref = list(core.iter_segments(NRN1, neurite_filter=lambda n: n.type == nm.APICAL_DENDRITE)) nt.eq_(len(ref), 210)
def test_iter_segments_pop(): ref = list(core.iter_segments(POP)) nt.eq_(len(ref), 3387) ref = list(core.iter_segments(POP, neurite_filter=lambda n: n.type == nm.AXON)) nt.eq_(len(ref), 919) ref = list(core.iter_segments(POP, neurite_filter=lambda n: n.type == nm.BASAL_DENDRITE)) nt.eq_(len(ref), 1549) ref = list(core.iter_segments(POP, neurite_filter=lambda n: n.type == nm.APICAL_DENDRITE)) nt.eq_(len(ref), 919)
def plot_tree3d(ax, tree, diameter_scale=_DIAMETER_SCALE, linewidth=_LINEWIDTH, color=None, alpha=_ALPHA): '''Generates a figure of the tree in 3d. If the tree contains one single point the plot will be empty \ since no segments can be constructed. Args: ax(matplotlib axes): on what to plot tree(neurom.core.Tree or neurom.core.Neurite): plotted tree diameter_scale(float): Scale factor multiplied with segment diameters before plotting linewidth(float): all segments are plotted with this width, but only if diameter_scale=None color(str or None): Color of plotted values, None corresponds to default choice alpha(float): Transparency of plotted values ''' segs = [(s[0][COLS.XYZ], s[1][COLS.XYZ]) for s in iter_segments(tree)] linewidth = _get_linewidth(tree, diameter_scale=diameter_scale, linewidth=linewidth) color = _get_color(color, tree.type) collection = Line3DCollection(segs, color=color, linewidth=linewidth, alpha=alpha) ax.add_collection3d(collection) _update_3d_datalim(ax, tree)
def plot_tree(ax, tree, plane='xy', diameter_scale=_DIAMETER_SCALE, linewidth=_LINEWIDTH, color=None, alpha=_ALPHA): '''Plots a 2d figure of the tree's segments Args: ax(matplotlib axes): on what to plot tree(neurom.core.Tree or neurom.core.Neurite): plotted tree plane(str): Any pair of 'xyz' diameter_scale(float): Scale factor multiplied with segment diameters before plotting linewidth(float): all segments are plotted with this width, but only if diameter_scale=None color(str or None): Color of plotted values, None corresponds to default choice alpha(float): Transparency of plotted values Note: If the tree contains one single point the plot will be empty since no segments can be constructed. ''' plane0, plane1 = _plane2col(plane) segs = [((s[0][plane0], s[0][plane1]), (s[1][plane0], s[1][plane1])) for s in iter_segments(tree)] linewidth = _get_linewidth(tree, diameter_scale=diameter_scale, linewidth=linewidth) color = _get_color(color, tree.type) collection = LineCollection(segs, color=color, linewidth=linewidth, alpha=alpha) ax.add_collection(collection)
def plot_tree3d(ax, tree, diameter_scale=_DIAMETER_SCALE, linewidth=_LINEWIDTH, color=None, alpha=_ALPHA): '''Generates a figure of the tree in 3d. If the tree contains one single point the plot will be empty \ since no segments can be constructed. Args: ax(matplotlib axes): on what to plot tree(neurom.core.Tree or neurom.core.Neurite): plotted tree diameter_scale(float): Scale factor multiplied with segment diameters before plotting linewidth(float): all segments are plotted with this width, but only if diameter_scale=None color(str or None): Color of plotted values, None corresponds to default choice alpha(float): Transparency of plotted values ''' segs = [(s[0][COLS.XYZ], s[1][COLS.XYZ]) for s in iter_segments(tree)] linewidth = _get_linewidth(tree, diameter_scale=diameter_scale, linewidth=linewidth) color = _get_color(color, tree.type), collection = Line3DCollection(segs, color=color, linewidth=linewidth, alpha=alpha) ax.add_collection3d(collection) _update_3d_datalim(ax, tree)
def has_no_jumps(neuron, max_distance=30.0, axis='z'): '''Check if there are jumps (large movements in the `axis`) Arguments: neuron(Neuron): The neuron object to test max_distance(float): value above which consecutive z-values are considered a jump axis(str): one of x/y/z, which axis to check for jumps Returns: CheckResult with result list of ids of bad sections ''' bad_ids = [] axis = { 'x': COLS.X, 'y': COLS.Y, 'z': COLS.Z, }[axis.lower()] for neurite in iter_neurites(neuron): section_segment = ((sec, seg) for sec in iter_sections(neurite) for seg in iter_segments(sec)) for sec, (p0, p1) in islice(section_segment, 1, None): # Skip neurite root segment if max_distance < abs(p0[axis] - p1[axis]): bad_ids.append((sec.id, [p0, p1])) return CheckResult(len(bad_ids) == 0, bad_ids)
def plot_tree(ax, tree, plane='xy', diameter_scale=_DIAMETER_SCALE, linewidth=_LINEWIDTH, color=None, alpha=_ALPHA, realistic_diameters=False): """Plots a 2d figure of the tree's segments. Args: ax(matplotlib axes): on what to plot tree(neurom.core.Tree or neurom.core.Neurite): plotted tree plane(str): Any pair of 'xyz' diameter_scale(float): Scale factor multiplied with segment diameters before plotting linewidth(float): all segments are plotted with this width, but only if diameter_scale=None color(str or None): Color of plotted values, None corresponds to default choice alpha(float): Transparency of plotted values realistic_diameters(bool): scale linewidths with axis data coordinates Note: If the tree contains one single point the plot will be empty since no segments can be constructed. """ plane0, plane1 = _plane2col(plane) section_segment_list = [(section, segment) for section in iter_sections(tree) for segment in iter_segments(section)] colors = [_get_color(color, section.type) for section, _ in section_segment_list] if realistic_diameters: def _get_rectangle(x, y, linewidth): """Draw a rectangle to represent a secgment.""" x, y = np.array(x), np.array(y) diff = y - x angle = np.arctan2(diff[1], diff[0]) % (2 * np.pi) return Rectangle(x - linewidth / 2. * np.array([-np.sin(angle), np.cos(angle)]), np.linalg.norm(diff), linewidth, np.rad2deg(angle)) segs = [_get_rectangle((seg[0][plane0], seg[0][plane1]), (seg[1][plane0], seg[1][plane1]), 2 * segment_radius(seg) * diameter_scale) for _, seg in section_segment_list] collection = PatchCollection(segs, alpha=alpha, facecolors=colors) else: segs = [((seg[0][plane0], seg[0][plane1]), (seg[1][plane0], seg[1][plane1])) for _, seg in section_segment_list] linewidth = _get_linewidth( tree, diameter_scale=diameter_scale, linewidth=linewidth, ) collection = LineCollection(segs, colors=colors, linewidth=linewidth, alpha=alpha) ax.add_collection(collection)
def test_iter_segments_section(): sec = core.Section([[1, 2, 3, 4], [5, 6, 7, 8], [8, 7, 6, 5], [4, 3, 2, 1], ]) ref = list(core.iter_segments(sec)) nt.eq_(ref, [([1, 2, 3, 4], [5, 6, 7, 8]), ([5, 6, 7, 8], [8, 7, 6, 5]), ([8, 7, 6, 5], [4, 3, 2, 1])])
def test_iter_segments_section(): sec = core.Section([ [1, 2, 3, 4], [5, 6, 7, 8], [8, 7, 6, 5], [4, 3, 2, 1], ]) ref = list(core.iter_segments(sec)) nt.eq_(ref, [([1, 2, 3, 4], [5, 6, 7, 8]), ([5, 6, 7, 8], [8, 7, 6, 5]), ([8, 7, 6, 5], [4, 3, 2, 1])])
def _get_linewidth(tree, linewidth, diameter_scale): '''calculate the desired linewidth based on tree contents If diameter_scale exists, it is used to scale the diameter of each of the segments in the tree If diameter_scale is None, the linewidth is used. ''' if diameter_scale is not None and tree: linewidth = [2 * segment_radius(s) * diameter_scale for s in iter_segments(tree)] return linewidth
def test_iter_segments_section(): sec = load_neuron(StringIO(u''' ((CellBody) (0 0 0 2)) ((Dendrite) (1 2 3 8) (5 6 7 16) (8 7 6 10) (4 3 2 2)) '''), reader='asc').sections[1] ref = [[p1[COLS.XYZR].tolist(), p2[COLS.XYZR].tolist()] for p1, p2 in core.iter_segments(sec)] assert_array_equal(ref, [[[1, 2, 3, 4], [5, 6, 7, 8]], [[5, 6, 7, 8], [8, 7, 6, 5]], [[8, 7, 6, 5], [4, 3, 2, 1]]])
def has_no_jumps(neuron, max_distance=30.0, axis='z'): '''Check if there are jumps (large movements in the `axis`) Arguments: neuron(Neuron): The neuron object to test max_z_distance(float): value above which consecutive z-values are considered a jump axis(str): one of x/y/z, which axis to check for jumps Returns: CheckResult with result list of ids bad sections ''' bad_ids = [] axis = {'x': COLS.X, 'y': COLS.Y, 'z': COLS.Z, }[axis.lower()] for sec in _nf.iter_sections(neuron): for i, (p0, p1) in enumerate(iter_segments(sec)): info = (sec.id, i) if max_distance < abs(p0[axis] - p1[axis]): bad_ids.append(info) return CheckResult(len(bad_ids) == 0, bad_ids)
def has_no_jumps(neuron, max_distance=30.0, axis='z'): '''Check if there are jumps (large movements in the `axis`) Arguments: neuron(Neuron): The neuron object to test max_distance(float): value above which consecutive z-values are considered a jump axis(str): one of x/y/z, which axis to check for jumps Returns: CheckResult with result list of ids of bad sections ''' bad_ids = [] axis = {'x': COLS.X, 'y': COLS.Y, 'z': COLS.Z, }[axis.lower()] for neurite in iter_neurites(neuron): section_segment = ((sec, seg) for sec in iter_sections(neurite) for seg in iter_segments(sec)) for sec, (p0, p1) in islice(section_segment, 1, None): # Skip neurite root segment if max_distance < abs(p0[axis] - p1[axis]): bad_ids.append((sec.id, [p0, p1])) return CheckResult(len(bad_ids) == 0, bad_ids)
def has_no_jumps(neuron, max_distance=30.0, axis='z'): '''Check if there are jumps (large movements in the `axis`) Arguments: neuron(Neuron): The neuron object to test max_z_distance(float): value above which consecutive z-values are considered a jump axis(str): one of x/y/z, which axis to check for jumps Returns: CheckResult with result list of ids bad sections ''' bad_ids = [] axis = { 'x': COLS.X, 'y': COLS.Y, 'z': COLS.Z, }[axis.lower()] for sec in _nf.iter_sections(neuron): for i, (p0, p1) in enumerate(iter_segments(sec)): info = (sec.id, i) if max_distance < abs(p0[axis] - p1[axis]): bad_ids.append(info) return CheckResult(len(bad_ids) == 0, bad_ids)
def segment_areas(neurites, neurite_type=NeuriteType.all): """Areas of the segments in a collection of neurites.""" return [ morphmath.segment_area(seg) for seg in iter_segments(neurites, is_type(neurite_type)) ]