### Install Documentation Dependencies Source: https://royerlab.github.io/tracksdata/contributing Installs necessary dependencies for documentation management using 'uv'. ```bash # Install dependencies uv sync --extra docs ``` -------------------------------- ### Install TracksData from Source (Development) Source: https://royerlab.github.io/tracksdata/installation Clone the repository and install the latest development version locally. This is useful for contributing to the project or using the most recent features. ```bash git clone https://github.com/royerlab/tracksdata.git cd tracksdata pip install . ``` -------------------------------- ### _setup_ops Source: https://royerlab.github.io/tracksdata/reference/tracksdata/attrs Setup the operator methods for the AttrExpr class. ```APIDOC ## _setup_ops ### Description Setup the operator methods for the AttrExpr class, including arithmetic, logical, and comparison operators. ### Returns None ``` -------------------------------- ### Install TracksData with Optional Test Dependencies Source: https://royerlab.github.io/tracksdata/installation Install TracksData along with the necessary dependencies for running tests. This is recommended if you plan to contribute or ensure the library's integrity. ```bash pip install .[test] ``` -------------------------------- ### Install TracksData with Optional Documentation Dependencies Source: https://royerlab.github.io/tracksdata/installation Install TracksData with the dependencies required to build or view the project's documentation. This is useful for developers who want to work on or inspect the documentation. ```bash pip install .[docs] ``` -------------------------------- ### Install TracksData from PyPI Source: https://royerlab.github.io/tracksdata/installation Use this command to install the latest stable version of TracksData from the Python Package Index. ```bash pip install tracksdata ``` -------------------------------- ### Serve Documentation Locally Source: https://royerlab.github.io/tracksdata/contributing Serves the documentation site locally with live reload using 'mkdocs'. Requires 'uv' to be installed. ```bash # Serve with live reload uv run mkdocs serve ``` -------------------------------- ### Install tracksdata Package Source: https://royerlab.github.io/tracksdata Install the tracksdata Python package using pip. This command fetches and installs the latest version of the library. ```bash pip install tracksdata ``` -------------------------------- ### List All Documentation Versions Source: https://royerlab.github.io/tracksdata/contributing Lists all managed documentation versions using 'mike'. Requires 'uv' to be installed. ```bash # List all versions uv run mike list ``` -------------------------------- ### Build Static Documentation Site Source: https://royerlab.github.io/tracksdata/contributing Builds the static version of the documentation site using 'mkdocs'. Requires 'uv' to be installed. ```bash # Build static site uv run mkdocs build ``` -------------------------------- ### Verify TracksData Installation Source: https://royerlab.github.io/tracksdata/installation Import the library and print its version to confirm a successful installation. This is a quick check to ensure TracksData is accessible in your Python environment. ```python import tracksdata as td print(td.__version__) ``` -------------------------------- ### Deploy New Documentation Version Source: https://royerlab.github.io/tracksdata/contributing Deploys a new documentation version using 'mike', updating aliases. Requires 'uv' to be installed. ```bash # Deploy a new version uv run mike deploy --push --update-aliases v1.0.0 latest ``` -------------------------------- ### Set Default Documentation Version Source: https://royerlab.github.io/tracksdata/contributing Sets the default documentation version to 'latest' using 'mike'. Requires 'uv' to be installed. ```bash # Set default version uv run mike set-default --push latest ``` -------------------------------- ### Main Function with Profiling Option Source: https://royerlab.github.io/tracksdata/examples The main entry point for the script. It accepts a '--profile' flag to enable performance profiling, which disables the napari viewer. Otherwise, it runs the tracking example with visualization. ```python @click.command() @click.option("--profile", is_flag=True, help="Enable performance profiling (disables napari viewer)") def main(profile: bool) -> None: """Run the basic tracking example with optional profiling.""" if profile: # Run with performance profiling, no visualization profile_hook(basic_tracking_example, immediate=True, sort="time")(show_napari_viewer=False) else: # Normal run with visualization basic_tracking_example(show_napari_viewer=True) if __name__ == "__main__": main() ``` -------------------------------- ### Example Usage of SpatialFilter Source: https://royerlab.github.io/tracksdata/reference/tracksdata/graph/filters Demonstrates how to create a graph, add nodes with spatial coordinates, initialize a SpatialFilter with specific 2D attributes, and query for nodes within a defined spatial region. ```python graph = RustWorkXGraph() # Add nodes with spatial coordinates graph.add_node({"t": 0, "y": 10, "x": 20}) graph.add_node({"t": 1, "y": 30, "x": 40}) # Create spatial filter with 2D coordinates spatial_filter = SpatialFilter(graph, attr_keys=["y", "x"]) # Query nodes in spatial region subgraph = spatial_filter[0:50, 0:50] ``` -------------------------------- ### Basic Tracking Example with TracksData Source: https://royerlab.github.io/tracksdata/examples Demonstrates the core TracksData workflow: node extraction, distance-based edge creation, IoU attribute computation, and nearest neighbors tracking solution. Requires Cell Tracking Challenge data and the Fluo-N2DL-HeLa dataset structure. Can be run with or without napari visualization. ```python """ Basic multi-object tracking example using TracksData. This example demonstrates the complete workflow for tracking objects across time: 1. Load segmented image data 2. Extract object features (nodes) from each frame 3. Create temporal connections (edges) between objects 4. Compute additional attributes to edges (e.g. IoU) 5. Solve the tracking optimization problem 6. Convert results to napari format 7. Visualize results Requirements: - Set CTC_DIR environment variable pointing to Cell Tracking Challenge data - Example assumes Fluo-N2DL-HeLa dataset structure Usage: python basic.py # Run with napari visualization python basic.py --profile # Run with performance profiling """ import os from pathlib import Path import click import napari import numpy as np from profilehooks import profile as profile_hook from tifffile import imread import tracksdata as td def basic_tracking_example(show_napari_viewer: bool = True) -> None: """ Perform basic multi-object tracking on segmented microscopy data. This function demonstrates the core TracksData workflow: - Node extraction from regionprops - Distance-based edge creation - IoU attribute computation - Nearest neighbors tracking solution Parameters ---------- show_napari_viewer : bool Whether to display results in napari viewer """ # Step 1: Load and prepare data # Load example data from Cell Tracking Challenge format data_dir = Path(os.environ["CTC_DIR"]) / "training/Fluo-N2DL-HeLa/01_GT/TRA" assert data_dir.exists(), f"Data directory {data_dir} does not exist." # Load all timepoints as a 3D array: (time, height, width) labels = np.stack( [imread(p) for p in sorted(data_dir.glob("*.tif"))], ) # Configure TracksData options (disable progress bars for cleaner output) td.options.set_options(show_progress=False) print("Starting tracking workflow...") # Step 2: Initialize graph and extract nodes graph = td.graph.InMemoryGraph() # Extract object features using region properties # This creates one node per object per timeframe nodes_operator = td.nodes.RegionPropsNodes() nodes_operator.add_nodes(graph, labels=labels) print(f"✓ Extracted {graph.num_nodes()} nodes from {labels.shape[0]} timeframes") # Step 3: Create temporal edges between consecutive frames # Add distance-based edges between objects in consecutive timeframes # Only connects objects within distance_threshold and limits to n_neighbors dist_operator = td.edges.DistanceEdges( distance_threshold=30.0, n_neighbors=5, ) dist_operator.add_edges(graph) print(f"✓ Created {graph.num_edges()} potential temporal connections") # Step 4: Add IoU (Intersection over Union) attributes to edges # Compute IoU between connected objects to measure shape similarity # Higher IoU values indicate better matches for tracking iou_operator = td.edges.IoUEdgeAttr(output_key="iou") iou_operator.add_edge_attrs(graph) print("✓ Computed IoU attributes for edge weights") # Step 5: Solve tracking optimization problem # Create edge weights combining distance and IoU information # Lower distance + higher IoU = better connection (lower cost) dist_weight = 1 / dist_operator.distance_threshold # Use nearest neighbors solver for fast, greedy tracking # Each edge weight is defined as: # - IoU(e_ij) * exp(-distance(e_ij) / dist_threshold) # Where e_ij is the edge between nodes i and j. # Alternative: ILPSolver for globally optimal but slower solutions solver = td.solvers.NearestNeighborsSolver( edge_weight=-td.EdgeAttr("iou") * (td.EdgeAttr("distance") * dist_weight).exp(), max_children=2, # Allow cell divisions (max 2 children per parent) ) ``` -------------------------------- ### Visualize Tracking Results with Napari Source: https://royerlab.github.io/tracksdata/examples Optionally opens a napari viewer to display the tracked labels and trajectories. This step requires the napari library to be installed and is controlled by the 'show_napari_viewer' flag. ```python # Step 7: Visualize results (optional) if show_napari_viewer: print("Opening napari viewer...") viewer = napari.Viewer() # Add original segmented labels viewer.add_labels(track_labels, name="Tracked Labels") # Add tracking trajectories with lineage information viewer.add_tracks(tracks_df, graph=track_graph, name="Tracks") # Start interactive viewer napari.run() ``` -------------------------------- ### Delete Documentation Version Source: https://royerlab.github.io/tracksdata/contributing Deletes a specific documentation version using 'mike'. Requires 'uv' to be installed. ```bash # Delete a version uv run mike delete --push v0.9.0 ``` -------------------------------- ### Setup Operators for AttrExpr (_setup_ops) Source: https://royerlab.github.io/tracksdata/reference/tracksdata/attrs This function sets up various operator methods for the AttrExpr class, including arithmetic and logical operators. It is designed to work with both Attr and AttrComparison types, ensuring proper handling of operations across different expression types. ```python def _setup_ops() -> None: """ Setup the operator methods for the AttrExpr class. """ # Arithmetic operators: generated for both Attr and AttrComparison. bin_ops = { "add": operator.add, "sub": operator.sub, "mul": operator.mul, "truediv": operator.truediv, "floordiv": operator.floordiv, "mod": operator.mod, "pow": operator.pow, } # Logical operators: generated only for Attr (bitwise on the polars expr). # AttrComparison inherits `& | ^ ~` from `Filter` (they build AttrFilter # compounds), so they are intentionally excluded here. logical_ops = { "and": operator.and_, "or": operator.or_, "xor": operator.xor, } comp_ops = { "eq": operator.eq, "ne": operator.ne, "lt": operator.lt, "le": operator.le, "gt": operator.gt, "ge": operator.ge, } for op_name, op_func in (bin_ops | logical_ops).items(): _add_operator(Attr, f"__{op_name}__", op_func, reverse=False) _add_operator(Attr, f"__r{op_name}__", op_func, reverse=True) for op_name, op_func in bin_ops.items(): _add_operator(AttrComparison, f"__{op_name}__", op_func, reverse=False) _add_operator(AttrComparison, f"__r{op_name}__", op_func, reverse=True) # No reverse comparison operators (`__rlt__` etc.) — Python uses the # opposite op for reflected `<>≤≥` and `__eq__`/`__ne__` symmetrically. for op_name, op_func in comp_ops.items(): _add_comparison_operator(f"__{op_name}__", op_func) # AttrComparison uses normal delegate_operator _add_operator(AttrComparison, f"__{op_name}__", op_func, reverse=False) ``` -------------------------------- ### Generate 3D Random Nodes with Consistent Count Source: https://royerlab.github.io/tracksdata/reference/tracksdata/nodes Example of generating 3D random nodes with a fixed number of nodes per time point. Useful for simulations requiring consistent data size. ```python node_op = RandomNodes( n_time_points=20, n_nodes_per_tp=(10, 10), # exactly 10 nodes per time point n_dim=3, ) ``` -------------------------------- ### Visualize Graph Matches with napari Source: https://royerlab.github.io/tracksdata/reference/tracksdata/metrics Use this function to visualize predicted matches against a reference graph. It requires napari to be installed and can be customized with arguments for points and vectors. If no viewer is provided, a new one is created. ```python def visualize_matches( input_graph: BaseGraph, ref_graph: BaseGraph, matched_node_id_key: str = DEFAULT_ATTR_KEYS.MATCHED_NODE_ID, match_score_key: str = DEFAULT_ATTR_KEYS.MATCH_SCORE, matched_edge_mask_key: str = DEFAULT_ATTR_KEYS.MATCHED_EDGE_MASK, viewer: Optional["napari.Viewer"] = None, points_kwargs: dict | None = None, vector_kwargs: dict | None = None, ) -> None: """ Visualize the matches between the graph and the gt_graph. Parameters ---------- input_graph : BaseGraph The predicted graph to visualize. ref_graph : BaseGraph The reference (ground truth) graph to visualize. matched_node_id_key : str, optional The key of the attribute that contains the matched node IDs. If not provided, the default key will be used. match_score_key : str, optional The key of the attribute that contains the match scores. If not provided, the default key will be used. matched_edge_mask_key : str, optional The key of the attribute that contains the matched edge mask. If not provided, the default key will be used. viewer : napari.Viewer, optional The napari viewer to use. If not provided, a new viewer will be created. points_kwargs : dict, optional Additional keyword arguments to the napari.Viewer.add_points method. vector_kwargs : dict, optional Additional keyword arguments to the napari.Viewer.add_vectors method. """ try: import napari except ImportError as e: raise ImportError( "napari must be installed to use this function.\nPlease install it with `pip install napari`.", ) from e if viewer is None: viewer = napari.Viewer() if DEFAULT_ATTR_KEYS.Z in input_graph.node_attr_keys(): pos = [DEFAULT_ATTR_KEYS.T, DEFAULT_ATTR_KEYS.Z, DEFAULT_ATTR_KEYS.Y, DEFAULT_ATTR_KEYS.X] else: pos = [DEFAULT_ATTR_KEYS.T, DEFAULT_ATTR_KEYS.Y, DEFAULT_ATTR_KEYS.X] node_attrs = input_graph.node_attrs() ref_node_attrs = ref_graph.node_attrs() matched_points_kwargs = _add_matching_text_and_color(points_kwargs) points_kwargs = _points_kwargs_defaults(points_kwargs) layer = viewer.add_points( node_attrs[pos], name="predicted", properties={ "matched_node_id": node_attrs[matched_node_id_key], "match_score": node_attrs[match_score_key], "matched": node_attrs[matched_node_id_key] >= 0, }, **matched_points_kwargs, ) layer.text.visible = False ``` -------------------------------- ### NodeAttr root_column examples Source: https://royerlab.github.io/tracksdata/reference/tracksdata Provides examples of how to retrieve the top-level column name from which a NodeAttr expression originates. ```python Attr("t").root_column == "t" NodeAttr("measurements").struct.field("score").root_column == "measurements" ``` -------------------------------- ### Options.__enter__ Source: https://royerlab.github.io/tracksdata/reference/tracksdata/options Enters the context manager, pushing the current options to the stack. ```APIDOC ## `__enter__` ```python __enter__() -> Options ``` Enter the context manager. ``` -------------------------------- ### Initialize ILPSolver with default parameters Source: https://royerlab.github.io/tracksdata/reference/tracksdata/solvers Instantiate ILPSolver with default edge weight. The solver finds globally optimal solutions by minimizing a cost function while satisfying flow conservation constraints. ```python from tracksdata.solvers import ILPSolver solver = ILPSolver(edge_weight="distance") solution = solver.solve(graph) ``` -------------------------------- ### _axis_names Method Source: https://royerlab.github.io/tracksdata/reference/tracksdata/nodes Get the names of the axes of the labels. ```APIDOC ## _axis_names ### Description Get the names of the axes of the labels. ### Parameters #### `labels` (`NDArray[integer]`) – The (t + nD) labels to get the axis names for. ### Returns * `list[str]` – The names of the axes of the labels. ``` -------------------------------- ### Initialize ILPSolver with appearance and disappearance costs Source: https://royerlab.github.io/tracksdata/reference/tracksdata/solvers Configure ILPSolver to include costs for track appearances and disappearances. This allows for more nuanced tracking in scenarios with frequent track initiation or termination. ```python solver = ILPSolver(edge_weight="distance", appearance_weight=10.0, disappearance_weight=10.0) solution = solver.solve(graph) ``` -------------------------------- ### attr_keys Method Source: https://royerlab.github.io/tracksdata/reference/tracksdata/nodes Get the keys of the node attributes that will be extracted. ```APIDOC ## attr_keys ### Description Get the keys of the node attributes that will be extracted. ### Returns * `list` - A list of attribute keys. ``` -------------------------------- ### Get Array Length Source: https://royerlab.github.io/tracksdata/reference/tracksdata/array Returns the length of the first dimension of the array. ```python def __len__(self) -> int: """Returns the length of the first dimension of the array.""" return self.shape[0] ``` -------------------------------- ### Get Array Size Source: https://royerlab.github.io/tracksdata/reference/tracksdata/array Returns the total number of elements in the array. ```python size: int ``` -------------------------------- ### Get Array Shape Source: https://royerlab.github.io/tracksdata/reference/tracksdata/array Returns the shape of the array as a tuple of integers. ```python shape: tuple[int, ...] ``` -------------------------------- ### ILPSolver Constructor Source: https://royerlab.github.io/tracksdata/reference/tracksdata/solvers Initializes the ILPSolver with various weighting parameters and solver configurations. ```APIDOC ## ILPSolver __init__ ### Description Initializes the ILPSolver with various weighting parameters and solver configurations. ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Method __init__ ### Parameters - **edge_weight** (str | ExprInput, optional): Weight for edge attributes. Defaults to DEFAULT_ATTR_KEYS.EDGE_DIST. - **node_weight** (str | ExprInput, optional): Weight for node attributes. Defaults to 0.0. - **appearance_weight** (str | ExprInput, optional): Weight for appearance attributes. Defaults to 0.0. - **disappearance_weight** (str | ExprInput, optional): Weight for disappearance attributes. Defaults to 0.0. - **division_weight** (str | ExprInput, optional): Weight for division attributes. Defaults to 0.0. - **merge_weight** (None | str | ExprInput, optional): Weight for merge attributes. Defaults to None. - **output_key** (str, optional): Key for the output solution. Defaults to DEFAULT_ATTR_KEYS.SOLUTION. - **num_threads** (int, optional): Number of threads to use for solving. Defaults to 1. - **reset** (bool, optional): Whether to reset the model. Defaults to True. - **return_solution** (bool, optional): Whether to return the solution. Defaults to True. - **gap** (float, optional): Solver gap tolerance. Defaults to 0.0. - **timeout** (float | None, optional): Solver timeout in seconds. Defaults to None. ### Request Example ```python ILPSolver( edge_weight="my_edge_weight", node_weight=0.5, appearance_weight="appearance_attr", disappearance_weight="disappearance_attr", division_weight="division_attr", merge_weight="merge_attr", output_key="my_solution", num_threads=4, reset=False, return_solution=True, gap=0.1, timeout=60.0 ) ``` ### Response None (constructor) ``` -------------------------------- ### SpatialFilter Source: https://royerlab.github.io/tracksdata/reference/tracksdata/graph/filters A general spatial filter class for graph data. It includes parameters and examples for usage. ```APIDOC ## Class SpatialFilter ### Description A base class or general implementation for spatial filtering in graphs. ### Parameters This class does not explicitly list parameters in the provided documentation. ### Examples Examples of how to use the SpatialFilter class are provided in the source documentation. ### Methods #### `__getitem__(self, keys)` Retrieves elements based on keys. ``` -------------------------------- ### Get Required Attributes Source: https://royerlab.github.io/tracksdata/reference/tracksdata/metrics Retrieves the list of node attributes that are required by a specific matching strategy. ```APIDOC ## get_required_attrs ### Description Get the list of required node attributes for this matching strategy. ### Method Signature `get_required_attrs(attr_keys: list[str]) -> list[str]` ### Parameters #### `attr_keys` - **`attr_keys`** (list[str]) - Required - List of attribute keys to consider. ### Returns - `list[str]` - List of attribute keys required by this matching strategy. ``` -------------------------------- ### Matching Class Initialization Source: https://royerlab.github.io/tracksdata/reference/tracksdata/metrics Initializes a matching strategy. Use 'optimal=True' for one-to-one matching and 'optimal=False' for multiple matches per node. ```python def __init__(self, optimal: bool): """ Initialize the matching strategy. Parameters ---------- optimal : bool Whether to perform optimal matching. """ self.optimal = optimal ``` -------------------------------- ### Get EdgeAttr Expression Columns Source: https://royerlab.github.io/tracksdata/reference/tracksdata Retrieves the names of columns involved in the expression of an EdgeAttr object. ```python expr_columns: list[str] ``` -------------------------------- ### Initialize ILPSolver Source: https://royerlab.github.io/tracksdata/reference/tracksdata/solvers Initializes the ILPSolver with various weighting parameters for edges, nodes, and appearance/disappearance events. Allows configuration of output keys, thread count, and solver parameters like gap and timeout. ```python def __init__( self, *, edge_weight: str | ExprInput = DEFAULT_ATTR_KEYS.EDGE_DIST, node_weight: str | ExprInput = 0.0, appearance_weight: str | ExprInput = 0.0, disappearance_weight: str | ExprInput = 0.0, division_weight: str | ExprInput = 0.0, merge_weight: None | str | ExprInput = None, output_key: str = DEFAULT_ATTR_KEYS.SOLUTION, num_threads: int = 1, reset: bool = True, return_solution: bool = True, gap: float = 0.0, timeout: float | None = None, ): super().__init__(output_key=output_key, reset=reset, return_solution=return_solution) self.edge_weight_expr = EdgeAttr(edge_weight) self.node_weight_expr = NodeAttr(node_weight) self.appearance_weight_expr = NodeAttr(appearance_weight) self.disappearance_weight_expr = NodeAttr(disappearance_weight) self.division_weight_expr = NodeAttr(division_weight) self.merge_weight_expr = None if merge_weight is None else NodeAttr(merge_weight) self.num_threads = num_threads self.gap = gap self.timeout = timeout self.reset_model() ``` -------------------------------- ### Initialize NearestNeighborsSolver Source: https://royerlab.github.io/tracksdata/reference/tracksdata/solvers Instantiate the solver with default parameters. Use this for basic tracking scenarios. ```python from tracksdata.solvers import NearestNeighborsSolver solver = NearestNeighborsSolver() ``` -------------------------------- ### Get Node Attribute Keys Source: https://royerlab.github.io/tracksdata/reference/tracksdata/nodes Retrieves a list of all attribute keys currently associated with nodes in the graph. ```python attr_keys() -> list[str] ``` -------------------------------- ### Create Graph and Add Tracking Data Source: https://royerlab.github.io/tracksdata/getting_started This snippet demonstrates how to initialize an in-memory graph, generate random nodes, connect them with edges based on distance, and solve the tracking problem using NearestNeighborsSolver. It's useful for testing and understanding the basic workflow. ```python import numpy as np import tracksdata as td # Create a graph graph = td.graph.InMemoryGraph() # Generate random nodes for testing node_generator = td.nodes.RandomNodes( n_time_points=5, n_nodes_per_tp=(10, 15), n_dim=2 ) node_generator.add_nodes(graph) # Connect nearby nodes across time edge_generator = td.edges.DistanceEdges( distance_threshold=0.3, n_neighbors=3 ) edge_generator.add_edges(graph) # Solve the tracking problem solver = td.solvers.NearestNeighborsSolver(edge_weight="distance") solution = solver.solve(graph) print(f"Original graph has {graph.num_nodes()} nodes and {graph.num_edges()} edges") print(f"Solution has {solution.num_nodes()} nodes and {solution.num_edges()} edges") ``` -------------------------------- ### NodeAttr field_path examples Source: https://royerlab.github.io/tracksdata/reference/tracksdata Demonstrates how to access the nested struct-field path relative to the root column for NodeAttr expressions. ```python Attr("t").field_path == () NodeAttr("measurements").struct.field("score").field_path == ("score",) NodeAttr("meta").struct.field("det").struct.field("conf").field_path == ("det", "conf") ``` -------------------------------- ### Get EdgeAttr Negative Infinity Expressions Source: https://royerlab.github.io/tracksdata/reference/tracksdata Retrieves the expressions that are multiplied by negative infinity within the EdgeAttr object. ```python neg_inf_exprs: list[Attr] ``` -------------------------------- ### Get EdgeAttr Positive Infinity Expressions Source: https://royerlab.github.io/tracksdata/reference/tracksdata Retrieves the expressions that are multiplied by positive infinity within the EdgeAttr object. ```python inf_exprs: list[Attr] ``` -------------------------------- ### Matching Strategy Initialization Source: https://royerlab.github.io/tracksdata/reference/tracksdata/metrics Initializes a matching strategy for graph nodes. The `optimal` parameter determines whether to use optimal bipartite matching algorithms. ```APIDOC ## Matching ### Description Base class for matching strategies between graph nodes. ### Method Signature `Matching(optimal: bool)` ### Parameters #### `optimal` - **`optimal`** (bool) - Required - Whether to perform optimal matching using bipartite matching algorithms. When True, ensures one-to-one correspondence between matched nodes. When False, allows multiple matches per node. ``` -------------------------------- ### Get EdgeAttr Negative Infinity Columns Source: https://royerlab.github.io/tracksdata/reference/tracksdata Retrieves the names of columns that are multiplied by negative infinity within the EdgeAttr expression. ```python neg_inf_columns: list[str] ``` -------------------------------- ### get_options Source: https://royerlab.github.io/tracksdata/reference/tracksdata/options Retrieves the current global options. ```APIDOC ## `get_options` Get the current global options. ``` -------------------------------- ### Get EdgeAttr Positive Infinity Columns Source: https://royerlab.github.io/tracksdata/reference/tracksdata Retrieves the names of columns that are multiplied by positive infinity within the EdgeAttr expression. ```python inf_columns: list[str] ``` -------------------------------- ### options_context Source: https://royerlab.github.io/tracksdata/reference/tracksdata/options A context manager for temporarily modifying global options. ```APIDOC ## `options_context` Context manager for temporarily modifying options. ``` -------------------------------- ### Enter Options Context Manager Source: https://royerlab.github.io/tracksdata/reference/tracksdata/options Enters the context manager for the Options class, pushing the current options to a stack. This method is part of the Options dataclass. ```python def __enter__(self) -> "Options": """Enter the context manager.""" # Push current options to stack _options_stack.append(self) return self ``` -------------------------------- ### Get Root Column of an Attribute Source: https://royerlab.github.io/tracksdata/reference/tracksdata/attrs Access the top-level column name from which an attribute expression originates. Useful for tracking data lineage. ```python root_column: str | None ``` -------------------------------- ### Initialize ILPSolver with attribute expressions for complex costs Source: https://royerlab.github.io/tracksdata/reference/tracksdata/solvers Utilize attribute expressions for defining complex edge costs, combining distance and angle change. This enables fine-grained control over track continuity and behavior. ```python from tracksdata.attrs import EdgeAttr solver = ILPSolver(edge_weight=EdgeAttr("distance") + 0.1 * EdgeAttr("angle_change"), division_weight=5.0) solution = solver.solve(graph) ``` -------------------------------- ### Get Node Attribute Keys Source: https://royerlab.github.io/tracksdata/reference/tracksdata/nodes Retrieves the keys for extra node properties that will be extracted. Centroid coordinates and mask are always included. ```python node_op = RegionPropsNodes(extra_properties=["area", "perimeter"]) keys = node_op.attr_keys() print(keys) # ['area', 'perimeter'] ``` -------------------------------- ### Mask Initialization Source: https://royerlab.github.io/tracksdata/reference/tracksdata/nodes Initializes a Mask object with a binary mask and its bounding box. ```APIDOC ## Mask ``` Mask(mask: NDArray[bool_], bbox: ArrayLike) ``` ### Description Object used to store an individual segmentation mask of a single instance (object). ### Parameters * **mask** (NDArray[np.bool_]) - A binary indicating the pixels that are part of the object (e.g. cell, nucleus, etc.). * **bbox** (np.ndarray) - The bounding box of the region of interest with shape (2 * ndim,). The first ndim elements are the start indices and the last ndim elements are the end indices. Equivalent to slicing a numpy array with `[start:end]`. ### Example ```python mask = Mask(mask=np.array([[True, False], [False, True]]), bbox=np.array([0, 0, 2, 2])) ``` ``` -------------------------------- ### Get Required Attributes for Distance Matching Source: https://royerlab.github.io/tracksdata/reference/tracksdata/metrics Retrieves the necessary attribute keys for distance matching. Returns default keys if none are specified. ```python def get_required_attrs(self, attr_keys: list[str]) -> list[str]: """ Get required attributes for distance matching. Returns ------- list[str] List of centroid coordinate keys. """ if self.attr_keys is None: if DEFAULT_ATTR_KEYS.Z in attr_keys: return [DEFAULT_ATTR_KEYS.Z, DEFAULT_ATTR_KEYS.Y, DEFAULT_ATTR_KEYS.X] else: return [DEFAULT_ATTR_KEYS.Y, DEFAULT_ATTR_KEYS.X] else: return list(self.attr_keys) ``` -------------------------------- ### Get Current Global Options Source: https://royerlab.github.io/tracksdata/reference/tracksdata/options Retrieves the current global options instance. Returns the top of the options stack or default options if the stack is empty. ```python def get_options() -> Options: """ Get the current global options. Returns ------- Options The current global options instance. """ # Return the top of the stack, or default if stack is empty return _options_stack[-1] if _options_stack else _default_options ``` -------------------------------- ### Options.__exit__ Source: https://royerlab.github.io/tracksdata/reference/tracksdata/options Exits the context manager, popping the current options from the stack. ```APIDOC ## `__exit__` ```python __exit__(exc_type: Any, exc_val: Any, exc_tb: Any) -> None ``` Exit the context manager. ``` -------------------------------- ### get_options Source: https://royerlab.github.io/tracksdata/reference/tracksdata/options Retrieves the current global options instance. This function allows you to inspect the active configuration settings. ```APIDOC ## get_options ### Description Get the current global options. ### Returns * `Options` – The current global options instance. ``` -------------------------------- ### Evaluate CTC Metrics with py-ctcmetrics Source: https://royerlab.github.io/tracksdata/reference/tracksdata/metrics Use this function to compute CTC metrics. Ensure `py-ctcmetrics` is installed. Note that the 'SEG' metric is derived from TRA masks. ```python from ctc_metrics.metrics import ALL_METRICS from ctc_metrics.scripts.evaluate import calculate_metrics def evaluate_ctc_metrics( input_graph: "RustWorkXGraph", reference_graph: "RustWorkXGraph", input_tracklet_id_key: str = DEFAULT_ATTR_KEYS.TRACKLET_ID, reference_tracklet_id_key: str = DEFAULT_ATTR_KEYS.TRACKLET_ID, input_reset: bool = True, reference_reset: bool = False, metrics: list[str] | None = None, ) -> dict[str, float]: """ Evaluate CTC metrics using `py-ctcmetrics` developed by [Timo Kaiser](https://github.com/TimoK93). If you use this function, please cite the respective papers of each metric, as described in [here](https://github.com/CellTrackingChallenge/py-ctcmetrics?tab=readme-ov-file#acknowledgement-and-citations). IMPORTANT: The `SEG` metric is computed from the TRA masks. Parameters ---------- input_graph : RustWorkXGraph Input graph. reference_graph : RustWorkXGraph Reference graph. input_tracklet_id_key : str, optional Key to obtain the track id from the input graph. If key does not exist, it will be created. reference_tracklet_id_key : str, optional Key to obtain the track id from the reference graph. If key does not exist, it will be created. input_reset : bool, optional Whether to reset the track ids of the input graph. If True, the track ids will be reset to -1. reference_reset : bool, optional Whether to reset the track ids of the reference graph. If True, the track ids will be reset to -1. metrics : list[str] | None, optional List of metrics to evaluate. If None, all metrics are evaluated. Available metrics: "CHOTA", "BC", "CT", "CCA", "TF", "TRA", "DET", "MOTA", "HOTA", "IDF1", "MTML", "FAF", "LNK", "OP_CTB", "OP_CSB", "BIO", "OP_CLB" Returns ------- dict[str, float] Dictionary with the results of the evaluated metrics. """ try: from ctc_metrics.metrics import ALL_METRICS from ctc_metrics.scripts.evaluate import calculate_metrics except ImportError as e: raise ImportError( "`py-ctcmetrics` is required to evaluate CTC metrics.\nPlease install it with `pip install py-ctcmetrics`." ) from e if metrics is None: metrics: list[str] = ALL_METRICS.copy() if "SEG" in metrics: LOG.warning("IMPORTANT! 'SEG' metric results are based on TRA masks, not the SEG masks.") if input_graph.num_nodes() == 0: LOG.warning("Input graph has no nodes, returning -1.0 for all metrics.") return dict.fromkeys(metrics, -1.0) if input_reset or input_tracklet_id_key not in input_graph.node_attr_keys(): input_graph.assign_tracklet_ids(input_tracklet_id_key, reset=input_reset) if reference_reset or reference_tracklet_id_key not in reference_graph.node_attr_keys(): reference_graph.assign_tracklet_ids(reference_tracklet_id_key, reset=reference_reset) input_tracks, reference_tracks, matching_data = compute_ctc_metrics_data( input_graph, reference_graph, input_tracklet_id_key, reference_tracklet_id_key ) results = calculate_metrics( comp_tracks=input_tracks, ref_tracks=reference_tracks, traj=matching_data, segm=matching_data, metrics=metrics, is_valid=True, ) results = {k: v.item() if hasattr(v, "item") else v for k, v in results.items()} return results ``` -------------------------------- ### ILPSolver Source: https://royerlab.github.io/tracksdata/reference/tracksdata/solvers The ILPSolver class provides methods for solving graph problems using Integer Linear Programming. It allows configuration of various weights, output options, and solver parameters like threads, gap, and timeout. ```APIDOC ## ILPSolver ### Description Provides methods for solving graph problems using Integer Linear Programming. Allows configuration of various weights, output options, and solver parameters. ### Parameters * **edge_weight** (float) - Optional - Weight for edges. * **node_weight** (float) - Optional - Weight for nodes. * **appearance_weight** (float) - Optional - Weight for appearance. * **disappearance_weight** (float) - Optional - Weight for disappearance. * **division_weight** (float) - Optional - Weight for division. * **merge_weight** (float) - Optional - Weight for merge. * **output_key** (string) - Optional - Key for output. * **num_threads** (int) - Optional - Number of threads to use. * **reset** (bool) - Optional - Whether to reset the solver. * **return_solution** (bool) - Optional - Whether to return the solution. * **gap** (float) - Optional - Solver gap tolerance. * **timeout** (float) - Optional - Solver timeout in seconds. ### Methods #### _evaluate_inf_expr Evaluates an infinite expression. ##### Parameters * **inf_expr** - The infinite expression to evaluate. * **df** (pandas.DataFrame) - DataFrame containing data. * **node_key** (string) - The key for the node. ``` -------------------------------- ### Get Required Attributes for Matching Source: https://royerlab.github.io/tracksdata/reference/tracksdata/metrics Abstract method to retrieve the list of node attributes required by a matching strategy. Filters attributes based on provided keys. ```python @abc.abstractmethod def get_required_attrs(self, attr_keys: list[str]) -> list[str]: """ Get the list of required node attributes for this matching strategy. Parameters ---------- attr_keys : list[str] List of attribute keys to consider. Returns ------- list[str] List of attribute keys required by this matching strategy. """ ``` -------------------------------- ### Set Tracksdata Options with Options Object Source: https://royerlab.github.io/tracksdata/reference/tracksdata/options Use this method to set global options by providing a pre-configured Options object. Ensure 'Options' and 'set_options' are imported. ```python >>> from tracksdata.options import Options, set_options >>> set_options(Options(show_progress=False)) ``` -------------------------------- ### Get Required Attributes for Mask Matching Source: https://royerlab.github.io/tracksdata/reference/tracksdata/metrics Retrieves the list of required attributes for mask matching. Raises a ValueError if the default mask attribute key is not provided. ```python def get_required_attrs(self, attr_keys: list[str]) -> list[str]: """ Get required attributes for mask matching. Returns ------- list[str] List containing the mask attribute key. """ if DEFAULT_ATTR_KEYS.MASK not in attr_keys: raise ValueError(f"Mask attribute key '{DEFAULT_ATTR_KEYS.MASK}' is required for mask matching") return [DEFAULT_ATTR_KEYS.MASK] ``` -------------------------------- ### Get EdgeAttr Field Path Source: https://royerlab.github.io/tracksdata/reference/tracksdata Retrieves the nested struct-field path relative to the root column for an EdgeAttr object. An empty tuple indicates no nested access. ```python field_path: tuple[str, ...] ``` -------------------------------- ### Options.copy Source: https://royerlab.github.io/tracksdata/reference/tracksdata/options Returns a copy of the current options object. ```APIDOC ## `copy` ```python copy() -> Options ``` Return a copy of the options. ``` -------------------------------- ### options_context Source: https://royerlab.github.io/tracksdata/reference/tracksdata/options Provides a context manager for temporarily modifying global options. Changes made within the `with` block are local and do not affect the global state outside of it. ```APIDOC ## options_context ### Description Context manager for temporarily modifying options. ### Parameters * **`**kwargs`** (`Any`, default: `{}` ) – Options parameters to temporarily set. ### Yields * `Options` – The options object with the temporary settings. ### Examples ```python from tracksdata.options import options_context with options_context(show_progress=False): # Operations here will not show progress pass ``` ``` -------------------------------- ### Get Pixel Indices for a Mask Source: https://royerlab.github.io/tracksdata/reference/tracksdata/nodes Retrieves the indices of pixels that constitute the object within a mask. An optional offset can be applied, which is useful when working with bounding box information. ```python def mask_indices(self, offset: NDArray[np.integer] | int = 0, ) -> tuple[NDArray[np.integer], ...]: """ Get the indices of the pixels that are part of the object. Parameters ---------- offset : NDArray[np.integer] | int, optional The offset to add to the indices, should be used with bounding box information. Returns ------- tuple[NDArray[np.integer], ...] The indices of the pixels that are part of the object. """ if isinstance(offset, int): offset = np.full(self._mask.ndim, offset) indices = list(np.nonzero(self._mask)) for i, index in enumerate(indices): indices[i] = index + self._bbox[i] + offset[i] return tuple(indices) ```