SFI.trajectory.reserved_extras module

Framework-owned extras and the single resolver that materialises them.

A force or diffusion expression reads two kinds of data through its extras mapping: user values attached to the trajectory (drive protocols, per-particle properties, geometry) and reserved values supplied by the framework. The reserved keys are defined once here, in a small registry, and assembled together with the user values by resolve_extras() — the single entry point used by simulation, inference, and diagnostics.

Reserved keys:

time

Absolute time at each resolved frame — lets time-dependent bases (e.g. time_fourier()) read the clock.

duration

Total trajectory span.

dataset_index

Dense index of the dataset within its collection, for pooled multi-experiment models (per_dataset_scalar(), dataset_indicator()).

particle_index

Per-particle integer ids, gathered per edge by interaction dispatchers.

class SFI.trajectory.reserved_extras.ExtrasContext(n_particles, dataset_index, frame_times, duration)[source]

Bases: object

Everything a reserved-key resolver needs for a set of frames.

Assembled by whoever drives the evaluation (the trajectory producer, the diagnostics residual builder, or the simulator) and passed to resolve_extras().

Parameters:
  • n_particles (int)

  • dataset_index (int)

  • frame_times (Any)

  • duration (Any)

dataset_index: int
duration: Any
frame_times: Any
n_particles: int
SFI.trajectory.reserved_extras.RESERVED_NAMES = frozenset({'dataset_index', 'duration', 'particle_index', 'time'})

The set of reserved key names; user extras may not use these.

class SFI.trajectory.reserved_extras.ReservedKey(name, resolve)[source]

Bases: object

A framework-owned extras key and how it is materialised.

Parameters:
name: str
resolve: Callable[[ExtrasContext], Any]
SFI.trajectory.reserved_extras.is_reserved(name)[source]

True when name is a framework-owned reserved key.

Parameters:

name (str)

Return type:

bool

SFI.trajectory.reserved_extras.register(key)[source]

Add a reserved key to the registry.

Parameters:

key (ReservedKey)

Return type:

None

SFI.trajectory.reserved_extras.resolve_extras(user_extras, ctx)[source]

Full per-frame extras: user values plus the resolved reserved keys.

Reserved names are framework-owned; a user entry colliding with one is rejected so the meaning of a reserved key is never ambiguous.

Parameters:
Return type:

Dict[str, Any]

SFI.trajectory.reserved_extras.resolve_reserved(ctx)[source]

Materialise every reserved key for ctx.

Parameters:

ctx (ExtrasContext)

Return type:

Dict[str, Any]

SFI.trajectory.reserved_extras.slice_frame_extras(extras_global, extras_local, *, frame_idx, context=None)[source]

Materialise user extras at frame_idx.

  • TimeSeriesExtra → sliced value.data[frame_idx];

  • FunctionExtra → its callable, forwarded;

  • plain callable → invoked as value(frame_idx, context=context);

  • anything else → forwarded unchanged.

extras_local overrides extras_global on key conflicts.

Parameters:
  • extras_global (Mapping[str, Any] | None)

  • extras_local (Mapping[str, Any] | None)

  • frame_idx (Any)

  • context (str | None)

Return type:

Dict[str, Any]