API Reference

Core API

The core components of PyEHM are the EHM and EHM2 classes, that constitute implementations of the EHM [EHM1] and EHM2 [EHM2] algorithms for data association.

The interfaces of these classes are documented below.

class pyehm.core.EHM[source]

Efficient Hypothesis Management (EHM)

An implementation of the EHM algorithm, as documented in [EHM1].

static construct_net(validation_matrix)[source]

Construct the EHM net as per Section 3.1 of [EHM1]

Parameters

validation_matrix (numpy.ndarray) – An indicator matrix of shape (num_tracks, num_detections + 1) indicating the possible (aka. valid) associations between tracks and detections. The first column corresponds to the null hypothesis (hence contains all ones).

Returns

The constructed net object

Return type

EHMNet

static compute_association_probabilities(net, likelihood_matrix)[source]

Compute the joint association weights, as described in Section 3.3 of [EHM1]

Parameters
  • net (EHMNet) – A net object representing the valid joint association hypotheses

  • likelihood_matrix (numpy.ndarray) – A matrix of shape (num_tracks, num_detections + 1) containing the unnormalised likelihoods for all combinations of tracks and detections. The first column corresponds to the null hypothesis.

Returns

A matrix of shape (num_tracks, num_detections + 1) containing the normalised association probabilities for all combinations of tracks and detecrtons. The first column corresponds to the null hypothesis.

Return type

numpy.ndarray

classmethod run(validation_matrix, likelihood_matrix)[source]

Run EHM to compute and return association probabilities

Parameters
  • validation_matrix (numpy.ndarray) – An indicator matrix of shape (num_tracks, num_detections + 1) indicating the possible (aka. valid) associations between tracks and detections. The first column corresponds to the null hypothesis (hence contains all ones).

  • likelihood_matrix (numpy.ndarray) – A matrix of shape (num_tracks, num_detections + 1) containing the unnormalised likelihoods for all combinations of tracks and detections. The first column corresponds to the null hypothesis.

Returns

A matrix of shape (num_tracks, num_detections + 1) containing the normalised association probabilities for all combinations of tracks and detections. The first column corresponds to the null hypothesis.

Return type

numpy.ndarray

class pyehm.core.EHM2[source]

Bases: pyehm.core.EHM

Efficient Hypothesis Management 2 (EHM2)

An implementation of the EHM2 algorithm, as documented in [EHM2].

classmethod construct_net(validation_matrix)[source]

Construct the EHM net as per Section 4 of [EHM2]

Parameters

validation_matrix (numpy.ndarray) – An indicator matrix of shape (num_tracks, num_detections + 1) indicating the possible (aka. valid) associations between tracks and detections. The first column corresponds to the null hypothesis (hence contains all ones).

Returns

The constructed net object

Return type

EHMNet

Raises

ValueError – If the provided validation_matrix is such that tracks can be divided into separate clusters. See the Note below for work-around.

Note

If the provided validation_matrix is such that tracks can be divided into separate clusters, this method will raise a ValueError exception. To work-around this issue, you can use the gen_clusters() function to first generate individual clusters and then generate a net for each cluster, as shown below:

from pyehm.core import EHM2
from pyehm.utils import gen_clusters

validation_matrix = <Your validation matrix>

clusters, _ = gen_clusters(validation_matrix)

