Utilities

Utility helpers for :mod:pyrecest.

anis = average_nis module-attribute

mae = mean_absolute_error module-attribute

mse = mean_squared_error module-attribute

nees = normalized_estimation_error_squared module-attribute

nis = normalized_innovation_squared module-attribute

rmse = root_mean_squared_error module-attribute

CandidateProvider = Callable[[int, int, int], Iterable[int | CompletionCandidate[PayloadT]]] module-attribute

CandidateSessionProvider = Callable[[int, int, _DirectionalCompletion], Iterable[int]] module-attribute

CompletionDirection = Literal['prefix', 'suffix', 'both'] module-attribute

__all__ = ['MultiSessionAssignmentResult', 'solve_multisession_assignment', 'solve_multisession_assignment_from_similarity', 'solve_multisession_assignment_with_observation_costs', 'stitch_tracks_from_pairwise_scores', 'tracks_to_index_matrix', 'tracks_to_session_labels', 'anis', 'anees', 'chi_square_confidence_bounds', 'chi_square_confidence_interval', 'consistency_fraction', 'eot_shape_iou', 'extent_error', 'extent_intersection_over_union', 'extent_matrix_error', 'extent_wasserstein_distance', 'false_track_rate', 'gaussian_wasserstein_distance', 'gospa_distance', 'iou_polygon', 'is_chi_square_consistent', 'is_within_chi_square_confidence_interval', 'mae', 'missed_track_rate', 'mospa_distance', 'mse', 'nees', 'nees_confidence_bounds', 'nees_confidence_interval', 'nis', 'nis_confidence_bounds', 'nis_confidence_interval', 'ospa_distance', 'rmse', 'score_false_tracks', 'score_missed_tracks', 'score_track_latency', 'score_track_outcomes', 'score_track_purity', 'track_latencies', 'track_purity', 'TrackEdit', 'TrackEditApplication', 'TrackEditDelta', 'apply_track_edit', 'rank_track_edits_by_delta', 'score_track_edit_delta', 'score_track_edits', 'CalibratedPairwiseAssociationModel', 'LogisticPairwiseAssociationModel', 'NamedPairwiseFeatureSchema', 'pairwise_feature_tensor', 'CandidatePruningConfig', 'candidate_mask_from_costs', 'candidate_pruning_config_from_mapping', 'prune_pairwise_cost_matrix', 'HistoryRecorder', 'ThinPlateSplineRegistrationResult', 'ThinPlateSplineTransform', 'estimate_thin_plate_spline', 'joint_tps_registration_assignment', 'min_cost_max_cardinality_assignment', 'murty_k_best_assignments', 'pairwise_covariance_shape_components', 'pairwise_mahalanobis_distances', 'CompletionCandidate', 'CompletionDirection', 'CompletionPath', 'CompletionStep', 'CandidateProvider', 'CandidateSessionProvider', 'enumerate_fragment_completion_paths', 'occupied_observations_by_session', 'path_observations', 'path_sessions', 'complete_track_set', 'normalize_track_matrix', 'pairwise_track_set', 'reference_fragment_counts', 'score_complete_tracks', 'score_false_continuations', 'score_fragmentation', 'score_pairwise_tracks', 'score_track_fragmentation', 'score_track_links', 'score_track_matrices', 'summarize_track_errors', 'summarize_tracks', 'track_error_ledger', 'track_lengths', 'track_pair_set'] module-attribute

CalibratedPairwiseAssociationModel dataclass

Association model wrapper that keeps a named pairwise feature schema.

model instance-attribute

schema instance-attribute

probability_clip instance-attribute

feature_names property

__init__(model, feature_names=None, *, schema=None, transforms=None, probability_clip=1e-12)

build_feature_tensor(components)

predict_match_probability(features_or_components)

pairwise_probability_matrix_from_components(components)

pairwise_cost_matrix_from_components(components, *, mode='negative_log_probability')

