Data types

Overview

navis is a Python package for analysing, manipulating and visualizing neurons.

pymaid lets you interface with a CATMAID server such as those hosted by VFB.

Both packages have extensive documentation (navis | pymaid) with introductory tutorials, examples and a list of all available functions.

Basic datatypes: neurons and neuron lists

navis knows three types of neurons:

  1. TreeNeurons = skeletons, e.g. from CATMAID
  2. MeshNeurons = meshes, e.g. from the hemibrain segmentation
  3. Dotprops = points + tangent vectors (typically only used for NBLAST)

Collections of neurons are typically held in a specialized container: aNeuronList.

Neurons

In this notebook we will focus on skeletons - a.k.a. TreeNeurons - since this is what you get out of CATMAID. Let’s kick things off by having a look at what neurons look like once it’s loaded:

import navis

# Load one of the example neurons shipped with navis
# (these are olfactory projection neurons from the hemibrain data set)
n = navis.example_neurons(1, kind='skeleton')

# Print some basic info
n
WARNING: Could not load OpenGL library.

type navis.TreeNeuron
name 1734350788
id 1734350788
n_nodes 4465
n_connectors None
n_branches 603
n_leafs 619
cable_length 266457.994591
soma [4176]
units 8 nanometer

Above summary lists a couple of (computed) properties of the neuron. Each of those can also be accessed directly like so:

n.id
1734350788

There are many more properties that you might find interesting! In theory, you can use type n. and TAB to get auto-complete suggestions of available properties and methods.

Deepnote appears to have problems with that sometimes - you can fall back to good ‘ole dir() in that case.

Here is an (incomplete) list of some of the more relevant properties:

  • bbox: bounding box of the neuron
  • cable_length: cable length
  • id: every neuron has an ID
  • nodes: the SWC node table underlying the neuron

And a couple of class methods:

  • reroot: reroot neuron
  • plot2d/plot3d: plot the neuron (see also subsequent lessons)
  • copy: make and return a copy
  • prune_twigs: remove small terminal twigs

At this point I encourage you to just explore and play around with what TreeNeuron has to offer. Also check out the docs!

As an example: this is how you get the ID of this neuron’s root node.

# Current root node of this neuron
n.root
array([1], dtype=int32)

Some of the properties such as .root or .ends are computed on-the-fly from the underlying raw data. For TreeNeurons that’s the node table (and it’s graph representation). The node table is a pandas DataFrame that looks effectively like a SWC:

# `.head()` gives us the first couple rows
n.nodes.head()

node_id label x y z radius parent_id type
0 1 0 15784.0 37250.0 28102.0 10.000000 -1 root
1 2 0 15764.0 37230.0 28102.0 18.284300 1 slab
2 3 0 15744.0 37190.0 28142.0 34.721401 2 slab
3 4 0 15744.0 37150.0 28182.0 34.721401 3 slab
4 5 0 15704.0 37130.0 28242.0 34.721401 4 slab

The methods (such as .reroot) are short-hands for main navis functions:

# Reroot neuron to another node
n2 = n.reroot(new_root=2)
# Print the new root -> expect "2"
n2.root
array([2])
# Instead of calling the shorthand method, we can also do this
n3 = navis.reroot_neuron(n, new_root=2)
n3.root
array([2])

NeuronLists

In practice you will likely work with multiple neurons at a time. For that, navis has a convenient container: NeuronLists

# Get more than one example neuron
nl = navis.example_neurons(5)

# `nl` is a NeuronList 
type(nl)
navis.core.neuronlist.NeuronList
# You can also create neuron lists yourself
my_nl = navis.NeuronList(n)

In many ways NeuronLists work like Python-lists with a couple of extras:

# Calling just the neuronlist produces a summary 
nl

type name id n_nodes n_connectors n_branches n_leafs cable_length soma units
0 navis.TreeNeuron 1734350788 1734350788 4465 None 603 619 266457.994591 [4176] 8 nanometer
1 navis.TreeNeuron 1734350908 1734350908 4845 None 733 760 304277.007958 [6] 8 nanometer
2 navis.TreeNeuron 722817260 722817260 4336 None 635 658 274910.568784 None 8 nanometer
3 navis.TreeNeuron 754534424 754534424 4702 None 697 727 286742.998887 [4] 8 nanometer
4 navis.TreeNeuron 754538881 754538881 4890 None 626 642 291434.992623 [703] 8 nanometer
# Get a single neuron from the neuronlist
nl[1]

type navis.TreeNeuron
name 1734350908
id 1734350908
n_nodes 4845
n_connectors None
n_branches 733
n_leafs 760
cable_length 304277.007958
soma [6]
units 8 nanometer

neuronlists also support fancy indexing similar to numpy arrays:

# Get multiple neurons from the neuronlist
nl[[1, 2]]

type name id n_nodes n_connectors n_branches n_leafs cable_length soma units
0 navis.TreeNeuron 1734350908 1734350908 4845 None 733 760 304277.007958 [6] 8 nanometer
1 navis.TreeNeuron 722817260 722817260 4336 None 635 658 274910.568784 None 8 nanometer
# Slicing is also supported
nl[1:3]

type name id n_nodes n_connectors n_branches n_leafs cable_length soma units
0 navis.TreeNeuron 1734350908 1734350908 4845 None 733 760 304277.007958 [6] 8 nanometer
1 navis.TreeNeuron 722817260 722817260 4336 None 635 658 274910.568784 None 8 nanometer

Strings will be matched against the neurons’ names.

# Get neuron(s) by their name
nl['754534424']

type name id n_nodes n_connectors n_branches n_leafs cable_length soma units
0 navis.TreeNeuron 754534424 754534424 4702 None 697 727 286742.998887 [4] 8 nanometer

neuronlists have a special .idx indexer that let’s you select neurons by their ID

# Get neuron(s) by their ID 
# -> note that for example neurons name == id 
nl.idx[[754534424, 722817260]]

type name id n_nodes n_connectors n_branches n_leafs cable_length soma units
0 navis.TreeNeuron 754534424 754534424 4702 None 697 727 286742.998887 [4] 8 nanometer
1 navis.TreeNeuron 722817260 722817260 4336 None 635 658 274910.568784 None 8 nanometer
# Access properties across neurons -> returns numpy arrays
nl.n_nodes 
array([4465, 4845, 4336, 4702, 4890])

# Select neurons by given property
# -> this works with any boolean array 
nl[nl.n_nodes >= 4500]

type name id n_nodes n_connectors n_branches n_leafs cable_length soma units
0 navis.TreeNeuron 1734350908 1734350908 4845 None 733 760 304277.007958 [6] 8 nanometer
1 navis.TreeNeuron 754534424 754534424 4702 None 697 727 286742.998887 [4] 8 nanometer
2 navis.TreeNeuron 754538881 754538881 4890 None 626 642 291434.992623 [703] 8 nanometer

Exercises:

  1. Select the first and the last neuron in the neuronlist
  2. Select all neurons with a soma
  3. Select all neurons with a soma and less than 300,000 cable length

Further reading: https://navis.readthedocs.io/en/latest/source/tutorials/neurons_intro.html


Last modified December 30, 2021: final fixes for tables and images (28ad241)