Architectures
- class stonesoup.architecture.Architecture(edges: Edges, current_time: datetime = None, name: str = None, force_connected: bool = True)[source]
Bases:
BaseAbstract Architecture Base class. Subclasses must implement the
propogate()method.- Parameters:
edges (
Edges) – An Edges object containing all edges. For A to be connected to B we would have an Edge with edge_pair=(A, B) in this object.current_time (
datetime.datetime, optional) – The time which the instance is at for the purpose of simulation. This is increased by the propagate method. This should be set to the earliest timestep from the ground truthname (
str, optional) – A name for the architecture, to be used to name files and/or title plots. Default is the class nameforce_connected (
bool, optional) – If True, the undirected version of the graph must be connected, ie. all nodes should be connected via some path. Set this to False to allow an unconnected architecture. Default is True
- edges: Edges
An Edges object containing all edges. For A to be connected to B we would have an Edge with edge_pair=(A, B) in this object.
- current_time: datetime
The time which the instance is at for the purpose of simulation. This is increased by the propagate method. This should be set to the earliest timestep from the ground truth
- force_connected: bool
If True, the undirected version of the graph must be connected, ie. all nodes should be connected via some path. Set this to False to allow an unconnected architecture. Default is True
- name: str
A name for the architecture, to be used to name files and/or title plots. Default is the class name
- recipients(node: Node)[source]
Returns a set of all nodes to which the input node has a direct edge to.
- Parameters:
node (Node) – Node of which to return the recipients of.
- Returns:
Set of nodes that are recipients of the given node.
- Return type:
- Raises:
ValueError – If the given node is not in the Architecture.
- senders(node: Node)[source]
Returns a set of all nodes from which the input node has a direct edge.
- Parameters:
node (Node) – Node of which to return the senders of.
- Returns:
Set of nodes that are senders to the given node.
- Return type:
- Raises:
ValueError – If the given node is not in the Architecture.
- property shortest_path_dict
Returns a dictionary where dict[key1][key2] gives the distance of the shortest path from node1 to node2 if key1=node1 and key2=node2. If no path exists from node1 to node2, a KeyError is raised.
- Returns:
Nested dictionary where dict[node1][node2] gives the distance of the shortest path from node1 to node2.
- Return type:
- property top_level_nodes
Returns a set of ‘top level nodes’ - nodes with no recipients (e.g., the single node at the top of a hierarchical architecture).
- Returns:
Set of nodes that have no recipients.
- Return type:
- number_of_leaves(node: Node)[source]
Returns the number of leaf nodes which are connected to the given node by a path from the leaf node to the parameter node.
- property leaf_nodes
Returns all the nodes in the Architecture which have no sender nodes (i.e., all nodes that do not receive any data from other nodes).
- Returns:
Set of all leaf nodes that exist in the Architecture.
- Return type:
- property all_nodes
Returns a set of all Nodes in the Architecture.
- Returns:
Set of all nodes in the Architecture.
- Return type:
- property sensor_nodes
Returns a set of all SensorNodes in the Architecture.
- Returns:
Set of nodes in the Architecture that have a Sensor.
- Return type:
- property fusion_nodes
Returns a set of all FusionNodes in the Architecture.
- Returns:
Set of nodes in the Architecture that perform data fusion.
- Return type:
- property repeater_nodes
Returns a set of all RepeaterNodes in the Architecture.
- Returns:
Set of nodes in the Architecture whose only role is to link two other nodes together.
- Return type:
- plot(use_positions=False, plot_title=False, bgcolour='transparent', node_style='filled', font_name='helvetica', plot_style=None)[source]
Creates a pdf plot of the directed graph and displays it.
- Parameters:
use_positions (bool, optional) – Whether to use node positions (default is False).
plot_title (str or bool, optional) – If a string is supplied, makes this the title of the plot. If True, uses the name attribute of the graph to title the plot. If False, no title is used. Default is False.
bgcolour (str, optional) – Background colour for the plot. Default is “transparent”.
node_style (str, optional) – Node style for the plot. Default is “filled”.
font_name (str, optional) – Font name for node labels. Default is ‘helvetica’.
plot_style (str, optional) – Style to be used to plot the graph. Currently only option is ‘hierarchical’.
- Returns:
The graphviz Source object for the plot.
- Return type:
graphviz.Source
- property density
Returns the density of the graph, i.e. the proportion of possible edges between nodes that exist in the graph.
- Returns:
Density of the architecture.
- Return type:
- property is_hierarchical
Returns True if the Architecture is hierarchical, otherwise False. An architecture is hierarchical if and only if there exists only one node with 0 recipients and all other nodes have exactly 1 recipient.
- Returns:
Whether the architecture is hierarchical.
- Return type:
- property is_centralised
Returns True if the Architecture is centralised, otherwise False. An architecture is centralised if and only if there exists only one node with 0 recipients, and there exists a path to this node from every other node in the architecture.
- Returns:
Whether the architecture is centralised.
- Return type:
- property is_connected
Returns True if the graph is connected, otherwise False.
- Returns:
Whether the graph is connected.
- Return type:
- property to_undirected
Returns an undirected version of self.digraph.
- Returns:
Undirected version of the directed graph.
- Return type:
- property fully_propagated
Checks if all data for each node have begun transfer to its recipients. With zero latency, this should be the case after running propagate.
- Returns:
Whether all data have begun transfer to recipients.
- Return type:
- measure(ground_truths: list[GroundTruthPath], noise: bool | ndarray = True, **kwargs) dict[SensorNode, set[TrueDetection | Clutter]][source]
Similar to the method for
SensorSuite. Updates each node.- Parameters:
ground_truths (list of GroundTruthPath) – List of ground truth paths.
noise (bool or np.ndarray, optional) – Whether to add noise or a noise array (default is True).
**kwargs – Additional keyword arguments passed to the sensor measure method.
- Returns:
Dictionary mapping SensorNode to set of TrueDetection or Clutter.
- Return type:
- class stonesoup.architecture.NonPropagatingArchitecture(edges: Edges, current_time: datetime = None, name: str = None, force_connected: bool = True)[source]
Bases:
ArchitectureA simple Architecture class that does not simulate propagation of any data. Can be used for performing network operations on an
Edgesobject.- Parameters:
edges (
Edges) – An Edges object containing all edges. For A to be connected to B we would have an Edge with edge_pair=(A, B) in this object.current_time (
datetime.datetime, optional) – The time which the instance is at for the purpose of simulation. This is increased by the propagate method. This should be set to the earliest timestep from the ground truthname (
str, optional) – A name for the architecture, to be used to name files and/or title plots. Default is the class nameforce_connected (
bool, optional) – If True, the undirected version of the graph must be connected, ie. all nodes should be connected via some path. Set this to False to allow an unconnected architecture. Default is True
- class stonesoup.architecture.InformationArchitecture(edges: Edges, current_time: datetime = None, name: str = None, force_connected: bool = True)[source]
Bases:
ArchitectureThe architecture for how information is shared through the network. Node A is connected to Node B if and only if the information A creates by processing and/or sensing is received and opened by B without modification by another node.
- Parameters:
edges (
Edges) – An Edges object containing all edges. For A to be connected to B we would have an Edge with edge_pair=(A, B) in this object.current_time (
datetime.datetime, optional) – The time which the instance is at for the purpose of simulation. This is increased by the propagate method. This should be set to the earliest timestep from the ground truthname (
str, optional) – A name for the architecture, to be used to name files and/or title plots. Default is the class nameforce_connected (
bool, optional) – If True, the undirected version of the graph must be connected, ie. all nodes should be connected via some path. Set this to False to allow an unconnected architecture. Default is True
- propagate(time_increment: float, failed_edges: Collection = None)[source]
Performs the propagation of the measurements through the network.
- Parameters:
time_increment (float) – Time increment for propagation.
failed_edges (Collection, optional) – Collection of failed edges (default is None).
- class stonesoup.architecture.NetworkArchitecture(edges: Edges, current_time: datetime = None, name: str = None, force_connected: bool = True, information_arch: InformationArchitecture = None, information_architecture_edges: Edges = None)[source]
Bases:
ArchitectureThe architecture for how data is propagated through the network. Node A is connected to Node B if and only if A sends its data through B.
- Parameters:
edges (
Edges) – An Edges object containing all edges. For A to be connected to B we would have an Edge with edge_pair=(A, B) in this object.current_time (
datetime.datetime, optional) – The time which the instance is at for the purpose of simulation. This is increased by the propagate method. This should be set to the earliest timestep from the ground truthname (
str, optional) – A name for the architecture, to be used to name files and/or title plots. Default is the class nameforce_connected (
bool, optional) – If True, the undirected version of the graph must be connected, ie. all nodes should be connected via some path. Set this to False to allow an unconnected architecture. Default is Trueinformation_arch (
InformationArchitecture, optional)information_architecture_edges (
Edges, optional)
- propagate(time_increment: float, failed_edges: Collection = None)[source]
Performs the propagation of the measurements through the network.
- Parameters:
time_increment (float) – Time increment for propagation.
failed_edges (Collection, optional) – Collection of failed edges (default is None).
- stonesoup.architecture.inherit_edges(network_architecture)[source]
Utility function that takes a NetworkArchitecture object and infers what the overlaying InformationArchitecture graph would be.
- Parameters:
network_architecture (NetworkArchitecture) – A NetworkArchitecture object.
- Returns:
A list of edges for the InformationArchitecture.
- Return type:
Edge
- class stonesoup.architecture.edge.FusionQueue(*args, **kwargs)[source]
Bases:
QueueA queue from which fusion nodes draw data they have yet to fuse
Iterable, where it blocks attempting to yield items on the queue
- property waiting_for_data
Returns True if the queue is consuming and waiting for data.
- Returns:
Whether the queue is waiting for data.
- Return type:
- get(*args, **kwargs)[source]
Remove and return an item from the queue.
If optional args ‘block’ is true and ‘timeout’ is None (the default), block if necessary until an item is available. If ‘timeout’ is a non-negative number, it blocks at most ‘timeout’ seconds and raises the Empty exception if no item was available within that time. Otherwise (‘block’ is false), return an item if one is immediately available, else raise the Empty exception (‘timeout’ is ignored in that case).
- class stonesoup.architecture.edge.DataPiece(node: Node, originator: Node, data: Detection | Track | Hypothesis, time_arrived: datetime, track: Track = None)[source]
Bases:
BaseA piece of data for use in an architecture. Sent via a
Message, and stored in a Node’sdata_held- Parameters:
node (
Node) – The Node this data piece belongs tooriginator (
Node) – The node which first created this data, ie by sensing or fusing information together. If the data is simply passed along the chain, the originator remains unchanged.data (
Union[Detection, Track, Hypothesis]) – A Detection, Track, or Hypothesistime_arrived (
datetime.datetime) – The time at which this piece of data was received by the Node, either by Message or by sensing.track (
Track, optional) – The Track in the event of data being a Hypothesis
- originator: Node
The node which first created this data, ie by sensing or fusing information together. If the data is simply passed along the chain, the originator remains unchanged.
- data: Detection | Track | Hypothesis
A Detection, Track, or Hypothesis
- class stonesoup.architecture.edge.Edge(nodes: tuple[Node, Node], edge_latency: float = 0.0)[source]
Bases:
BaseComprised of two connected
Nodeinstances- Parameters:
nodes (
tuple) – A pair of nodes in the form (sender, recipient)edge_latency (
float, optional) – The latency stemming from the edge itself, and not either of the nodes
- send_message(data_piece, time_pertaining, time_sent)[source]
Takes a piece of data retrieved from the edge’s sender node, and propagates it along the edge.
- Parameters:
data_piece (DataPiece) – DataPiece object pulled from the edge’s sender.
time_pertaining (datetime) – The latest time for which the data pertains. For a Detection, this would be the time of the Detection, or for a Track this is the time of the last State in the Track.
time_sent (datetime) – Time at which the message was sent.
- pass_message(message)[source]
Takes a message from a Node’s ‘messages_to_pass_on’ store and propagates it to the relevant edges.
- Parameters:
message (Message) – Message to propagate.
- update_messages(current_time, to_network_node=False)[source]
Updates the category of messages stored in edge.messages_held if latency time has passed. Adds messages that have ‘arrived’ at recipient to the relevant holding area of the node.
- Parameters:
current_time (datetime) – Current time in simulation.
to_network_node (bool, optional) – True if recipient node is not in the information architecture (default is False).
- failed(current_time, delta)[source]
Keeps track of when this edge was failed using the time_ranges_failed property.
- Parameters:
current_time (datetime) – The current time.
delta (timedelta) – The duration for which the edge is failed.
- property unsent_data
Data modified by the sender that has not been sent to the recipient.
- class stonesoup.architecture.edge.Edges(edges: list[Edge] = None)[source]
Bases:
Base,CollectionContainer class for
Edge- Parameters:
edges (
list, optional) – List of Edge objects
- property edge_list
Returns a list of tuples in the form (sender, recipient)
- class stonesoup.architecture.edge.Message(edge: Edge, time_pertaining: datetime, time_sent: datetime, data_piece: DataPiece, destinations: set[Node] = None)[source]
Bases:
BaseA message, containing a piece of information, that gets propagated between two Nodes. Messages are opened by nodes that are a recipient of the node that sent the message
- Parameters:
edge (
Edge) – The directed edge containing the sender and receiver of the messagetime_pertaining (
datetime.datetime) – The latest time for which the data pertains. For a Detection, this would be the time of the Detection, or for a Track this is the time of the last State in the Track. Different from time_sent when data is passed on that was not generated by the sendertime_sent (
datetime.datetime) – Time at which the message was sentdata_piece (
DataPiece) – Info that the sent message containsdestinations (
set, optional) – Nodes in the information architecture that the message is being sent to
Node
- class stonesoup.architecture.node.Node(latency: float = 0.0, label: str = None, position: tuple[float, float] = None, colour: str = '#909090', shape: str = 'rectangle', font_size: int = None, node_dim: tuple[float, float] = None)[source]
Bases:
BaseBase Node class. Generally a subclass should be used. Note that most user-defined properties are for graphical use only, all with default values.
- Parameters:
latency (
float, optional) – Contribution to edge latency stemming from this node. Default is 0.0label (
str, optional) – Label to be displayed on graph. Default is to label by class and then differentiate via alphabetical labelsposition (
tuple, optional) – Cartesian coordinates for node. Determined automatically by defaultcolour (
str, optional) – Colour to be displayed on graph. Default is greyshape (
str, optional) – Shape used to display nodes. Default is a rectanglefont_size (
int, optional) – Font size for node labels. Default is Nonenode_dim (
tuple, optional) – Width and height of nodes for graph icons. Default is None, which will size to label automatically.
- label: str
Label to be displayed on graph. Default is to label by class and then differentiate via alphabetical labels
- node_dim: tuple[float, float]
Width and height of nodes for graph icons. Default is None, which will size to label automatically.
- update(time_pertaining, time_arrived, data_piece, category, track=None)[source]
Updates this Node’s data_held using a new data piece.
- Parameters:
time_pertaining (datetime) – Time the data is relevant to, when it was created.
time_arrived (datetime) – Time the data arrived at this node.
data_piece (DataPiece) – The specific data piece, containing for example a Detection.
category (str) – A string matching either “fused”, “created”, or “unfused”.
track (Track, optional) – Track to which the data piece is assigned, if it contains a Hypothesis (default is None).
- Returns:
True if new data has been added.
- Return type:
- class stonesoup.architecture.node.SensorNode(sensor: Sensor, latency: float = 0.0, label: str = None, position: tuple[float, float] = None, colour: str = '#006eff', shape: str = 'oval', font_size: int = None, node_dim: tuple[float, float] = None)[source]
Bases:
NodeA
Nodecorresponding to aSensor. Fresh data is created here- Parameters:
sensor (
Sensor) – Sensor corresponding to this nodelatency (
float, optional) – Contribution to edge latency stemming from this node. Default is 0.0label (
str, optional) – Label to be displayed on graph. Default is to label by class and then differentiate via alphabetical labelsposition (
tuple, optional) – Cartesian coordinates for node. Determined automatically by defaultcolour (
str, optional) – Colour to be displayed on graph. Default is the hex colour code #006effshape (
str, optional) – Shape used to display nodes. Default is an ovalfont_size (
int, optional) – Font size for node labels. Default is Nonenode_dim (
tuple, optional) – Width and height of nodes for graph icons. Default is None, which will size to label automatically.
- class stonesoup.architecture.node.FusionNode(tracker: Tracker, latency: float = 0.0, label: str = None, position: tuple[float, float] = None, colour: str = '#00b53d', shape: str = 'hexagon', font_size: int = None, node_dim: tuple[float, float] = None, fusion_queue: FusionQueue = None, tracks: set = None)[source]
Bases:
NodeA
Nodethat does not measure new data, but does process data it receives- Parameters:
tracker (
Tracker) – Tracker used by this Node to fuse together Tracks and Detectionslatency (
float, optional) – Contribution to edge latency stemming from this node. Default is 0.0label (
str, optional) – Label to be displayed on graph. Default is to label by class and then differentiate via alphabetical labelsposition (
tuple, optional) – Cartesian coordinates for node. Determined automatically by defaultcolour (
str, optional) – Colour to be displayed on graph. Default is the hex colour code #00b53dshape (
str, optional) – Shape used to display nodes. Default is a hexagonfont_size (
int, optional) – Font size for node labels. Default is Nonenode_dim (
tuple, optional) – Width and height of nodes for graph icons. Default is None, which will size to label automatically.fusion_queue (
FusionQueue, optional) – The queue from which this node draws data to be fused. Default is a standard FusionQueuetracks (
set, optional) – Set of tracks tracked by the fusion node
- fusion_queue: FusionQueue
The queue from which this node draws data to be fused. Default is a standard FusionQueue
- class stonesoup.architecture.node.SensorFusionNode(tracker: Tracker, sensor: Sensor, latency: float = 0.0, label: str = None, position: tuple[float, float] = None, colour: str = '#fc9000', shape: str = 'diamond', font_size: int = None, node_dim: tuple[float, float] = None, fusion_queue: FusionQueue = None, tracks: set = None)[source]
Bases:
SensorNode,FusionNodeA
Nodethat is both aSensorand also processes data- Parameters:
tracker (
Tracker) – Tracker used by this Node to fuse together Tracks and Detectionssensor (
Sensor) – Sensor corresponding to this nodelatency (
float, optional) – Contribution to edge latency stemming from this node. Default is 0.0label (
str, optional) – Label to be displayed on graph. Default is to label by class and then differentiate via alphabetical labelsposition (
tuple, optional) – Cartesian coordinates for node. Determined automatically by defaultcolour (
str, optional) – Colour to be displayed on graph. Default is the hex colour code #fc9000shape (
str, optional) – Shape used to display nodes. Default is a diamondfont_size (
int, optional) – Font size for node labels. Default is Nonenode_dim (
tuple, optional) – Width and height of nodes for graph icons. Default is None, which will size to label automatically.fusion_queue (
FusionQueue, optional) – The queue from which this node draws data to be fused. Default is a standard FusionQueuetracks (
set, optional) – Set of tracks tracked by the fusion node
- class stonesoup.architecture.node.RepeaterNode(latency: float = 0.0, label: str = None, position: tuple[float, float] = None, colour: str = '#909090', shape: str = 'rectangle', font_size: int = None, node_dim: tuple[float, float] = None)[source]
Bases:
NodeA
Nodewhich simply passes data along to others, without manipulating the data itself. Consequently,NetworkArchitecture- Parameters:
latency (
float, optional) – Contribution to edge latency stemming from this node. Default is 0.0label (
str, optional) – Label to be displayed on graph. Default is to label by class and then differentiate via alphabetical labelsposition (
tuple, optional) – Cartesian coordinates for node. Determined automatically by defaultcolour (
str, optional) – Colour to be displayed on graph. Default is the hex colour code #909090shape (
str, optional) – Shape used to display nodes. Default is a rectanglefont_size (
int, optional) – Font size for node labels. Default is Nonenode_dim (
tuple, optional) – Width and height of nodes for graph icons. Default is None, which will size to label automatically.
Generator
- class stonesoup.architecture.generator.InformationArchitectureGenerator(arch_type: str = 'decentralised', start_time: datetime = None, node_ratio: tuple = None, mean_degree: float = None, base_sensor: Sensor = None, sensor_max_distance: tuple = None, base_tracker: Tracker = None, iteration_limit: int = 10000, allow_invalid_graph: bool = False, n_archs: int = 2)[source]
Bases:
BaseConvenience class that can be used to generate one or multiple
The graph is generated randomly subject to the parameters such as `node_ratioand mean_degree, rather than having to be user-defined.- Parameters:
arch_type (
str, optional) – Type of architecture to be modelled. Currently only ‘hierarchical’ and ‘decentralised’ are supported.start_time (
datetime.datetime, optional) – Start time of simulation to be passed to the Architecture class.node_ratio (
tuple, optional) – Tuple containing the number of each type of node, in the order of (sensor nodes, sensor fusion nodes, fusion nodes).mean_degree (
float, optional) – Average (mean) degree of nodes in the network.base_sensor (
Sensor, optional) – Sensor class object that will be duplicated to create multiple sensors. Position of this sensor is used with ‘sensor_max_distance’ to calculate a position for duplicated sensors.sensor_max_distance (
tuple, optional) – Max distance each sensor can be from base_sensor.position. Should be a tuple of length equal to len(base_sensor.position_mapping)base_tracker (
Tracker, optional) – Tracker class object that will be duplicated to create multiple trackers. Should have detector=None.iteration_limit (
int, optional) – Limit for the number of iterations the generate_edgelist() method can make when attempting to build a suitable graph.allow_invalid_graph (
bool, optional) – Bool where True allows invalid graphs to be returned without throwing an error. False by defaultn_archs (
int, optional) – How many architectures should be generated.
- arch_type: str
Type of architecture to be modelled. Currently only ‘hierarchical’ and ‘decentralised’ are supported.
- node_ratio: tuple
Tuple containing the number of each type of node, in the order of (sensor nodes, sensor fusion nodes, fusion nodes).
- base_sensor: Sensor
Sensor class object that will be duplicated to create multiple sensors. Position of this sensor is used with ‘sensor_max_distance’ to calculate a position for duplicated sensors.
- base_tracker: Tracker
Tracker class object that will be duplicated to create multiple trackers. Should have detector=None.
- iteration_limit: int
Limit for the number of iterations the generate_edgelist() method can make when attempting to build a suitable graph.
- allow_invalid_graph: bool
Bool where True allows invalid graphs to be returned without throwing an error. False by default
- class stonesoup.architecture.generator.NetworkArchitectureGenerator(arch_type: str = 'decentralised', start_time: datetime = None, node_ratio: tuple = None, mean_degree: float = None, base_sensor: Sensor = None, sensor_max_distance: tuple = None, base_tracker: Tracker = None, iteration_limit: int = 10000, allow_invalid_graph: bool = False, n_archs: int = 2, n_routes: tuple = (1, 2))[source]
Bases:
InformationArchitectureGeneratorConvenience class that can be used to generate one or multiple
The graph is generated randomly subject to the parameters such as `node_ratioand mean_degree, rather than having to be user-defined.- Parameters:
arch_type (
str, optional) – Type of architecture to be modelled. Currently only ‘hierarchical’ and ‘decentralised’ are supported.start_time (
datetime.datetime, optional) – Start time of simulation to be passed to the Architecture class.node_ratio (
tuple, optional) – Tuple containing the number of each type of node, in the order of (sensor nodes, sensor fusion nodes, fusion nodes).mean_degree (
float, optional) – Average (mean) degree of nodes in the network.base_sensor (
Sensor, optional) – Sensor class object that will be duplicated to create multiple sensors. Position of this sensor is used with ‘sensor_max_distance’ to calculate a position for duplicated sensors.sensor_max_distance (
tuple, optional) – Max distance each sensor can be from base_sensor.position. Should be a tuple of length equal to len(base_sensor.position_mapping)base_tracker (
Tracker, optional) – Tracker class object that will be duplicated to create multiple trackers. Should have detector=None.iteration_limit (
int, optional) – Limit for the number of iterations the generate_edgelist() method can make when attempting to build a suitable graph.allow_invalid_graph (
bool, optional) – Bool where True allows invalid graphs to be returned without throwing an error. False by defaultn_archs (
int, optional) – How many architectures should be generated.n_routes (
tuple, optional) – Tuple containing a minimum and maximum value for the number of routes created in the network architecture to represent a single edge in the information architecture.