pairwise_cost_matrix(features_or_components, *, mode='negative_log_probability')

NamedPairwiseFeatureSchema dataclass

Named schema for building pairwise feature tensors from components.

feature_names instance-attribute

transforms instance-attribute

__init__(feature_names, *, transforms=None)

__len__()

__iter__()

feature_index(feature_name)

build_tensor(components)

LogisticPairwiseAssociationModel

Learn pairwise match probabilities from arbitrary association features.

The model uses binary logistic regression with optional feature standardization, L2 regularization, and support for severe class imbalance. It is intentionally dependency-light and implemented with NumPy only so that it can be used inside PyRecEst without adding a machine-learning stack.

Parameters

fit_intercept: Whether to learn an intercept term. l2_regularization: Non-negative L2 regularization strength applied to the coefficients. The intercept is not regularized. max_iterations: Maximum number of Newton / IRLS iterations. tolerance: Stop once the largest absolute parameter update falls below this value. standardize: Whether to z-score features before optimization. class_weight: None for unweighted fitting, "balanced" to automatically rebalance positive and negative examples, or a dictionary containing weights for labels 0 and 1. probability_clip: Numerical clipping applied to probabilities before taking logarithms.

Notes

The fit method accepts both a flattened feature matrix and a pairwise tensor. This makes it convenient to train directly from a ground-truth match matrix:

model = LogisticPairwiseAssociationModel(class_weight="balanced") model.fit(pairwise_features, match_labels) costs = model.pairwise_cost_matrix(pairwise_features)

Here pairwise_features may contain, for example, centroid distance, overlap, and shape-correlation channels for every candidate neuron pair.

fit_intercept = fit_intercept instance-attribute

l2_regularization = l2_regularization instance-attribute

max_iterations = max_iterations instance-attribute

tolerance = tolerance instance-attribute

standardize = standardize instance-attribute

class_weight = class_weight instance-attribute

probability_clip = probability_clip instance-attribute

n_features_in_ = None instance-attribute

feature_mean_ = None instance-attribute

feature_scale_ = None instance-attribute

coefficients_ = None instance-attribute

intercept_ = None instance-attribute

n_iter_ = 0 instance-attribute

converged_ = False instance-attribute

class_weights_ = None instance-attribute

__init__(*, fit_intercept=True, l2_regularization=0.001, max_iterations=100, tolerance=1e-08, standardize=True, class_weight='balanced', probability_clip=1e-12)

fit(features, labels, sample_weight=None)

Fit the association model.

decision_function(features)

Return posterior log-odds for the provided feature vectors.

predict_log_odds(features)

Alias for :meth:decision_function.

predict_match_probability(features)

Return posterior match probabilities for the provided feature vectors.

predict(features, threshold=0.5)

Predict binary match decisions using the supplied threshold.

pairwise_cost_matrix(pairwise_features, *, mode='negative_log_probability')

Convert pairwise features into an assignment cost matrix.

CandidatePruningConfig dataclass

Configuration for pairwise cost/probability candidate pruning.

The enabled criteria are combined by union: a candidate is kept when any active row/column top-k, probability-threshold, cost-threshold, or percentile criterion selects it. If no criterion is enabled, all finite costs are kept.

row_top_k = None class-attribute instance-attribute

column_top_k = None class-attribute instance-attribute

probability_threshold = None class-attribute instance-attribute

max_cost = None class-attribute instance-attribute

max_cost_percentile = None class-attribute instance-attribute

always_keep_finite = False class-attribute instance-attribute

large_cost = 1000000.0 class-attribute instance-attribute

__post_init__()

__init__(row_top_k=None, column_top_k=None, probability_threshold=None, max_cost=None, max_cost_percentile=None, always_keep_finite=False, large_cost=1000000.0)

HistoryRecorder

Record and retrieve named histories.

Histories come in two flavors:

  • padded numeric histories, which are stored as a 2-D backend array and can grow in their first dimension over time while earlier columns are padded with NaNs, and
  • generic histories, which are stored as Python lists of deep-copied values.

