algorithm
OpenDGM algorithm provides pre-made algorithms that look for objects of interest in cardiac data.
There are algorithms for: - Find cycles in a graph - Find focal sources in a graph - Create a vector field - Apply basic phasemapping to find rotors - Apply extended phasemapping to find reentries through phase defects
Algorithm
Bases: ABC, PropertyMixin
Base class for graph algorithms implementation. Intended for use by a backend (third party) library as the basis for algorithmic solutions.
Before applying algorithms from the library, it is necessary to create an internal graph representation that will meet the requirements of the library.
run()
abstractmethod
Run algorithm.
AreaFlows
Bases: NodeFlows
radius = 10
instance-attribute
__init__(graph)
filter_area_paths(node_source, area_nodes)
Filter area nodes that have no in-area connection to the source node. i.e. all area nodes for which the source node has no connection into said area node are removed.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
node_source |
int
|
the graph nodes for which we want to filter connections |
required |
area_nodes |
ndarray
|
all nodes within its area |
required |
Returns:
| Type | Description |
|---|---|
ndarray
|
np.ndarray: filtered area nodes |
run()
Calculate the in-, out- and contained degree of each node to an area within radius.
Returns:
| Type | Description |
|---|---|
tuple[ndarray, ndarray, ndarray]
|
tuple[np.ndarray]: in-, out- and contained degree |
set_radius(radius)
Boundary
arrows = None
instance-attribute
connections = None
instance-attribute
hist = []
instance-attribute
ids = np.array(ids)
instance-attribute
index = 0
instance-attribute
label = ''
instance-attribute
period = 0
instance-attribute
points = np.array(points[ids]).astype(float)
instance-attribute
projection = None
instance-attribute
scalars = np.array(scalars[ids])
instance-attribute
section_count = 12
instance-attribute
sections = None
instance-attribute
__init__(ids, points, scalars)
build_sections(t=0, period=-1, amount=12, geo_center=np.zeros(3))
calc_index(period)
Given an array of edges ex [1, 1, 1, -1, 0, 1, 1, -1, -1] between sections, calculate the sum of phase differences between each two consecutive lats
extend(points, triangles, scalars, distance=0)
get_arrows_object()
Get edge visualization around a boundary with arrows colored by direction. Clockwise, counterclockwise or neutral.
Returns:
| Name | Type | Description |
|---|---|---|
list |
EdgeBuilder
|
List of arrows |
get_center()
get_label_object()
reduce(distance=5)
set_period(period)
to_single_scalars(t=0)
Convert irregular data to single LATs For each node keeping the first LAT after time t
BoundaryFilter
Bases: PolydataFilter
get_boundaries(coords, triangles, scalars, min_points=3)
staticmethod
label(boundaries, maptype)
staticmethod
Automatic labeling of anatomical boundaries based on default orientation of CARTO and Rhythmia exported data. The three largest boundaries are labeled "MV", "LPV" and "RPV". Any remaining boundaries are labeled "scar".
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
boundaries |
list[Boundary]
|
List of boundaries to label. |
required |
maptype |
str
|
Mapping system. Options are "carto" or "rhythmia". |
required |
CompleteSearch
Bases: NKAlgorithm
Searching all possible cycles with number of nodes greater than 2.
algorithm = DijkstraShortestPath
instance-attribute
min_length = 0
instance-attribute
search_algorithms = {'dijkstra': DijkstraShortestPath, 'bfs': BreadthFirstSearch}
instance-attribute
search_type = 'shortest'
instance-attribute
__init__(graph)
compute_weight_matrix()
Calculate weight matrix. The weight matrix has, for each set of two nodes a value of 0 if the nodes are not connected. If the nodes are connected, the value in the matrix is the weight of the edge connectint them.
Returns:
| Type | Description |
|---|---|
ndarray
|
np.ndarray[N, N]: weight matrix |
cycle_pairs()
For each node, find all edges connecting to it (in-neighbors). Using the distance matrix, verify if a cycle exists between with a distance larger than min_distance. If self.search_type is 'shortest', only return the closest in-neighbor, else return all in-neighbors.
Returns:
| Type | Description |
|---|---|
tuple[ndarray, ndarray]
|
tuple[np.ndarrays]: sources and targets |
run()
Find all possible cycles in the graph.
Returns:
| Name | Type | Description |
|---|---|---|
Dataframe |
DataFrame
|
Dataframe of cycles. |
set_algorithm(algorithm)
Default: 'dijkstra'
set_min_length(min_length)
minimum length of a valid cycle found by the cycle search Default: 0
set_search_type(search_type)
Default: 'shortest'
to_nk_graph(graph)
DirectedHelmholtz
Bases: Algorithm
Performs the Directed Helmholtz decomposition for valued (weighted) directed graphs. The decomposition decomposes the edge weights X into a curl-free X_G and gradient-free X_C component.
The algorithm employs the cut method, which calculates X_G from the cut matrix D of the graph by minimizing the difference (X - X_C).(X - X_C)^T with the restriction that D.X_C = 0, a condition that translates into the incoming edge values of X_C being equal to the outgoing edge values (divergence-free). X_G = X - X_C has the property that the sum of edge values along every cycle equals 0 (curl-free).
Taken from DOI: 10.13140/RG.2.2.18011.64807
graph = graph
instance-attribute
matrix = None
instance-attribute
method = 'cut'
instance-attribute
projector = None
instance-attribute
use_points = False
instance-attribute
__init__(graph)
calc_cut_matrix(incidence_matrix)
staticmethod
Given a spanning tree, the cut matrix (n_nodes x n_edges) is the collection of directional edges (+-1) contained in the cut for each node, where only nodes containing one edge from the spanning tree are considered. The cut matrix can be obtained by removing one row from the incidence matrix, yielding a matrix with linearly independent rows.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
incidence_matrix |
ndarray[n_nodes, n_edges]
|
Incidence matrix. |
required |
Returns:
| Type | Description |
|---|---|
ndarray
|
np.ndarray[n_cuts, n_edges]: Cut matrix. |
calc_cycle_matrix(span_forest)
The cycle matrix (n_cycles x n_edges) contains for each elementary cycle (cycle basis) in the graph the direction (+-1) of the edges contained in this cycle. The cycle basis can be used to obtain all possible cycles in the graph. This cycle basis can be constructed by calculating the undirected Spanning Tree (span_forest), consisting of the birth edges of the graph, iteratively adding the remaining edges (death edges), and searching for cycles for each iteration. As each death edge adds one elementary cycle to the graph, the number of cycles is equal to the number of death edges.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
span_forest |
ndarray[n_edges, 2]
|
Spanning forest |
required |
Returns:
| Type | Description |
|---|---|
ndarray
|
np.ndarray[n_cycles, n_edges]: Cycle matrix. |
calc_incidence_matrix()
The incidence matrices with dimensions n_nodes x n_edges contains for each directed edge a -1 for the node at the base and +1 for the node at the tip of the edge.
Returns:
| Type | Description |
|---|---|
ndarray
|
np.ndarray[n_nodes, n_edges]: Incidence matrix. |
calc_matrix()
calc_projector()
Matrix that projects the edge values to their gradient-free subspace.
This matrix is obtained from the generalized restricted least square estimation of (X - X_C).(X - X_C).T with the restriction D.X_C = 0. The reduced laplacian matrix DD^T has the same eigenvalues as the laplacian matrix II^T but has linearly independent rows (with D the cut matrix and I the incidence matrix).
Matrix that projects the edge values to their curl-free subspace. This matrix is obtained from the generalized restricted least square estimation of (X - X_G).(X - X_G).T with the restriction C.X_G = 0. The cycle overlap matrix CC^T contains the lengths of the elementary cycles on the diagonal and the signed overlap of two cycles for the off diagonal elements.
Returns:
| Type | Description |
|---|---|
ndarray
|
np.ndarray[n_edges, n_edges]: Projection matrix. |
get_undirected_cycle(graph, source, target)
staticmethod
Calculates the cycle starting from a source node and ending in a target node from a graph where the connection between the source node and target node is missing.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
source |
int
|
Source node. |
required |
target |
int
|
Target node. |
required |
Returns:
| Type | Description |
|---|---|
ndarray
|
np.ndarray[n_cycle_edges, 2]: Edges of the undirected cycle. |
mask_approx_zero(edges, edge_scalar, threshold=0.05)
staticmethod
Mask edge values that are close to zero using a threshold.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
edges |
ndarray[n_edges, 2]
|
Edges of the graph. |
required |
edge_scalar |
ndarray[n_edges]
|
Edge values. |
required |
threshold |
float
|
Mask threshold. |
0.05
|
Returns:
| Name | Type | Description |
|---|---|---|
tuple |
(ndarray[n_unmasked, 2], ndarray[n_unmasked])
|
Unmasked edges and edge values. |
orient_cycle(points, cycle_edges)
staticmethod
Orients a given cycle so that the cycle normal points away from the origin.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
points |
ndarray[N, 3]
|
Coordinates of the graph. |
required |
cycle_edges |
ndarray[n_cycle_edges, 2]
|
Edges of the cycle. |
required |
Returns:
| Type | Description |
|---|---|
ndarray
|
np.ndarray[n_cycle_edges, 2]: Oriented edges of the cycle. |
run()
Applies the curl or gradient projection matrix of the input edge values X to yield the curl-free and gradient-free components X_G andX_C. Returns: tuple(np.ndarray[n_edges], np.ndarray[n_edges]): Curl-free and gradient-free component.
set_method(method)
Define the decomposition method, default: 'cut'
set_use_points(use_points=True)
ExtendedPhaseMapping
Pipeline for extended phase mapping on phasefield data.
This class processes a given phasefield by applying optional filters, extracting cycles (from faces and/or boundaries), and categorizing them into critical, noncritical, and wavefront cycles. It provides a structured way to analyze spatiotemporal phase dynamics using topological criteria.
Attributes:
| Name | Type | Description |
|---|---|---|
phasefield |
PhaseField
|
The input phasefield mesh. |
phasefield_filters |
list
|
List of filters to apply to the phasefield. |
cycles |
DataFrame
|
DataFrame containing all extracted cycles. |
critical_cycles |
DataFrame
|
Cycles with non-zero topological charge. |
noncritical_cycles |
DataFrame
|
Cycles with zero topological charge and more nodes than a single face. |
wavefront_cycles |
DataFrame
|
Cycles corresponding to propagating wavefronts (non-zero wave number, zero topological charge, and equal to the face size). |
critical_cycles = pd.DataFrame()
instance-attribute
cycles = None
instance-attribute
noncritical_cycles = pd.DataFrame()
instance-attribute
phasefield = phasefield
instance-attribute
phasefield_filters = phasefield_filters or []
instance-attribute
wavefront_cycles = pd.DataFrame()
instance-attribute
__init__(phasefield, phasefield_filters=None)
Initialize the ExtendedPhaseMapping pipeline.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
phasefield |
PhaseField
|
The phasefield mesh to be processed. |
required |
phasefield_filters |
list
|
List of functions to filter the phasefield. |
None
|
run(extract_faces=True, extract_boundaries=True)
Execute the ExtendedPhaseMapping pipeline.
Applies filters and extracts cycles from the phasefield.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
extract_faces |
bool
|
Whether to extract cycles from the faces of the phasefield (Default=True). |
True
|
extract_boundaries |
bool
|
Whether to extract cycles from the boundaries of the phasefield (Default=True). |
True
|
NKAlgorithm
Bases: Algorithm, ABC
Abstract base class for running networkit-based algorithms.
graph = graph.dgm_graph
instance-attribute
nk_graph = graph.nk_graph
instance-attribute
__init__(graph)
Pass either a preconfigured dgm.graph.NKGraph or a Networkit graph. Alternatively, you can pas a dgm.graph.Graph and a networkit graph will be created using a default template.
set_number_of_threads(number_of_threads)
Set number of threads used by Networkit.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
number_of_threads |
int
|
Number of threads. |
required |
to_nk_graph(graph)
NodeSources
Calculate normalized in/out flow balance and determine if each node is a source or a sink.
contained_flows = contained_flows
instance-attribute
in_flows = in_flows
instance-attribute
out_flows = out_flows
instance-attribute
__init__(in_flows, out_flows, contained_flows)
run(min_edges=2)
Calculate normalized in/out flow balance and determine if each node is a source or a sink.
Source nodes are labeled as 1, sink nodes are labeled as -1. If the balance falls within the range [-threshold, threshold], the nodes are neither sources nor sinks and labeled as 0.
Returns:
| Type | Description |
|---|---|
ndarray
|
np.ndarray: nodes heatmap of normalized in/out flow balance |
PhaseMapping
Bases: Algorithm
Convert LATs or signals into phase values.
- For signals, the Hilbert transform method is used.
- For LATs, the sawtooth method is used.
method = method
instance-attribute
observables = observables
instance-attribute
time_axis = time_axis
instance-attribute
__init__(observables, time_axis, method)
from_lats(lats, start=None, stop=None, dt=1.0)
classmethod
Generate a sawtooth phase map from local activation times (LATs).
from_periodic_lat(initial_lats, period, num_of_period=3, start=None, stop=None, dt=1.0)
classmethod
Construct a PhaseMapping by extrapolating a single LAT value periodically.
from_signals(signals, start=None, stop=None, dt=1.0)
classmethod
Create phase values from signals using the Hilbert transform.
run()
Dispatch to the selected method.
VectorField
delta_lat = graph.edges.weights
instance-attribute
distances = graph.edges.distances
instance-attribute
edges = graph.edges.indices
instance-attribute
normalized = False
instance-attribute
points = graph.points
instance-attribute
__init__(graph)
Creates VectorField object.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
graph |
Graph object
|
The graph for which to calculate the vector field. |
required |
calculate_weighted_vf(delta_lat)
Calculates the vector field in each node by taking a weighted average over all incoming and outgoing vectors for a node.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
delta_lat |
N dimensional array
|
The delta_lat on each vector. N has to be equal to the amount of vectors in the graph. |
required |
Returns:
| Type | Description |
|---|---|
ndarray
|
VectorField in each node of the graph. |
normalize(vectors)
staticmethod
Normalizes M-dimensional vectors.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
vectors |
[N, M] dimensional array
|
The vectors to normalize. |
required |
Returns:
| Type | Description |
|---|---|
ndarray
|
np.ndarray: The normalized vectors ([N, M] dimensional array). |
normalized_avg()
Calculates the vector field in each node by taking the average over all normalized incoming and outgoing vectors of a node.
Returns:
| Type | Description |
|---|---|
ndarray
|
np.ndarray: Vector field in each node of the graph. |
set_normalized(normalized=True)
If set to True, the vector field is normalized.
weighted_avg_inverse_speed()
Calculates the vector field in each node by taking a weighted average over all incoming and outgoing vectors for a node. The weight on the vectors is the lat difference between the start and end point divided by the distance between start and end point (= inverse speed). This is the most stable vector field.
Returns:
| Type | Description |
|---|---|
ndarray
|
np.ndarray: Vector field in each node of the graph. |
weighted_avg_speed()
Calculates the vector field in each node by taking a weighted average over all incoming and outgoing vectors for a node. The weight on the vectors is the distance between start and end point divided by the lat difference between the start and end point (= speed).
Returns:
| Type | Description |
|---|---|
ndarray
|
np.ndarray: Vector field in each node of the graph. |