.. _local_data_skels_tut: 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 :ref:`example gallery ` for tutorials on these. Skeletons in ``navis`` are represented by the :class:`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. .. code:: ipython3 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! .. code:: ipython3 skeletons = navis.read_swc('~/Downloads/mmc2/skeletons_swc.zip', include_subdirs=True) skeletons .. raw:: html <class 'navis.core.neuronlist.NeuronList'> containing 480 neurons (101.1MiB)
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: .. code:: ipython3 # Load only the first 10 skeletons sample = navis.read_swc('~/Downloads/mmc2/skeletons_swc.zip', include_subdirs=True, limit=10) sample .. raw:: html <class 'navis.core.neuronlist.NeuronList'> containing 10 neurons (1.1MiB)
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 :func:`navis.read_swc` at single files instead of folders or zip archives: .. code:: ipython3 # For this I extraced the skeletons_swc.zip archive s = navis.read_swc('~/Downloads/mmc2/swc/CENT/11519759.swc') s .. raw:: html
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: .. code:: ipython3 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! .. code:: ipython3 # Write a single neuron navis.write_swc(s, '~/Downloads/mmc2/my_neuron.swc') .. code:: ipython3 # 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') .. code:: ipython3 # Write directly to a zip file navis.write_swc(sample, '~/Downloads/mmc2/skeletons.zip') .. code:: ipython3 # 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 :func:`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. .. code:: ipython3 # Read a single file s = navis.read_nmx('~/Downloads/WannerAA201605_SkeletonsGlomeruli/Neuron_id0001.nmx') s .. raw:: html
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
.. code:: ipython3 # Read all files in folder nl = navis.read_nmx('~/Downloads/WannerAA201605_SkeletonsGlomeruli/') nl .. parsed-literal:: WARNING : Skipped "Glomeruli.nmx": failed to import skeleton. (navis) .. raw:: html <class 'navis.core.neuronlist.NeuronList'> containing 1022 neurons (142.1MiB)
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 :class:`~navis.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 :func:`navis.read_precomputed` and :func:`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 :class:`~navis.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: .. code:: ipython3 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 .. raw:: html
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 :class:`~navis.TreeNeuron`: .. code:: ipython3 s = navis.TreeNeuron(swc, name='my_neuron', units='microns') s .. raw:: html
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 :class:`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 :ref:`pickling tutorial `. Hopefully the above has given you some entry points on how to load your data. See also the :ref:`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 :ref:`neuron_conversion`).