__init__()

register(name, initial_value=None, pad_with_nan=False)

Register a named history and return its storage object.

record(name, value, pad_with_nan=None, copy_value=True)

Append a value to the named history and return the updated history.

clear(name=None)

Clear a named history or all histories in place.

get(name, default=None)

Return the stored history for name.

items()

Iterate over (name, history) pairs.

keys()

Return the registered history names.

values()

Return the stored histories.

__contains__(name)

__getitem__(name)

__len__()

append_padded(curr_ests, estimates_over_time) staticmethod

Append a column to a possibly growing 2-D history array.

MultiSessionAssignmentResult dataclass

Result of :func:solve_multisession_assignment.

Attributes

tracks One dictionary per recovered track. Keys are session indices and values are detection indices within that session. matched_edges Directed edges selected by the optimizer as ((source_session, source_detection), (target_session, target_detection), adjusted_cost). The reported edge cost already includes the configured gap penalty. total_cost Objective value of the globally optimal assignment, including track start and end costs.

tracks instance-attribute

matched_edges instance-attribute

total_cost instance-attribute

observation_to_track_index()

Return a mapping from observation to recovered track index.

to_session_labels(session_sizes=None, *, fill_value=-1)

Convert the recovered tracks to dense per-session label arrays.

Parameters

session_sizes Optional per-session detection counts. When omitted, sizes are inferred from the track content. fill_value Value used for unassigned detections.

__init__(tracks, matched_edges, total_cost)

ThinPlateSplineRegistrationResult dataclass

Bases: RegistrationResultBase

Result of alternating TPS registration and assignment.

transform instance-attribute

__init__(assignment, matched_reference_indices, matched_moving_indices, transformed_reference_points, matched_costs, rmse, n_iterations, converged, transform)

ThinPlateSplineTransform dataclass

Two-dimensional thin-plate-spline transform.

Parameters

control_points: Control points with shape (n_control, 2). weights: Non-rigid TPS weights with shape (n_control, 2). affine_coefficients: Affine coefficients with shape (3, 2) acting on [1, x, y].

control_points instance-attribute

weights instance-attribute

affine_coefficients instance-attribute

dim property

Dimensionality of the transform domain.

__post_init__()

identity() staticmethod

Return the identity 2D TPS transform.

from_translation(translation) staticmethod

Return a TPS transform representing a pure translation.

apply(points)

Apply the transform to an (n_points, 2) array of points.

__init__(control_points, weights, affine_coefficients)

CompletionCandidate dataclass

Bases: Generic[PayloadT]

One candidate observation returned by a domain-specific provider.

Parameters

observation: Observation index in the candidate session. score: Optional additive score or cost contribution for the step. The generic enumerator only sums these values unless score_path is supplied. payload: Optional domain-specific payload retained in the emitted step.

observation instance-attribute

score = 0.0 class-attribute instance-attribute

payload = None class-attribute instance-attribute

__init__(observation, score=0.0, payload=None)

CompletionPath dataclass

Bases: Generic[PayloadT]

A candidate prefix or suffix completion path for one predicted row.

track_index instance-attribute

direction instance-attribute

steps instance-attribute

score instance-attribute

start_session property

start_observation property

end_session property

end_observation property

path_length property

__init__(track_index, direction, steps, score)

CompletionStep dataclass

Bases: Generic[PayloadT]

One chronological edge in a fragment-completion path.

from_session instance-attribute

from_observation instance-attribute

to_session instance-attribute

to_observation instance-attribute

score = 0.0 class-attribute instance-attribute

payload = None class-attribute instance-attribute

__init__(from_session, from_observation, to_session, to_observation, score=0.0, payload=None)

TrackEdit dataclass

A local structural edit to a multi-session track matrix.

The common link-edit fields describe an adjacent or non-adjacent link session_a:source_observation -> session_b:target_observation. Extra edit-specific details, such as the wrong edge removed by a swap, live in metadata so domain packages can annotate edits without extending the generic API.

