def __init__(
self,
manifest: pd.DataFrame | None = None,
*,
root: pathlib.Path | str | None = None,
bbox: tuple[float, float, float, float] | None = None,
image_size: int = 224,
require_local_image: bool = True,
prefer_cog: bool = True,
rationale_cache: pd.DataFrame | pathlib.Path | str | None = None,
transforms: Callable[[dict[str, Any]], dict[str, Any]] | None = None,
) -> None:
if manifest is None:
if root is None:
raise ValueError("Either manifest or root must be provided.")
manifest = build_observation_manifest(
root,
bbox=bbox,
require_local_image=require_local_image,
prefer_cog=prefer_cog,
)
else:
manifest = manifest.copy()
if require_local_image and "has_local_image" in manifest.columns:
mask = manifest["has_local_image"].fillna(False).astype(bool)
manifest = manifest[mask].copy()
if require_local_image and "image_path" in manifest.columns:
manifest = manifest[manifest["image_path"].notna()].copy()
if manifest.empty:
raise ValueError("Manifest is empty after filtering.")
if rationale_cache is not None:
manifest = merge_rationale_cache(manifest, rationale_cache)
elif "rationale_expanded" not in manifest.columns:
manifest = manifest.copy()
manifest["rationale_expanded"] = None
manifest["has_rationale_expanded"] = False
self.manifest = manifest.reset_index(drop=True)
self.image_size = int(image_size)
self.transforms = transforms