spacr.custom_features

Custom per-object feature functions.

Users can drop Python files under ~/.spacr/features/*.py that export functions:

def <name>(mask: np.ndarray, image: np.ndarray, **kwargs) -> float | dict

discover_features() collects each such function — it has to be public, defined in the file itself and take at least two parameters — and call_feature() invokes one, coercing the result into a {column_name: value} mapping (<name> for a scalar, <name>_<key> per key for a dict).

Note

This is a standalone API. No part of the measure pipeline calls it yet, so dropping a file into ~/.spacr/features/ does not on its own add columns to the measurements DB — a caller has to run the discovery and invocation loop itself.

Example ~/.spacr/features/asymmetry.py:

import numpy as np
def asymmetry(mask, image, **_):
    ys, xs = np.where(mask > 0)
    if len(xs) < 5:
        return 0.0
    # Something the built-ins don't compute
    return float(np.std(xs) / (np.std(ys) + 1e-9))

Errors are logged and swallowed: a feature that raises yields an empty mapping, so one bad function cannot break the caller’s loop.

Public API:

from spacr.custom_features import (
    features_dir, discover_features, call_feature,
)

Classes

CustomFeature

One discovered feature function.

Functions

call_feature(→ Dict[str, Any])

Invoke a custom feature safely, coercing the result to a

discover_features(→ List[CustomFeature])

Walk features_dir() and return every public callable found.

features_dir(→ pathlib.Path)

Return ~/.spacr/features/ — created if it doesn't exist.

Module Contents

class spacr.custom_features.CustomFeature[source]

One discovered feature function.

Parameters:
  • name – public function name discovered in the user module; call_feature() uses it as the scalar output key or as the prefix in <name>_<returned_key>.

  • source – path of the user .py module that defined fn, retained as the feature’s origin metadata.

  • fn – discovered callable invoked by call_feature() as fn(mask, image, **kwargs). Exceptions are logged under name and produce an empty result.

spacr.custom_features.call_feature(cf: CustomFeature, mask, image, **kwargs) → Dict[str, Any][source]

Invoke a custom feature safely, coercing the result to a {column_name: value} dict.

Parameters:
  • cf – discovered feature.

  • mask – 2-D uint16 mask (background 0).

  • image – 2-D uint16 image aligned with mask.

Returns:

mapping of DB column name → scalar. Empty dict on exception.

spacr.custom_features.discover_features() → List[CustomFeature][source]

Walk features_dir() and return every public callable found.

Silently skips files that fail to import — the offending path is logged at INFO and users see a warning in the Console.

spacr.custom_features.features_dir() → pathlib.Path[source]

Return ~/.spacr/features/ — created if it doesn’t exist.