Source: src/mcss/dynamic/cache.py · Plain text

src/mcss/dynamic/cache.py

"""Append-only observed evidence; independent from scene fields and fast weights."""

from dataclasses import dataclass

import torch
from torch import Tensor

from mcss.dynamic.types import OnlineObservation
from mcss.types import Cameras


@dataclass(frozen=True)
class CachedObservation:
    observation: OnlineObservation
    features: Tensor


@dataclass(frozen=True)
class ObservationCache:
    episode_id: str
    scene_id: str
    entries: tuple[CachedObservation, ...] = ()

    @property
    def revision(self):
        return len(self.entries)

    def append(self, observation: OnlineObservation, features: Tensor):
        if observation.scene_id != self.scene_id:
            raise ValueError("Cannot mix scenes in an observation cache")
        if self.entries and observation.frame_id <= self.entries[-1].observation.frame_id:
            raise ValueError("Observations must arrive in strictly increasing frame order")
        if features.ndim != 3 or not torch.isfinite(features).all():
            raise ValueError("Features must be finite [F,H,W]")
        if features.device != observation.rgb.device:
            raise ValueError("Features and observation must share device")
        camera = observation.camera
        copied = OnlineObservation(
            observation.scene_id,
            observation.frame_id,
            observation.rgb.clone(),
            Cameras(camera.intrinsics.clone(), camera.c2w.clone(), camera.image_size),
        )
        entry = CachedObservation(copied, features.clone())
        return ObservationCache(self.episode_id, self.scene_id, (*self.entries, entry))