Property#

class deeptrack.properties.Property(sampling_rule: Callable[..., Any] | list[Any] | dict[Any, Any] | tuple[Any, ...] | np.ndarray | torch.Tensor | slice | DeepTrackNode | Any, node_name: str | None = None, **dependencies: Property)#

Bases: DeepTrackNode

Property of a feature in the DeepTrack2 framework.

A Property defines a rule for sampling values used to evaluate features. It supports various data types and structures, such as constants, functions, lists, iterators, dictionaries, tuples, NumPy arrays, PyTorch tensors, slices, and DeepTrackNode objects.

The behavior of a Property depends on the type of the sampling rule:

  • Constant values (including tuples, NumPy arrays, and PyTorch

    tensors) always return the same value.

  • Functions are evaluated dynamically, potentially using other

    properties as arguments.

  • **Lists, dictionaries, or tuples ** evaluate and sample each member

    individually.

  • Iterators return the next value in the sequence, repeating the final

    value indefinitely.

  • Slices sample the start, stop, and step values individually.

  • DeepTrackNode’s (e.g., other properties or features) use the value

    computed by the node.

Dependencies between properties are tracked automatically, enabling efficient recomputation when dependencies change.

Parameters#

sampling_rule: Any

The rule for sampling values. Can be a constant, function, list, dictionary, iterator, tuple, NumPy array, PyTorch tensor, slice, or DeepTrackNode.

node_name: str | None

The name of this node. Defaults to None.

**dependencies: Property

Additional dependencies passed as named arguments. These dependencies can be used as inputs to functions or other dynamic components of the sampling rule.

Methods#

create_action(sampling_rule, **dependencies) -> Callable[…, Any]

Creates an action that defines how the property is evaluated. The behavior of the action depends on the type of sampling_rule.

Examples#

>>> import deeptrack as dt

Constant properties are returned forever:

>>> const_prop = dt.Property(42)  # Number
>>> const_prop()
42
>>> const_prop = dt.Property([1, 2, 3])  # List
>>> const_prop()
[1, 2, 3]
>>> const_prop = dt.Property((1, 2, 3))  # Tuple
>>> const_prop()
(1, 2, 3)
>>> import numpy as np
>>>
>>> const_prop = dt.Property(np.array([1, 2, 3]))  # NumPy array
>>> const_prop()
array([1, 2, 3])
>>> import torch
>>>
>>> const_prop = dt.Property(torch.Tensor([1, 2, 3]))  # PyTorch tensor
>>> const_prop()
tensor([1., 2., 3.])

Dynamic property typically use functions and can also depend on other properties:

>>> dynamic_prop = dt.Property(lambda: np.random.rand())
>>> dynamic_prop()  # Returns random value
0.37700241766131415
>>> dynamic_prop()  # Returns same random value
0.37700241766131415
>>> dynamic_prop.update()  # Updates the value
>>> dynamic_prop()  # Returns different random value
0.5862725216547282
>>> dynamic_prop.new()  # Returns different random value
0.36122033451938484
>>> const_prop = dt.Property(5)
>>> dynamic_prop = dt.Property(lambda x: 2 * x, x=const_prop)
>>> dynamic_prop()
10
>>> def func(x):
...     return 2 * x
>>>
>>> const_prop = dt.Property(5)
>>> dynamic_prop = dt.Property(func, x=const_prop)
>>> dynamic_prop()
10

Slices can be constructed from dynamic or static components:

>>> slice_prop = dt.Property(slice(1, lambda: 10, dt.Property(2)))
>>> s = slice_prop()
>>> s.start, s.stop, s.step
(1, 10, 2)

Iterators return their next value each time, repeating the last indefinitely:

>>> iter_prop = dt.Property(iter([1, 2, 3]))
>>> iter_prop()
1
>>> iter_prop.new()  # equivalent to iter_prop.update()()
2
>>> iter_prop.new()
3
>>> iter_prop.new()  # Last value repeats
3

Lists, dictionaries, and tuples can contain properties, functions, or constants:

>>> list_prop = dt.Property([
...     1,
...     lambda: 2,
...     dt.Property(3),
... ])
>>> list_prop()
[1, 2, 3]
>>> dict_prop = dt.Property({
...     "a": 1,
...     "b": lambda: 2,
...     "c": dt.Property(3),
... })
>>> dict_prop()
{'a': 1, 'b': 2, 'c': 3}
>>> tuple_prop = dt.Property((
...     1,
...     lambda: 2,
...     dt.Property(3),
... ))
>>> tuple_prop()
(1, 2, 3)

Property can wrap a DeepTrackNode, such as another feature node:

>>> node = dt.DeepTrackNode(100)
>>> node_prop = dt.Property(node)
>>> node_prop()
100
>>> node = dt.DeepTrackNode(lambda _ID=(): np.random.rand())
>>> node_prop = dt.Property(node)
>>> node_prop()
0.5065650298607408

The ID mechanism allows parameterizing evaluation:

>>> id_prop0 = dt.Property(lambda _ID: _ID)
>>> id_prop0()
()
>>> id_prop0((1,))
()
>>> id_prop0((1, 2, 3))
()
>>> id_prop1 = dt.Property(lambda _ID: _ID)
>>> id_prop1((1,))
(1,)
>>> id_prop1((1, 2, 3))
(1,)
>>> id_prop2 = dt.Property(lambda _ID: _ID)
>>> id_prop2((1, 2, 3))
(1, 2, 3)

Properties can be combined in complex nested structures:

>>> P = dt.Property(
...     {
...         "constant": 42,
...         "list": [1, lambda: 2, dt.Property(3)],
...         "dict": {"a": dt.Property(1), "b": lambda: 2},
...         "function": lambda x, y: x * y,
...         "slice": slice(1, lambda: 10, dt.Property(2)),
...     },
...     x=dt.Property(5),
...     y=dt.Property(3),
... )
>>> result = P()
>>> result["constant"]
42
>>> result["list"]
[1, 2, 3]
>>> result["dict"]
{'a': 1, 'b': 2}
>>> result["function"]
15
>>> result["slice"].start
1
>>> result["slice"].stop
10
>>> result["slice"].step
2

Methods Summary

create_action(sampling_rule, **dependencies)

Create an action defining how the property is evaluated.

Methods Documentation

create_action(sampling_rule: Callable[..., Any] | list[Any] | dict[Any, Any] | tuple[Any, ...] | np.ndarray | torch.Tensor | slice | DeepTrackNode | Any, **dependencies: Property) Callable[..., Any]#

Create an action defining how the property is evaluated.

Parameters#

sampling_rule: Any

The rule to sample values for the property. It can be essentially anything, most often: Callable[…, Any] or list[Any] or dict[Any, Any] or tuple or NumPy array or PyTorch tensor or slice or DeepTrackNode or Any

**dependencies: Property

Dependencies to be used in the sampling rule.

Returns#

Callable[…, Any]

A callable that defines the evaluation behavior of the property.