Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Convert '-' to '_' in summary dataframe #215

Merged
merged 20 commits into from
Nov 20, 2023
Merged
Show file tree
Hide file tree
Changes from 13 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 19 additions & 19 deletions src/skan/csr.py
Original file line number Diff line number Diff line change
Expand Up @@ -734,44 +734,44 @@ def summarize(
_, skeleton_ids = csgraph.connected_components(skel.graph, directed=False)
endpoints_src = skel.paths.indices[skel.paths.indptr[:-1]]
endpoints_dst = skel.paths.indices[skel.paths.indptr[1:] - 1]
summary['skeleton-id'] = skeleton_ids[endpoints_src]
summary['node-id-src'] = endpoints_src
summary['node-id-dst'] = endpoints_dst
summary['branch-distance'] = skel.path_lengths()
summary['skeleton_id'] = skeleton_ids[endpoints_src]
summary['node_id_src'] = endpoints_src
summary['node_id_dst'] = endpoints_dst
summary['branch_distance'] = skel.path_lengths()
deg_src = skel.degrees[endpoints_src]
deg_dst = skel.degrees[endpoints_dst]
kind = np.full(deg_src.shape, 2) # default: junction-to-junction
kind[(deg_src == 1) | (deg_dst == 1)] = 1 # tip-junction
kind[(deg_src == 1) & (deg_dst == 1)] = 0 # tip-tip
kind[endpoints_src == endpoints_dst] = 3 # cycle
summary['branch-type'] = kind
summary['mean-pixel-value'] = skel.path_means()
summary['stdev-pixel-value'] = skel.path_stdev()
summary['branch_type'] = kind
summary['mean_pixel_value'] = skel.path_means()
summary['stdev_pixel_value'] = skel.path_stdev()
for i in range(ndim): # keep loops separate for best insertion order
summary[f'image-coord-src-{i}'] = skel.coordinates[endpoints_src, i]
summary[f'image_coord_src_{i}'] = skel.coordinates[endpoints_src, i]
for i in range(ndim):
summary[f'image-coord-dst-{i}'] = skel.coordinates[endpoints_dst, i]
summary[f'image_coord_dst_{i}'] = skel.coordinates[endpoints_dst, i]
coords_real_src = skel.coordinates[endpoints_src] * skel.spacing
for i in range(ndim):
summary[f'coord-src-{i}'] = coords_real_src[:, i]
summary[f'coord_src_{i}'] = coords_real_src[:, i]
if value_is_height:
values_src = skel.pixel_values[endpoints_src]
summary[f'coord-src-{ndim}'] = values_src
summary[f'coord_src_{ndim}'] = values_src
coords_real_src = np.concatenate(
[coords_real_src, values_src[:, np.newaxis]],
axis=1,
) # yapf: ignore
)
coords_real_dst = skel.coordinates[endpoints_dst] * skel.spacing
for i in range(ndim):
summary[f'coord-dst-{i}'] = coords_real_dst[:, i]
summary[f'coord_dst_{i}'] = coords_real_dst[:, i]
if value_is_height:
values_dst = skel.pixel_values[endpoints_dst]
summary[f'coord-dst-{ndim}'] = values_dst
summary[f'coord_dst_{ndim}'] = values_dst
coords_real_dst = np.concatenate(
[coords_real_dst, values_dst[:, np.newaxis]],
axis=1,
) # yapf: ignore
summary['euclidean-distance'] = (
)
summary['euclidean_distance'] = (
np.sqrt((coords_real_dst - coords_real_src)**2
@ np.ones(ndim + int(value_is_height)))
)
Expand Down Expand Up @@ -1052,9 +1052,9 @@ def _simplify_graph(skel):
return skel.graph, np.arange(skel.graph.shape[0])

summary = summarize(skel)
src = np.asarray(summary['node-id-src'])
dst = np.asarray(summary['node-id-dst'])
distance = np.asarray(summary['branch-distance'])
src = np.asarray(summary['node_id_src'])
dst = np.asarray(summary['node_id_dst'])
distance = np.asarray(summary['branch_distance'])

