Metrics¶
Functions for computing localisation metrics and registering custom ones.
Localisation metrics¶
- bayesian_listener.metrics.localization_error(targets, estimations, metric, auxiliary_output=False, degrees=False, **kwargs)[source]¶
Compute the localization error between two sets of coordinates using the specified metric.
- Parameters:
targets (pyfar.Coordinates) – The target (reference) coordinates, shape
(n_targets,).estimations (pyfar.Coordinates) – The estimated coordinates to compare against. May have an extra repetitions dimension, i.e. shape
(n_targets, repetitions);targetsis broadcast accordingly and both are flattened to(n_targets * repetitions,)before the metric is applied.metric (str or
Callable) –The metric to use for error computation.
If a string, it must be a registered metric name. Use
describe_metricsto list registered names anddescribe_metrics(name)for details on a specific one.If a callable, it must accept two
pyfar.Coordinatesarguments(targets, estimations)as the first two positional arguments, plus any keyword arguments forwarded via**kwargs. The user is responsible for coordinate convention and units. The callable must return either a single float or a tuple(error_value, auxiliary_data).
auxiliary_output (bool, default=False) – Ignored when
metricis a callable (the callable handles its own return shape). WhenTrueandmetricis a registered string, returns the auxiliary output dict alongside the error value.degrees (bool, default=False) – When
True, convert the returned error value to degrees. Has no effect for metrics whoseoutput_unitis already'degrees'or'percentage'.**kwargs (dict, optional) –
Forwarded to the metric function.
For registered metrics, kwargs are validated against the function signature. Unknown kwargs raise a
UserWarningand are dropped; valid ones are forwarded. Seedescribe_metrics(name)for the per-metric kwarg list.For callables, kwargs are forwarded as-is with no validation.
- Returns:
The computed localization error. If auxiliary_output is True, the output will be a tuple: (error_value, auxiliary_data_dict). If the metric function does not provide auxiliary data, auxiliary_data_dict will be an empty dictionary.
- Return type:
Examples
Registered metric with extra kwarg:
>>> error = localization_error(targets, estimations, ... 'accL_cutoff', ... cutoff=np.deg2rad(30))
Registered metric with auxiliary output:
>>> error, aux = localization_error(targets, estimations, ... 'querrMiddlebrooks', ... auxiliary_output=True) >>> print(error) 9.375 >>> print(aux) {'confusion_count': 48, 'response_count': 512}
Custom callable with extra kwarg:
>>> def my_metric(targets, estimations, threshold=0.5): ... ... >>> error = localization_error(targets, estimations, ... my_metric, ... threshold=0.1)
- bayesian_listener.metrics.wrap_polar_angle(angle_rad)[source]¶
Wrap polar (vertical) angles to \([-\pi/2, 3\pi/2)\).
The interaural-polar convention places the front pole at
0and the rear pole atπ; wrapping to[-π/2, 3π/2)keeps the upper hemisphere contiguous and simplifies front/back error computations.- Parameters:
angle_rad (float or
numpy.ndarray) – Polar angle(s) in radians.- Returns:
Wrapped angle(s) in radians, same shape as
angle_rad.- Return type:
float or
numpy.ndarray
Metric registry¶
Custom metrics can be registered and queried via the decorator API.
- bayesian_listener.metrics.register_metric(name, coord_convention, input_unit, output_unit=None, description=None, kwargs_description=None, **extra_metadata)[source]¶
Decorator to register a metric function with metadata.
- Parameters:
name (str) – Name of the metric.
coord_convention (str) – Coordinate convention used (e.g., ‘horizontal-polar’).
input_unit (str) – Unit of the input data (e.g., ‘radians’).
output_unit (str, optional) – Unit of the output data (e.g., ‘radians’, ‘percentage’).
description (str, optional) – Description of the metric.
kwargs_description (dict, optional) – Dictionary describing extra keyword arguments expected by the metric function. Keys are argument names, values are descriptions.
**extra_metadata (dict) – Additional metadata to store.
- Returns:
decorator – Decorator that wraps the target function and registers it under
nameinMETRIC_FUNCTIONS.- Return type:
callable
Built-in metrics¶
Lateral error¶
- bayesian_listener.metrics.sdL(true, est)[source]¶
Lateral standard-deviation error within \(\pm 80^\circ\) lateral.
Returns the standard deviation (square root of variance) of the response–target lateral-angle difference, restricted to estimations whose lateral angle satisfies \(|\hat{\alpha}| \le 80^\circ\). See Middlebrooks[1] for the foundational definition.
- Parameters:
true (
numpy.ndarray) – Target directions in horizontal-polar convention with lateral angles in radians, shape(..., 3).est (
numpy.ndarray) – Estimated directions, same shape and convention astrue.
- Returns:
Lateral SD in radians, or
np.nanif no estimations fall within the ±80° band.- Return type:
- bayesian_listener.metrics.rmsL(true, est)[source]¶
Lateral RMS error within \(\pm 60^\circ\) lateral (Middlebrooks[1]).
- Parameters:
true (
numpy.ndarray) – Target directions, horizontal-polar with lateral angle in radians.est (
numpy.ndarray) – Estimated directions, same convention astrue.
- Returns:
Lateral RMS in radians, or
np.nanif no estimations fall within the ±60° band.- Return type:
- bayesian_listener.metrics.accL_cutoff(true, est, cutoff=3.141592653589793)[source]¶
Lateral bias (mean signed error) within \(\pm\)
cutoff.- Parameters:
true (
numpy.ndarray) – Target directions, horizontal-polar with lateral angle in radians.est (
numpy.ndarray) – Estimated directions.cutoff (float, default=π) – Lateral-angle threshold in radians; only targets with \(|\alpha| \le\)
cutoffare included.
- Returns:
Mean signed lateral error in radians (positive: rightward bias), or
np.nanif no targets fall within the band.- Return type:
Polar error¶
- bayesian_listener.metrics.rmsPmedianlocal(true, est)[source]¶
Local RMS polar error within \(\pm 30^\circ\) lateral, excluding quadrant errors.
Restricted to estimations with lateral angle \(|\hat{\alpha}| \le 30^\circ\) and polar error \(|\Delta \beta| < 90^\circ\). Definition follows Middlebrooks[1].
- Parameters:
true (
numpy.ndarray) – Target directions, horizontal-polar with angles in radians.est (
numpy.ndarray) – Estimated directions.
- Returns:
Local polar RMS in radians.
- Return type:
- Raises:
ValueError – If estimated lateral angles fall outside \([-\pi/2, \pi/2]\), if no estimations land in the central band, or if every central estimation has a polar error \(\ge 90^\circ\).
- bayesian_listener.metrics.accP_cutoff(true, est, cutoff=np.float64(0.5235987755982988))[source]¶
- Polar bias (mean signed error) within \(\pm\)
cutoff lateral (Middlebrooks[1]).
- Parameters:
true (
numpy.ndarray) – Target directions, horizontal-polar with angles in radians.est (
numpy.ndarray) – Estimated directions.cutoff (float, default=π/6) – Lateral-angle threshold in radians; only estimations with \(|\hat{\alpha}| \le\)
cutoffare included.
- Returns:
Mean signed polar error in radians (positive: upward bias), or
np.nanif no estimations fall within the band.- Return type:
- Polar bias (mean signed error) within \(\pm\)
Global error¶
- bayesian_listener.metrics.querrMiddlebrooks(true, est)[source]¶
Quadrant-error rate within \(\pm 30^\circ\) lateral (Middlebrooks[1]).
Counts the fraction of central-band estimations whose polar error satisfies \(|\Delta \beta| \ge 90^\circ\).
- Parameters:
true (
numpy.ndarray) – Target directions, horizontal-polar with angles in radians.est (
numpy.ndarray) – Estimated directions.
- Returns:
qerr (float) – Quadrant-error rate as a percentage.
aux (dict) – Mapping with keys:
'confusion_count'(int) — number of estimations with \(|\Delta \beta| \ge 90^\circ\).'response_count'(int) — total estimations within the central ±30° lateral band.
- Raises:
ValueError – If estimated lateral angles fall outside \([-\pi/2, \pi/2]\), or if no estimations land in the central ±30° band.
- bayesian_listener.metrics.angular_error(true, est)[source]¶
Mean great-circle angular error between target and estimation unit vectors.
Computes \(\bar{\theta} = \frac{1}{N} \sum \arccos( \mathbf{t}_i \cdot \hat{\mathbf{e}}_i)\) with the dot product clipped to \([-1, 1]\) for numerical safety.
- Parameters:
true (
numpy.ndarray) – Target directions in Cartesian coordinates, shape(..., 3); each row should be unit-norm.est (
numpy.ndarray) – Estimated directions, same shape and convention.
- Returns:
Mean angular error in radians.
- Return type: