NeuroM 1.1.0¶
NeuroM is a Python-based toolkit for the analysis and processing of neuron morphologies.
Contents¶
NeuroM Quick-Start¶
Install¶
Install the latest release:
$ pip install neurom
Install a specific version:
$ pip install neurom==1.2.3
Note
It is recommended that you install NeuroM
into a virtualenv.
See virtualenv setup for details on how to set that up.
See also
The installation instructions for more details and alternative installation methods.
Analyze, visualize, and check¶
The neurom
module has various helper functions and command line applications
to simplify loading neuron morphologies from files into neurom
data structures and
obtaining morphometrics, either from single or multiple neurons.
The functionality described here is limited, but it is hoped
that it will suffice for most analyses.
Extract morphometrics with neurom.get()
¶
These are some of the properties can be obtained for a single neurite type or for all
neurites regardless of type via the neurom.get()
function:
- Segment lengths
- Section lengths
- Segment radii
- Number of sections
- Number of sections per neurite
- Number of neurites
- Number of segments
- Local and remote bifurcation angles
- Section path distances
- Section radial distances
- Section branch orders
- Total neurite length
The usage is simple:
import neurom as nm
nrn = nm.load_neuron('some/data/path/morph_file0.swc')
nrn_ap_seg_len = nm.get('segment_lengths', nrn, neurite_type=nm.APICAL_DENDRITE)
pop = nm.load_neurons('some/data/path')
pop_ap_seg_len = nm.get('segment_lengths', pop, neurite_type=nm.APICAL_DENDRITE)
This function also allows obtaining the soma radius and surface area.
Iterate over neurites with neurom.iter_neurites()
¶
The neurom.iter_neurites()
function allows to iterate over the neurites
of a sungle neuron or a neuron population. It can also be applied to a single
neurite or a list of neurites. It allows to optionally pass a function to be
mapped onto each neurite, as well as a neurite filter function. In this example,
we apply a simple user defined function to the apical dendrites in a population:
import neurom as nm
def user_func(neurite):
print 'Analysinz neurite', neurite
return len(neurite.points)
stuff = [x for x in nm.iter_neurites(pop, user_func, lambda n : n.type == nm.APICAL_DENDRITE)]
See also
The neurom
documentation for more details and examples.
View neurons with neurom.viewer
¶
There are also helper functions to plot a neuron in 2 and 3 dimensions.
The neurom.viewer.draw()
function allows the user to make two and three-dimensional
plots of neurites, somata and neurons. It also has a dendrogram neurom plotting mode.
See also
The neurom.viewer
documentation for more details and examples.
Extract morphometrics into JSON files¶
The morph_stats application lets you obtain various morphometrics
quantities from a set of morphology files. It is highly configurable, and gives access
to all the features avaulable via the neurom.get()
function.
For example,
$ morph_stats some/path/morph.swc # single file
{
"some/path/morph.swc":{
"axon":{
"total_section_length":207.87975220908129,
"max_section_length":11.018460736176685,
"max_section_branch_order":10,
"total_section_volume":276.73857657289523
},
"all":{
"total_section_length":840.68521442251949,
"max_section_length":11.758281556059444,
"max_section_branch_order":10,
"total_section_volume":1104.9077419665782
},
"mean_soma_radius":0.17071067811865476,
"apical_dendrite":{
"total_section_length":214.37304577550353,
"max_section_length":11.758281556059444,
"max_section_branch_order":10,
"total_section_volume":271.9412385728449
},
"basal_dendrite":{
"total_section_length":418.43241643793476,
"max_section_length":11.652508126101711,
"max_section_branch_order":10,
"total_section_volume":556.22792682083821
}
}
}
$ morph_stats some/path # all files in directory
See also
Check data validity¶
The morph_check application applies some structural and semantic checks to morphology data files in order to determine whether it is suitable to construct a neuron structure and whether certain defects within the structure are detected. It can be invoked from the command line, and takes as main argument the path to either a single file or a directory of morphology files.
For example,
$ morph_check some/path/morph.swc # single file
INFO: ========================================
INFO: File: test_data/swc/Neuron.swc
INFO: Is single tree PASS
INFO: Has soma points PASS
INFO: No missing parents PASS
INFO: Has sequential ids PASS
INFO: Has increasing ids PASS
INFO: Has valid soma PASS
INFO: Has valid neurites PASS
INFO: Has basal dendrite PASS
INFO: Has axon PASS
INFO: Has apical dendrite PASS
INFO: Has all nonzero segment lengths PASS
INFO: Has all nonzero section lengths PASS
INFO: Has all nonzero neurite radii PASS
INFO: Has nonzero soma radius PASS
INFO: ALL PASS
INFO: ========================================
$ morph_check test_data/swc # all files in directory
# loops over all morphology files found in test_data/swc
See also
Applications¶
NeuroM ships with configurable command line applications for commonly needed
functionality. These are convenience tools which leverage NeuroM
library funtionality
without users having to concern themselves with writing any code beyond simple and optional
configuration scripts. These commanline tools are installed as executable scripts with
NeuroM
. The tools are designed to be used in batch mode, i.e. they do not require any
user interactivity upon launch, and do not require access to a display.
morph_check: the morphology checker¶
The morph_check
application performs checks on reconstructed morphologies from
data contained in morphology files, and so may be used as a morphology validaiton
of sorts.
The tests are grouped in two categories:
- Structural tests. These apply to the structure of the data and are a good indicator as to whether a neuron object or any of its sub-components can actually be reconstructed. Failure in some of these may make further tests fail.
- Neuron tests. These are applied to properties of reconstructed neurons and their constituent soma and neurites, and can be thought of as “quality” checks.
It is very likely that a failure in the structural tests will make the neuron tests fail. Furthermore, inability to build a soma typically results in an inability to build neurites. Failure to build a soma or neurites results in an early faulure for a given morphology file.
The application may be invoked with a YAML configuration file specifying which checks to perform. The structure of the configuration file reflects the test categories mentioned above. Here is an example configuration:
checks:
structural_checks:
- is_single_tree
- has_soma_points
- has_valid_soma
- has_valid_neurites
neuron_checks:
- has_basal_dendrite
- has_axon
- has_all_nonzero_segment_lengths
- has_all_nonzero_section_lengths
- has_all_nonzero_neurite_radii
- has_nonzero_soma_radius
options :
has_nonzero_soma_radius : 0.0
has_all_nonzero_neurite_radii : 0.007
has_all_nonzero_segment_lengths : 0.01
has_all_nonzero_section_lengths : 0.01
As can be seen, the configuration file is split into two sections checks
, and options
.
Each of the checks
sub-items corresponds to a sub-module of neurom.check
, namely
structural_checks
and neuron_checks
. And each
of their sub-items corresponds to a function in that sub-module. This illustrates the possible
checks that may be applied by morph_check
.
The application also produces a summary json file, which can be useful when processing more than one file:
{
"files": {
"test_data/swc/Neuron.swc": {
"Is single tree": true,
"Has soma points": true,
"No missing parents": true,
"Has sequential ids": true,
"Has increasing ids": true,
"Has valid soma": true,
"Has valid neurites": true,
"Has basal dendrite": true,
"Has axon": true,
"Has apical dendrite": true,
"Has all nonzero segment lengths": true,
"Has all nonzero section lengths": true,
"Has all nonzero neurite radii": true,
"Has nonzero soma radius": true,
"ALL": true
}
},
"STATUS": "PASS"
}
For more information on the application and available options, invoke it with the --help
or -h
option.
morph_check --help
morph_stats: morphometric statistics extraction¶
The morph_stats
application extracts morphometrics from a set of neuron morphology
files and produces a summary in JSON or CSV format. It may obtain any of the morphometrics available
in the neurom.get()
function, and is highly configurable, allowing the user to get
raw or summary statistics from a large set of neurite and neuron features.
The functionality can be best explained by looking at a sample configuration file:
neurite:
section_lengths:
- max
- total
section_volumes:
- total
section_branch_orders:
- max
neurite_type:
- AXON
- APICAL_DENDRITE
- BASAL_DENDRITE
- ALL
neuron:
soma_radii:
- mean
Here, there are two feature categories,
neurite
: these are morphometrics obtained from neurites, e.g. branch orders, section lengths, bifurcation angles, path lengths.neuron
: these are morphometrics that can be applied to a whole neuron, e.g. the soma radius, the trunk radii, etc.
Each category sub-item (section_lengths, soma_radii, etc) corresponds to a
neurom.get()
feature, and each one of its sub-items corresponds to a statistic, e.g.
raw
: array of raw valuesmax
,min
,mean
,median
,std
: self-explanatory.total
: sum of the raw values
An additional field neurite_type
specifies the neurite types into which the morphometrics
are to be split. This is a sample output using the above configuration:
{
"some/path/morph.swc":{
"mean_soma_radius":0.17071067811865476,
"axon":{
"total_section_length":207.87975220908129,
"max_section_length":11.018460736176685,
"max_section_branch_order":10,
"total_section_volume":276.73857657289523
},
"all":{
"total_section_length":840.68521442251949,
"max_section_length":11.758281556059444,
"max_section_branch_order":10,
"total_section_volume":1104.9077419665782
},
"apical_dendrite":{
"total_section_length":214.37304577550353,
"max_section_length":11.758281556059444,
"max_section_branch_order":10,
"total_section_volume":271.9412385728449
},
"basal_dendrite":{
"total_section_length":418.43241643793476,
"max_section_length":11.652508126101711,
"max_section_branch_order":10,
"total_section_volume":556.22792682083821
}
}
}
For more information on the application and available options, invoke it with the --help
or -h
option.
morph_stats --help
NeuroM morphology definitions¶
These are NeuroM
specific working definitions of various components of
neuron morpholigies.
Point¶
A point is a vector of numbers [X, Y, Z, R, TYPE, ID, PID] where the components are
- X, Y, Z: Cartesian coordinates of position
- R: Radius
- TYPE: One of the
NeuroM valid point types
- ID: Unique identifier of the point.
- PID: ID of the parent of the point.
Typically only the first four or five components are of interest to morphology analysis. The rest are used to construct the soma and hierarchical tree structures of the neuron, and to check its semantic validity.
In NeuroM
a point is represented as an iterable of floating point numbers, usually
a numpy
array.
Note
For most of what follows, it suffices to consider a point as a vector of [X, Y, Z, R, TYPE]. The remaining components ID and PID can be considered book-keeping.
Todo
Point types may need to be restricted to align SWC with H5. This is dependent on future H5 specs.
Segment¶
A segment consists of two consecutive points belonging to the same neurite and section.
In NeuroM
a segment is represented as a length 2 tuple or numpy array of
points<point-label>.
Section¶
A section is a tree node containing a series of two or more points whose first and last element are any of the following combinations:
- root node, forking point
- forking point, forking point
- forking point, end point
- root node, end point
The first point of a section is a duplicate of the last point of its parent section, unless the latter is a soma section.
In NeuroM
, a section is represented by class Section
.
This pseudocode shows the relevant parts of the section class:
section = {
section_id,
points,
parent,
children
}
Soma¶
A soma can be represented by one, three or more points. The soma is classified solely based on the number of points it contains thus:
- Type A: 1 point defining the center and radius.
- Type B: 3 points. Only the centers of the points are considered. The first point defines the center. The radius is estimated from the mean distance between the center and the two remaining points.
- Type C: More than three points. The center is defined as the mean position of all points. The radius is defined as the mean distance of all points to the center.
Todo
Expand list if and when specifications require new types of soma.
The soma is represented by classes derived from Soma
.
The interface exports a center and radius. These can be calculated in different
ways, but the default is to use the center and radius for type A and the mean center
and radius for types B and C.
Todo
In the future, type B may be interpreted as 3 points on an ellipse. In this case, the points would have to be non-collinear. Currently there is no such restriction.
See also
See also
Neurite tree¶
A neurite is essentially a tree of sections. The tree structure implies the following:
- A node can only have one parent.
- A node can have an arbitrary number of children.
- No loops are present in the structure.
Neurites are represented by the class Neurite
, which contains
the root node of the aforementioned tree as well as some helper functions to aid iteration
over sections and collection of points.
In NeuroM
neurite trees are implemented using the recursive structure
neurom.fst.Section
, described above.
Neuron¶
A neuron structure consists of a single soma and a collection of neurites.
The trees that are expected to be present depend on the type of cell:
- Interneuron (IN): basal dendrite, axon
- Pyramidal cell (PC): basal dendrite, apical dendrite, axon
Neurons are represented by the class Neuron
. This is more
or less what it looks like:
neuron = {
soma,
neurites,
points,
name
}
Code Documentation¶
Public API¶
The public API is the stable, minimal set of entry points for end-users and developers who build code on top of NeuroM.
neurom |
NeuroM neurom morphology analysis package |
neurom.viewer |
Tools to visualize neuron morphological objects |
neurom.core |
Core functionality and data types of NeuroM |
neurom.io |
IO operations module for NeuroM |
neurom.check |
Basic tools to check neuronal morphologies. |
neurom.stats |
Statistical analysis helper functions |
neurom.exceptions |
Module containing NeuroM specific exceptions |
Developer API¶
The developer API consists of implementation code supporting the public API, as well as rough experimental code that is not stable enough to be made public. This is intended for developers of NeuroM itself.
neurom.morphmath |
Mathematical and geometrical functions used to compute morphometrics |
neurom.fst |
NeuroM, lightweight and fast |
neurom.fst.sectionfunc |
Section functions and functional tools |
neurom.check.structural_checks |
Module with consistency/validity checks for raw data blocks |
neurom.check.neuron_checks |
NeuroM neuron checking functions. |
neurom.core.types |
Type enumerations |
neurom.core.tree |
Generic tree class and iteration functions |
neurom.core._neuron |
Neuron classes and functions |
neurom.core._soma |
Soma classes and functions |
neurom.core.point |
Point classes and functions |
neurom.core.dataformat |
Data format definitions |
neurom.io.utils |
Utility functions and for loading neurons |
neurom.io.swc |
Module for morphology SWC data loading |
neurom.io.hdf5 |
Module for morphology HDF5 data loading |
neurom.view |
View tools to visualize morphologies |
neurom.view.common |
Module containing the common functionality to be used by view-plot modules. |
neurom.view.view |
Python module of NeuroM to visualize morphologies |
Supported file formats¶
NeuroM currently supports the SWC format, the BBP HDF5 formats, and offers experimental support for NeuroLucida .asc files.
See also
The morphology definitions page for definitions of concepts such as point, section, soma and neurite in NeuroM.
Todo
Complete this section with additional NeuroM specific restrictions on the formats below.
SWC¶
The SWC format represents a neuron as a set of trees that are connected to a soma. The neuronal morphology is encoded as a rooted tree of 3D points and the corresponding radii. More information can be found here.
Note
The following information about SWC format concern the standard representation as it has been established in the neuromorpho.org database. This file format is not yet supported by NeuroM, but it may be modified to do so in the future. Currently, NeuroM does not enforce all the semantic restrictions for the different soma representations, and is therefore more permissive.
The points of type “1” that represent the soma, have to be in the beginning of the file. The soma can be represented in one of the following formats:
TypeA: One point soma¶
The soma is represented by its center and a radius that corresponds to the sphere that preserves the surface area of the soma. The center of the soma has as parent ID -1 and all the initial points of the neuronal trees are connected to the soma.
TypeB: Three point soma¶
The soma is represented by three points that correspond to the center of the soma (x, y, z), with parent ID -1, and two diametrically opposite points (x, y-r, z) and (x, y+r, z), where r is the radius of the sphere that preserves the surface area of the soma. The radii of the soma points are not necessarily meaningful, so they can be set to zero. As such, they should not be taken into account in further calculations. The other two of the soma points are connected to the center of the soma, as well as the first points of all the neuronal trees.
TypeC: N - points soma¶
The soma is represented by a set of points. The first point of the soma has as parent ID -1. The other points define a contour of the soma in the maximum cross-section of the x-y plane. The radii of the soma points are not necessarily meaningful, so they can be set to zero. As such, they should not be taken into account in further calculations. The radius of the soma is computed from the equivalent sphere that preserves the surface area of the soma. The first points of all the neuronal trees have as parent one of the soma points.
Tree sections¶
It is not considered a good practice to represent the same section of the tree in different places within a file, but it is not forbidden. The parent ID should always be smaller that the current ID of a point.
Todo
Add reference to SWC paper and more semantic constraints.
Todo
Add semantic constraints on different soma types once these have been determined. For more info on what is to be considered, see neuromorpho.org’s.
HDF5¶
The HDF5 morphology formats developed by the BBP represent the neuron as a tree of sections. The specifications for the two versions of the format cn be found in the HBP morphology format documentation page.
NeuroLucida (experimental)¶
The NeuroLucida .asc file format is commonly used but lacking in an open format specification. NeuroM provides a best-effort experimental reader that parses information equivalent to the two formats above, that is to say, it does not deal with annotations or other meta-data, and is restricted purely to the topological and geometrical features of a neuron, as well as the neurite type information.
Warning
The NeuroLucida parser is experimental. Use at own risk when extracting numerical information. We make no statement as to the correctness of numerical output.
Todo
References and more information?
Installation¶
It is recommended that you use pip version 8.1.0
or higher to install into
NeuroM
into a virtualenv. For details on
how to set it up, see Virtualenv setup
Once the virtualenv is set up is set up,
there are three ways to install NeuroM
- From the official Python Package Index server (PyPI)
- From the git repository
- From source (for NeuroM developers)
Install from the official PyPI server¶
Install the latest release:
(nrm)$ pip install neurom
Install a specific version:
(nrm)$ pip install neurom==1.2.3
Install from git¶
Install a particular release:
(nrm)$ pip install git+https://github.com/BlueBrain/NeuroM.git@v0.1.0
Install the latest version:
(nrm)$ pip install git+https://github.com/BlueBrain/NeuroM.git
Install from source¶
Clone the repository and install it:
(nrm)$ git clone https://github.com/BlueBrain/NeuroM.git
(nrm)$ pip install -e ./NeuroM
This installs NeuroM
into your virtualenv
in “editable” mode. That means
that changes made to the source code after the installation procedure are seen by the
installed package. To install in read-only mode, omit the -e
.
Virtualenv setup¶
$ virtualenv --system-site-packages nrm # creates a virtualenv called "nrm" in nrm directory
$ source nrm/bin/activate # activates virtualenv
(nrm)$ # now we are in the nrm virtualenv
Here, the --system-site-packages
option has been used. This is because dependencies such as
matplotlib
aren’t trivial to build in a virtualenv
. This setting allows python packages
installed in the system to be used inside the virtualenv
.
The prompt indicates that the virtualenv
has been activated.
For efficient installation of dependencies with C extensions, it is recommended to
use pip
version 8 or higher. You can check your virtuanenv
‘s version
with pip --version
, and upgrade if it is too low:
$(nrm) pip --version # Check pip version. Should output version >= 8.0.0
$(nrm) pip install --upgrade pip # Install newest pip inside virtualenv if version too old.
$(nrm) pip --version # New version should be >= 8.0.0
This will allow use of pre-compiled python packages most platforms.
To de-activate the virtualenvr run the deactivate
command:
(nrm)$ deactivate
Note that you do not have to work in the nrm
directory. This is where python
packages will get installed, but you can work anywhere on your file system, as long as
you have activated the virtualenv
.
Note
In following code samples, the prompts (nrm)$
and $
are used to indicate
that the user virtualenv is activated or deactivated respectively.
Note
In following code samples, the prompt >>>
indicates a python interpreter session
started with the virtualenv activated. That gives access to the neurom
installation.
Examples¶
Fast analysis with neurom
¶
Here we load a neuron and obtain some information from it:
>>> import neurom as nm
>>> nrn = nm.load_neuron('some/data/path/morph_file.swc')
>>> ap_seg_len = nm.get('segment_lengths', nrn, neurite_type=nm.APICAL_DENDRITE)
>>> ax_sec_len = nm.get('section_lengths', nrn, neurite_type=nm.AXON)
Morphology visualization with the neurom.viewer
module¶
Here we visualize a neuronal morphology:
>>> # Initialize nrn as above
>>> from neurom import viewer
>>> fig, ax = viewer.draw(nrn)
>>> fig.show()
>>> fig, ax = viewer.draw(nrn, mode='3d') # valid modes '2d', '3d', 'dendrogram'
>>> fig.show()
Basic feature extraction example¶
These basic examples illustrate the type of morphometrics that can be easily obtained
directly from the neurom
module, without the need for any other neurom
sub-modules or tools.
The idea here is to pre-package the most common analyses so that users can obtain the
morphometrics with a very minimal knowledge of python
and neurom
.
'''Easy analysis examples
These examples highlight most of the pre-packaged neurom.nm.get
morphometrics functionality.
'''
from __future__ import print_function
from pprint import pprint
import numpy as np
import neurom as nm
def stats(data):
'''Dictionary with summary stats for data
Returns:
dicitonary with length, mean, sum, standard deviation,\
min and max of data
'''
return {'len': len(data),
'mean': np.mean(data),
'sum': np.sum(data),
'std': np.std(data),
'min': np.min(data),
'max': np.max(data)}
def pprint_stats(data):
'''Pretty print summary stats for data'''
pprint(stats(data))
if __name__ == '__main__':
filename = 'test_data/swc/Neuron.swc'
# load a neuron from an SWC file
nrn = nm.load_neuron(filename)
# Get some soma information
# Soma radius and surface area
print("Soma radius", nm.get('soma_radii', nrn)[0])
print("Soma surface area", nm.get('soma_surface_areas', nrn)[0])
# Get information about neurites
# Most neurite data can be queried for a particular type of neurite.
# The allowed types are members of the NeuriteType enumeration.
# NEURITE_TYPES is a list of valid neurite types.
# We start by calling methods for different neurite types separately
# to warm up...
# number of neurites
print('Number of neurites (all):', nm.get('number_of_neurites', nrn)[0])
print('Number of neurites (axons):',
nm.get('number_of_neurites', nrn, neurite_type=nm.NeuriteType.axon)[0])
print('Number of neurites (apical dendrites):',
nm.get('number_of_neurites', nrn, neurite_type=nm.NeuriteType.apical_dendrite)[0])
print('Number of neurites (basal dendrites):',
nm.get('number_of_neurites', nrn, neurite_type=nm.NeuriteType.basal_dendrite)[0])
# number of sections
print('Number of sections:',
nm.get('number_of_sections', nrn)[0])
print('Number of sections (axons):',
nm.get('number_of_sections', nrn, neurite_type=nm.NeuriteType.axon)[0])
print('Number of sections (apical dendrites):',
nm.get('number_of_sections', nrn, neurite_type=nm.NeuriteType.apical_dendrite)[0])
print('Number of sections (basal dendrites):',
nm.get('number_of_sections', nrn, neurite_type=nm.NeuriteType.basal_dendrite)[0])
# number of sections per neurite
print('Number of sections per neurite:',
nm.get('number_of_sections_per_neurite', nrn))
print('Number of sections per neurite (axons):',
nm.get('number_of_sections_per_neurite', nrn, neurite_type=nm.NeuriteType.axon))
print('Number of sections per neurite (apical dendrites):',
nm.get('number_of_sections_per_neurite',
nrn, neurite_type=nm.NeuriteType.apical_dendrite))
print('Number of sections per neurite (basal dendrites):',
nm.get('number_of_sections_per_neurite',
nrn, neurite_type=nm.NeuriteType.apical_dendrite))
# OK, this is getting repetitive, so lets loop over valid neurite types.
# The following methods return arrays of measurements. We will gather some
# summary statistics for each and print them.
# Section lengths for all and different types of neurite
for ttype in nm.NEURITE_TYPES:
sec_len = nm.get('section_lengths', nrn, neurite_type=ttype)
print('Section lengths (', ttype, '):', sep='')
pprint_stats(sec_len)
# Segment lengths for all and different types of neurite
for ttype in nm.NEURITE_TYPES:
seg_len = nm.get('segment_lengths', nrn, neurite_type=ttype)
print('Segment lengths (', ttype, '):', sep='')
pprint_stats(seg_len)
# Section radial distances for all and different types of neurite
# Careful! Here we need to pass tree type as a named argument
for ttype in nm.NEURITE_TYPES:
sec_rad_dist = nm.get('section_radial_distances', nrn, neurite_type=ttype)
print('Section radial distance (', ttype, '):', sep='')
pprint_stats(sec_rad_dist)
# Section path distances for all and different types of neurite
# Careful! Here we need to pass tree type as a named argument
for ttype in nm.NEURITE_TYPES:
sec_path_dist = nm.get('section_path_distances', nrn, neurite_type=ttype)
print('Section path distance (', ttype, '):', sep='')
pprint_stats(sec_path_dist)
# Local bifurcation angles for all and different types of neurite
for ttype in nm.NEURITE_TYPES:
local_bifangles = nm.get('local_bifurcation_angles', nrn, neurite_type=ttype)
print('Local bifurcation angles (', ttype, '):', sep='')
pprint_stats(local_bifangles)
# Remote bifurcation angles for all and different types of neurite
for ttype in nm.NEURITE_TYPES:
rem_bifangles = nm.get('remote_bifurcation_angles', nrn, neurite_type=ttype)
print('Local bifurcation angles (', ttype, '):', sep='')
pprint_stats(rem_bifangles)
Advanced iterator-based feature extraction example¶
These slightly more complex examples illustrate what can be done with the neurom
module’s various generic iterators and simple morphometric functions.
The idea here is that there is a great deal of flexibility to build new analyses based
on some limited number of orthogonal iterator and morphometric components that can
be combined in many ways. Users with some knowledge of python
and neurom
can easily
implement code to obtain new morphometrics.
All of the examples in the previous sections can be implemented in a similar way to those presented here.
'''Advanced analysis examples
These examples highlight more advanced neurom
morphometrics functionality using iterators.
'''
from __future__ import print_function
from neurom.core.dataformat import COLS
import neurom as nm
from neurom import geom
from neurom.fst import iter_sections, iter_segments, sectionfunc
from neurom.core import Tree
from neurom.core.types import tree_type_checker, NEURITES
from neurom import morphmath as mm
import numpy as np
if __name__ == '__main__':
filename = 'test_data/swc/Neuron.swc'
# load a neuron from an SWC file
nrn = nm.load_neuron(filename)
# Some examples of what can be done using iteration
# instead of pre-packaged functions that return lists.
# The iterations give us a lot of flexibility: we can map
# any function that takes a segment or section.
# Get of all neurites in cell by iterating over sections,
# and summing the section lengths
def sec_len(sec):
'''Return the length of a section'''
return mm.section_length(sec.points)
print('Total neurite length (sections):',
sum(sec_len(s) for s in iter_sections(nrn)))
# Get length of all neurites in cell by iterating over segments,
# and summing the segment lengths.
# This should yield the same result as iterating over sections.
print('Total neurite length (segments):',
sum(mm.segment_length(s) for s in iter_segments(nrn)))
# get volume of all neurites in cell by summing over segment
# volumes
print('Total neurite volume:',
sum(mm.segment_volume(s) for s in iter_segments(nrn)))
# get area of all neurites in cell by summing over segment
# areas
print('Total neurite surface area:',
sum(mm.segment_area(s) for s in iter_segments(nrn)))
# get total number of neurite points in cell.
def n_points(sec):
'''number of points in a section'''
n = len(sec.points)
# Non-root sections have duplicate first point
return n if sec.parent is None else n - 1
print('Total number of points:',
sum(n_points(s) for s in iter_sections(nrn)))
# get mean radius of neurite points in cell.
# p[COLS.R] yields the radius for point p.
# Note: this includes duplicated points at beginning of
# non-trunk sections
print('Mean radius of points:',
np.mean([s.points[:, COLS.R] for s in iter_sections(nrn)]))
# get mean radius of neurite points in cell.
# p[COLS.R] yields the radius for point p.
# Note: this includes duplicated points at beginning of
# non-trunk sections
pts = [p[COLS.R] for s in nrn.sections[1:] for p in s.points]
print('Mean radius of points:',
np.mean(pts))
# get mean radius of segments
print('Mean radius of segments:',
np.mean(list(mm.segment_radius(s) for s in iter_segments(nrn))))
# get stats for the segment taper rate, for different types of neurite
for ttype in NEURITES:
ttt = ttype
seg_taper_rate = [mm.segment_taper_rate(s)
for s in iter_segments(nrn, neurite_filter=tree_type_checker(ttt))]
print('Segment taper rate (', ttype,
'):\n mean=', np.mean(seg_taper_rate),
', std=', np.std(seg_taper_rate),
', min=', np.min(seg_taper_rate),
', max=', np.max(seg_taper_rate),
sep='')
# Number of bifurcation points.
print('Number of bifurcation points:',
sum(1 for _ in iter_sections(nrn,
iterator_type=Tree.ibifurcation_point)))
# Number of bifurcation points for apical dendrites
print('Number of bifurcation points (apical dendrites):',
sum(1 for _ in iter_sections(nrn,
iterator_type=Tree.ibifurcation_point,
neurite_filter=tree_type_checker(nm.APICAL_DENDRITE))))
# Maximum branch order
print('Maximum branch order:',
max(sectionfunc.branch_order(s) for s in iter_sections(nrn)))
# Neuron's bounding box
# Note: does not account for soma radius
print('Bounding box ((min x, y, z), (max x, y, z))', geom.bounding_box(nrn))
Reporting issues¶
Issues should be reported to the NeuroM github repository issue tracker. The ability and speed with which issues can be resolved depends on how complete and succinct the report is. For this reason, it is recommended that reports be accompanied with
- A minimal but self-contained code sample that reproduces the issue. Minimal means no code that is irrelevant to the issue should be included. Self-contained means it should be possible to run the code without modifications and reproduce the problem.
- The observed and expected output and/or behaviour. If the issue is an error, the python error stack trace is extremely useful.
- The commit ID of the version used. This is particularly important if reporting an error from an older version of NeuroM.
- If reporting a regression, the commit ID of the change that introduced the problem
- If the issue depends on data, a data sample which reproduces the problem should be
up-loaded. But check first whether the error can be reproduced with any of the data
samples available in the
test_data
directory.
Developer Documentation¶
Development Workflow¶
- Fork from github
- Develop on your fork
- Test locally
- Make a pull request
Before making a pull request, make sure that your fork is up to date and that all the tests pass locally. This will make it less likely that your pull request will get rejected by making breaking chages or by failing the test requirements.
Running the tests¶
The tests require that you have cloned the repository, since the test code is
not distributed in the package. It is recommended to use nosetests
for
this. There are two options:
Use the provided Makefile
to run the tests using make
:
$ git clone https://github.com/BlueBrain/NeuroM.git
$ cd NeuroM
$ make test
This runs pep8
, pylint
and the unit tests in sequence.
This method takes care of
installing all extra dependencies needed for running the tests, diagnosing the results,
performing linting on the source code. These dependencies are installed into a
virtuanelv
named neurom_test_venv
:
The Makefile
also has targets for running only pylint and pep8 individually:
$ make lint # runs pep8 and pylint if that succeeds
$ make run_pep8 # run only pep8
$ make run_pylint # run only pep8
Note that you can also install the test dependencies and run the tests inside of your own virtualenv:
(nrm)$ pip install -r requirements_dev.txt
This installs the following packages into your virtualenv
unless they are already installed:
enum34>=1.0.4
mock>=1.3.0
pep8>=1.6.0
astroid>=1.3,<1.4
pylint>=1.4.0,<1.5
nose>=1.3.0
coverage==3.7
nosexcover>=1.0.8
Then, run the tests manually in the virtualenv
. For example,
(nrm)$ nosetests -v --with-coverage --cover-min-percentage=100 --cover-package neurom
Warning
To ensure that the test requirements are the same as those run in continuous
integration, you should run the tests using the make test
command. This is the
same command used in continuous integration. Failure to pass means will result in
a pull request being rejected.
Building the Documentation¶
The documentation requires that you clone the repository. Once you have done that,
there’s a make
target to build the HTML version of the documentation:
$ git clone https://github.com/BlueBrain/NeuroM.git
....
$ cd NeuroM # repository location
$ make doc
This builds the documentation in doc/build
.
To view it, point a browser at doc/build/html/index.html
Dependencies¶
Build and runtime¶
NeuroM
requires Python version 2.6 or higher (but not version 3.x).
When installed using pip, NeuroM
will take care of installing unmet dependencies.
However, for best performance, it may be preferable to pre-install the following
subset into your system before installing NeuroM
. These typically have installation
packages available for must common Linux distributions and Mac OSX:
These remaining dependencies are lightweight and can be left to the automatic installation:
Installing and building¶
- pip version 8.1.0 or higher.
- virtualenv
License¶
Copyright © 2015, Ecole Polytechnique Federale de Lausanne, Blue Brain Project All rights reserved.
This file is part of NeuroM <https://github.com/BlueBrain/NeuroM>
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
- Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
- Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.