Skip to content

Commit

Permalink
Merge pull request #166 from navis-org/read_nrrd
Browse files Browse the repository at this point in the history
Various improvements
  • Loading branch information
schlegelp authored Oct 9, 2024
2 parents 97509f0 + 5971854 commit 488d975
Show file tree
Hide file tree
Showing 59 changed files with 2,340 additions and 1,233 deletions.
58 changes: 41 additions & 17 deletions docs/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -124,9 +124,12 @@ In addition, a [`navis.TreeNeuron`][] has a range of different properties:

| Method | Description |
|--------|-------------|
| [`TreeNeuron.adjacency_matrix`][navis.TreeNeuron.adjacency_matrix] | {{ autosummary("navis.TreeNeuron.adjacency_matrix") }} |
| [`TreeNeuron.cable_length`][navis.TreeNeuron.cable_length] | {{ autosummary("navis.TreeNeuron.cable_length") }} |
| [`TreeNeuron.cycles`][navis.TreeNeuron.cycles] | {{ autosummary("navis.TreeNeuron.cycles") }} |
| [`TreeNeuron.downsample`][navis.TreeNeuron.downsample] | {{ autosummary("navis.TreeNeuron.downsample") }} |
| [`TreeNeuron.edges`][navis.TreeNeuron.edges] | {{ autosummary("navis.TreeNeuron.edges") }} |
| [`TreeNeuron.edge_coords`][navis.TreeNeuron.edge_coords] | {{ autosummary("navis.TreeNeuron.edge_coords") }} |
| [`TreeNeuron.igraph`][navis.TreeNeuron.igraph] | {{ autosummary("navis.TreeNeuron.igraph") }} |
| [`TreeNeuron.is_tree`][navis.TreeNeuron.is_tree] | {{ autosummary("navis.TreeNeuron.is_tree") }} |
| [`TreeNeuron.n_branches`][navis.TreeNeuron.n_branches] | {{ autosummary("navis.TreeNeuron.n_branches") }} |
Expand All @@ -140,9 +143,22 @@ In addition, a [`navis.TreeNeuron`][] has a range of different properties:
| [`TreeNeuron.simple`][navis.TreeNeuron.simple] | {{ autosummary("navis.TreeNeuron.simple") }} |
| [`TreeNeuron.soma_pos`][navis.TreeNeuron.soma_pos] | {{ autosummary("navis.TreeNeuron.soma_pos") }} |
| [`TreeNeuron.subtrees`][navis.TreeNeuron.subtrees] | {{ autosummary("navis.TreeNeuron.subtrees") }} |
| [`TreeNeuron.vertices`][navis.TreeNeuron.vertices] | {{ autosummary("navis.TreeNeuron.vertices") }} |
| [`TreeNeuron.volume`][navis.TreeNeuron.volume] | {{ autosummary("navis.TreeNeuron.volume") }} |


#### Skeleton utility functions

| Function | Description |
|----------|-------------|
| [`navis.rewire_skeleton()`][navis.rewire_skeleton] | {{ autosummary("navis.rewire_skeleton") }} |
| [`navis.insert_nodes()`][navis.insert_nodes] | {{ autosummary("navis.insert_nodes") }} |
| [`navis.remove_nodes()`][navis.remove_nodes] | {{ autosummary("navis.remove_nodes") }} |
| [`navis.graph.simplify_graph()`][navis.graph.simplify_graph] | {{ autosummary("navis.graph.simplify_graph") }} |
| [`navis.graph.skeleton_adjacency_matrix()`][navis.graph.skeleton_adjacency_matrix] | {{ autosummary("navis.graph.skeleton_adjacency_matrix") }} |



### Mesh neurons

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

