napari_track_edit.motile.backend.solve

Attributes

logger

PIN_ATTR

PIN_UNSET

PIN_UNSELECTED

PIN_SELECTED

_SKIP_ATTRS

_SKIP_ATTRS

Classes

TernaryPin

Like motile's Pin, but treats PIN_UNSET as unconstrained.

Functions

graphview_to_motile_dicts(→ tuple[dict[int, dict], ...)

Unpack a tracksdata GraphView into plain node/edge dicts for motile.TrackGraph.

solve(→ tracksdata.graph.BaseGraph)

Get a tracking solution for the given segmentation and parameters.

build_candidate_graph(→ tracksdata.graph.BaseGraph)

Build the candidate graph from input data.

_solve_full(→ tracksdata.graph.BaseGraph)

Solve the tracking problem on the full candidate graph at once.

_solve_window(→ tracksdata.graph.BaseGraph | None)

Solve a single window subgraph.

_solve_single_window(→ tracksdata.graph.BaseGraph)

Solve a single window for interactive parameter testing.

_solve_chunked(→ tracksdata.graph.BaseGraph)

Solve the tracking problem in chunks using a sliding window approach.

_set_pinning_on_graph(→ None)

Set PIN_ATTR on candidate graph nodes/edges in the overlap region.

construct_solver(→ motile.Solver)

Construct a motile solver with the parameters specified in the solver

get_solver_name(→ str)

Return the name of the ILP solver backend that will be used.

Module Contents

napari_track_edit.motile.backend.solve.logger
napari_track_edit.motile.backend.solve.PIN_ATTR = 'pinned'
napari_track_edit.motile.backend.solve.PIN_UNSET = -1
napari_track_edit.motile.backend.solve.PIN_UNSELECTED = 0
napari_track_edit.motile.backend.solve.PIN_SELECTED = 1
napari_track_edit.motile.backend.solve._SKIP_ATTRS
napari_track_edit.motile.backend.solve.graphview_to_motile_dicts(cand_graph: tracksdata.graph.GraphView) → tuple[dict[int, dict], dict[tuple[int, int], dict]]

Unpack a tracksdata GraphView into plain node/edge dicts for motile.TrackGraph.

GraphView is always backed by an in-memory rustworkx.PyDiGraph (regardless of the root graph’s backend), so this walks that graph directly instead of going through tracksdata’s polars-based node_attrs()/edge_attrs(), which is dramatically slower for large candidate graphs.

Parameters:

cand_graph – The candidate graph to unpack. Node and edge attribute dicts are reused by reference (not copied), matching how GraphView itself shares attribute storage with an in-memory root.

Returns:

A tuple (nodes, edges) matching the shape expected by motile.TrackGraph.add_node/add_edge:

  • nodes: mapping from node id to its attribute dict.

  • edges: mapping from (source_id, target_id) to its attribute dict.

napari_track_edit.motile.backend.solve.solve(solver_params: napari_track_edit.motile.backend.solver_params.SolverParams, input_data: numpy.ndarray, on_solver_update: collections.abc.Callable | None = None, scale: list | None = None, cand_graph: tracksdata.graph.BaseGraph | None = None) → tracksdata.graph.BaseGraph

Get a tracking solution for the given segmentation and parameters.

Constructs a candidate graph from the segmentation (unless one is provided), a solver from the parameters, and then runs solving and returns a networkx graph with the solution. Most of this functionality is implemented in the motile toolbox.

Parameters:
  • solver_params (SolverParams) – The solver parameters to use when initializing the solver

  • input_data (np.ndarray) – The input segmentation or points list to run tracking on. If 2D, assumed to be a list of points, otherwise a segmentation.

  • on_solver_update (Callable, optional) – A function that is called whenever the motile solver emits an event. The function should take a dictionary of event data, and can be used to track progress of the solver. Defaults to None.

  • scale (list, optional) – The scale of the data in each dimension.

  • cand_graph (td.graph.BaseGraph, optional) – A pre-built candidate graph. If provided, skips candidate graph construction (except for single-window mode which always builds its own). Defaults to None.

Returns:

A solution graph where the ids of the nodes correspond to

the time and ids of the passed in segmentation labels. See funtracks for exact implementation details.

Return type:

td.graph.BaseGraph

napari_track_edit.motile.backend.solve.build_candidate_graph(input_data: numpy.ndarray, solver_params: napari_track_edit.motile.backend.solver_params.SolverParams, scale: list | None = None, time_offset: int = 0) → tracksdata.graph.BaseGraph

Build the candidate graph from input data.

napari_track_edit.motile.backend.solve._solve_full(cand_graph: tracksdata.graph.BaseGraph, solver_params: napari_track_edit.motile.backend.solver_params.SolverParams, on_solver_update: collections.abc.Callable | None = None) → tracksdata.graph.BaseGraph

Solve the tracking problem on the full candidate graph at once.

napari_track_edit.motile.backend.solve._solve_window(window_subgraph: tracksdata.graph.GraphView, solver_params: napari_track_edit.motile.backend.solver_params.SolverParams, on_solver_update: collections.abc.Callable | None = None) → tracksdata.graph.BaseGraph | None

Solve a single window subgraph.

This is the core solving logic shared by both single window mode and chunked solving.

Parameters:
  • window_subgraph – The subgraph for this window. If any nodes or edges have the PIN_ATTR attribute set, a Pin constraint will be used.

  • solver_params – The solver parameters.

  • on_solver_update – Callback for solver progress updates.

Returns:

The solution graph for this window, or None if the window has no nodes.

napari_track_edit.motile.backend.solve._solve_single_window(input_data: numpy.ndarray, solver_params: napari_track_edit.motile.backend.solver_params.SolverParams, on_solver_update: collections.abc.Callable | None = None, scale: list | None = None) → tracksdata.graph.BaseGraph

Solve a single window for interactive parameter testing.

Builds the full candidate graph, filters it to the window frames, and solves. Node times are naturally correct (no adjustment needed).

Parameters:
  • input_data – The full input segmentation or points list.

  • solver_params – The solver parameters including window_size and single_window_start.

  • on_solver_update – Callback for solver progress updates.

  • scale – The scale of the data in each dimension.

Returns:

The solution graph for the requested window.

Raises:

ValueError – If single_window_start is beyond the data range.

napari_track_edit.motile.backend.solve._solve_chunked(cand_graph: tracksdata.graph.BaseGraph, solver_params: napari_track_edit.motile.backend.solver_params.SolverParams, on_solver_update: collections.abc.Callable | None = None) → tracksdata.graph.BaseGraph

Solve the tracking problem in chunks using a sliding window approach.

This function solves the tracking problem in windows of window_size frames, with overlap_size frames of overlap between consecutive windows. The overlap region from the previous window is pinned (fixed) when solving the next window to maintain consistency across windows.

Parameters:
  • cand_graph – The full candidate graph with all nodes and edges.

  • solver_params – The solver parameters including window_size and overlap_size.

  • on_solver_update – Callback for solver progress updates.

Returns:

The combined solution graph from all windows.

napari_track_edit.motile.backend.solve._set_pinning_on_graph(cand_graph: tracksdata.graph.BaseGraph, solution_graph: tracksdata.graph.BaseGraph, overlap_start: int, overlap_end: int) → None

Set PIN_ATTR on candidate graph nodes/edges in the overlap region.

For all nodes and edges in the overlap region [overlap_start, overlap_end), sets PIN_ATTR to PIN_SELECTED if selected in the solution, PIN_UNSELECTED if not selected. Everything outside the overlap region stays PIN_UNSET.

Parameters:
  • cand_graph – The full candidate graph to modify in place.

  • solution_graph – The solution graph from the current window.

  • overlap_start – Start frame of overlap region (inclusive).

  • overlap_end – End frame of overlap region (exclusive).

napari_track_edit.motile.backend.solve._SKIP_ATTRS
class napari_track_edit.motile.backend.solve.TernaryPin(attribute: str)

Bases: motile.constraints.constraint.Constraint

Like motile’s Pin, but treats PIN_UNSET as unconstrained.

motile.constraints.Pin evaluates {attribute} == True for every node/edge and only skips ones where the attribute is entirely absent (NameError). Since tracksdata can’t store nulls, our PIN_ATTR is always present once the schema key exists, so Pin would force-unselect every node/edge that hasn’t actually been decided yet. This constraint instead only pins nodes/edges whose attribute value is PIN_SELECTED or PIN_UNSELECTED, leaving PIN_UNSET ones free for the solver to decide.

attribute
instantiate(solver: motile.Solver) → list[ilpy.Constraint]

Create and return specific linear constraints for the given solver.

Parameters:

solver – The Solver instance to create linear constraints for.

Returns:

An iterable of ilpy.Constraint.

napari_track_edit.motile.backend.solve.construct_solver(cand_graph: tracksdata.graph.GraphView, solver_params: napari_track_edit.motile.backend.solver_params.SolverParams) → motile.Solver

Construct a motile solver with the parameters specified in the solver params object.

Parameters:
  • cand_graph (td.graph.GraphView) – The candidate graph to use in the solver

  • solver_params (SolverParams) – The costs and constraints to use in the solver

Returns:

A motile solver with the specified graph, costs, and

constraints.

Return type:

Solver

napari_track_edit.motile.backend.solve.get_solver_name() → str

Return the name of the ILP solver backend that will be used.

Attempts Gurobi first; falls back to SCIP.