Events & Localization Metrics#

This module contains functions to calculate additional information and metrics about event localisations including:
  • the distance between events and their nearest neighbour

  • the local density of events

  • the local average contrast of events

  • the intersection/Jaccard index of two sets of points

  • detection efficiency and accuracy of predicted points if ground truth points are provided

massphoto.events.distance_nearest_neighbour(a, b=None, r=inf, return_idx=False)[source]#

Calculate the distance between each point in a and its nearest neighbour in b.

Parameters: a (array-like, Kxn): First set of nD points. b (array-like, Kxn): Second set of nD points. If None, b is set to a. Default is None. r (float): Cutoff distance for considering points as neighbours. Default is inf. return_idx (bool): Whether to return the index of the nearest neighbour. Default is False.

Returns: array-like: An array of the same length as a, containing the distance to the nearest neighbour in b for each point in a.

Parameters:
Return type:

ndarray

massphoto.events.points_intersect(a, b, r=1.0)[source]#

Calculate the intersection of two sets of nD points.

Parameters: a (array-like, Kxn): First set of nD points. b (array-like, Kxn): Second set of nD points. r (float): Tolerance parameter for considering points as similar. Default is 1.0.

Returns: array-like: A boolean array of the same length as a, indicating whether the corresponding point in a is within r of any point in b.

Parameters:
Return type:

ndarray

massphoto.events.jaccard_index_tree(a, b, r=1.0)[source]#

Calculate the Jaccard index between two sets of 2D points.

Parameters: a (array-like, Nx2): First set of 2D points. b (array-like, Nx2): Second set of 2D points. r (float): Tolerance parameter for considering points as similar. Default is 1.0.

Returns: float: Jaccard index, a value between 0 and 1 representing the similarity between the two sets.

Parameters:
Return type:

ndarray

massphoto.events.detection_stats(gt, pred, r=1.0)[source]#

Calculate detection recall and precision given ground-truth and predicted positions.

Evaluates the fraction of ground truth points recovered (recall / detection efficiency) and the fraction of predicted points that match ground truth (precision / accuracy) within a distance threshold r.

Parameters:
  • gt (np.ndarray) – Ground-truth point coordinates of shape (N, 2).

  • pred (np.ndarray) – Predicted point coordinates of shape (M, 2).

  • r (float, default=1.0) – Tolerance radius for considering points matched.

Returns:

(recall, precision) representing the detection efficiency and accuracy.

Return type:

tuple[float, float]

massphoto.events.filter_nearest_neighbour(locs, r_min=5.0, ratio_temporal_spatial=1.0, return_df=True)[source]#

Filter out points that are too close to their nearest neighbour.

This function takes a DataFrame of localizations and filters out points that have a nearest neighbor within a minimum distance (r_min). The distance calculation considers both spatial and temporal coordinates, where the temporal coordinate can be weighted differently using the ratio_temporal_spatial parameter.

Parameters:
  • locs (pd.DataFrame) – DataFrame containing localizations with at least ‘frame’, ‘y’, and ‘x’ columns.

  • r_min (float, optional) – Minimum allowed distance to nearest neighbour. Default is 5.0.

  • ratio_temporal_spatial (float, optional) – Scaling factor for temporal dimension relative to spatial dimensions. Default is 1.0.

  • return_df (bool, optional) – If True, returns filtered DataFrame. If False, returns boolean mask. Default is True.

Returns:

If return_df is True, returns filtered DataFrame containing only points that are farther than r_min from their nearest neighbour. If return_df is False, returns boolean mask where True indicates points that pass the distance filter.

Return type:

np.ndarray or pd.DataFrame

massphoto.events.add_nearest_neighbour(locs, r_max=10.0, ratio_temporal_spatial=1.0)[source]#

Add the nearest neighbour distance to the localizations DataFrame.

Note

Available as both massphoto.add_nearest_neighbour and massphoto.events.add_nearest_neighbour.

This function takes a DataFrame of localizations and adds a new column containing the distance to the nearest neighbour for each point. The distance calculation considers both spatial and temporal coordinates, where the temporal coordinate can be weighted differently using the ratio_temporal_spatial parameter.

