Skip to content

Frequently Asked Questions

General Questions

What is TracksData?

TracksData is a Python library that provides a common data structure and tools for multi-object tracking. It uses a graph-based representation where objects are nodes and tracks are edges connecting objects across time.

When should I use TracksData?

TracksData is ideal for:

  • Multi-object tracking in microscopy or computer vision
  • Biological cell tracking and lineage analysis
  • Particle tracking in physics simulations
  • Any scenario requiring temporal object associations

How does TracksData differ from other tracking libraries?

TracksData focuses on providing a general unified data structure and modular components that can be combined for different tracking scenarios and scale to large datasets (e.g. millions of nodes in terabytes of 3D + time imaging data).

Which graph backend should I use?

  • RustWorkXGraph: For most applications where data fits in memory
  • SQLGraph: For large datasets or when you need persistent storage
  • GraphView: You shouldn't instantiate this directly, it is used internally by the library when you use graph.subgraph()

Can TracksData handle cell divisions?

Yes! The :class:tracksdata.solvers.NearestNeighborsSolver lets you defined the maximum number of children nodes and :class:tracksdata.solvers.ILPSolver specifically supports division events with configurable division costs.

How do I add custom attributes?

# Add new attribute keys to the graph
graph.add_node_attr_key("my_feature", 0.0)
graph.add_edge_attr_key("confidence", 1.0)

# Use them when adding nodes/edges
graph.add_node({"t": 0, "x": 10, "my_feature": 42.0})
graph.add_edge(source_id, target_id, {"confidence": 0.95})

How do I create custom operators?

Inherit from :class:tracksdata.edges.BaseEdgesOperator or :class:tracksdata.nodes.BaseNodesOperator and implement _add_edges_per_time or _add_nodes_per_time:

from tracksdata.nodes import BaseNodesOperator

class CustomNodes(BaseNodesOperator):
    def _add_nodes_per_time(self, graph, *, t):
        # Your custom logic here
        pass

How do I visualize results?

TracksData provides utilities for converting to napari format:

from tracksdata.functional import to_napari_format

labels, tracks_df, track_graph = to_napari_format(solution_graph)

viewer = napari.Viewer()
viewer.add_labels(labels)
viewer.add_tracks(tracks_df, graph=track_graph)
napari.run()