graph

Defines SpatioTemporalGraph and the RC5 interval-algebra enum.

Defines spatio-temporal graphs and related structures.

class fstg_toolkit.graph.RC5(*values)[source]

Bases: Enum

Defines an RC5 temporal transition.

DC = 5
EQ = 1
PO = 4
PP = 2
PPi = 3
static from_name(name: str) RC5[source]

Find the RC5 transition from its name.

Parameters:

name (string) – The name of the RC5 transition.

Returns:

The corresponding RC5 transition if it has been found.

Return type:

RC5

Raises:

ValueError – if no RC5 transition can be found with the given name.:

Examples

Access to a transition is simple as typing the right transition. >>> RC5.PPi <RC5.PPi: 3>

To access to all the available transition, one can iterate on the RC5 enumeration. >>> for transition in RC5: … print(transition) … EQ PP PPi PO DC

When only the transition name is available, the transition itself can be retrieved from it with the from_name static method. >>> RC5.from_name(“PO”) <RC5.PO: 4> >>> RC5.from_name(“EQ”) <RC5.EQ: 1>

When the provided name does not match any available transition, a ValueError transition is thrown. >>> RC5.from_name(“NN”) Traceback (most recent call last): ValueError: Unable to find a transition named “NN”!

static includes(name: str) bool[source]

Check whether a name corresponds to a valid RC5 transition.

Parameters:

name (str) – The name to test.

Returns:

True if name matches one of the RC5 transitions; False otherwise.

Return type:

bool

class fstg_toolkit.graph.SpatioTemporalGraph(*args, backend=None, **kwargs)[source]

Bases: DiGraph

A spatio-temporal graph wrapping a directed NetworkX graph.

Nodes carry brain area/region metadata; spatial edges carry correlation values; temporal edges carry RC5 transition types.

Parameters:
  • graph (nx.Graph, optional) – An existing NetworkX graph to initialise from.

  • areas (pandas.DataFrame, optional) – A DataFrame describing brain areas with columns Name_Area and Name_Region, indexed by Id_Area.

__eq__(other: SpatioTemporalGraph) bool[source]

Test equality with another spatio-temporal graph.

Two graphs are equal when their nodes, edges (including data) and areas DataFrames are all equal.

Parameters:

other (SpatioTemporalGraph) – The graph to compare against.

Returns:

True if both graphs are structurally and data-wise identical.

Return type:

bool

__init__(graph: Graph = None, areas: DataFrame = None) None[source]

Initialise the spatio-temporal graph.

Parameters:
  • graph (nx.Graph, optional) – An existing NetworkX graph to initialise from.

  • areas (pandas.DataFrame, optional) – A DataFrame describing brain areas (index: Id_Area).

__repr__() str[source]

Return the canonical string representation (same as __str__).

__str__() str[source]

Return a human-readable summary of the spatio-temporal graph.

sub(**conditions) SpatioTemporalGraph[source]

Helper to take the subgraph of the spatio-temporal graph matching the specified conditions.

See subgraph() for the arguments.

sub_spatial() SpatioTemporalGraph[source]
sub_temporal() SpatioTemporalGraph[source]
property time_range: range

Get the time range covered by the spatio-temporal graph.

fstg_toolkit.graph.are_st_graphs_close(graph1: SpatioTemporalGraph, graph2: SpatioTemporalGraph) bool[source]

Test if two spatio-temporal graphs are equal with some tolerance on numerical values.

Parameters:
Returns:

True if graphs are almost equal; false otherwise.

Return type:

bool

Examples

>>> g1 = nx.DiGraph()
>>> g1.add_nodes_from([(1, dict(t=0, areas={1, 2}, region="R1", internal_strength=0.8)),
...                    (2, dict(t=0, areas={3}, region="R1", internal_strength=1)),
...                    (3, dict(t=1, areas={1, 2, 3}, region="R1", internal_strength=0.9))])
>>> g1.add_edges_from([(1, 3, dict(transition=RC5.PP, type='temporal'))])
>>> a1 = pd.DataFrame({'Id_Area': [1, 2, 3], 'Name_Area': ["A1", "A2", "A3"], 'Name_Region': ["R1", "R1", "R1"]})
>>> st_g1 = SpatioTemporalGraph(g1, a1)
>>> g2 = nx.DiGraph()
>>> g2.add_nodes_from([(1, dict(t=0, areas={1, 2}, region="R1", internal_strength=0.7999999999999)),
...                    (2, dict(t=0, areas={3}, region="R1", internal_strength=1.000000000001)),
...                    (3, dict(t=1, areas={1, 2, 3}, region="R1", internal_strength=0.8999999999999))])
>>> g2.add_edges_from([(1, 3, dict(transition=RC5.PP, type='temporal'))])
>>> a2 = pd.DataFrame({'Id_Area': [1, 2, 3], 'Name_Area': ["A1", "A2", "A3"], 'Name_Region': ["R1", "R1", "R1"]})
>>> st_g2 = SpatioTemporalGraph(g2, a2)
>>> g3 = nx.DiGraph()
>>> g3.add_nodes_from([(1, dict(t=0, areas={1, 2}, region="R1", internal_strength=0.8)),
...                    (2, dict(t=1, areas={1, 2}, region="R1", internal_strength=0.8))])
>>> g3.add_edges_from([(1, 2, dict(transition=RC5.EQ, type='temporal'))])
>>> a3 = pd.DataFrame({'Id_Area': [1, 2], 'Name_Area': ["A1", "A2"], 'Name_Region': ["R1", "R1"]})
>>> st_g3 = SpatioTemporalGraph(g3, a3)
>>> are_st_graphs_close(st_g1, st_g1)
True
>>> are_st_graphs_close(st_g1, st_g2)
True
>>> are_st_graphs_close(st_g1, st_g3)
False
fstg_toolkit.graph.subgraph_edges(graph: Graph, **conditions: Any) Graph[source]

Take the subgraph induced by edges that match the conditions.

Parameters:
  • graph (nx.Graph) – The initial graph.

  • conditions (dict[str, Any]) – Conditions on the edge data as keyword arguments. As value, any single value or iterable of values is supported.

Returns:

The edge-induced subgraph matching the specified conditions.

Return type:

nx.Graph

fstg_toolkit.graph.subgraph_nodes(graph: Graph, **conditions: Any) Graph[source]

Take the subgraph that matches the conditions on the nodes.

Parameters:
  • graph (nx.Graph) – The initial graph.

  • conditions (dict[str, any]) – The conditions on the nodes of the subgraph as keywords arguments. As value, any single value or iterable of values is supported.

Returns:

The subgraph matching the specified conditions.

Return type:

nx.Graph

Example

>>> G = nx.Graph()
>>> G.add_nodes_from([(1, dict(a=0, b=1)), (2, dict(a=2, b=1)), (3, dict(a=2, b=2)), (4, dict(a=2, b=1))])
>>> G.add_edges_from([(1, 2), (3, 4), (1, 4)])
>>> subgraph_nodes(G).nodes
NodeView((1, 2, 3, 4))
>>> subgraph_nodes(G, a=0).nodes
NodeView((1,))
>>> subgraph_nodes(G, b=1).nodes
NodeView((1, 2, 4))
>>> subgraph_nodes(G, a=2).nodes
NodeView((2, 3, 4))
>>> subgraph_nodes(G, a=2, b=2).nodes
NodeView((3,))
>>> subgraph_nodes(G, b=(1, 2), a=2).nodes
NodeView((2, 3, 4))
>>> subgraph_nodes(G, b=range(1, 3)).nodes
NodeView((1, 2, 3, 4))