kind instance-attribute

session_a = None class-attribute instance-attribute

session_b = None class-attribute instance-attribute

source_observation = None class-attribute instance-attribute

target_observation = None class-attribute instance-attribute

track_index = None class-attribute instance-attribute

metadata = field(default_factory=dict) class-attribute instance-attribute

__init__(kind, session_a=None, session_b=None, source_observation=None, target_observation=None, track_index=None, metadata=dict())

TrackEditApplication dataclass

Result of applying one structural edit to a track matrix.

edit instance-attribute

track_matrix instance-attribute

applied instance-attribute

action instance-attribute

reason instance-attribute

creates_duplicate_source = False class-attribute instance-attribute

creates_duplicate_target = False class-attribute instance-attribute

__init__(edit, track_matrix, applied, action, reason, creates_duplicate_source=False, creates_duplicate_target=False)

TrackEditDelta dataclass

Metric delta induced by a structural track edit.

edit instance-attribute

pairwise_tp_delta instance-attribute

pairwise_fp_delta instance-attribute

pairwise_fn_delta instance-attribute

complete_tp_delta instance-attribute

complete_fp_delta instance-attribute

complete_fn_delta instance-attribute

new_pairwise_f1 instance-attribute

new_complete_track_f1 instance-attribute

creates_duplicate_source instance-attribute

creates_duplicate_target instance-attribute

breaks_complete_track instance-attribute

applied = False class-attribute instance-attribute

action = '' class-attribute instance-attribute

reason = '' class-attribute instance-attribute

__init__(edit, pairwise_tp_delta, pairwise_fp_delta, pairwise_fn_delta, complete_tp_delta, complete_fp_delta, complete_fn_delta, new_pairwise_f1, new_complete_track_f1, creates_duplicate_source, creates_duplicate_target, breaks_complete_track, applied=False, action='', reason='')

tracks_to_session_labels(tracks, session_sizes=None, *, fill_value=-1)

Convert explicit tracks to dense per-session label arrays.

min_cost_max_cardinality_assignment(cost_matrix)

Compute the cheapest assignment among maximum-cardinality matchings.

murty_k_best_assignments(cost_matrix, k=1, row_non_assignment_costs=None, col_non_assignment_costs=None)

Compute the k best one-to-one partial assignments.

pairwise_feature_tensor(components, feature_names, transforms=None)

Build a pairwise feature tensor from named component planes.

All feature planes must have the same shape. Non-finite values are converted to finite sentinels: nan -> 0, +inf -> 1e6, and -inf -> -1e6.

candidate_mask_from_costs(cost_matrix, *, probability_matrix=None, config=None)

Return a boolean candidate mask for a pairwise association matrix.

candidate_pruning_config_from_mapping(value)

Normalize optional pruning config inputs.

prune_pairwise_cost_matrix(cost_matrix, *, probability_matrix=None, config=None, large_cost=None)

Replace pruned candidate entries by a large finite cost.

anees(estimates, uncertainties, groundtruths)

Backward-compatible alias for average NEES.

chi_square_confidence_bounds(degrees_of_freedom, *, n_samples=1, confidence=0.95)

Return two-sided chi-square bounds for an averaged NEES/NIS statistic.

chi_square_confidence_interval(degrees_of_freedom, *, n_samples=1, confidence=0.95)

Alias for :func:chi_square_confidence_bounds.

consistency_fraction(values, lower, upper)

Return the fraction of scalar values inside [lower, upper].

eot_shape_iou(shape1, shape2)

Return polygon IoU for extended-object shape estimates.

extent_error(estimated_extent, reference_extent, *, ord='fro', relative=False)

Alias for :func:extent_matrix_error.

extent_intersection_over_union(shape1, shape2)

Alias for polygon IoU used by extended-object tracking metrics.

extent_matrix_error(estimated_extent, reference_extent, *, ord='fro', relative=False)

