Spaces:
Sleeping
Sleeping
| """ | |
| Base adapter interface. | |
| All dataset adapters must provide: | |
| - meta: DatasetMeta (robot_type, stats, fps, features, ...) | |
| - __getitem__(idx) → dict with raw column-name keys | |
| - __len__() → total frames | |
| """ | |
| from dataclasses import dataclass, field | |
| from pathlib import Path | |
| from typing import Any, Optional, TYPE_CHECKING | |
| import torch.utils.data | |
| if TYPE_CHECKING: | |
| from src.schema import DatasetSchema | |
| class DatasetMeta: | |
| """Minimal metadata interface that the Transform chain needs.""" | |
| robot_type: str | |
| stats: dict[str, dict] | None # per-key normalization stats | |
| fps: int | |
| total_episodes: int | |
| total_frames: int | |
| features: dict[str, Any] | |
| video_keys: list[str] = field(default_factory=list) | |
| camera_keys: list[str] = field(default_factory=list) | |
| # Optional only for the brief pre-discovery window inside adapter __init__; | |
| # once the adapter returns, schema MUST be non-None. Use require_schema(). | |
| schema: Optional["DatasetSchema"] = None | |
| # MultiLeRobotDataset expects `meta.episodes["dataset_from_index"/"to_index"]` | |
| # to build combined frame indices across multi-repo concatenation. | |
| episodes: dict = field(default_factory=lambda: { | |
| "dataset_from_index": [], | |
| "dataset_to_index": [], | |
| }) | |
| def require_schema(self) -> "DatasetSchema": | |
| """Return ``self.schema`` or raise if it is still ``None``. | |
| Code paths after adapter construction should use this accessor rather | |
| than carrying a ``None`` schema forward: a missing schema means | |
| hydrate_all has no state/action keys, no delta mask, and no image | |
| mapping — silently training on raw features with zero normalization. | |
| """ | |
| if self.schema is None: | |
| from src.schema.errors import SchemaDiscoveryError | |
| raise SchemaDiscoveryError( | |
| "DatasetMeta.schema is None after adapter construction. " | |
| "Every adapter __init__ must populate meta.schema via " | |
| "schema.discover_schema(root, robot_type=...). If this meta " | |
| "was constructed manually (tests, ablations), attach a " | |
| "DatasetSchema before handing it to the transform/dataset " | |
| "pipeline." | |
| ) | |
| return self.schema | |
| class BaseAdapter(torch.utils.data.Dataset): | |
| """Abstract base for all dataset format adapters.""" | |
| meta: DatasetMeta | |
| repo_id: str | |
| root: Path | |
| def __getitem__(self, idx: int) -> dict: | |
| raise NotImplementedError | |
| def __len__(self) -> int: | |
| return self.meta.total_frames | |
| def num_episodes(self) -> int: | |
| return self.meta.total_episodes | |
| def num_frames(self) -> int: | |
| return self.meta.total_frames | |