nets = []
for cluster in clusters:
    nets.append(EHM2.construct_net(cluster.validation_matrix)
static construct_tree(validation_matrix)[source]

Construct the EHM2 tree as per section 4.3 of [EHM2]

Parameters

validation_matrix (numpy.ndarray) – An indicator matrix of shape (num_tracks, num_detections + 1) indicating the possible (aka. valid) associations between tracks and detections. The first column corresponds to the null hypothesis (hence contains all ones).

Returns

The constructed tree object

Return type

EHM2Tree

Raises

ValueError – If the provided validation_matrix is such that tracks can be divided into separate clusters. See the Note below for work-around.

Note

If the provided validation_matrix is such that tracks can be divided into separate clusters, this method will raise a ValueError exception. To work-around this issue, you can use the gen_clusters() function to first generate individual clusters and then generate a tree for each cluster, as shown below:

from pyehm.core import EHM2
from pyehm.utils import gen_clusters

validation_matrix = <Your validation matrix>

clusters, _ = gen_clusters(validation_matrix)

trees = []
for cluster in clusters:
    trees.append(EHM2.construct_tree(cluster.validation_matrix)
static compute_association_probabilities(net, likelihood_matrix)[source]

Compute the joint association weights, as described in Section 4.2 of [EHM2]

Parameters
  • net (EHMNet) – A net object representing the valid joint association hypotheses

  • likelihood_matrix (numpy.ndarray) – A matrix of shape (num_tracks, num_detections + 1) containing the unnormalised likelihoods for all combinations of tracks and detections. The first column corresponds to the null hypothesis.

Returns

A matrix of shape (num_tracks, num_detections + 1) containing the normalised association probabilities for all combinations of tracks and detecrtons. The first column corresponds to the null hypothesis.

Return type

numpy.ndarray

classmethod run(validation_matrix, likelihood_matrix)

Run EHM to compute and return association probabilities

Parameters
  • validation_matrix (numpy.ndarray) – An indicator matrix of shape (num_tracks, num_detections + 1) indicating the possible (aka. valid) associations between tracks and detections. The first column corresponds to the null hypothesis (hence contains all ones).

  • likelihood_matrix (numpy.ndarray) – A matrix of shape (num_tracks, num_detections + 1) containing the unnormalised likelihoods for all combinations of tracks and detections. The first column corresponds to the null hypothesis.

Returns

A matrix of shape (num_tracks, num_detections + 1) containing the normalised association probabilities for all combinations of tracks and detections. The first column corresponds to the null hypothesis.

Return type

numpy.ndarray

Utils API

The pyehm.utils module contains helper classes and functions used by pyehm.core.

class pyehm.utils.EHMNetNode(layer, identity=None)[source]

A node in the EHMNet constructed by EHM.

Parameters
  • layer (int) – Index of the network layer in which the node is placed. Since a different layer in the network is built for each track, this also represented the index of the track this node relates to.

  • identity (set of int) – The identity of the node. As per Section 3.1 of [EHM1], “the identity for each node is an indication of how measurement assignments made for tracks already considered affect assignments for tracks remaining to be considered”.

class pyehm.utils.EHM2NetNode(layer, track=None, subnet=0, identity=None)[source]

Bases: pyehm.utils.EHMNetNode

A node in the EHMNet constructed by EHM2.

Parameters
  • layer (int) – Index of the network layer in which the node is placed.

  • track (int) – Index of track this node relates to.

  • subnet (int) – Index of subnet to which the node belongs.

  • identity (set of int) – The identity of the node. As per Section 3.1 of [EHM1], “the identity for each node is an indication of how measurement assignments made for tracks already considered affect assignments for tracks remaining to be considered”.

class pyehm.utils.EHMNet(nodes, validation_matrix, edges=None)[source]

Represents the nets constructed by EHM and EHM2.

Parameters
  • nodes (list of EHMNetNode or EHM2NetNode) – The nodes comprising the net.

  • validation_matrix (numpy.ndarray) – An indicator matrix of shape (num_tracks, num_detections + 1) indicating the possible (aka. valid) associations between tracks and detections. The first column corresponds to the null hypothesis (hence contains all ones).

  • edges (dict) – A dictionary that represents the edges between nodes in the network. The dictionary keys are tuples of the form `(parent, child)`, where `parent` and `child` are the source and target nodes respectively. The values of the dictionary are the measurement indices that describe the parent-child relationship.

property root: Union[pyehm.utils.EHMNetNode, pyehm.utils.EHM2NetNode]

The root node of the net.

property num_nodes: int

Number of nodes in the net

property num_layers: int

Number of layers in the net

property nodes: Union[List[pyehm.utils.EHMNetNode], List[pyehm.utils.EHM2NetNode]]

The nodes comprising the net

property nodes_forward: Union[Sequence[pyehm.utils.EHMNetNode], Sequence[pyehm.utils.EHM2NetNode]]

The net nodes, ordered by increasing layer

property nx_graph: networkx.classes.graph.Graph

A NetworkX representation of the net. Mainly used for plotting the net.

add_node(node: Union[pyehm.utils.EHMNetNode, pyehm.utils.EHM2NetNode], parent: Union[pyehm.utils.EHMNetNode, pyehm.utils.EHM2NetNode], detection: int)[source]

Add a new node in the network.

Parameters
add_edge(parent: Union[pyehm.utils.EHMNetNode, pyehm.utils.EHM2NetNode], child: Union[pyehm.utils.EHMNetNode, pyehm.utils.EHM2NetNode], detection: int)[source]

Add edge between two nodes, or update an already existing edge by adding the detection to it.

Parameters
  • parent (EHMNetNode or EHM2NetNode) – The parent node, i.e. the source of the edge.

  • child (EHMNetNode or EHM2NetNode) – The child node, i.e. the target of the edge.

  • detection (int) – Index of measurement representing the parent child relationship.

get_parents(node: Union[pyehm.utils.EHMNetNode, pyehm.utils.EHM2NetNode]) Union[Sequence[pyehm.utils.EHMNetNode], Sequence[pyehm.utils.EHM2NetNode]][source]

Get the parents of a node.

Parameters

node (EHMNetNode or EHM2NetNode) – The node whose parents should be returned

Returns

List of parent nodes

Return type

list of EHMNetNode or EHM2NetNode

get_children(node: Union[pyehm.utils.EHMNetNode, pyehm.utils.EHM2NetNode]) Union[Sequence[pyehm.utils.EHMNetNode], Sequence[pyehm.utils.EHM2NetNode]][source]

Get the children of a node.

Parameters

node (EHMNetNode or EHM2NetNode) – The node whose children should be returned

Returns

List of child nodes

Return type

list of EHMNetNode or EHM2NetNode

plot(ax: Optional[matplotlib.axes._axes.Axes] = None, annotate=True)[source]

Plot the net.

Parameters
  • ax (matplotlib.axes.Axes) – Axes on which to plot the net

  • annotate (bool) – Flag that dictates whether or not to draw node and edge labels on the plotted net. The default is True

class pyehm.utils.EHM2Tree(track, children, detections, subtree)[source]

Represents the track tree structure generated by construct_tree().

The EHM2Tree object represents both a tree as well as the root node in the tree.

Parameters
  • track (int) – The index of the track represented by the root node of the tree

  • children (list of EHM2Tree) – Sub-trees that are children of the current tree

  • detections (set of int) – Set of accumulated detections

  • subtree (int) – Index of subtree the current tree belongs to.

property depth: int

The depth of the tree

property nodes: List[pyehm.utils.EHM2Tree]

The nodes/subtrees in the tree

property nx_graph: networkx.classes.graph.Graph

A NetworkX representation of the tree. Mainly used for plotting the tree.

plot(ax: Optional[matplotlib.axes._axes.Axes] = None)[source]

Plot the tree.

Parameters

ax (matplotlib.axes.Axes) – Axes on which to plot the tree

class pyehm.utils.Cluster(tracks=None, detections=None, validation_matrix=None, likelihood_matrix=None)[source]

A cluster of tracks sharing common detections.

Parameters
  • tracks (list of int) – Indices of tracks in cluster

  • detections (list of int) – Indices of detections in cluster

  • validation_matrix (numpy.ndarray) – The validation matrix for tracks and detections in the cluster

  • likelihood_matrix (numpy.ndarray) – The likelihood matrix for tracks and detections in the cluster

pyehm.utils.gen_clusters(validation_matrix, likelihood_matrix=None)[source]

Cluster tracks into groups sharing detections

Parameters
  • validation_matrix (numpy.ndarray) – An indicator matrix of shape (num_tracks, num_detections + 1) indicating the possible (aka. valid) associations between tracks and detections. The first column corresponds to the null hypothesis (hence contains all ones).

  • likelihood_matrix (numpy.ndarray) – A matrix of shape (num_tracks, num_detections + 1) containing the unnormalised likelihoods for all combinations of tracks and detections. The first column corresponds to the null hypothesis. The default is None, in which case the likelihood matrices of the generated clusters will also be None.

Returns

  • list of Cluster objects – A list of Cluster objects, where each cluster contains the indices of the rows (tracks) and columns (detections) pertaining to the cluster

  • list of int – A list of row (track) indices that have not been associated to any detections

Plugins

Stone Soup

class pyehm.plugins.stonesoup.JPDAWithEHM(hypothesiser: stonesoup.hypothesiser.probability.PDAHypothesiser)[source]

Bases: stonesoup.dataassociator.probability.JPDA

Joint Probabilistic Data Association with Efficient Hypothesis Management (EHM)

This is a faster alternative of the standard JPDA algorithm, which makes use of Efficient Hypothesis Management (EHM) to efficiently compute the joint associations. See Maskell et al. (2004) [EHM1] for more details.

associate(tracks, detections, timestamp, **kwargs)[source]

Associate tracks and detections

Parameters
Returns

Mapping of track to Hypothesis

Return type

mapping of stonesoup.types.track.Track : stonesoup.types.hypothesis.Hypothesis

class pyehm.plugins.stonesoup.JPDAWithEHM2(hypothesiser: stonesoup.hypothesiser.probability.PDAHypothesiser)[source]

Bases: pyehm.plugins.stonesoup.JPDAWithEHM

Joint Probabilistic Data Association with Efficient Hypothesis Management 2 (EHM2)

This is an enhanced version of the JPDAWithEHM algorithm, that makes use of the Efficient Hypothesis Management 2 (EHM2) algorithm to efficiently compute the joint associations. See Horridge et al. (2006) [EHM2] for more details.

associate(tracks, detections, timestamp, **kwargs)

Associate tracks and detections

Parameters
Returns

Mapping of track to Hypothesis

Return type

mapping of stonesoup.types.track.Track : stonesoup.types.hypothesis.Hypothesis