| Property | Description |
|------|------|
| [`VoxelNeuron.density`][navis.VoxelNeuron.density] | {{ autosummary("navis.VoxelNeuron.density") }} |
| [`VoxelNeuron.grid`][navis.VoxelNeuron.grid] | {{ autosummary("navis.VoxelNeuron.grid") }} |
| [`VoxelNeuron.voxels`][navis.VoxelNeuron.voxels] | {{ autosummary("navis.VoxelNeuron.voxels") }} |
| [`VoxelNeuron.max`][navis.VoxelNeuron.max] | {{ autosummary("navis.VoxelNeuron.max") }} |
| [`VoxelNeuron.min`][navis.VoxelNeuron.min] | {{ autosummary("navis.VoxelNeuron.min") }} |
| [`VoxelNeuron.nnz`][navis.VoxelNeuron.nnz] | {{ autosummary("navis.VoxelNeuron.nnz") }} |
| [`VoxelNeuron.offset`][navis.VoxelNeuron.offset] | {{ autosummary("navis.VoxelNeuron.offset") }} |
| [`VoxelNeuron.shape`][navis.VoxelNeuron.shape] | {{ autosummary("navis.VoxelNeuron.shape") }} |
| [`VoxelNeuron.strip()`][navis.VoxelNeuron.strip] | {{ autosummary("navis.VoxelNeuron.strip") }} |
| [`VoxelNeuron.threshold()`][navis.VoxelNeuron.threshold] | {{ autosummary("navis.VoxelNeuron.threshold") }} |
| [`VoxelNeuron.voxels`][navis.VoxelNeuron.voxels] | {{ autosummary("navis.VoxelNeuron.voxels") }} |


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

