Newer
Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
import numpy as np
from abc import ABC, abstractmethod
import xarray as xr
from enstools.feature.identification._proto_gen import identification_pb2
class TrackingTechnique(ABC):
"""
Base abstract class for feature tracking algorithms.
Implementations need to override the abstract track() method.
"""
@abstractmethod
def track(self, timeline, subset: xr.Dataset):
"""
Abstract tracking method. This gets called for each timeline of the feature descriptions.
A timeline can be for example a reforecast or a member of an ensemble forecast, in which detected objects should
be tracked over multiple timestamps. This method gets called in parallel for all timelines in the dataset.
This method should compute links of corresponding objects of two consecutive timestamps. Each object in a
timeline has its unique ID, and a computed tuple (id1, id2) remarks that object id1 from timestamp t is the
same object as id2 from timestamp t+1. One tuple is an edge in a tracking graph.
Parameters
----------
timeline : identification_pb2.Timeline
The timeline to be tracked.
subset : xarray.Dataset
Subset to be tracked. Forwarded from identification
Returns
-------
connections : list of tuples of int
The connections forming the path of the objects in the timeline.
"""
connections = []
return connections
def execute(self, object_desc: identification_pb2.DatasetDescription, dataset_ref: xr.Dataset):
"""
Execute the tracking procedure.
The description is split into the timelines which can be executed in parallel.
Parameters
----------
object_desc : identification_pb2.DatasetDescription
The description of the detected features from the identificaiton technique.
dataset_ref : xarray.Dataset
Reference to the dataset used in the pipeline.
"""
tracking_sets = object_desc.sets
from enstools.misc import get_ensemble_dim
# TODO parallelize sets (intra-set is parallelized in comparer)
for tracking_set in tracking_sets:
# TODO split if init time exists?
ensemble_dim = get_ensemble_dim(dataset_ref)
if ensemble_dim is not None:
dataset_sel = dataset_ref.sel({ensemble_dim: tracking_set.member})
else:
dataset_sel = dataset_ref
connections = self.track(tracking_set.timeline, dataset_sel)
for connection in connections:
co_ = tracking_set.connections.add()
co_.id_1 = connection[0]
co_.id_2 = connection[1]
# TODO next link pairs together to "path"
# track then has N-list of IDs
# object_desc has now the links.
# TODO more to do? is edge list of graph enough? maybe wrapper for graph
# TODO what if tracks are the identification? e.g. AEW identification in Hovmoller
pass