Parameters:
  • locs (pd.DataFrame) – DataFrame containing localizations with at least ‘frame’, ‘y’, and ‘x’ columns.

  • r_max (float, optional) – Search radius for nearest neighbour. Default is 10.0. Larger values may increase computation time.

  • ratio_temporal_spatial (float, optional) – Scaling factor for temporal dimension relative to spatial dimensions. Default is 1.0. Increase for long average times.

Returns:

DataFrame with a new column ‘nn_dist’ containing the distance to the nearest neighbour.

Return type:

pd.DataFrame

massphoto.events.add_local_density(locs, r_smooth=1.0, resolution=1.0, filter_str=None, return_map=False)[source]#

Add the local density to the localizations DataFrame.

Note

Available as both massphoto.add_local_density and massphoto.events.add_local_density.

This function computes a local density estimate map and looks up the density for each localization. The local density is estimated by binning spatial coordinates into a 2D histogram and smoothing with a Gaussian filter. The result is added as a new column ‘local_density’ in the DataFrame. Optionally, the smoothed density map can also be returned.

Parameters:
  • locs (pd.DataFrame) – DataFrame containing localizations with at least ‘frame’, ‘y’, and ‘x’ columns.

  • r_smooth (float, optional) – Standard deviation (in pixels) for Gaussian smoothing of the density map. Default is 1.0.

  • resolution (float, optional) – Bin size for the histogram in pixels. Default is 1.0.

  • filter_str (str or None, optional) – Optional pandas query string to filter localizations before density calculation. Default is None (all finite localizations are included).

  • return_map (bool, optional) – If True, also returns the smoothed density map as a numpy array. Default is False.

Returns:

DataFrame with a new column ‘local_density’ containing the local density for each localization. If return_map is True, also returns the smoothed density map as a numpy array.

Return type:

pd.DataFrame or tuple of (pd.DataFrame, np.ndarray)

Notes

  • No correction for edge effects is applied; densities near the edge may be underestimated. Especially

    for large r_smooth values.

  • The density is normalized by the number of frames. The units are events/pixel^2/frame.

massphoto.events.remove_duplicates(df, merge_radius=2, precedence='-index', iterative=True, ratio_temporal_spatial=1.0)[source]#

Removes duplicate detections in the DataFrame based on the 3D (frame, y, x) distance.

This function identifies detections that are within a specified radius of each other (in both space and time), and merges them by keeping only one detection per group of duplicates. The detection to keep is determined by the precedence argument, which can be any valid pandas DataFrame expression (e.g., ‘-index’, ‘contrasts’, etc.). The temporal dimension can be weighted relative to the spatial dimensions using the ratio_temporal_spatial parameter.

Parameters:
  • df (pd.DataFrame) – DataFrame containing detections with at least ‘frame’, ‘y’, and ‘x’ columns.

  • merge_radius (float, optional) – Maximum allowed distance (in scaled 3D space) for detections to be considered duplicates. Default is 2.

  • precedence (str, optional) – Expression to determine which detection to keep among duplicates. Default is ‘-index’ (keep lowest index).

  • iterative (bool, optional) – Whether to iteratively merge duplicates until no more are found. Default is True.

  • ratio_temporal_spatial (float, optional) – Scaling factor for the temporal (‘frame’) dimension relative to spatial (‘y’, ‘x’) dimensions. Default is 1.0.

Returns:

DataFrame with duplicate detections merged according to the specified criteria.

Return type:

pd.DataFrame

Notes

  • The function uses a KDTree to efficiently find nearby detections in 3D (frame, y, x) space.

  • If iterative is True, the merging process is repeated up to 10 times or until no further merges occur.

  • The precedence argument is evaluated using pandas .eval() and can reference any column in the DataFrame.

massphoto.events.annotate_frame_metrics(events, frame_metrics=None, columns=None)[source]#

Annotate an event DataFrame with frame-level metrics.

Note

Available as both massphoto.annotate_frame_metrics and massphoto.events.annotate_frame_metrics.

Parameters:
  • events (pd.DataFrame) – Event DataFrame containing a frame column.

  • frame_metrics (pd.DataFrame | None, optional) – Frame-indexed DataFrame containing metrics. If None, it is retrieved from events.attrs['frame_metrics'].

  • columns (Sequence[str] | None, optional) – Subset of columns from frame_metrics to add to events. If None, all available metric columns are mapped.

Returns:

Events DataFrame with metric columns added.

Return type:

pd.DataFrame