Skip to content

Commit 488d975

Browse files
authored
Merge pull request #166 from navis-org/read_nrrd
Various improvements
2 parents 97509f0 + 5971854 commit 488d975

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

59 files changed

+2340
-1233
lines changed

docs/api.md

Lines changed: 41 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -124,9 +124,12 @@ In addition, a [`navis.TreeNeuron`][] has a range of different properties:
124124

125125
| Method | Description |
126126
|--------|-------------|
127+
| [`TreeNeuron.adjacency_matrix`][navis.TreeNeuron.adjacency_matrix] | {{ autosummary("navis.TreeNeuron.adjacency_matrix") }} |
127128
| [`TreeNeuron.cable_length`][navis.TreeNeuron.cable_length] | {{ autosummary("navis.TreeNeuron.cable_length") }} |
128129
| [`TreeNeuron.cycles`][navis.TreeNeuron.cycles] | {{ autosummary("navis.TreeNeuron.cycles") }} |
129130
| [`TreeNeuron.downsample`][navis.TreeNeuron.downsample] | {{ autosummary("navis.TreeNeuron.downsample") }} |
131+
| [`TreeNeuron.edges`][navis.TreeNeuron.edges] | {{ autosummary("navis.TreeNeuron.edges") }} |
132+
| [`TreeNeuron.edge_coords`][navis.TreeNeuron.edge_coords] | {{ autosummary("navis.TreeNeuron.edge_coords") }} |
130133
| [`TreeNeuron.igraph`][navis.TreeNeuron.igraph] | {{ autosummary("navis.TreeNeuron.igraph") }} |
131134
| [`TreeNeuron.is_tree`][navis.TreeNeuron.is_tree] | {{ autosummary("navis.TreeNeuron.is_tree") }} |
132135
| [`TreeNeuron.n_branches`][navis.TreeNeuron.n_branches] | {{ autosummary("navis.TreeNeuron.n_branches") }} |
@@ -140,9 +143,22 @@ In addition, a [`navis.TreeNeuron`][] has a range of different properties:
140143
| [`TreeNeuron.simple`][navis.TreeNeuron.simple] | {{ autosummary("navis.TreeNeuron.simple") }} |
141144
| [`TreeNeuron.soma_pos`][navis.TreeNeuron.soma_pos] | {{ autosummary("navis.TreeNeuron.soma_pos") }} |
142145
| [`TreeNeuron.subtrees`][navis.TreeNeuron.subtrees] | {{ autosummary("navis.TreeNeuron.subtrees") }} |
146+
| [`TreeNeuron.vertices`][navis.TreeNeuron.vertices] | {{ autosummary("navis.TreeNeuron.vertices") }} |
143147
| [`TreeNeuron.volume`][navis.TreeNeuron.volume] | {{ autosummary("navis.TreeNeuron.volume") }} |
144148

145149

150+
#### Skeleton utility functions
151+
152+
| Function | Description |
153+
|----------|-------------|
154+
| [`navis.rewire_skeleton()`][navis.rewire_skeleton] | {{ autosummary("navis.rewire_skeleton") }} |
155+
| [`navis.insert_nodes()`][navis.insert_nodes] | {{ autosummary("navis.insert_nodes") }} |
156+
| [`navis.remove_nodes()`][navis.remove_nodes] | {{ autosummary("navis.remove_nodes") }} |
157+
| [`navis.graph.simplify_graph()`][navis.graph.simplify_graph] | {{ autosummary("navis.graph.simplify_graph") }} |
158+
| [`navis.graph.skeleton_adjacency_matrix()`][navis.graph.skeleton_adjacency_matrix] | {{ autosummary("navis.graph.skeleton_adjacency_matrix") }} |
159+
160+
161+
146162
### Mesh neurons
147163

148164
Properties specific to [`navis.MeshNeuron`][]:
@@ -173,10 +189,16 @@ These are methods and properties specific to [VoxelNeurons][navis.VoxelNeuron]:
173189

