Welcome to NNGT’s documentation!¶
Introduction¶
Yet another graph library?¶
It is not ;)
This library is based on existing graph libraries (such as graph_tool, and possibly soon SNAP) and acts as a convenient interface to build various networks from efficient and verified algorithms.
Moreover, it also acts as an interface between those graph libraries and the NEST simulator.
Description¶
- Neural networks are described by four container classes:
Graph
: container for simple topological graphs with no spatial structure, nor biological propertiesSpatialGraph
: container for spatial graphs without biological propertiesNetwork
: container for topological graphs with biological properties (to interact with NEST)SpatialNetwork
: container with spatial and biological properties (to interact with NEST)
Using these objects, the user can access to a the graph
attribute, which contains the topological structure of the network (including the connections’ type – inhibitory or excitatory – and its weight which is always positive)
Warning
This object should never be directly modified through its methods but rather using those of the four containing classes. The only reason to access this object should be to perform graph-theoretical measurements on it which do not modify its structure; any other action will lead to undescribed behaviour.
Nodes/neurons are defined by a unique index which can be used to access their properties and those of the connections between them.
- In addition to
graph
, the containers can have other attributes, such as: shape
forSpatialGraph
: andSpatialNetwork
:, which describes the spatial delimitations of the neurons’ environment (e.g. many in vitro culture are contained in circular dishes).population
which contains informations on the various groups of neurons that exist in the network (for instance inhibitory and excitatory neurons can be grouped together)connections
which stores the informations about the synaptic connections between the neurons
Graph-theoretical models¶
Several classical graphs are efficiently implemented and the generation procedures are detailed in the documentation.
Main module¶
For more details regarding the main classes, see:
Graph container classes¶
-
class
nngt.
Graph
(nodes=0, name='Graph', weighted=True, directed=True, libgraph=None, **kwargs)[source] The basic class that contains a
graph_tool.Graph
and some of is properties or methods to easily access them.Variables: -
add_edges
(lst_edges)[source] Add a list of edges to the graph.
Parameters: - lst_edges (list of 2-tuples or np.array of shape (edge_nb, 2)) – List of the edges that should be added as tuples (source, target)
- @todo (add example, check the edges for self-loops and multiple edges)
-
adjacency_matrix
(typed=True, weighted=True)[source] Returns the adjacency matrix of the graph as a
scipy.sparse.csr_matrix
.Parameters: weighted (bool or string, optional (default: True)) – If True, each entry adj[i,j] = w_ij
wherew_ij
is the strength of the connection from i to j, if False,adj[i,j] = 0. or 1.
. Weighted can also be a string describing an edge attribute (e.g. if “distance” refers to an edge attributedist
, thenajacency_matrix("distance")
will returnadj[i,i] = dist_ij
).Returns: adj ( scipy.sparse.csr_matrix
) – The adjacency matrix of the graph.
-
attributes
()[source] List of the graph’s attributes (synaptic weights, delays...)
-
clear_edges
()[source] Remove all the edges in the graph.
-
copy
()[source] Returns a deepcopy of the current
Graph
instance
-
edge_nb
()[source] Number of edges in the graph
-
edges
-
excitatory_subgraph
()[source] create a
Graph
instance which graph contains only the excitatory edges of the current instance’sGraphObject
-
get_betweenness
(use_weights=True)[source] Betweenness centrality sequence of all nodes and edges.
Parameters: use_weights (bool, optional (default: True)) – Whether to use weighted (True) or simple degrees (False). Returns: - node_betweenness (
numpy.array
) – Betweenness of the nodes. - edge_betweenness (
numpy.array
) – Betweenness of the edges.
- node_betweenness (
-
get_degrees
(node_list=None, deg_type='total', use_weights=True)[source] Degree sequence of all the nodes.
Parameters: - node_list (list, optional (default: None)) – List of the nodes which degree should be returned
- deg_type (string, optional (default: “total”)) – Degree type (among ‘in’, ‘out’ or ‘total’).
- use_weights (bool, optional (default: True)) – Whether to use weighted (True) or simple degrees (False).
Returns: numpy.array
or None (if an invalid type is asked).
-
get_density
()[source] Density of the graph: \(\frac{E}{N^2}\), where E is the number of edges and N the number of nodes.
-
get_edge_types
()[source]
-
get_name
()[source] Get the name of the graph
-
get_weights
()[source] Returns the weighted adjacency matrix as a
scipy.sparse.lil_matrix
.
-
graph
graph_tool.Graph
attribute of the instance
-
id
unique
int
identifying the instance
-
inhibitory_subgraph
()[source] Create a
Graph
instance which graph contains only the inhibitory edges of the current instance’sgraph_tool.Graph
-
is_directed
()[source] Whether the graph is directed or not
-
is_weighted
()[source] Whether the edges have weights
-
name
name of the graph
-
node_nb
()[source] Number of nodes in the graph
-
classmethod
num_graphs
()[source] Returns the number of alive instances.
-
set_edge_attribute
(attribute, values=None, val=None, value_type=None)[source]
-
set_name
(name='')[source] set graph name
-
set_weights
(elist=None, wlist=None, distrib=None, distrib_prop=None, correl=None, noise_scale=None)[source] Set the synaptic weights.
Parameters: - elist (class:numpy.array, optional (default: None)) – List of the edges (for user defined weights).
- wlist (class:numpy.array, optional (default: None)) – List of the weights (for user defined weights).
- distrib (class:string, optional (default: None)) – Type of distribution (choose among “constant”, “uniform”, “gaussian”, “lognormal”, “lin_corr”, “log_corr”).
- distrib_prop (dict, optional (default: {})) – Dictoinary containing the properties of the weight distribution.
- correl (class:string, optional (default: None)) – Property to which the weights should be correlated.
- noise_scale (class:int, optional (default: None)) – Scale of the multiplicative Gaussian noise that should be applied on the weights.
-
-
class
nngt.
SpatialGraph
(nodes=0, name='Graph', weighted=True, directed=True, libgraph=None, shape=None, positions=None, **kwargs)[source] The detailed class that inherits from
Graph
and implements additional properties to describe various biological functions and interact with the NEST simulator.Variables: - shape –
Shape
Shape of the neurons environment. - positions –
numpy.array
Positions of the neurons. - graph –
GraphObject
Main attribute of the class instance.
-
classmethod
make_spatial
(graph, shape=<nngt.core.graph_datastruct.Shape instance>, positions=None)[source]
-
position
-
shape
- shape –
-
class
nngt.
Network
(name='Graph', weighted=True, directed=True, libgraph=None, population=None, **kwargs)[source] The detailed class that inherits from
Graph
and implements additional properties to describe various biological functions and interact with the NEST simulator.Variables: - population –
NeuralPop
Object reparting the neurons into groups with specific properties. - graph –
GraphObject
Main attribute of the class instance - nest_gid –
numpy.array
Array containing the NEST gid associated to each neuron; it isNone
until a NEST network has been created. - id_from_nest_gid – dict
Dictionary mapping each NEST gid to the corresponding neuron index in
the
nngt.~Network
-
classmethod
ei_network
(size, ei_ratio=0.2, en_model='aeif_cond_alpha', en_param={}, es_model='static_synapse', es_param={}, in_model='aeif_cond_alpha', in_param={}, is_model='static_synapse', is_param={})[source] Generate a network containing a population of two neural groups: inhibitory and excitatory neurons.
Parameters: - size (int) – Number of neurons in the network.
- ei_ratio (double, optional (default: 0.2)) – Ratio of inhibitory neurons: \(\frac{N_i}{N_e+N_i}\).
- en_model (string, optional (default: ‘aeif_cond_alpha’)) – Nest model for the excitatory neuron.
- en_param (dict, optional (default: {})) – Dictionary of parameters for the the excitatory neuron.
- es_model (string, optional (default: ‘static_synapse’)) – NEST model for the excitatory synapse.
- es_param (dict, optional (default: {})) – Dictionary containing the excitatory synaptic parameters.
- in_model (string, optional (default: ‘aeif_cond_alpha’)) – Nest model for the inhibitory neuron.
- in_param (dict, optional (default: {})) – Dictionary of parameters for the the inhibitory neuron.
- is_model (string, optional (default: ‘static_synapse’)) – NEST model for the inhibitory synapse.
- is_param (dict, optional (default: {})) – Dictionary containing the inhibitory synaptic parameters.
Returns: net (
Network
or subclass) – Network of disconnected excitatory and inhibitory neurons.
-
static
make_network
(graph, neural_pop)[source] Turn a
Graph
object into aNetwork
, or aSpatialGraph
into aSpatialNetwork
.Parameters: - graph (
Graph
orSpatialGraph
) – Graph to convert - neural_pop (
NeuralPop
) – Population to associate to the newNetwork
Notes
In-place operation that directly converts the original graph.
- graph (
-
neuron_properties
(idx_neuron)[source] Properties of a neuron in the graph.
Parameters: idx_neuron (int) – Index of a neuron in the graph. Returns: dict of the neuron properties.
-
classmethod
num_networks
()[source] Returns the number of alive instances.
-
population
NeuralPop
that divides the neurons into groups with specific properties.
-
classmethod
uniform_network
(size, neuron_model='aeif_cond_alpha', neuron_param={}, syn_model='static_synapse', syn_param={})[source] Generate a network containing only one type of neurons.
Parameters: - size (int) – Number of neurons in the network.
- neuron_model (string, optional (default: ‘aief_cond_alpha’)) – Name of the NEST neural model to use when simulating the activity.
- neuron_param (dict, optional (default: {})) – Dictionary containing the neural parameters; the default value will make NEST use the default parameters of the model.
- syn_model (string, optional (default: ‘static_synapse’)) – NEST synaptic model to use when simulating the activity.
- syn_param (dict, optional (default: {})) – Dictionary containing the synaptic parameters; the default value will make NEST use the default parameters of the model.
Returns: net (
Network
or subclass) – Uniform network of disconnected neurons.
- population –
-
class
nngt.
SpatialNetwork
(population, name='Graph', weighted=True, directed=True, shape=None, graph=None, positions=None, **kwargs)[source] Class that inherits from
Network
andSpatialGraph
to provide a detailed description of a real neural network in space, i.e. with positions and biological properties to interact with NEST.Variables: - shape –
nngt.core.Shape
Shape of the neurons environment. - positions –
numpy.array
Positions of the neurons. - population –
NeuralPop
Object reparting the neurons into groups with specific properties. - graph –
GraphObject
Main attribute of the class instance. - nest_gid –
numpy.array
Array containing the NEST gid associated to each neuron; it isNone
until a NEST network has been created. - id_from_nest_gid – dict
Dictionary mapping each NEST gid to the corresponding neuron index in
the
nngt.~SpatialNetwork
- shape –
Side classes¶
-
class
nngt.
Shape
(parent=None)[source]¶ Class containing the shape of the area where neurons will be distributed to form a network.
-
area
¶ double
Area of the shape in mm^2.
-
com
¶ tuple of doubles
Position of the center of mass of the current shape.
-
add_subshape: void
Add a AGNet.generation.Shape to a preexisting one.
-
add_subshape
(subshape, position, unit='mm')[source]¶ Add a AGNet.generation.Shape to the current one.
Parameters: - subshape (AGNet.generation.Shape) – Length of the rectangle (by default in mm).
- position (tuple of doubles) – Position of the subshape’s center of gravity in space.
- unit (string (default ‘mm’)) – Unit in the metric system among ‘um’, ‘mm’, ‘cm’, ‘dm’, ‘m’
Returns: None
-
area
-
com
-
-
class
nngt.
NeuralPop
(size=None, parent=None, with_models=True, **kwargs)[source]¶ The basic class that contains groups of neurons and their properties.
Variables: has_models – bool
,True
if every group has amodel
attribute.-
classmethod
ei_population
(size, iratio=0.2, parent=None, en_model='aeif_cond_alpha', en_param={}, es_model='static_synapse', es_param={}, in_model='aeif_cond_alpha', in_param={}, is_model='static_synapse', is_param={})[source]¶ Make a NeuralPop with a given ratio of inhibitory and excitatory neurons.
-
has_models
¶
-
is_valid
¶
-
new_group
(name, id_list, ntype=1, neuron_model=None, neuron_param={}, syn_model='static_synapse', syn_param={})[source]¶
-
classmethod
pop_from_network
(graph, *args)[source]¶ Make a NeuralPop object from a network. The groups of neurons are determined using instructions from an arbitrary number of
GroupProperties
.
-
set_model
(model, group=None)[source]¶ Set the groups’ models.
Parameters: - model (dict) – Dictionary containing the model type as key (“neuron” or “synapse”) and the model name as value (e.g. {“neuron”: “iaf_neuron”}).
- group (list of strings, optional (default: None)) – List of strings containing the names of the groups which models should be updated.
- .. warning (:) – No check is performed on the validity of the models, which means that errors will only be detected when building the graph in NEST.
- .. note (:) –
By default, synapses are registered as “static_synapse”s in NEST;
because of this, only the
neuron_model
attribute is checked by thehas_models
function: it will answerTrue
if all groups have a ‘non-None’neuron_model
attribute.
-
set_param
(param, group=None)[source]¶ Set the groups’ parameters.
Parameters: - param (dict) – Dictionary containing the model type as key (“neuron” or “synapse”) and the model parameter as value (e.g. {“neuron”: {“C_m”: 125.}}).
- group (list of strings, optional (default: None)) – List of strings containing the names of the groups which models should be updated.
- .. warning (:) – No check is performed on the validity of the parameters, which means that errors will only be detected when building the graph in NEST.
-
size
¶
-
classmethod
NNGT¶
Neural Networks Growth and Topology analyzing tool.
- Provides algorithms for
- growing networks
- analyzing their activity
- studying the graph theoretical properties of those networks
Documentation is not yet really available. I will try to implement more extensive docstrings within the code. I recommend exploring the docstrings using IPython, an advanced Python shell with TAB-completion and introspection capabilities. See below for further instructions. The docstring examples assume that numpy has been imported as np:
>>> import numpy as np
Code snippets are indicated by three greater-than signs:
>>> x = 42
>>> x = x + 1
Use the built-in help
function to view a function’s docstring:
>>> help(nggt.GraphClass)
- core
- Contains the main network classes.
These are loaded in nngt at import so specifying
nngt.core
is not necessary - generation
- Functions to generate specific networks
- lib
- Basic functions used by several sub-packages.
- io
- @todo: Tools for input/output operations
- nest
- NEST integration tools
- growth
- @todo: Growing networks tools
- plot
- plot data or graphs (@todo) using matplotlib and graph_tool
- show_config
- @todo: Show build configuration
- version
- NNGT version string
Functions related to spatial embedding of networks are using milimeters (mm) as default unit; other units from the metric system can also be provided:
- um for micrometers
- cm centimeters
- dm for decimeters
- m for meters
-
class
nngt.
Graph
(nodes=0, name='Graph', weighted=True, directed=True, libgraph=None, **kwargs)[source]¶ The basic class that contains a
graph_tool.Graph
and some of is properties or methods to easily access them.Variables:
-
class
nngt.
SpatialGraph
(nodes=0, name='Graph', weighted=True, directed=True, libgraph=None, shape=None, positions=None, **kwargs)[source]¶ The detailed class that inherits from
Graph
and implements additional properties to describe various biological functions and interact with the NEST simulator.Variables: - shape –
Shape
Shape of the neurons environment. - positions –
numpy.array
Positions of the neurons. - graph –
GraphObject
Main attribute of the class instance.
- shape –
-
class
nngt.
Network
(name='Graph', weighted=True, directed=True, libgraph=None, population=None, **kwargs)[source]¶ The detailed class that inherits from
Graph
and implements additional properties to describe various biological functions and interact with the NEST simulator.Variables: - population –
NeuralPop
Object reparting the neurons into groups with specific properties. - graph –
GraphObject
Main attribute of the class instance - nest_gid –
numpy.array
Array containing the NEST gid associated to each neuron; it isNone
until a NEST network has been created. - id_from_nest_gid – dict
Dictionary mapping each NEST gid to the corresponding neuron index in
the
nngt.~Network
- population –
-
class
nngt.
SpatialNetwork
(population, name='Graph', weighted=True, directed=True, shape=None, graph=None, positions=None, **kwargs)[source]¶ Class that inherits from
Network
andSpatialGraph
to provide a detailed description of a real neural network in space, i.e. with positions and biological properties to interact with NEST.Variables: - shape –
nngt.core.Shape
Shape of the neurons environment. - positions –
numpy.array
Positions of the neurons. - population –
NeuralPop
Object reparting the neurons into groups with specific properties. - graph –
GraphObject
Main attribute of the class instance. - nest_gid –
numpy.array
Array containing the NEST gid associated to each neuron; it isNone
until a NEST network has been created. - id_from_nest_gid – dict
Dictionary mapping each NEST gid to the corresponding neuron index in
the
nngt.~SpatialNetwork
- shape –
Core module¶
Classes | |
---|---|
GraphClass | Main object |
SpatialGraph | Spatially-embedded graph |
Network | More detailed network that inherits from GraphClass |
SpatialNetwork | Spatially-embedded network |
InputConnect | Connectivity to input analogic signals on a graph |
GraphObject for subclassing the libraries graphs
Generation module¶
Functions that generates the underlying connectivity of graphs, as well as the synaptic properties (weight/strength and delay).
Functions (connectivity) | |
---|---|
erdos_renyi | Random graph studied by Erdos and Renyi |
random_free_scale | An uncorrelated free-scale graph |
price_free_scale | Price’s network (Barabasi-Albert if undirected) |
newman_watts | Newman-Watts small world network |
distance_rule | Distance-dependent connection probability |
Functions (weigths/delays) | |
---|---|
gaussian_eprop | Random gaussian distribution |
lognormal_eprop | Random lognormal distribution |
uniform_eprop | Random uniform distribution |
custom_eprop | User defined distribution |
correlated_fixed_eprop | Computed from an edge property |
correlated_proba_eprop | Randomly drawn, correlated to an edge property |
-
nngt.generation.
erdos_renyi
(nodes=0, density=0.1, edges=-1, avg_deg=-1.0, reciprocity=-1.0, weighted=True, directed=True, multigraph=False, name='ER', shape=None, positions=None, population=None, from_graph=None)[source]¶ Generate a random graph as defined by Erdos and Renyi but with a reciprocity that can be chosen.
Parameters: - nodes (int, optional (default: None)) – The number of nodes in the graph.
- density (double, optional (default: 0.1)) – Structural density given by edges / nodes\(^2\).
- edges (int (optional)) – The number of edges between the nodes
- avg_deg (double, optional) – Average degree of the neurons given by edges / nodes.
- reciprocity (double, optional (default: -1 to let it free)) – Fraction of edges that are bidirectional (only for directed graphs – undirected graphs have a reciprocity of 1 by definition)
- weighted (bool, optional (default: True)) – Whether the graph edges have weights.
- directed (bool, optional (default: True)) – Whether the graph is directed or not.
- multigraph (bool, optional (default: False)) – Whether the graph can contain multiple edges between two nodes.
- name (string, optional (default: “ER”)) – Name of the created graph.
- shape (
Shape
, optional (default: None)) – Shape of the neurons’ environment. - positions (
numpy.ndarray
, optional (default: None)) – A 2D or 3D array containing the positions of the neurons in space. - population (
NeuralPop
, optional (default: None)) – Population of neurons defining their biological properties (to create aNetwork
). - from_graph (
Graph
or subclass, optional (default: None)) – Initial graph whose nodes are to be connected.
Returns: graph_er (
Graph
, or subclass) – A new generated graph or the modified from_graph.Notes
nodes is required unless from_graph or population is provided. If an from_graph is provided, all preexistant edges in the object will be deleted before the new connectivity is implemented.
-
nngt.generation.
newman_watts
(coord_nb, proba_shortcut, nodes=0, directed=True, multigraph=False, name='ER', shape=None, positions=None, population=None, from_graph=None, **kwargs)[source]¶ Generate a small-world graph using the Newman-Watts algorithm. @todo: generate the edges of a circular graph to not replace the graph of the from_graph and implement chosen reciprocity.
Parameters: - coord_nb (int) – The number of neighbours for each node on the initial topological lattice.
- proba_shortcut (double) – Probability of adding a new random (shortcut) edge for each existing edge on the initial lattice.
- nodes (int, optional (default: None)) – The number of nodes in the graph.
- density (double, optional (default: 0.1)) – Structural density given by edges / (nodes`*`nodes).
- edges (int (optional)) – The number of edges between the nodes
- avg_deg (double, optional) – Average degree of the neurons given by edges / nodes.
- directed (bool, optional (default: True)) – Whether the graph is directed or not.
- multigraph (bool, optional (default: False)) – Whether the graph can contain multiple edges between two nodes.
- name (string, optional (default: “ER”)) – Name of the created graph.
- shape (
Shape
, optional (default: None)) – Shape of the neurons’ environment - positions (
numpy.ndarray
, optional (default: None)) – A 2D or 3D array containing the positions of the neurons in space - from_graph (
Graph
or subclass, optional (default: None)) – Initial graph whose nodes are to be connected.
Returns: graph_nw (
Graph
or subclass)Notes
nodes is required unless from_graph or population is provided.
-
nngt.generation.
connect_neural_types
(network, source_type, target_type, graph_model, model_param)[source]¶ Function to connect excitatory and inhibitory population with a given graph model.
Parameters: - network (
Network
orSpatialNetwork
) – The network to connect. - source_type (int) –
The type of source neurons (
1
for excitatory, ``-1 for inhibitory neurons). - source_type (int) – The type of target neurons.
- graph_model (string) – The name of the connectivity model (among “erdos_renyi”, “random_scale_free”, “price_scale_free”, and “newman_watts”).
- model_param (dict) – Dictionary containing the model parameters (the keys are the keywords of the associated generation function — see above).
- network (
-
nngt.generation.
connect_neural_groups
(network, source_groups, target_groups, graph_model, model_param)[source]¶ Function to connect excitatory and inhibitory population with a given graph model.
Parameters: - network (
Network
orSpatialNetwork
) – The network to connect. - source_groups (tuple of strings) – Names of the source groups (which contain the pre-synaptic neurons)
- target_groups (tuple of strings) – Names of the target groups (which contain the post-synaptic neurons)
- graph_model (string) – The name of the connectivity model (among “erdos_renyi”, “random_scale_free”, “price_scale_free”, and “newman_watts”).
- model_param (dict) – Dictionary containing the model parameters (the keys are the keywords of the associated generation function — see above).
- network (
Simulation module¶
Module to interact easily with the NEST simulator. It allows to :
- build a NEST network from
Network
orSpatialNetwork
objects, - monitor the activity of the network (taking neural groups into account)
- plot the activity while separating the behaviours of predefined neural groups
Functions | |
---|---|
make_nest_network | Create a network in NEST from a Graph object |
get_nest_network | Create a Graph object from a NEST network |
-
nngt.simulation.
make_nest_network
(network, use_weights=True)[source]¶ Create a new subnetwork which will be filled with neurons and connector objects to reproduce the topology from the initial network.
Parameters: - network (
nngt.Network
ornngt.SpatialNetwork
) – the network we want to reproduce in NEST. - use_weights (bool, optional (default: True)) – Whether to use the network weights or default ones (value: 10.).
Returns: - subnet (tuple (node in NEST)) – GID of the new NEST subnetwork
- gids (tuple (nodes in NEST)) – GIDs of the neurons in subnet
- network (
-
nngt.simulation.
get_nest_network
(nest_subnet, id_converter=None)[source]¶ Get the adjacency matrix describing a NEST subnetwork.
Parameters: - nest_subnet (tuple) – Subnetwork node in NEST.
- id_converter (dict, optional (default: None)) – A dictionary which maps NEST gids to the desired neurons ids.
Returns: mat_adj (
lil_matrix
) – Adjacency matrix of the network.
-
nngt.simulation.
set_noise
(gids, mean, std)[source]¶ Submit neurons to a current white noise. @todo: check how NEST handles the \(\sqrt{t}\) in the standard dev.
Parameters: - gids (tuple) – NEST gids of the target neurons.
- mean (float) – Mean current value.
- std (float) – Standard deviation of the current
-
nngt.simulation.
set_poisson_input
(gids, rate)[source]¶ Submit neurons to a Poissonian rate of spikes.
Parameters: - gids (tuple) – NEST gids of the target neurons.
- rate (float) – Rate of the spike train.
-
nngt.simulation.
monitor_nodes
(gids, nest_recorder=['spike_detector'], record=[['spikes']], accumulator=True, interval=1.0, to_file='', network=None)[source]¶ Monitoring the activity of nodes in the network.
Parameters: - gids (tuple of ints or list of tuples) – GIDs of the neurons in the NEST subnetwork; either one list per recorder if they should monitor different neurons or a unique list which will be monitored by all devices.
- nest_recorder (list of strings, optional (default: [“spike_detector”])) – List of devices to monitor the network.
- record (list of lists of strings, optional (default: ([“spikes”],))) – List of the variables to record; one list per recording device.
- accumulator (bool, optional (default: True)) – Whether multi/volt/conductancemeters should sum the records of all the nodes they are conencted to.
- interval (float, optional (default: 1.)) – Interval of time at which multimeter-like devices sample data.
- to_file (string, optional (default: “”)) – File where the recorded data should be stored; if “”, the data will not be saved in a file.
Returns: recorders (tuple) – Tuple of the recorders’ gids
-
nngt.simulation.
plot_activity
(gid_recorder, record, network=None, gids=None, show=True)[source]¶ Plot the monitored activity.
Parameters: - gid_recorder (tuple or list) – The gids of the recording devices.
- record (tuple or list) – List of the monitored variables for each device.
- network (
Network
or subclass, optional (default: None)) – Network which activity will be monitored. - gids (tuple, optional (default: None)) – NEST gids of the neurons which should be monitored.
- show (bool, optional (default: True)) – Whether to show the plot right away or to wait for the next plt.show().
Analysis module¶
-
nngt.analysis.
degree_distrib
(net, deg_type='total', node_list=None, use_weights=True, log=False, num_bins=30)[source]¶ Computing the degree distribution of a network.
Parameters: - net (
Graph
or subclass) – the network to analyze. - deg_type (string, optional (default: “total”)) – type of degree to consider (“in”, “out”, or “total”).
- node_list (list or numpy.array of ints, optional (default: None)) – Restrict the distribution to a set of nodes (default: all nodes).
- use_weights (bool, optional (default: True)) – use weighted degrees (do not take the sign into account: all weights are positive).
- log (bool, optional (default: False)) – use log-spaced bins.
Returns: - counts (
numpy.array
) – number of nodes in each bin - deg (
numpy.array
) – bins
- net (
-
nngt.analysis.
betweenness_distrib
(net, use_weights=True, log=False)[source]¶ Computing the betweenness distribution of a network
Parameters: - net (
Graph
or subclass) – the network to analyze. - use_weights (bool, optional (default: True)) – use weighted degrees (do not take the sign into account : all weights are positive).
- log (bool, optional (default: False)) – use log-spaced bins.
Returns: - ncounts (
numpy.array
) – number of nodes in each bin - nbetw (
numpy.array
) – bins for node betweenness - ecounts (
numpy.array
) – number of edges in each bin - ebetw (
numpy.array
) – bins for edge betweenness
- net (
-
nngt.analysis.
assortativity
(net, deg_type='total')[source]¶ Assortativity of the graph. àtodo: check how the various libraries functions work.
Parameters: - net (
Graph
or subclass) – Network to analyze. - deg_type (string, optional (default: ‘total’)) – Type of degree to take into account (among ‘in’, ‘out’ or ‘total’).
Returns: a float describing the network assortativity.
- net (
-
nngt.analysis.
reciprocity
(net)[source]¶ Returns the network reciprocity, defined as \(E^\leftrightarrow/E\), where \(E^\leftrightarrow\) and \(E\) are, respectively, the number of bidirectional edges and the total number of edges in the network.
-
nngt.analysis.
clustering
(net)[source]¶ Returns the global clustering coefficient of the graph, defined as
\[c = 3 imes\]- rac{ ext{number of triangles}}
- { ext{number of connected triples}}
-
nngt.analysis.
num_scc
(net, listing=False)[source]¶ Returns the number of strongly connected components, i.e. ensembles where all nodes inside the ensemble can reach any other node in the ensemble using the directed edges.
See also
-
nngt.analysis.
num_wcc
(net, listing=False)[source]¶ Connected components if the directivity of the edges is ignored (i.e. all edges are considered as bidirectional).
See also
-
nngt.analysis.
spectral_radius
(net, typed=True, weighted=True)[source]¶ Spectral radius of the graph, defined as the eigenvalue of greatest module.
Parameters: - net (
Graph
or subclass) – Network to analyze. - typed (bool, optional (default: True)) – Whether the excitatory/inhibitory type of the connnections should be considered.
- weighted (bool, optional (default: True)) – Whether the weights should be taken into account.
Returns: the spectral radius as a float.
- net (
-
nngt.analysis.
adjacency_matrix
(net, typed=True, weighted=True)[source]¶ Adjacency matrix of the graph.
Parameters: - net (
Graph
or subclass) – Network to analyze. - typed (bool, optional (default: True)) – Whether the excitatory/inhibitory type of the connnections should be considered (only if the weighing factor is the synaptic strength).
- weighted (bool, optional (default: True)) – Whether weights should be taken into account; if True, then connections are weighed by their synaptic strength, if False, then a binary matrix is returned, if weighted is a string, then the ponderation is the correponding value of the edge attribute (e.g. “distance” will return an adjacency matrix where each connection is multiplied by its length).
Returns: a
csr_matrix
.- net (
Installation¶
Simple install¶
Under most linux distributions, the simplest way is to install pip <https://pip.pypa.io/en/stable/installing/> and git, then simply type into a terminal: >>> sudo pip install git+https://github.com/Silmathoron/NNGT.git
There are ways for windows users, but NEST won’t work anyway...
Dependencies¶
This package depends on several libraries (the number varies according to which modules you want to use).
Basic dependencies¶
- Regardless of your needs, the following libraries are required:
- numpy
- scipy
- matplotlib
- graph_tool
- or igraph
- or networkx
Note
If they are not present on your computer, pip
will directly try to install the three first libraries, however:
- lapack is necessary for scipy and pip cannot install it on its own
- you will have to install the graph library yourself (only networkx can be installed directly using
pip
only)
Using NEST¶
- If you want to simulate activities on your complex networks, NNGT can directly interact with the NEST simulator to implement the network inside PyNEST. For this, you will need to install NEST with Python bindings, which requires:
- Python headers (python-dev package on many linux distributions)
- autoconf
- automake
- libtool
- libltdl
Graph generation¶
Principle¶
In order to keep the code as generic and easy to maintain as possible, the generation of graphs or networks is divided in several steps:
- Structured connectivity: a simple graph is generated as an assembly of nodes and edges, without any biological properties. This allows us to implement known graph-theoretical algorithms in a straightforward fashion.
- Populations: detailed properties can be implemented, such as inhibitory synapses and separation of the neurons into inhibitory and excitatory populations – these can be done while respecting user-defined constraints.
- Synaptic properties: eventually, synaptic properties such as weight/strength and delays can be added to the network.
Modularity¶
The library as been designed so that these various operations can be realized in any order!
- Juste to get work on a topological graph/network:
- Create graph class
- Connect
- Set connection weights (optional)
- Spatialize (optional)
- Set types (optional: to use with NEST)
- To work on a really spatially embedded graph/network:
- Create spatial graph/network
- Connect (can depend on positions)
- Set connection weights (optional, can depend on positions)
- Set types (optional)
- Or to model a complex neural network in NEST:
- Create spatial network (with space and neuron types)
- Connect (can depend on types and positions)
- Set connection weights and types (optional, can depend on types and positions)
Setting weights¶
The weights can be either user-defined or generated by one of the available distributions (MAKE A REF). User-defined weights are generated via:
- a list of edges
- a list of weights
Pre-defined distributions require the following variables:
- a distribution name (“constant”, “gaussian”...)
- a dictionary containing the distribution properties
- an optional attribute for distributions that are correlated to another (e.g. the distances between neurons)
- a optional value defining the variance of the Gaussian noise that should be applied on the weights
There are several ways of settings the weights of a graph which depend on the time at which you assign them.
- At graph creation
- You can define the weights by entering a
weight_prop
argument to the constructor; this should be a dictionary containing at least the name of the weight distribution:{"distrib": "distribution_name"}
. If entered, this will be stored as a graph property and used to assign the weights whenever new edges are created unless you specifically assign rules for those new edges’ weights. - At any given time
You can use the
Connections
class to set the weights of agraph
explicitely by using:>>> nngt.Connections.weights(graph, elist=edges_to_weigh, distrib="distrib_of_choice", ...)
Examples¶
import nngt
import nngt.generation as ng
Generating simple graphs:
# random graphs
g1 = ng.erdos_renyi(1000, avg_deg=25)
g2 = ng.erdos_renyi(1000, avg_deg=25, directed=False) # the same graph but undirected
# scale-free with Gaussian weight distribution
g3 = nngt.Graph(1000, weight_prop={"distrib":"gaussian", "distrib_prop":{"avg": 60., "std":5.}})
ng.random_scale_free(2.2, 2.9, from_graph=g3)
Generating a network with excitatory and inhibitory neurons:
# 800 excitatory neurons, 200 inhibitory
net = nngt.Network.ei_network(1000, ei_ratio=0.2)
# connect the populations
ng.connect_neural_types(net, 1, -1, "erdos_renyi", {"density": 0.035}) # exc -> inhib
ng.connect_neural_types(net, 1, 1, "newman_watts", {"coord_nb":10, "proba_shortcut": 0.1}) # exc -> exc
ng.connect_neural_types(net, -1, 1, "random_scale_free", {"in_exp": 2.1, "out_exp": 2.6, "density": 0.2}) # inhib -> exc
ng.connect_neural_types(net, -1, -1, "erdos_renyi", {"density": 0.04}) # inhib -> inhib
Properties of graph components¶
Components¶
In the graph libraries used by NNGT, the main components of a graph are nodes (also called vertices in graph theory), which correspond to neurons in neural networks, and edges, which link nodes and correspond to synaptic connections between neurons in biology.
The library supposes for now that nodes/neurons and edges/synapses are always added and never removed. Because of this, we can attribute indices to the nodes and the edges which will be directly related to the order in which they have been created (the first node will have index 0, .
Node properties¶
If you are just working with basic graphs (for instance looking at the influence of topology with purely excitatory networks), then your nodes do not need to have properties. This is the same if you consider only the average effect of inhibitory neurons by including inhibitory connections between the neurons but not a clear distinction between populations of purely excitatory and purely inhibitory neurons. To model more realistic networks, however, you might want to define these two types of populations and connect them in specific ways.
Two types of node properties¶
- In the library, there is a difference between:
- spatial properties (the positions of the neurons), which are stored in a specific
numpy.array
, - biological/group properties, which define assemblies of nodes sharing common properties, and are stored inside a
NeuralPop
object.
- spatial properties (the positions of the neurons), which are stored in a specific
Biological/group properties¶
Note
All biological/group properties are stored in a NeuralPop
object inside a Network
instance (let us call it graph
in this example); this attribute can be accessed using graph.population
.
NeuralPop
objects can also be created from a Graph
or SpatialGraph
but they will not be stored inside the object.
The NeuralPop
class allows you to define specific groups of neurons (described by a NeuralGroup
). Once these populations are defined, you can constrain the connections between those populations.
If the connectivity already exists, you can use the GroupProperties
class to create a population with groups that respect specific constraints.
Warning
The implementation of this library has been optimized for generating an arbitrary number of neural populations where neurons share common properties; this implies that accessing the properties of one specific neuron will take O(N) operations, where N is the number of neurons. This might change in the future if such operations are judged useful enough.
Edge properties¶
In the library, there is a difference between the (synaptic) weights and types (excitatory or inhibitory) and the other biological properties (delays, synaptic models and synaptic parameters).
This is because the weights and types are directly involved in many measurements in graph theory and are therefore directly stored inside the GraphObject
.
Detailed structure¶
Here is a small bottom-up approach of the library to justify its structure.
Rationale for the structure¶
The basis: a graph¶
The core object is nngt.core.GraphObject
that inherits from either graph_tool.Graph
or snap.TNEANet
and Shape
that encodes the spatial structure of the neurons’ environment.
The purpose of GraphObject
is simple: implementing a library independant object with a unique set of functions to interact with graphs.
Warning
This object should never be directly modified through its methods but rather using those of the four containing classes. The only reason to access this object should be to perform graph-theoretical measurements on it which do not modify its structure; any other action will lead to undescribed behaviour.
Frontend¶
Detailed neural networks contain properties that the GraphObject
does not know about; because of this, direct modification of the structure can lead to nodes or edges missing properties or to properties assigned to nonexistent nodes or edges.
The user can safely interact with the graph using one of the following classes:
Graph
: container for simple topological graphs with no spatial embedding, nor biological propertiesSpatialGraph
: container for spatial graphs without biological propertiesNetwork
: container for topological graphs with biological properties (to interact with NEST)SpatialNetwork
: container with spatial and biological properties (to interact with NEST)
The reason behind those four objects is to ensure coherence in the properties: either nodes/edges all have a given property or they all don’t. Namely:
- adding a node will always require a position parameter when working with a spatial graph,
- adding a node or a connection will always require biological parameters when working with a network.
Moreover, these classes contain the GraphObject
in their graph
attribute and do not inherit from it. The reason for this is to make it easy to maintain different addition/deletion functions for the topological and spatial container by keeping independant of the graph library. (otherwise overwriting one of these function would require the use of library-dependant features).
Graph attributes¶
The Graph
class and its subclasses contain several attributes regarding the properties of the edges and nodes. Edges attributes are contained in the graph dictionary; more complex properties about the biological details of the nodes/neurons are contained in the NeuralPop member of the Graph
. These are briefly described in Properties of graph components; a more detailed description is provided here.
Attributes and graph libraries¶
Usual graph libraries can store node and edge properties; as an example, many graphs are weighted and these weights can then be used to compute other properties such as weighted centralities, which is why it is interesting to have those properties stored in the basic graph library class.
The graph_object.py file contains the _GtEProperty
and _GtNProperty
classes which allow a generic interactions with the various libraries ways of storing properties.
However, several problems occurs:
- for graph_tool, the edge properties are stored in a linear array that is not directly related to the adjacency matrix, thus difficult to handle; this could however be avoided by multiplying the adjacency matrix by the property of interest...
- but for igraph, there is not straightforward way to obtain a scipy adjacency matrix multiplied by an edge property...
To get rid of those problems, the (possibly temporary) solution adopted is to have the weights (synaptic strength) and types (inhibitory or excitatory) attributes stored both in the graph library object and in the Graph
container.
The libraries indices the edges in the order they are created; because of this, weights must be added to the library using the edge list, which is stored inside the Graph
container (access it through the ''edges''
key). The addition is performed in the following way: let lil_matrix_attribute
contain the attribute of interest and network
be the graph container to which we want to add the property, then the following code is used,
>>> sources, targets = network["edges"][:,0], network["edges"][:,1]
>>> list_ordered_weights = lil_matrix_attribute[sources,targets].data[0]
>>> network.graph.new_edge_attribute("weight", "double", values=list_ordered_weights)
Use of attributes in a graph object¶
This allows for fast graph filtering: we can keep only the edges or nodes we are interested in.
This property is invaluable if you want to study the graph properties of only the inhibitory network or look a the squeleton of the strongest synapses in the graph...
Note
This mixed format is not too good... I should either store everything in the container or in the library graph.
- Library graph:
- difficult to manage
- but users can use the library on the graph
- if I cannot provide a fast conversion, it will be bad to interact with NEST
- Container:
- easier to manage
- but need to convert for the analysis functions
- users cannot use the library as the graph misses its attributes
- optimized for NEST interactions
Overview¶
The Neural Network Growth and Topology (NNGT) module provides tools to grow and study detailed biological networks by interfacing efficient graph libraries with highly distributed activity simulators.
Main classes¶
NNGT uses four main classes:
Graph
- provides a simple implementation over graphs objects from graph libraries (namely the addition of a name, management of detailed nodes and connection properties, and simple access to basic graph measurements).
SpatialGraph
- a Graph embedded in space (neurons have positions and connections are associated to a distance)
Network
- provides more detailed characteristics to emulate biological neural networks, such as classes of inhibitory and excitatory neurons, synaptic properties...
SpatialNetwork
- combines spatial embedding and biological properties
Generation of graphs¶
- Structured connectivity:
- connectivity between the nodes can be chosen from various well-known graph models
- Populations:
- populations of neurons are distributed afterwards on the structured connectivity, and can be set to respect various constraints (for instance a given fraction of inhibitory neurons and synapses)
- Synaptic properties:
- synaptic weights and delays can be set from various distributions or correlated to edge properties
Interacting with NEST¶
The generated graphs can be used to easily create complex networks using the NEST simulator, on which you can then simulate their activity.