Product#

class deeptrack.sources.base.Product(_Product__source: Source | None = None, **kwargs: Sequence[Any])#

Bases: Source

Cartesian product of a source with one or more additional fields.

Product constructs a new source by taking the Cartesian product between an existing Source and one or more sequences passed as keyword arguments. Each item in the result is a unique combination of an item from the original source and a value from each added field.

This is typically used via Source.product(…), and the resulting Product can be passed to DeepTrack features for dynamic evaluation.

If no base source is provided, a dummy source with a single empty item is used. This allows syntax such as:

>>> Product(x=[1, 2], y=[3, 4])
Product(x=[1, 1, 2, 2], y=[3, 4, 3, 4])

to create a Cartesian product of just the keyword arguments.

While a list of dictionaries like [{}] would also technically work, this approach is not type-safe. Internally, Source(__dummy=[0]) is used and then cleaned up to preserve correctness and consistency.

Notes#

If the base source is empty, the Cartesian product is also empty. In this case, the resulting Product contains the expected field names, but all fields have length 0.

Parameters#

__source: Source | None, optional

The base source to be expanded. If None, a default single-item source is used, allowing Product to act on keyword arguments alone.

**kwargs: Sequence[Any]

Named sequences to take the product with. Each field will be broadcasted across all items in the base source.

Examples#

>>> from deeptrack.sources import Source

Using the recommended Source.product() method:

>>> source = Source(a=[1, 2])
>>> product = source.product(b=[10, 20])
>>> product
Product(b=[10, 20, 10, 20], a=[1, 1, 2, 2])
>>> list(product)
[SourceItem({'b': 10, 'a': 1}, 1 callback(s)),
 SourceItem({'b': 20, 'a': 1}, 1 callback(s)),
 SourceItem({'b': 10, 'a': 2}, 1 callback(s)),
 SourceItem({'b': 20, 'a': 2}, 1 callback(s))]

Equivalent direct usage of Product (advanced):

>>> from deeptrack.sources.base import Product
>>>
>>> product = Product(source, b=[10, 20])
>>> product
Product(b=[10, 20, 10, 20], a=[1, 1, 2, 2])

Using Product without a base source:

>>> product = Product(x=[1, 2], y=["a", "b"])
>>> product
Product(x=[1, 1, 2, 2], y=['a', 'b', 'a', 'b'])

Empty base sources are supported:

>>> empty = Source(a=[], b=[])
>>> product = empty.product(c=[1, 2])
>>> len(product)
Product(b=[], a=[], c=[])