Return matrix-norm error between estimated and reference extents.

extent_wasserstein_distance(estimated_extent, reference_extent, *, squared=False)

Return the covariance/extent part of the Gaussian 2-Wasserstein distance.

gaussian_wasserstein_distance(mean1, covariance1, mean2, covariance2, *, squared=False)

Return the 2-Wasserstein distance between Gaussian distributions.

gospa_distance(estimated_points, reference_points, *, cutoff, order=1.0, alpha=2.0, distance_fn=None, return_components=False)

Return the generalized OSPA distance between two finite sets.

iou_polygon(polygon1, polygon2)

Return intersection over union for two polygonal shapes.

is_chi_square_consistent(statistic, degrees_of_freedom, *, n_samples=1, confidence=0.95)

Return whether a scalar statistic lies inside chi-square bounds.

is_within_chi_square_confidence_interval(statistic, degrees_of_freedom, *, n_samples=1, confidence=0.95)

Alias for :func:is_chi_square_consistent.

mospa_distance(estimated_point_sets, reference_point_sets, *, cutoff, order=1.0, distance_fn=None, return_per_step=False)

Return mean OSPA over a sequence of finite-set estimates.

nees_confidence_bounds(state_dim, *, n_samples=1, confidence=0.95)

Return chi-square consistency bounds for NEES or ANEES.

nees_confidence_interval(state_dim, *, n_samples=1, confidence=0.95)

Alias for :func:nees_confidence_bounds.

nis_confidence_bounds(measurement_dim, *, n_samples=1, confidence=0.95)

Return chi-square consistency bounds for NIS or ANIS.

nis_confidence_interval(measurement_dim, *, n_samples=1, confidence=0.95)

Alias for :func:nis_confidence_bounds.

ospa_distance(estimated_points, reference_points, *, cutoff, order=1.0, distance_fn=None, return_components=False)

Return the optimal sub-pattern assignment distance between two finite sets.

solve_multisession_assignment(pairwise_costs, session_sizes=None, *, start_cost=0.0, end_cost=0.0, gap_penalty=0.0, cost_threshold=None)

Recover globally consistent tracks across multiple sessions.

Parameters

pairwise_costs Either a mapping from (source_session, target_session) to a cost matrix of shape (n_source, n_target), or a sequence of consecutive session-to-session cost matrices. When a sequence is supplied, matrix k is interpreted as the cost matrix for session k to session k + 1. session_sizes Optional per-session detection counts. This is only required when some sessions have no pairwise cost matrix, or when isolated singleton detections should still be represented in the result. A sequence is interpreted as counts for sessions 0, 1, ..., S-1. start_cost Penalty for starting a new track. end_cost Penalty for ending a track. gap_penalty Additional penalty applied per skipped session for non-consecutive edges. This penalty is added on top of the supplied edge cost. cost_threshold Optional upper bound for admissible link costs after gap penalties are applied. Edges with larger costs are forbidden.

Returns

MultiSessionAssignmentResult Globally optimal tracks and the selected directed edges.

Notes

Let N be the total number of observations. If every observation starts as a singleton track, the baseline cost is

N * (start_cost + end_cost).

Adding an admissible edge with adjusted cost c merges two track ends and therefore changes the objective by c - start_cost - end_cost. The implementation maximizes the total gain

start_cost + end_cost - c

subject to at-most-one-predecessor and at-most-one-successor constraints. This is equivalent to the minimum-cost path-cover objective. Internally, the sparse matching problem is reduced to a rectangular assignment in which every source observation can either connect to an admissible successor or to its own dummy "unmatched" column.

solve_multisession_assignment_with_observation_costs(pairwise_costs, session_sizes=None, *, start_cost=0.0, end_cost=0.0, start_costs=None, end_costs=None, gap_penalty=0.0, cost_threshold=None)

Solve multi-session assignment with per-observation start/end costs.