# to reduce the size of simplified graph
nodes = np.unique(np.append(src, dst))
Expand Down
8 changes: 4 additions & 4 deletions src/skan/draw.py
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ def overlay_euclidean_skeleton_2d(
stats,
*,
image_cmap=None,
skeleton_color_source='branch-type',
skeleton_color_source='branch_type',
skeleton_colormap='viridis',
axes=None
):
Expand All @@ -124,7 +124,7 @@ def overlay_euclidean_skeleton_2d(

- skeleton-id: each individual skeleton (connected component) will
have a different colour.
- branch-type: each branch type (tip-tip, tip-junction,
- branch_type: each branch type (tip-tip, tip-junction,
junction-junction, path-path). This is the default.
- branch-distance: the curved length of the skeleton branch.
- euclidean-distance: the straight-line length of the skeleton branch.
Expand All @@ -142,8 +142,8 @@ def overlay_euclidean_skeleton_2d(
image = _normalise_image(image, image_cmap=image_cmap)
summary = stats
# transforming from row, col to x, y
coords_cols = (['image-coord-src-%i' % i for i in [1, 0]]
+ ['image-coord-dst-%i' % i for i in [1, 0]])
coords_cols = (['image_coord_src_%i' % i for i in [1, 0]]
+ ['image_coord_dst_%i' % i for i in [1, 0]])
coords = summary[coords_cols].values.reshape((-1, 2, 2))
if axes is None:
fig, axes = plt.subplots()
Expand Down
8 changes: 4 additions & 4 deletions src/skan/pipe.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,11 +67,11 @@ def process_single_image(
skeleton = morphology.skeletonize(thresholded) * quality
framedata = csr.summarize(csr.Skeleton(skeleton, spacing=scale))
framedata['squiggle'] = np.log2(
framedata['branch-distance'] / framedata['euclidean-distance']
framedata['branch_distance'] / framedata['euclidean_distance']
)
framedata['scale'] = scale
framedata.rename(
columns={'mean-pixel-value': 'mean-shape-index'},
columns={'mean_pixel_value': 'mean_shape_index'},
inplace=True,
errors='raise',
)
Expand Down Expand Up @@ -152,9 +152,9 @@ def process_images(
image_stats['branch density'] = (
framedata.shape[0] / image_stats['area']
)
j2j = framedata[framedata['branch-type'] == 2]
j2j = framedata[framedata['branch_type'] == 2]
image_stats['mean J2J branch distance'] = (
j2j['branch-distance'].mean()
j2j['branch_distance'].mean()
)
image_results.append(image_stats)
yield filename, image, thresholded, skeleton, framedata
Expand Down
6 changes: 3 additions & 3 deletions src/skan/summary_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,9 @@ def find_main_branches(summary: DataFrame) -> np.ndarray:
skeleton
"""
is_main = np.zeros(summary.shape[0], dtype=bool)
us = summary['node-id-src']
vs = summary['node-id-dst']
ws = summary['branch-distance']
us = summary['node_id_src']
vs = summary['node_id_dst']
ws = summary['branch_distance']

edge2idx = {(u, v): i for i, (u, v) in enumerate(zip(us, vs))}

Expand Down
45 changes: 23 additions & 22 deletions src/skan/test/test_csr.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ def _old_branch_statistics(
skeleton_image, spacing=spacing, value_is_height=value_is_height
)
summary = csr.summarize(skel, value_is_height=value_is_height)
columns = ['node-id-src', 'node-id-dst', 'branch-distance', 'branch-type']
columns = ['node_id_src', 'node_id_dst', 'branch_distance', 'branch_type']
return summary[columns].to_numpy()


Expand Down Expand Up @@ -55,22 +55,22 @@ def test_skeleton1_stats():

def test_2skeletons():
df = csr.summarize(csr.Skeleton(skeleton2))
assert_almost_equal(np.unique(df['euclidean-distance']), np.sqrt([5, 10]))
assert_equal(np.unique(df['skeleton-id']), [0, 1])
assert_equal(np.bincount(df['branch-type']), [0, 4, 4])
assert_almost_equal(np.unique(df['euclidean_distance']), np.sqrt([5, 10]))
assert_equal(np.unique(df['skeleton_id']), [0, 1])
assert_equal(np.bincount(df['branch_type']), [0, 4, 4])


def test_summarize_spacing():
df = csr.summarize(csr.Skeleton(skeleton2))
df2 = csr.summarize(csr.Skeleton(skeleton2, spacing=2))
assert_equal(np.array(df['node-id-src']), np.array(df2['node-id-src']))
assert_equal(np.array(df['node_id_src']), np.array(df2['node_id_src']))
assert_almost_equal(
np.array(df2['euclidean-distance']),
np.array(2 * df['euclidean-distance'])
np.array(df2['euclidean_distance']),
np.array(2 * df['euclidean_distance'])
)
assert_almost_equal(
np.array(df2['branch-distance']),
np.array(2 * df['branch-distance'])
np.array(df2['branch_distance']),
np.array(2 * df['branch_distance'])
)


Expand Down Expand Up @@ -108,8 +108,8 @@ def test_topograph_summary():
csr.Skeleton(topograph1d, spacing=2.5, value_is_height=True),
value_is_height=True,
)
assert stats.loc[0, 'euclidean-distance'] == 5.0
columns = ['coord-src-0', 'coord-src-1', 'coord-dst-0', 'coord-dst-1']
assert stats.loc[0, 'euclidean_distance'] == 5.0
columns = ['coord_src_0', 'coord_src_1', 'coord_dst_0', 'coord_dst_1']
assert_almost_equal(sorted(stats.loc[0, columns]), [0, 3, 3, 5])


Expand All @@ -124,20 +124,20 @@ def test_multiplicity_stats():
stats1 = csr.summarize(csr.Skeleton(skeleton0))
stats2 = csr.summarize(csr.Skeleton(skeleton0, spacing=2))
assert_almost_equal(
2 * stats1['branch-distance'].values,
stats2['branch-distance'].values
2 * stats1['branch_distance'].values,
stats2['branch_distance'].values
)
assert_almost_equal(
2 * stats1['euclidean-distance'].values,
stats2['euclidean-distance'].values
2 * stats1['euclidean_distance'].values,
stats2['euclidean_distance'].values
)


def test_pixel_values():
image = np.random.random((45,))
expected = np.mean(image)
stats = csr.summarize(csr.Skeleton(image))
assert_almost_equal(stats.loc[0, 'mean-pixel-value'], expected)
assert_almost_equal(stats.loc[0, 'mean_pixel_value'], expected)


def test_tip_junction_edges():
Expand Down Expand Up @@ -172,15 +172,15 @@ def test_transpose_image():
skeleton1 = csr.Skeleton(image)
skeleton2 = csr.Skeleton(image.T)

assert (skeleton1.n_paths == skeleton2.n_paths)
assert skeleton1.n_paths == skeleton2.n_paths
np.testing.assert_allclose(
np.sort(skeleton1.path_lengths()),
np.sort(skeleton2.path_lengths()),
)


@pytest.mark.parametrize(
"skeleton,prune_branch,target",
'skeleton,prune_branch,target',
[
(
skeleton1, 1,
Expand Down Expand Up @@ -209,7 +209,7 @@ def test_prune_paths(
"""Test pruning of paths."""
s = csr.Skeleton(skeleton, keep_images=True)
summary = summarize(s)
indices_to_remove = summary.loc[summary['branch-type'] == prune_branch
indices_to_remove = summary.loc[summary['branch_type'] == prune_branch
].index
pruned = s.prune_paths(indices_to_remove)
np.testing.assert_array_equal(pruned, target)
Expand All @@ -220,7 +220,7 @@ def test_prune_paths_exception_single_point() -> None:
can not be created and returned."""
s = csr.Skeleton(skeleton0)
summary = summarize(s)
indices_to_remove = summary.loc[summary['branch-type'] == 1].index
indices_to_remove = summary.loc[summary['branch_type'] == 1].index
with pytest.raises(ValueError):
s.prune_paths(indices_to_remove)

Expand Down Expand Up @@ -312,7 +312,8 @@ def test_skeleton_path_image_no_keep_image():
pli = s.path_label_image()
assert np.max(pli) == s.n_paths


def test_skeletonlabel():
stats = csr.summarize(csr.Skeleton(skeletonlabel))
assert stats['mean-pixel-value'].max() == skeletonlabel.max()
assert stats['mean-pixel-value'].max() > 1
assert stats['mean_pixel_value'].max() == skeletonlabel.max()
assert stats['mean_pixel_value'].max() > 1
2 changes: 1 addition & 1 deletion src/skan/test/test_draw.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ def test_overlay_skeleton(test_image, test_skeleton):
def test_overlay_euclidean_skeleton(test_image, test_stats):
draw.overlay_euclidean_skeleton_2d(test_image, test_stats)
draw.overlay_euclidean_skeleton_2d(
test_image, test_stats, skeleton_color_source='branch-distance'
test_image, test_stats, skeleton_color_source='branch_distance'
)


Expand Down
6 changes: 3 additions & 3 deletions src/skan/test/test_napari_plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ def test_get_skeleton_simple():
labels_layer, skeleton_type
)

assert type(layer_kwargs["metadata"]["skeleton"]) is Skeleton
assert type(layer_kwargs['metadata']['skeleton']) is Skeleton
np.testing.assert_array_equal(
shapes_data[0],
[[5, 1], [5, 2], [5, 3], [5, 4], [5, 5], [5, 6], [5, 7], [5, 8]]
Expand All @@ -41,7 +41,7 @@ def test_get_skeleton_horse():
)
assert len(shapes_data) == 24 # 24 line segments in the horse skeleton
assert 'features' in layer_kwargs
assert type(layer_kwargs["features"]) is pd.DataFrame
assert type(layer_kwargs['features']) is pd.DataFrame


def test_gui(make_napari_viewer):
Expand All @@ -56,7 +56,7 @@ def test_gui(make_napari_viewer):
dw, widget = viewer.window.add_plugin_dock_widget(
'skan', 'Color Skeleton Widget'
)
widget.feature_name.value = "euclidean-distance"
widget.feature_name.value = 'euclidean_distance'
widget()
layer = viewer.layers[-1]
assert layer.edge_colormap.name == 'viridis'
Expand Down
8 changes: 4 additions & 4 deletions src/skan/test/test_skeleton_class.py
Original file line number Diff line number Diff line change
Expand Up @@ -102,16 +102,16 @@ def test_skeleton_summarize():
image[skeleton2] = 1 + np.random.random(np.sum(skeleton2))
skeleton = Skeleton(image)
summary = summarize(skeleton)
assert set(summary['skeleton-id']) == {0, 1}
assert set(summary['skeleton_id']) == {0, 1}
assert (
np.all(summary['mean-pixel-value'] < 2)
and np.all(summary['mean-pixel-value'] > 1)
np.all(summary['mean_pixel_value'] < 2)
and np.all(summary['mean_pixel_value'] > 1)
)


def test_skeleton_label_image_strict():
"""Test that the skeleton pixel labels match the branch IDs.

This does pixel-wise pairing of the label image with the expected label
image. There should be the same number of unique pairs as there are unique
labels in the expected label image. This assumes that the branches are
Expand Down
2 changes: 1 addition & 1 deletion src/skan/test/test_summary_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ def test_find_main():
non_main_df = summary_df.loc[summary_df['main'] == False]
assert non_main_df.shape[0] == 1
coords = non_main_df[[
'coord-src-0', 'coord-src-1', 'coord-dst-0', 'coord-dst-1'
'coord_src_0', 'coord_src_1', 'coord_dst_0', 'coord_dst_1'
]].to_numpy()
assert (
np.all(coords == non_main_edge_start + non_main_edge_finish)
Expand Down
Loading