174190
| Property | Description |
175191
|------|------|
192+
| [`VoxelNeuron.density`][navis.VoxelNeuron.density] | {{ autosummary("navis.VoxelNeuron.density") }} |
176193
| [`VoxelNeuron.grid`][navis.VoxelNeuron.grid] | {{ autosummary("navis.VoxelNeuron.grid") }} |
177-
| [`VoxelNeuron.voxels`][navis.VoxelNeuron.voxels] | {{ autosummary("navis.VoxelNeuron.voxels") }} |
194+
| [`VoxelNeuron.max`][navis.VoxelNeuron.max] | {{ autosummary("navis.VoxelNeuron.max") }} |
195+
| [`VoxelNeuron.min`][navis.VoxelNeuron.min] | {{ autosummary("navis.VoxelNeuron.min") }} |
196+
| [`VoxelNeuron.nnz`][navis.VoxelNeuron.nnz] | {{ autosummary("navis.VoxelNeuron.nnz") }} |
197+
| [`VoxelNeuron.offset`][navis.VoxelNeuron.offset] | {{ autosummary("navis.VoxelNeuron.offset") }} |
178198
| [`VoxelNeuron.shape`][navis.VoxelNeuron.shape] | {{ autosummary("navis.VoxelNeuron.shape") }} |
179199
| [`VoxelNeuron.strip()`][navis.VoxelNeuron.strip] | {{ autosummary("navis.VoxelNeuron.strip") }} |
200+
| [`VoxelNeuron.threshold()`][navis.VoxelNeuron.threshold] | {{ autosummary("navis.VoxelNeuron.threshold") }} |
201+
| [`VoxelNeuron.voxels`][navis.VoxelNeuron.voxels] | {{ autosummary("navis.VoxelNeuron.voxels") }} |
180202

181203

182204
### Dotprops
@@ -207,6 +229,8 @@ These functions will let you convert between neuron types:
207229
| [`navis.conversion.voxels2mesh()`][navis.conversion.voxels2mesh] | {{ autosummary("navis.conversion.voxels2mesh") }} |
208230
| [`navis.conversion.tree2meshneuron()`][navis.conversion.tree2meshneuron] | {{ autosummary("navis.conversion.tree2meshneuron") }} |
209231

