Skeletons¶
navis
lets you import neurons from a variety of local and remote sources. In this tutorial you will learn how to load skeletons from local data and - failing that - construct them from scratch. For loading remote data (e.g. the MICrONS, neuromorpho, Virtual Fly Brain or Janelia hemibrain datasets), navis
has dedicated interfaces. See the example gallery for tutorials on these.
Skeletons in navis
are represented by the navis.TreeNeuron
class. You can either construct these manually (see bottom of this page) or use one of the built-in functions to them from one of the various file formats:
SWC files¶
SWC is a common format for storing neuron skeletons. Thus navis
provides functions to both read and write SWC files. To demo these, we will be using supplemental data from Bates, Schlegel et al. (Current Biology, 2020). If you want to follow along, please download Supplemental Data S1 (link). If you do, make sure to adjust the filepath accordingly.
import navis
I extracted the archive with the supplemental data inside my downloads folder. It contains a bunch of CSV files with meta data but the important file for us is the skeletons_swc.zip
. Now you could extract that zip archive too but navis
can actually read directly from (and write to) zip files!
skeletons = navis.read_swc('~/Downloads/mmc2/skeletons_swc.zip', include_subdirs=True)
skeletons
type | name | n_nodes | n_connectors | n_branches | n_leafs | cable_length | soma | units | created_at | origin | |
---|---|---|---|---|---|---|---|---|---|---|---|
0 | navis.TreeNeuron | 1313071 | 11634 | None | 600 | 611 | 2899338.75 | None | 1 dimensionless | 2022-05-09 08:44:26.013419 | /Users/philipps/Downloads/mmc2/skeletons_swc.zip |
1 | navis.TreeNeuron | 5002989 | 1670 | None | 24 | 25 | 628291.75 | None | 1 dimensionless | 2022-05-09 08:44:26.009716 | /Users/philipps/Downloads/mmc2/skeletons_swc.zip |
... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
478 | navis.TreeNeuron | 11519759 | 14782 | None | 663 | 673 | 2714858.25 | None | 1 dimensionless | 2022-05-09 08:44:29.017471 | /Users/philipps/Downloads/mmc2/skeletons_swc.zip |
479 | navis.TreeNeuron | 11543484 | 6256 | None | 367 | 371 | 1229948.00 | None | 1 dimensionless | 2022-05-09 08:44:29.010490 | /Users/philipps/Downloads/mmc2/skeletons_swc.zip |
Let’s say you are looking at a huge collection of SWC files and you only want to sample a few of them:
# Load only the first 10 skeletons
sample = navis.read_swc('~/Downloads/mmc2/skeletons_swc.zip', include_subdirs=True, limit=10)
sample
type | name | n_nodes | n_connectors | n_branches | n_leafs | cable_length | soma | units | created_at | origin | |
---|---|---|---|---|---|---|---|---|---|---|---|
0 | navis.TreeNeuron | 1313071 | 11634 | None | 600 | 611 | 2.899339e+06 | None | 1 dimensionless | 2022-05-09 08:44:44.072213 | /Users/philipps/Downloads/mmc2/skeletons_swc.zip |
1 | navis.TreeNeuron | 5002989 | 1670 | None | 24 | 25 | 6.282918e+05 | None | 1 dimensionless | 2022-05-09 08:44:44.099230 | /Users/philipps/Downloads/mmc2/skeletons_swc.zip |
... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
8 | navis.TreeNeuron | 6082926 | 3112 | None | 164 | 171 | 8.933154e+05 | None | 1 dimensionless | 2022-05-09 08:44:44.289857 | /Users/philipps/Downloads/mmc2/skeletons_swc.zip |
9 | navis.TreeNeuron | 2122447 | 2694 | None | 112 | 115 | 8.098385e+05 | None | 1 dimensionless | 2022-05-09 08:44:44.312675 | /Users/philipps/Downloads/mmc2/skeletons_swc.zip |
We can also point navis.read_swc()
at single files instead of folders or zip archives:
# For this I extraced the skeletons_swc.zip archive
s = navis.read_swc('~/Downloads/mmc2/swc/CENT/11519759.swc')
s
type | navis.TreeNeuron |
---|---|
name | 11519759 |
n_nodes | 14782 |
n_connectors | None |
n_branches | 663 |
n_leafs | 673 |
cable_length | 2714858.25 |
soma | None |
units | 1 dimensionless |
created_at | 2022-04-14 22:01:20.455672 |
origin | /Users/philipps/Downloads/mmc2/swc/CENT/115197... |
You can even use URLs directly:
s = navis.read_swc('http://neuromorpho.org/dableFiles/jefferis/CNG%20version/AV4c1_140213c1.CNG.swc')
Now let’s say you have skeletons and you want to save them to disk. Easy!
# Write a single neuron
navis.write_swc(s, '~/Downloads/mmc2/my_neuron.swc')
# Write a whole list of skeletons to a folder and use the neurons' `name` property as filename
navis.write_swc(sample, '~/Downloads/mmc2/{neuron.name}.swc')
# Write directly to a zip file
navis.write_swc(sample, '~/Downloads/mmc2/skeletons.zip')
# Write directly to a zip file and use the neuron name as filename
navis.write_swc(sample, '~/Downloads/mmc2/{neuron.name}.swc@skeletons.zip')
See navis.write_swc()
for further details!
NMX files¶
NMX is a xml-based format used e.g. by pyKNOSSOS to store skeletons (+ meta data). navis
supports reading (but not writing) this format. If you want to follow along download this dataset by Wanner et al. (2016). Same procedure as with the SWCs: I extracted the archive to my downloads folder.
# Read a single file
s = navis.read_nmx('~/Downloads/WannerAA201605_SkeletonsGlomeruli/Neuron_id0001.nmx')
s
type | navis.TreeNeuron |
---|---|
name | NML |
id | Neuron_id0001 |
n_nodes | 3369 |
n_connectors | None |
n_branches | 64 |
n_leafs | 69 |
cable_length | 151639.171875 |
soma | None |
units | 1 dimensionless |
# Read all files in folder
nl = navis.read_nmx('~/Downloads/WannerAA201605_SkeletonsGlomeruli/')
nl
WARNING : Skipped "Glomeruli.nmx": failed to import skeleton. (navis)
type | name | id | n_nodes | n_connectors | n_branches | n_leafs | cable_length | soma | units | |
---|---|---|---|---|---|---|---|---|---|---|
0 | navis.TreeNeuron | NML | Neuron_id0742 | 4351 | None | 91 | 96 | 200111.703125 | None | 1 dimensionless |
1 | navis.TreeNeuron | NML | Neuron_id0756 | 4779 | None | 0 | 3 | 9099.673828 | None | 1 dimensionless |
... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
1020 | navis.TreeNeuron | NML | Neuron_id0997 | 2395 | None | 61 | 71 | 136052.546875 | None | 1 dimensionless |
1021 | navis.TreeNeuron | NML | Neuron_id0983 | 3332 | None | 115 | 123 | 223207.265625 | None | 1 dimensionless |
Note the error message? NMX files don’t always contain skeletons. If navis
comes across one that can’t be turned into a TreeNeuron
, it will skip the file and produce a warning.
Neuroglancer precomputed format¶
Among other formats, neuroglancer supports a “precomputed” format for skeletons (see specs here). This binary format is more compact than uncompressed SWC files but probably is not used outside of neuroglancer afaik. That said: navis
lets you read and write skeletons from/to precomputed format using navis.read_precomputed()
and navis.write_precomputed()
. Note that these functions work on both precomputed skeletons and meshes.
Manually constructing skeletons¶
What if you have some obscure data format for which navis
does not have a read function? The data underlying a TreeNeuron
is a simple SWC table - so as long as you can produce that from your data, you can create your own skeletons. Here’s a quick & dirty example:
import pandas as pd
# Create a mock SWC table for a 2-node skeleton
swc = pd.DataFrame()
swc['node_id'] = [0, 1]
swc['parent_id'] = [-1, 0] # negative indices indicate roots
swc['x'] = [0, 1]
swc['y'] = [0, 1]
swc['z'] = [0, 1]
swc['radius'] = 0
swc
node_id | parent_id | x | y | z | radius | |
---|---|---|---|---|---|---|
0 | 0 | -1 | 0 | 0 | 0 | 0 |
1 | 1 | 0 | 1 | 1 | 1 | 0 |
This SWC can now be used to construct a TreeNeuron
:
s = navis.TreeNeuron(swc, name='my_neuron', units='microns')
s
type | navis.TreeNeuron |
---|---|
name | my_neuron |
n_nodes | 2 |
n_connectors | None |
n_branches | 0 |
n_leafs | 1 |
cable_length | 1.732051 |
soma | None |
units | 1 micrometer |
There are a few other ways to construct a navis.TreeNeuron
(e.g. using a graph) - see the docstring for details.
Also note that all navis neurons can be stored to disk using pickle
- see the pickling tutorial.
Hopefully the above has given you some entry points on how to load your data. See also the I/O API reference api_io>. Please keep in mind that you can also convert one neuron type into another - for example by skeletonizing MeshNeurons
(see Converting neuron types).