See also [Utility](#utility) for functions to convert to/from basic data types.

### NeuronList methods

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


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

### Graphs

Functions to convert between neurons graph representation (networkx or iGraph).

| Function | Description |
|----------|-------------|
| [`navis.neuron2nx()`][navis.neuron2nx] | {{ autosummary("navis.neuron2nx") }} |
| [`navis.neuron2igraph()`][navis.neuron2igraph] | {{ autosummary("navis.neuron2igraph") }} |
| [`navis.neuron2KDTree()`][navis.neuron2KDTree] | {{ autosummary("navis.neuron2KDTree") }} |
| [`navis.network2nx()`][navis.network2nx] | {{ autosummary("navis.network2nx") }} |
| [`navis.network2igraph()`][navis.network2igraph] | {{ autosummary("navis.network2igraph") }} |
| [`navis.rewire_skeleton()`][navis.rewire_skeleton] | {{ autosummary("navis.rewire_skeleton") }} |
| [`navis.insert_nodes()`][navis.insert_nodes] | {{ autosummary("navis.insert_nodes") }} |
| [`navis.remove_nodes()`][navis.remove_nodes] | {{ autosummary("navis.remove_nodes") }} |
| [`navis.graph.simplify_graph()`][navis.graph.simplify_graph] | {{ autosummary("navis.graph.simplify_graph") }} |

### Connectivity metrics

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

### Conversion

Functions to convert between data types.

| Function | Description |
|----------|-------------|
| [`navis.neuron2nx()`][navis.neuron2nx] | {{ autosummary("navis.neuron2nx") }} |
| [`navis.neuron2igraph()`][navis.neuron2igraph] | {{ autosummary("navis.neuron2igraph") }} |
| [`navis.neuron2KDTree()`][navis.neuron2KDTree] | {{ autosummary("navis.neuron2KDTree") }} |
| [`navis.neuron2tangents()`][navis.neuron2tangents] | {{ autosummary("navis.neuron2tangents") }} |
| [`navis.network2nx()`][navis.network2nx] | {{ autosummary("navis.network2nx") }} |
| [`navis.network2igraph()`][navis.network2igraph] | {{ autosummary("navis.network2igraph") }} |
| [`navis.nx2neuron()`][navis.nx2neuron] | {{ autosummary("navis.nx2neuron") }} |
| [`navis.edges2neuron()`][navis.edges2neuron] | {{ autosummary("navis.edges2neuron") }} |

## Network Models

{{ navis }} comes with a simple network traversal model (used in [Schlegel, Bates et al., 2021](https://elifesciences.org/articles/66018)).
Expand Down
7 changes: 3 additions & 4 deletions docs/examples/0_io/tutorial_io_00_skeletons.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@
(e.g. the MICrONS, neuromorpho, Virtual Fly Brain or Janelia hemibrain datasets).
These are covered in separate [tutorials](../../gallery).
If you have light-level microscopy data, you might also be interested in the
tutorial on [skeletons from light-level data](../zzz_tutorial_io_05_skeletonize).
## From SWC files
SWC is a common format for storing neuron skeletons. Thus {{ navis }} provides functions to both
Expand Down Expand Up @@ -182,8 +185,4 @@
#
# Please also keep in mind that you can also convert one neuron type into another - for example by skeletonizing [`MeshNeurons`][navis.MeshNeuron]
# (see also the API reference on [neuron conversion](../../../api.md#converting-between-types)).
#
# If you have light-level microscopy data, you might also be interested in the
# [tutorial on skeletons from light-level data](../zzz_tutorial_io_05_skeletonize).


90 changes: 77 additions & 13 deletions docs/examples/0_io/tutorial_io_02_dotprops.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,34 +2,98 @@
Dotprops
========
This tutorial will show you have to work with Dotprops.
This tutorial will show you how to load/create Dotprops.
[`navis.Dotprops`][] are point clouds with associated principal vectors which are mostly used for
NBLASTing. They are typically derivatives of skeletons or meshes but you can load them straight from
confocal data using [`navis.read_nrrd`][]:
e.g. confocal image stacks using [`navis.read_nrrd`][] or [`navis.read_tiff`][].
![dotprops](../../../../_static/dotprops.png)
"""

# %%
import navis
import matplotlib.pyplot as plt

# %%
# ## From image data
#
# For this example I downloaded one of Janelia's Fly Light confocal stacks ([link](https://splitgal4.janelia.org/))
# and converted it to NRRD format using [ImageJ](https://imagej.net/ij/).
# For this example we will use a stack from [Janelia's split Gal4 collection](https://splitgal4.janelia.org/).
# 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)
# where, conveniently, they can be downloaded in NRRD format which we can directly read into {{ navis }}.
#
# Let's do this step-by-step first:

# Load raw NRRD image
im, header = navis.read_nrrd(
"https://v2.virtualflybrain.org/data/VFB/i/0010/2926/VFB_00101567/volume.nrrd",
output="raw"
)

# Plot a maximum projection
max_proj = im.max(axis=2)
plt.imshow(
max_proj.T,
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
cmap='Greys_r',
vmax=10 # make it really bright so we can see neurons + outline of the brain
)

# %%
# At this point we could threshold the image, extract above-threshold voxels and convert them to a Dotprops object.
# However, the easier option is to use [`navis.read_nrrd`][] with the `output="dotprops"` parameter:

dp = navis.read_nrrd(
"https://v2.virtualflybrain.org/data/VFB/i/0010/2926/VFB_00101567/volume.nrrd",
output="dotprops",
threshold=5, # threshold to determine which voxels are used for the dotprops
thin=True, # see note below on this parameter!
k=10 # number of neighbours to consider when calculating the tangent vector
)

# %%
# !!! note "Thinning"
# In the above [`read_nrrd`][navis.read_nrrd] call we used `thin=True`. This is a post-processing step that
# thins the image to a single pixel width. This will produce "cleaner" dotprops but can also remove denser
# neurites thus emphasizing the backbone of the neuron. This option requires the `scikit-image` package:
#
# ```bash
# pip install scikit-image
# ```
#
# Load NRRD file into Dotprops instead of VoxelNeuron:
# ```python
# dp = navis.read_nrrd(
# "~/Downloads/JRC_SS86025_JRC_SS86025-20211112_49_B6.nrrd",
# output="dotprops",
# threshold=3000,
# )
# ```
# Let's overlay the dotprops on the maximum projection:

fig, ax = plt.subplots()
ax.imshow(
max_proj.T,
extent=(0, int(0.5189 * 1210), (0.5189 * 566), 0),
cmap='Greys_r',
vmax=10
)
navis.plot2d(dp, ax=ax, view=("x", "-y"), method="2d", color="r", linewidth=1.5)

# %%
# This looks pretty good but we have a bit of little fluff around the brain which we may want to get rid off:

# Drop everything but the two largest connected components
dp = navis.drop_fluff(dp, n_largest=2)

# Plot again
fig, ax = plt.subplots()
ax.imshow(
max_proj.T,
extent=(0, int(0.5189 * 1210), (0.5189 * 566), 0),
cmap='Greys_r',
vmax=10
)
navis.plot2d(dp, ax=ax, view=("x", "-y"), method="2d", color="r", linewidth=1.5)

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

0 comments on commit 488d975

Please sign in to comment.