232+
See also [Utility](#utility) for functions to convert to/from basic data types.
233+
210234
### NeuronList methods
211235

212236
[`NeuronLists`][navis.NeuronList] let you access all the properties and methods of the neurons
@@ -346,6 +370,7 @@ Functions to edit morphology:
346370
| [`navis.smooth_skeleton()`][navis.smooth_skeleton] | {{ autosummary("navis.smooth_skeleton") }} |
347371
| [`navis.smooth_mesh()`][navis.smooth_mesh] | {{ autosummary("navis.smooth_mesh") }} |
348372
| [`navis.smooth_voxels()`][navis.smooth_voxels] | {{ autosummary("navis.smooth_voxels") }} |
373+
| [`navis.thin_voxels()`][navis.thin_voxels] | {{ autosummary("navis.thin_voxels") }} |
349374

350375

351376
### Resampling
@@ -508,22 +533,6 @@ Collection of functions to work with graphs and adjacency matrices.
508533
|----------|-------------|
509534
| [`navis.NeuronConnector`][] | {{ autosummary("navis.NeuronConnector") }} |
510535

511-
### Graphs
512-
513-
Functions to convert between neurons graph representation (networkx or iGraph).
514-
515-
| Function | Description |
516-
|----------|-------------|
517-
| [`navis.neuron2nx()`][navis.neuron2nx] | {{ autosummary("navis.neuron2nx") }} |
518-
| [`navis.neuron2igraph()`][navis.neuron2igraph] | {{ autosummary("navis.neuron2igraph") }} |
519-
| [`navis.neuron2KDTree()`][navis.neuron2KDTree] | {{ autosummary("navis.neuron2KDTree") }} |
520-
| [`navis.network2nx()`][navis.network2nx] | {{ autosummary("navis.network2nx") }} |
521-
| [`navis.network2igraph()`][navis.network2igraph] | {{ autosummary("navis.network2igraph") }} |
522-
| [`navis.rewire_skeleton()`][navis.rewire_skeleton] | {{ autosummary("navis.rewire_skeleton") }} |
523-
| [`navis.insert_nodes()`][navis.insert_nodes] | {{ autosummary("navis.insert_nodes") }} |
524-
| [`navis.remove_nodes()`][navis.remove_nodes] | {{ autosummary("navis.remove_nodes") }} |
525-
| [`navis.graph.simplify_graph()`][navis.graph.simplify_graph] | {{ autosummary("navis.graph.simplify_graph") }} |
526-
527536
### Connectivity metrics
528537

529538
Functions to analyse/cluster neurons based on connectivity.
@@ -581,6 +590,21 @@ Various utility functions.
581590
| [`navis.example_neurons()`][navis.example_neurons] | {{ autosummary("navis.example_neurons") }} |
582591
| [`navis.example_volume()`][navis.example_volume] | {{ autosummary("navis.example_volume") }} |
583592

593+
### Conversion
594+
595+
Functions to convert between data types.
596+
597+
| Function | Description |
598+
|----------|-------------|
599+
| [`navis.neuron2nx()`][navis.neuron2nx] | {{ autosummary("navis.neuron2nx") }} |
600+
| [`navis.neuron2igraph()`][navis.neuron2igraph] | {{ autosummary("navis.neuron2igraph") }} |
601+
| [`navis.neuron2KDTree()`][navis.neuron2KDTree] | {{ autosummary("navis.neuron2KDTree") }} |
602+
| [`navis.neuron2tangents()`][navis.neuron2tangents] | {{ autosummary("navis.neuron2tangents") }} |
603+
| [`navis.network2nx()`][navis.network2nx] | {{ autosummary("navis.network2nx") }} |
604+
| [`navis.network2igraph()`][navis.network2igraph] | {{ autosummary("navis.network2igraph") }} |
605+
| [`navis.nx2neuron()`][navis.nx2neuron] | {{ autosummary("navis.nx2neuron") }} |
606+
| [`navis.edges2neuron()`][navis.edges2neuron] | {{ autosummary("navis.edges2neuron") }} |
607+
584608
## Network Models
585609

586610
{{ navis }} comes with a simple network traversal model (used in [Schlegel, Bates et al., 2021](https://elifesciences.org/articles/66018)).

docs/examples/0_io/tutorial_io_00_skeletons.py

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@
1616
(e.g. the MICrONS, neuromorpho, Virtual Fly Brain or Janelia hemibrain datasets).
1717
These are covered in separate [tutorials](../../gallery).
1818
19+
If you have light-level microscopy data, you might also be interested in the
20+
tutorial on [skeletons from light-level data](../zzz_tutorial_io_05_skeletonize).
21+
1922
## From SWC files
2023
2124
SWC is a common format for storing neuron skeletons. Thus {{ navis }} provides functions to both
@@ -182,8 +185,4 @@
182185
#
183186
# Please also keep in mind that you can also convert one neuron type into another - for example by skeletonizing [`MeshNeurons`][navis.MeshNeuron]
184187
# (see also the API reference on [neuron conversion](../../../api.md#converting-between-types)).
185-
#
186-
# If you have light-level microscopy data, you might also be interested in the
187-
# [tutorial on skeletons from light-level data](../zzz_tutorial_io_05_skeletonize).
188-
189188

docs/examples/0_io/tutorial_io_02_dotprops.py

Lines changed: 77 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,34 +2,98 @@
22
Dotprops
33
========
44
5-
This tutorial will show you have to work with Dotprops.
5+
This tutorial will show you how to load/create Dotprops.
66
77
[`navis.Dotprops`][] are point clouds with associated principal vectors which are mostly used for
88
NBLASTing. They are typically derivatives of skeletons or meshes but you can load them straight from
9-
confocal data using [`navis.read_nrrd`][]:
9+
e.g. confocal image stacks using [`navis.read_nrrd`][] or [`navis.read_tiff`][].
10+
11+
![dotprops](../../../../_static/dotprops.png)
1012
"""
1113

1214
# %%
1315
import navis
16+
import matplotlib.pyplot as plt
1417

1518
# %%
1619
# ## From image data
1720
#
18-
# For this example I downloaded one of Janelia's Fly Light confocal stacks ([link](https://splitgal4.janelia.org/))
19-
# and converted it to NRRD format using [ImageJ](https://imagej.net/ij/).
21+
# For this example we will use a stack from [Janelia's split Gal4 collection](https://splitgal4.janelia.org/).
22+
# This `LH2094` line is also available from [Virtual Fly Brain](https://v2.virtualflybrain.org/org.geppetto.frontend/geppetto?id=VFB_00102926&i=VFB_00101567,VFB_00102926)
23+
# where, conveniently, they can be downloaded in NRRD format which we can directly read into {{ navis }}.
24+
#
25+
# Let's do this step-by-step first:
26+
27+
# Load raw NRRD image
28+
im, header = navis.read_nrrd(
29+
"https://v2.virtualflybrain.org/data/VFB/i/0010/2926/VFB_00101567/volume.nrrd",
30+
output="raw"
31+
)
32+
33+
# Plot a maximum projection
34+
max_proj = im.max(axis=2)
35+
plt.imshow(
36+
max_proj.T,
37+
extent=(0, int(0.5189 * 1210), (0.5189 * 566), 0), # extent is calculated from the spacing (see `header`) times the no of x/y pixels
38+
cmap='Greys_r',
39+
vmax=10 # make it really bright so we can see neurons + outline of the brain
40+
)
41+
42+
# %%
43+
# At this point we could threshold the image, extract above-threshold voxels and convert them to a Dotprops object.
44+
# However, the easier option is to use [`navis.read_nrrd`][] with the `output="dotprops"` parameter:
45+
46+
dp = navis.read_nrrd(
47+
"https://v2.virtualflybrain.org/data/VFB/i/0010/2926/VFB_00101567/volume.nrrd",
48+
output="dotprops",
49+
threshold=5, # threshold to determine which voxels are used for the dotprops
50+
thin=True, # see note below on this parameter!
51+
k=10 # number of neighbours to consider when calculating the tangent vector
52+
)
53+
54+
# %%
55+
# !!! note "Thinning"
56+
# In the above [`read_nrrd`][navis.read_nrrd] call we used `thin=True`. This is a post-processing step that
57+
# thins the image to a single pixel width. This will produce "cleaner" dotprops but can also remove denser
58+
# neurites thus emphasizing the backbone of the neuron. This option requires the `scikit-image` package:
59+
#
60+
# ```bash
61+
# pip install scikit-image
62+
# ```
2063
#
21-
# Load NRRD file into Dotprops instead of VoxelNeuron:
22-
# ```python
23-
# dp = navis.read_nrrd(
24-
# "~/Downloads/JRC_SS86025_JRC_SS86025-20211112_49_B6.nrrd",
25-
# output="dotprops",
26-
# threshold=3000,
27-
# )
28-
# ```
64+
# Let's overlay the dotprops on the maximum projection:
65+
66+
fig, ax = plt.subplots()
67+
ax.imshow(
68+
max_proj.T,
69+
extent=(0, int(0.5189 * 1210), (0.5189 * 566), 0),
70+
cmap='Greys_r',
71+
vmax=10
72+
)
73+
navis.plot2d(dp, ax=ax, view=("x", "-y"), method="2d", color="r", linewidth=1.5)
74+
75+
# %%
76+
# This looks pretty good but we have a bit of little fluff around the brain which we may want to get rid off:
77+
78+
# Drop everything but the two largest connected components
79+
dp = navis.drop_fluff(dp, n_largest=2)
80+
81+
# Plot again
82+
fig, ax = plt.subplots()
83+
ax.imshow(
84+
max_proj.T,
85+
extent=(0, int(0.5189 * 1210), (0.5189 * 566), 0),
86+
cmap='Greys_r',
87+
vmax=10
88+
)
89+
navis.plot2d(dp, ax=ax, view=("x", "-y"), method="2d", color="r", linewidth=1.5)
2990

3091
# %%
3192
# !!! note
32-
# Note the threshold parameter? It determines which voxels (by brightness) are used and which are ignored!
93+
# To extract the connected components, [`navis.drop_fluff`][] treats all pairs of points within a certain distance
94+
# as connected. The distance is determined by the `dp_dist` parameter which defaults to 5 x the average distance
95+
# between points. This is a good value ehre but you may need adjust it for your data.
96+
#
3397
#
3498
# ## From other neurons
3599
#

0 commit comments

Comments
 (0)