def test_section_tortuosity(): sec_a = load_neuron(StringIO(u""" ((CellBody) (0 0 0 2)) ((Dendrite) (0 0 0 2) (1 0 0 2) (2 0 0 2) (3 0 0 2))"""), reader='asc').sections[1] sec_b = load_neuron(StringIO(u""" ((CellBody) (0 0 0 2)) ((Dendrite) (0 0 0 2) (1 0 0 2) (1 2 0 2) (0 2 0 2))"""), reader='asc').sections[1] nt.eq_(_sf.section_tortuosity(sec_a), 1.0) nt.eq_(_sf.section_tortuosity(sec_b), 4.0 / 2.0) for s in _nf.iter_sections(NRN): nt.eq_( _sf.section_tortuosity(s), mmth.section_length(s.points) / mmth.point_dist(s.points[0], s.points[-1]))
def __init__(self, points): super(SomaNeuromorphoThreePointCylinders, self).__init__(points) # X Y Z R P # xs ys zs rs -1 # xs (ys-rs) zs rs 1 # xs (ys+rs) zs rs 1 r = points[0, COLS.R] # make sure the above invariant holds assert (np.isclose(r, points[1, COLS.R]) and np.isclose(r, points[2, COLS.R])), \ 'All radii must be the same' # only warn users about invalid format if r < 1e-5: warnings.warn('Zero radius for {}'.format(self)) if not np.isclose(points[0, COLS.Y] - points[1, COLS.Y], r): warnings.warn( 'The second point must be one radius below 0 on the y-plane for {}' .format(self)) if not np.isclose(points[0, COLS.Y] - points[2, COLS.Y], -r): warnings.warn( 'The third point must be one radius above 0 on the y-plane for {}' .format(self)) h = morphmath.point_dist(points[1, COLS.XYZ], points[2, COLS.XYZ]) self.area = 2.0 * math.pi * r * h # ignores the 'end-caps' of the cylinder self.radius = math.sqrt(self.area / (4. * math.pi))
def test_section_tortuosity(): sec_a = load_neuron(StringIO(u""" ((CellBody) (0 0 0 2)) ((Dendrite) (0 0 0 2) (1 0 0 2) (2 0 0 2) (3 0 0 2))"""), reader='asc').sections[SECTION_ID] sec_b = load_neuron(StringIO(u""" ((CellBody) (0 0 0 2)) ((Dendrite) (0 0 0 2) (1 0 0 2) (1 2 0 2) (0 2 0 2))"""), reader='asc').sections[SECTION_ID] assert _sf.section_tortuosity(sec_a) == 1.0 assert _sf.section_tortuosity(sec_b) == 4.0 / 2.0 for s in _nf.iter_sections(NRN): assert (_sf.section_tortuosity(s) == mmth.section_length(s.points) / mmth.point_dist(s.points[0], s.points[-1]))
def section_end_distance(section): '''End to end distance of a section The end to end distance of a section is defined as the euclidian distnce between its end points. If the section contains less than 2 points, the value 0 is returned. ''' pts = section.points return 0 if len(pts) < 2 else mm.point_dist(pts[-1], pts[0])
def test_section_tortuosity(): sec_a = Section([(0, 0, 0), (1, 0, 0), (2, 0, 0), (3, 0, 0)]) sec_b = Section([(0, 0, 0), (1, 0, 0), (1, 2, 0), (0, 2, 0)]) nt.eq_(_sf.section_tortuosity(sec_a), 1.0) nt.eq_(_sf.section_tortuosity(sec_b), 4.0 / 2.0) for s in _nf.iter_sections(NRN): nt.eq_(_sf.section_tortuosity(s), mmth.section_length(s.points) / mmth.point_dist(s.points[0], s.points[-1]))
def section_radial_distance(section, origin): '''Return the radial distances of a tree section to a given origin point The radial distance is the euclidian distance between the end-point point of the section and the origin point in question. Parameters: section: neurite section object origin: point to which distances are measured. It must have at least 3\ components. The first 3 components are (x, y, z). ''' return mm.point_dist(section.points[-1], origin)
def section_tortuosity(section): '''Tortuosity of a section The tortuosity is defined as the ratio of the path length of a section and the euclidian distnce between its end points. The path length is the sum of distances between consecutive points. If the section contains less than 2 points, the value 1 is returned. ''' pts = section.points return 1 if len(pts) < 2 else mm.section_length(pts) / mm.point_dist(pts[-1], pts[0])
def test_section_tortuosity(): sec_a = Section([(0, 0, 0), (1, 0, 0), (2, 0, 0), (3, 0, 0)]) sec_b = Section([(0, 0, 0), (1, 0, 0), (1, 2, 0), (0, 2, 0)]) nt.eq_(_sf.section_tortuosity(sec_a), 1.0) nt.eq_(_sf.section_tortuosity(sec_b), 4.0 / 2.0) for s in _nf.iter_sections(NRN): nt.eq_( _sf.section_tortuosity(s), mmth.section_length(s.points) / mmth.point_dist(s.points[0], s.points[-1]))
def __init__(self, morphio_soma): """Initialize a SomaNeuromorphoThreePointCylinders object.""" super().__init__(morphio_soma) # X Y Z R P # xs ys zs rs -1 # xs (ys-rs) zs rs 1 # xs (ys+rs) zs rs 1 r = self.points[0, COLS.R] # make sure the above invariant holds assert (np.isclose(r, self.points[1, COLS.R]) and np.isclose(r, self.points[2, COLS.R])), \ 'All radii must be the same' if r < 1e-5: warnings.warn('Zero radius for {}'.format(self)) h = morphmath.point_dist(self.points[1, COLS.XYZ], self.points[2, COLS.XYZ]) self.area = 2.0 * math.pi * r * h # ignores the 'end-caps' of the cylinder self.radius = math.sqrt(self.area / (4. * math.pi))
def i_section_radial_dist(tree, pos=None, use_start_point=False): '''Return an iterator of radial distances of tree sections to a given point The radial distance is the euclidian distance between the either the end-point or rhe start point of the section and the point in question. Parameters: tree: tree object pos: origin to which distances are measured. It must have at least 3\ components. The first 3 components are (x, y, z).\ (default tree origin) use_start_point: If true, calculate distance from section start point,\ else from end-point (default, False) ''' pos = tree.value if pos is None else pos sec_idx = 0 if use_start_point else -1 return imap_val(lambda s: mm.point_dist(s[sec_idx], pos), ptr.isection(tree))
def _add_coords(synapse, morphology): """Adds coordinates and direction fields to ``synapses`` via ``apply`` function.""" is_pre = PRE_SECTION_ID in synapse.index and not pd.isnull( synapse[PRE_SECTION_ID]) is_post = POST_SECTION_ID in synapse.index and not pd.isnull( synapse[POST_SECTION_ID]) assert is_pre != is_post, 'Synapse must have either afferent or efferent section ids for the ' \ 'morphology. It cant have both at the same time.' if is_post: sec_id = int(synapse[POST_SECTION_ID]) seg_id = int(synapse[POST_SEGMENT_ID]) seg_ofst = float(synapse[POST_SEGMENT_OFFSET]) synapse['direction'] = 'afferent' else: sec_id = int(synapse[PRE_SECTION_ID]) seg_id = int(synapse[PRE_SEGMENT_ID]) seg_ofst = float(synapse[PRE_SEGMENT_OFFSET]) synapse['direction'] = 'efferent' if sec_id == 0: # synapse is on soma p = morphology.soma.points[0] synapse['x'], synapse['y'], synapse['z'] = p[COLS.XYZ] # place synapse on surface of soma along Z axes so it won't be hidden by soma on the plot synapse['z'] += p[COLS.R] return synapse # NeuroM morphology counts sections from 0. Synapses count sections from 1 because section # id 0 is for soma. sec_id -= 1 sec = morphology.sections[sec_id] assert sec_id == sec.id, f'Error. Synapse with section id {sec_id} must map to the same ' \ f'section id in `morphology` arg but maps to {sec.id}.' assert 0 <= seg_id <= len(sec.points), f'No such segment id {seg_id} for section id ' \ f'{sec_id} of `morphology` arg' seg_p1, seg_p2 = sec.points[seg_id - 1], sec.points[seg_id] seg_len = morphmath.point_dist(seg_p1, seg_p2) coords = morphmath.linear_interpolate(seg_p1, seg_p2, seg_ofst / seg_len) synapse['x'], synapse['y'], synapse['z'] = coords return synapse
def __init__(self, points): super(SomaNeuromorphoThreePointCylinders, self).__init__(points) # X Y Z R P # xs ys zs rs -1 # xs (ys-rs) zs rs 1 # xs (ys+rs) zs rs 1 # make sure the above invariant holds assert (np.isclose(points[0, COLS.R], points[1, COLS.R]) and np.isclose(points[0, COLS.R], points[2, COLS.R])), \ 'All radii must be the same' # These checks were turned off after https://github.com/BlueBrain/NeuroM/issues/614 # assert np.isclose(points[0, COLS.Y] - points[1, COLS.Y], points[0, COLS.R]), \ # 'The second point must be one radius below 0 on the y-plane' # assert np.isclose(points[0, COLS.Y] - points[2, COLS.Y], -points[0, COLS.R]), \ # 'The third point must be one radius above 0 on the y-plane' r = points[0, COLS.R] h = morphmath.point_dist(points[1, COLS.XYZ], points[2, COLS.XYZ]) self.area = 2.0 * math.pi * r * h # ignores the 'end-caps' of the cylinder self.radius = math.sqrt(self.area / (4. * math.pi))
def path_end_to_end_distance(neurite): """Calculate and return end-to-end-distance of a given neurite.""" trunk = neurite.root_node.points[0] return max( morphmath.point_dist(l.points[-1], trunk) for l in neurite.root_node.ileaf())
def test_segment_radial_dist(): seg = ((11, 11, 11), (33, 33, 33)) assert_almost_equal(mm.segment_radial_dist(seg, (0, 0, 0)), mm.point_dist((0, 0, 0), (22, 22, 22)))
def test_point_dist(): p1 = Point(3.0, 4.0, 5.0, 3.0) p2 = Point(4.0, 5.0, 6.0, 3.0) dist = mm.point_dist(p1, p2) assert dist == sqrt(3)
def _dist(section): '''Hacky closure''' return mm.point_dist(pos, section[sec_idx])
def test_segment_radial_dist(): seg = ((11,11,11), (33, 33, 33)) nt.assert_almost_equal(mm.segment_radial_dist(seg, (0,0,0)), mm.point_dist((0,0,0), (22,22,22)))
def test_point_dist(): p1 = Point(3.0, 4.0, 5.0, 3.0, 1) p2 = Point(4.0, 5.0, 6.0, 3.0, 1) dist = mm.point_dist(p1,p2) nt.eq_(dist, sqrt(3))
def _dist(seg): """Distance between segmenr end and trunk.""" return morphmath.point_dist(seg[1], neurite.root_node.points[0])
def path_end_to_end_distance(neurite): '''Calculate and return end-to-end-distance of a given neurite.''' trunk = neurite.root_node.points[0] return max(morphmath.point_dist(l.points[-1], trunk) for l in neurite.root_node.ileaf())
def _dist(seg): '''Distance between segmenr end and trunk''' return morphmath.point_dist(seg[1], neurite.root_node.points[0])