solve_multisession_assignment_from_similarity(pairwise_scores, session_sizes=None, *, min_score=None, max_gap=None, gap_penalty=0.0, start_cost=0.0, end_cost=0.0, score_to_cost=None)

Score-native wrapper around :func:solve_multisession_assignment.

stitch_tracks_from_pairwise_scores(pairwise_scores, session_sizes=None, **kwargs)

Track2p-style alias for the score-native wrapper.

tracks_to_index_matrix(tracks, session_sizes=None, *, fill_value=-1)

Convert tracks to a dense track x session ROI-index matrix.

estimate_thin_plate_spline(source_points, target_points, *, regularization=0.001)

Estimate a thin-plate-spline transform from matched 2D point pairs.

Parameters

source_points, target_points: Arrays of shape (n_points, 2) describing matched point pairs. regularization: Non-negative ridge penalty applied to the TPS kernel matrix.

joint_tps_registration_assignment(reference_points, moving_points, *, initial_transform=None, max_cost=float('inf'), cost_function=None, max_iterations=25, tolerance=1e-06, min_matches=3, regularization=0.001)

Alternating thin-plate-spline registration and one-to-one assignment.

This function alternates between: 1. assigning transformed reference points to moving points using the Hungarian algorithm with optional gating; and 2. refitting a smooth thin-plate-spline warp from the current matches.

Parameters

reference_points: Landmark locations from the reference session, shape (n_ref, 2). moving_points: Landmark locations from the moving/current session, shape (n_moving, 2). initial_transform: Optional starting transform. If omitted, the transform is initialized with a robust median-based translation. max_cost: Optional gating threshold on the association cost. cost_function: Optional callable receiving transformed reference points and moving points and returning a cost matrix of shape (n_ref, n_moving). This allows centroid costs, ROI overlap costs, or morphology-aware hybrid costs to be plugged into the registration loop. max_iterations: Maximum number of alternating assignment/refit iterations. tolerance: Convergence threshold on the change of the transformed reference point set. min_matches: Minimum number of matched pairs required before refitting the TPS warp. regularization: Non-negative ridge penalty for TPS fitting.

pairwise_covariance_shape_components(covariances_a, covariances_b, *, epsilon=1e-06)

Return pairwise covariance shape, scale, and similarity components.

The covariance-shape cost compares trace-normalized covariance matrices with a Frobenius norm. This makes the feature sensitive to orientation and anisotropy while ignoring overall scale. The log-determinant cost measures scale mismatch separately. The shape similarity is exp(-shape_cost).

Parameters

covariances_a, covariances_b: Covariance stacks with shape (dim, dim, n_items). epsilon: Strictly positive floor used for traces and determinants.

Returns

shape_cost, logdet_cost, shape_similarity: Three matrices with shape (n_a, n_b).

pairwise_mahalanobis_distances(means_a, covariances_a, means_b, covariances_b, *, regularization=0.0)

Return covariance-normalized distances between two Gaussian stacks.

For a pair of items i and j, the returned value is

sqrt((mu_i - nu_j)^T (Sigma_i + Lambda_j + regularization * I)^+ (mu_i - nu_j)),

where ^+ denotes the Moore-Penrose pseudoinverse. Using the summed covariance makes the feature symmetric in the two uncertain estimates and is the standard normalization for comparing two independent Gaussian position estimates.

Parameters

means_a, means_b: Mean stacks with shape (dim, n_items). covariances_a, covariances_b: Covariance stacks with shape (dim, dim, n_items). The number of covariance matrices must match the corresponding number of means. regularization: Optional non-negative diagonal loading added to every summed covariance before inversion.

Returns

array-like Matrix with shape (n_a, n_b).

enumerate_fragment_completion_paths(track_matrix, *, max_path_length=2, direction='both', candidate_provider, candidate_session_provider=None, allow_duplicate_source=False, allow_duplicate_target=False, score_path=None, max_paths_per_fragment=None)

