simulation

Synthetic data generation. SpatioTemporalGraphSimulator generates graphs from pattern sequences; CorrelationMatrixSequenceSimulator regenerates correlation matrices from an existing graph.

Defines the tools to simulate spatio-temporal graphs and functional connectivity data.

class fstg_toolkit.simulation.CorrelationMatrixSequenceSimulator(graph: ~fstg_toolkit.graph.SpatioTemporalGraph, threshold: float = 0.4, rng: ~numpy.random._generator.Generator = Generator(PCG64) at 0x742EE4ADD700)[source]

Bases: object

Simulate a sequence of correlation matrices from a spatio-temporal graph.

Examples

>>> graph = nx.DiGraph()
>>> graph.add_node(1, t=0, areas={1, 2}, region='Region 1', internal_strength=0.98)
>>> graph.add_node(2, t=0, areas={3, 4}, region='Region 2', internal_strength=-0.98)
>>> graph.add_edge(1, 2, correlation=0.94, t=0, type='spatial')
>>> graph.add_edge(2, 1, correlation=0.94, t=0, type='spatial')
>>> graph.graph['min_time'] = 0
>>> graph.graph['max_time'] = 0
>>> areas = pd.DataFrame({'Id_Area': [1, 2, 3, 4],
...                       'Name_Area': ['A1', 'A2', 'A3', 'A4'],
...                       'Name_Region': ['R1', 'R1', 'R2', 'R2']})
>>> areas.set_index('Id_Area', inplace=True)
>>> simulator = CorrelationMatrixSequenceSimulator(SpatioTemporalGraph(graph, areas), threshold=0.4,
...                                                rng=np.random.default_rng(40))
>>> matrix = simulator.simulate()
>>> matrix.shape
(1, 4, 4)
>>> matrix
array([[[ 1.        ,  0.98      ,  0.65453818,  0.94      ],
        [ 0.98      ,  1.        ,  0.85381682,  0.61873641],
        [ 0.65453818,  0.85381682,  1.        , -0.98      ],
        [ 0.94      ,  0.61873641, -0.98      ,  1.        ]]])
__init__(graph: ~fstg_toolkit.graph.SpatioTemporalGraph, threshold: float = 0.4, rng: ~numpy.random._generator.Generator = Generator(PCG64) at 0x742EE4ADD700) None[source]

Initialise the simulator.

Parameters:
  • graph (SpatioTemporalGraph) – The reference spatio-temporal graph from which correlation matrices will be back-generated.

  • threshold (float, optional) – Minimum absolute correlation required for spatial edges to be considered significant (default 0.4, must be in [0, 1]).

  • rng (numpy.random.Generator, optional) – Random number generator for reproducible results.

Raises:

ValueError – If threshold is outside [0, 1].

__init_validation__()[source]

Validate constructor parameters.

Raises:

ValueError – If threshold is not in [0, 1].

simulate() array[source]

Simulate the sequence of correlation matrices.

Returns:

A 3D-shaped array that contains the correlations matrices for each time.

Return type:

numpy.array

class fstg_toolkit.simulation.SpatioTemporalGraphSimulator(**patterns: SpatioTemporalGraph)[source]

Bases: object

Simulator for spatio-temporal graphs.

The simulator needs predefined patterns (created either manually or automatically) to generate a full spatio-temporal graph with those patterns included as instructed, eventually with in-between repeats.

Examples

>>> pattern1 = generate_pattern(
...     networks_list=[
...         [((1, 2), 1, 0.7), (3, 1, 1), ((4, 5), 2, -0.8)],
...         [((1, 3), 1, 0.8), ((4, 5), 2, -0.8)]],
...     spatial_edges=[(1, 3, 0.5), (4, 5, 0.6)],
...     temporal_edges=[((1, 2), 4, 'merge'), (3, 5, 'eq')])
>>> pattern2 = generate_pattern(
...     networks_list=[
...         [((1, 3), 1, 0.8), ((4, 5), 2, -0.8)],
...         [((1, 2), 1, 0.7), (3, 1, 1), ((4, 5), 2, -0.8)]],
...     spatial_edges=[(1, 2, 0.6), (3, 5, 0.5)],
...     temporal_edges=[(1, (3, 4), 'split'), (2, 5, 'eq')])
>>> simulator = SpatioTemporalGraphSimulator(p1=pattern1, p2=pattern2)
>>> graph = simulator.simulate('p2', 3, 'p1')
>>> graph.nodes
NodeView((1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19))
>>> graph.edges
OutEdgeView([(1, 2), (1, 3), (1, 4), (2, 1), (2, 5), (3, 5), (3, 6), (4, 7), (5, 3), (5, 8),
(6, 8), (6, 9), (7, 10), (8, 6), (8, 11), (9, 11), (9, 12), (10, 13), (11, 9), (11, 14), (12, 14),
(12, 15), (13, 16), (14, 12), (14, 17), (15, 17), (15, 18), (16, 18), (17, 15), (17, 19), (18, 19), (19, 18)])
__init__(**patterns: SpatioTemporalGraph) None[source]

Initialise the simulator with a set of named patterns.

Parameters:

**patterns (SpatioTemporalGraph) – Keyword arguments mapping pattern names (str) to their SpatioTemporalGraph definitions.

simulate(*patterns: str | int) SpatioTemporalGraph[source]

Simulate the given sequence of pattern.

Parameters:

patterns (tuple[str | int]) – The sequence of patterns. A string references a pattern registered at the creation of the simulator and an integer reference a number of times repeats in-between patterns. A repeat is a subgraph of the last time of the last pattern.

Returns:

The built spatio-temporal graph.

Return type:

SpatioTemporalGraph

fstg_toolkit.simulation.generate_pattern(networks_list: list[list[tuple[tuple[int, int], int, float]]], spatial_edges: list[tuple[int, int, float]], temporal_edges: list[tuple[Iterable[int] | int, Iterable[int] | int, str]]) SpatioTemporalGraph[source]

Generate a pattern with the specified properties.

Parameters:
  • networks_list (list[list[tuple[tuple[int, int], int, float]]]) – A list of nodes per time instant, defined themselves by a tuple of area range, region id and internal strength.

  • spatial_edges (list[tuple[int, int, float]]) – A list of spatial edges defined by a tuple of source/target nodes and a correlation.

  • temporal_edges (list[tuple[Iterable[int] | int, Iterable[int] | int, str]]) – A list of temporal edges, defined by a tuple of source(s)/target(s) nodes and a transition.

Returns:

A spatio-temporal graph that can be used as a pattern.

Return type:

SpatioTemporalGraph

Example

>>> pattern = generate_pattern(
...     networks_list=[[((1, 5), 1, -0.2), ((6, 7), 2, 0.3), ((8, 10), 2, 0.6)],
...                    [((1, 5), 1, 0.6), ((6, 10), 2, -0.5)]],
...     spatial_edges=[(1, 2, 0.45), (4, 5, 0.8)],
...     temporal_edges=[(1, 4, 'eq'), ((2, 3), 5, 'merge')])
>>> pattern.nodes
NodeView((1, 2, 3, 4, 5))
>>> pattern.edges
OutEdgeView([(1, 2), (1, 4), (2, 1), (2, 5), (3, 5), (4, 5), (5, 4)])
>>> pattern.areas
        Name_Area Name_Region
Id_Area
1          Area 1    Region 1
2          Area 2    Region 1
3          Area 3    Region 1
4          Area 4    Region 1
5          Area 5    Region 1
6          Area 6    Region 2
7          Area 7    Region 2
8          Area 8    Region 2
9          Area 9    Region 2
10        Area 10    Region 2