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 plot_soma3d(ax, soma, color=None, alpha=_ALPHA): '''Generates a 3d figure of the soma. Args: ax(matplotlib axes): on what to plot soma(neurom.core.Soma): plotted soma color(str or None): Color of plotted values, None corresponds to default choice alpha(float): Transparency of plotted values ''' color = _get_color(color, tree_type=NeuriteType.soma) if isinstance(soma, SomaCylinders): for start, end in zip(soma.points, soma.points[1:]): common.plot_cylinder(ax, start=start[COLS.XYZ], end=end[COLS.XYZ], start_radius=start[COLS.R], end_radius=end[COLS.R], color=color, alpha=alpha) else: common.plot_sphere(ax, center=soma.center[COLS.XYZ], radius=soma.radius, color=color, alpha=alpha) # unlike w/ 2d Axes, the dataLim isn't set by collections, so it has to be updated manually _update_3d_datalim(ax, soma)
def _render_dendrogram(dnd, ax, displacement): '''Renders dendrogram''' # set of unique colors that reflect the set of types of the neurites colors = set() for n, (indices, ctype) in enumerate(zip(dnd.groups, dnd.types)): # slice rectangles array for the current neurite group = dnd.data[indices[0]:indices[1]] if n > 0: # displace the neurites by half of their maximum x dimension # plus half of the previous neurite's maxmimum x dimension displacement += 0.5 * (dnd.dims[n - 1][0] + dnd.dims[n][0]) # arrange the trees without overlapping with each other group += (displacement, 0.) # create the polygonal collection of the dendrogram # segments _generate_collection(group, ax, ctype, colors) soma_square = dnd.soma if soma_square is not None: _generate_collection((soma_square + (displacement / 2., 0.), ), ax, NeuriteType.soma, colors) ax.plot((displacement / 2., displacement), (0., 0.), color='k') ax.plot((0., displacement / 2.), (0., 0.), color='k') return displacement
def _render_dendrogram(dnd, ax, displacement): '''Renders dendrogram''' # set of unique colors that reflect the set of types of the neurites colors = set() for n, (indices, ctype) in enumerate(zip(dnd.groups, dnd.types)): # slice rectangles array for the current neurite group = dnd.data[indices[0]:indices[1]] if n > 0: # displace the neurites by half of their maximum x dimension # plus half of the previous neurite's maxmimum x dimension displacement += 0.5 * (dnd.dims[n - 1][0] + dnd.dims[n][0]) # arrange the trees without overlapping with each other group += (displacement, 0.) # create the polygonal collection of the dendrogram # segments _generate_collection(group, ax, ctype, colors) soma_square = dnd.soma if soma_square is not None: _generate_collection((soma_square + (displacement / 2., 0.),), ax, NeuriteType.soma, colors) ax.plot((displacement / 2., displacement), (0., 0.), color='k') ax.plot((0., displacement / 2.), (0., 0.), color='k') return displacement
def plot_soma(ax, soma, plane='xy', soma_outline=True, linewidth=_LINEWIDTH, color=None, alpha=_ALPHA): '''Generates a 2d figure of the soma. Args: ax(matplotlib axes): on what to plot soma(neurom.core.Soma): plotted soma 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 ''' plane0, plane1 = _plane2col(plane) color = _get_color(color, tree_type=NeuriteType.soma) if isinstance(soma, SomaCylinders): plane0, plane1 = _plane2col(plane) for start, end in zip(soma.points, soma.points[1:]): common.project_cylinder_onto_2d(ax, (plane0, plane1), start=start[COLS.XYZ], end=end[COLS.XYZ], start_radius=start[COLS.R], end_radius=end[COLS.R], color=color, alpha=alpha) else: if soma_outline: ax.add_artist( Circle(soma.center[[plane0, plane1]], soma.radius, color=color, alpha=alpha)) else: plane0, plane1 = _plane2col(plane) points = [(p[plane0], p[plane1]) for p in soma.iter()] if points: points.append(points[0]) # close the loop ax.plot(points, color=color, alpha=alpha, linewidth=linewidth) ax.set_xlabel(plane[0]) ax.set_ylabel(plane[1]) bounding_box = geom.bounding_box(soma) ax.dataLim.update_from_data_xy(np.vstack( ([bounding_box[0][plane0], bounding_box[0][plane1]], [bounding_box[1][plane0], bounding_box[1][plane1]])), ignore=False)
def iter_segments(obj, neurite_filter=None): '''Return an iterator to the segments in a collection of neurites Parameters: obj: neuron, population, neurite, section, or iterable containing neurite objects neurite_filter: optional top level filter on properties of neurite neurite objects Note: This is a convenience function provideded for generic access to neuron segments. It may have a performance overhead WRT custom-made segment analysis functions that leverage numpy and section-wise iteration. ''' sections = iter((obj,) if isinstance(obj, Section) else iter_sections(obj, neurite_filter=neurite_filter)) return chain.from_iterable(zip(sec.points[:-1], sec.points[1:]) for sec in sections)
def iter_segments(obj, neurite_filter=None): '''Return an iterator to the segments in a collection of neurites Parameters: obj: neuron, population, neurite, section, or iterable containing neurite objects neurite_filter: optional top level filter on properties of neurite neurite objects Note: This is a convenience function provideded for generic access to neuron segments. It may have a performance overhead WRT custom-made segment analysis functions that leverage numpy and section-wise iteration. ''' sections = iter((obj, ) if isinstance(obj, Section) else iter_sections( obj, neurite_filter=neurite_filter)) return chain.from_iterable( zip(sec.points[:-1], sec.points[1:]) for sec in sections)
def plot_soma(ax, soma, plane='xy', soma_outline=True, linewidth=_LINEWIDTH, color=None, alpha=_ALPHA): '''Generates a 2d figure of the soma. Args: ax(matplotlib axes): on what to plot soma(neurom.core.Soma): plotted soma 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 ''' plane0, plane1 = _plane2col(plane) color = _get_color(color, tree_type=NeuriteType.soma) if isinstance(soma, SomaCylinders): plane0, plane1 = _plane2col(plane) for start, end in zip(soma.points, soma.points[1:]): common.project_cylinder_onto_2d(ax, (plane0, plane1), start=start[COLS.XYZ], end=end[COLS.XYZ], start_radius=start[COLS.R], end_radius=end[COLS.R], color=color, alpha=alpha) else: if soma_outline: ax.add_artist(Circle(soma.center[[plane0, plane1]], soma.radius, color=color, alpha=alpha)) else: plane0, plane1 = _plane2col(plane) points = [(p[plane0], p[plane1]) for p in soma.iter()] if points: points.append(points[0]) # close the loop ax.plot(points, color=color, alpha=alpha, linewidth=linewidth) ax.set_xlabel(plane[0]) ax.set_ylabel(plane[1]) bounding_box = geom.bounding_box(soma) ax.dataLim.update_from_data_xy(np.vstack(([bounding_box[0][plane0], bounding_box[0][plane1]], [bounding_box[1][plane0], bounding_box[1][plane1]])), ignore=False)
def has_all_nonzero_segment_lengths(neuron, threshold=0.0): '''Check presence of neuron segments with length not above threshold Arguments: neuron(Neuron): The neuron object to test threshold(float): value above which a segment length is considered to be non-zero Returns: CheckResult with result including list of (section_id, segment_id) of zero length segments ''' bad_ids = [] for sec in _nf.iter_sections(neuron): p = sec.points for i, s in enumerate(zip(p[:-1], p[1:])): if segment_length(s) <= threshold: bad_ids.append((sec.id, i)) return CheckResult(len(bad_ids) == 0, bad_ids)
def iter_segments(obj, neurite_filter=None, neurite_order=NeuriteIter.FileOrder): '''Return an iterator to the segments in a collection of neurites Parameters: obj: neuron, population, neurite, section, or iterable containing neurite objects neurite_filter: optional top level filter on properties of neurite neurite objects neurite_order: order upon which neurite should be iterated. Values: - NeuriteIter.FileOrder: order of appearance in the file - NeuriteIter.NRN: NRN simulator order: soma -> axon -> basal -> apical Note: This is a convenience function provided for generic access to neuron segments. It may have a performance overhead WRT custom-made segment analysis functions that leverage numpy and section-wise iteration. ''' sections = iter((obj,) if isinstance(obj, Section) else iter_sections(obj, neurite_filter=neurite_filter, neurite_order=neurite_order)) return chain.from_iterable(zip(sec.points[:-1], sec.points[1:]) for sec in sections)
def iter_segments(obj, neurite_filter=None, neurite_order=NeuriteIter.FileOrder): """Return an iterator to the segments in a collection of neurites. Arguments: obj: neuron, population, neurite, section, or iterable containing neurite objects neurite_filter: optional top level filter on properties of neurite neurite objects neurite_order: order upon which neurite should be iterated. Values: - NeuriteIter.FileOrder: order of appearance in the file - NeuriteIter.NRN: NRN simulator order: soma -> axon -> basal -> apical Note: This is a convenience function provided for generic access to neuron segments. It may have a performance overhead WRT custom-made segment analysis functions that leverage numpy and section-wise iteration. """ sections = iter((obj,) if isinstance(obj, Section) else iter_sections(obj, neurite_filter=neurite_filter, neurite_order=neurite_order)) return chain.from_iterable(zip(sec.points[:-1], sec.points[1:]) for sec in sections)
def _check_fst_neurite_rotate(nrt_a, nrt_b, rot_mat): for sa, sb in zip(_nf.iter_sections(nrt_a), _nf.iter_sections(nrt_b)): nt.assert_true(np.allclose(sb.points[:, 0:3], _apply_rot(sa.points[:, 0:3], rot_mat)))
def _check_fst_neurite_translate(nrts_a, nrts_b, t): # neurite sections for sa, sb in zip(_nf.iter_sections(nrts_a), _nf.iter_sections(nrts_b)): nt.assert_true(np.allclose((sb.points[:, 0:3] - sa.points[:, 0:3]), t))
def map_segments(fun, section): '''Map a function to segments in a section''' pts = section.points return list(fun(s) for s in zip(pts[:-1], pts[1:]))