Enumerate candidate prefix/suffix completions for incomplete track rows.

Parameters

track_matrix: Matrix-like object with rows as tracks and columns as sessions. Missing values are parsed by :func:pyrecest.utils.normalize_track_matrix. max_path_length: Maximum number of candidate edges per emitted path. direction: Which fragment endpoints to complete. "suffix" extends after the last observation in a row, "prefix" extends before the first observation, and "both" does both. candidate_provider: Callback candidate_provider(anchor_session, anchor_observation, candidate_session) returning observations in candidate_session. For suffix completion the candidate session is after the anchor; for prefix completion it is before the anchor. Returned values may be raw integer observation ids or :class:CompletionCandidate objects. candidate_session_provider: Optional callback returning candidate session indices for an endpoint. If omitted, only the adjacent previous/next session is considered. allow_duplicate_source / allow_duplicate_target: Whether paths may reuse already-occupied observations. In ordinary track completion both should remain false. score_path: Optional aggregate scorer for a tuple of chronological steps. If omitted, path scores are the sum of step scores. max_paths_per_fragment: Optional post-enumeration cap per endpoint, keeping the lowest-score paths first. This is intended for diagnostics and small candidate sets; high-branching production trackers should pre-prune in the provider.

occupied_observations_by_session(track_matrix)

Return occupancy counts keyed by (session, observation).

path_observations(path)

Return chronological observation ids in a completion path.

path_sessions(path)

Return chronological session indices in a completion path.

apply_track_edit(track_matrix, edit)

Apply edit to track_matrix and return the edited matrix.

Missing observations are represented as None in the returned matrix. Callers that use integer -1 sentinels can convert the result after the edit, while scoring functions in this module can consume it directly.

rank_track_edits_by_delta(predicted_track_matrix, reference_track_matrix, edits, *, session_pairs=None, complete_session_indices=None, count_duplicates=False)

Return independent edits sorted by complete-track then pairwise F1 gain.

score_track_edit_delta(predicted_track_matrix, reference_track_matrix, edit, *, session_pairs=None, complete_session_indices=None, count_duplicates=False)

Score the metric delta produced by one edit.

By default, pairwise and complete tracks are scored as identity sets, matching PyRecEst's generic track-evaluation helpers. Set count_duplicates=True for benchmark protocols where duplicate predicted rows or links should count as false positives.

score_track_edits(predicted_track_matrix, reference_track_matrix, edits, *, session_pairs=None, complete_session_indices=None, count_duplicates=False)

Score a collection of independent one-edit what-ifs.

false_track_rate(predicted_track_matrix, reference_track_matrix, *, min_length=1)

Return the fraction of evaluated predicted tracks that are false.

missed_track_rate(predicted_track_matrix, reference_track_matrix, *, min_length=1)

Return the fraction of evaluated reference tracks that are missed.

score_false_tracks(predicted_track_matrix, reference_track_matrix, *, min_length=1)

Return metrics for predicted tracks that contain no reference observation.

score_missed_tracks(predicted_track_matrix, reference_track_matrix, *, min_length=1)

Return metrics for reference tracks with no predicted observation support.

score_track_latency(predicted_track_matrix, reference_track_matrix, *, session_times=None)

Return aggregate first-detection latency metrics.

score_track_outcomes(predicted_track_matrix, reference_track_matrix, *, session_times=None)

Return fragmentation, purity, false-track, missed-track, and latency metrics.

score_track_purity(predicted_track_matrix, reference_track_matrix)

Return predicted-track identity purity metrics.

A predicted track's purity is the fraction of its observations that belong to its dominant reference identity. Observations absent from the reference matrix count as impure in mean_track_purity and observation_weighted_track_purity.

track_latencies(predicted_track_matrix, reference_track_matrix, *, session_times=None, missed_value=np.nan)

Return first-detection latency for each non-empty reference track.

track_purity(predicted_track_matrix, reference_track_matrix)

Return observation-weighted predicted-track purity.