Files
NODEDC_MISSION_CORE/src/k1link/compute/e30_materialization.py
T

1120 lines
44 KiB
Python

"""Source-bound point materialization for an immutable E30 review pack.
The E30 selection pack records which E29 observations require review. This
module replays the exact bound E29 method over the exact E10/L2.6 inputs and
publishes point-index ownership plus bounded projection context for each
selected item. It does not create reviewer decisions or a LAB acceptance.
"""
from __future__ import annotations
import hashlib
import json
import math
import os
import re
import shutil
from dataclasses import asdict, dataclass
from datetime import UTC, datetime
from pathlib import Path
from typing import Any, Final
import numpy as np
import numpy.typing as npt
from k1link.device_plugins.xgrids_k1.analyze.calibrated_projection import (
Kb4ProjectionProfile,
ProjectedPointCloud,
project_map_points_kb4,
)
from .e30_camera_evidence import (
E30CameraEvidenceSource,
materialize_e30_camera_frames,
open_e30_camera_evidence_source,
)
from .lidar_field_review import E10LidarFieldSource
from .lidar_local_surface import K1LocalSurfaceV1
from .semantic_geometry_fusion import (
CAMERA_GEOMETRY_FUSION_SCHEMA,
CameraGeometryFusionProfile,
_claimed_indices,
_fusion_frame,
_geometry_cluster_supports,
_projection_profile,
_semantic_support,
)
E30_MATERIALIZATION_SCHEMA: Final = "missioncore.e30-evidence-materialization/v2"
E30_MATERIALIZATION_ITEM_SCHEMA: Final = (
"missioncore.e30-evidence-materialization-item/v2"
)
E30_MATERIALIZATION_INDEX_NAME: Final = "materialized-items.jsonl"
E30_MATERIALIZATION_MANIFEST_NAME: Final = "manifest.json"
_REVIEW_PACK_ID = re.compile(r"^e30-review-pack-[a-f0-9]{64}$")
_REVIEW_ITEM_ID = re.compile(r"^e30-review-item-[a-f0-9]{64}$")
_E29_RESULT_ID = re.compile(r"^e29-camera-geometry-[a-f0-9]{64}$")
_SOURCE_RESULT_ID = re.compile(r"^e10-integrated-perception-[a-f0-9]{64}$")
_SHA256 = re.compile(r"^[a-f0-9]{64}$")
FloatArray = npt.NDArray[np.float64]
IntArray = npt.NDArray[np.int64]
class E30MaterializationError(ValueError):
"""A source binding or materialized review artifact violates the contract."""
@dataclass(frozen=True, slots=True)
class E30MaterializationProfile:
profile_id: str = "e30-source-bound-point-materialization/v1"
maximum_context_projection_points: int = 6000
def __post_init__(self) -> None:
if (
not self.profile_id
or len(self.profile_id) > 160
or not 256 <= self.maximum_context_projection_points <= 50_000
):
raise E30MaterializationError("E30 materialization profile is invalid")
def to_dict(self) -> dict[str, object]:
return {
"schema_version": "missioncore.e30-materialization-profile/v1",
**asdict(self),
"selected_and_candidate_points": "lossless-frame-local-indices",
"context_selection": "deterministic-even-index",
"camera_evidence": "exact-bound-frame-when-camera-job-is-supplied",
"primary_review_view": "camera-with-lidar-projection",
"secondary_review_view": "map-frame-3d",
"free_space_valid": False,
"navigation_or_safety_accepted": False,
}
DEFAULT_E30_MATERIALIZATION_PROFILE: Final = E30MaterializationProfile()
@dataclass(frozen=True, slots=True)
class E30Materialization:
result_root: Path
result_id: str
manifest: dict[str, Any]
@dataclass(frozen=True, slots=True)
class _ReviewPack:
root: Path
manifest: dict[str, Any]
items: tuple[dict[str, Any], ...]
items_sha256: str
@dataclass(frozen=True, slots=True)
class _ItemArrays:
selected_source_indices: IntArray
selected_points_map_xyz_m: npt.NDArray[np.float32]
candidate_source_indices: IntArray
candidate_points_map_xyz_m: npt.NDArray[np.float32]
projected_source_indices: IntArray
projected_points_map_xyz_m: npt.NDArray[np.float32]
projected_pixels_xy: npt.NDArray[np.float32]
projected_depth_m: npt.NDArray[np.float32]
projected_point_class: npt.NDArray[np.uint8]
projected_point_height_m: npt.NDArray[np.float32]
projected_candidate_mask: npt.NDArray[np.uint8]
projected_selected_mask: npt.NDArray[np.uint8]
sensor_position_map_xyz_m: npt.NDArray[np.float64]
sensor_orientation_map_from_lidar_xyzw: npt.NDArray[np.float64]
def to_dict(self) -> dict[str, npt.NDArray[Any]]:
return {
"selected_source_indices": self.selected_source_indices,
"selected_points_map_xyz_m": self.selected_points_map_xyz_m,
"candidate_source_indices": self.candidate_source_indices,
"candidate_points_map_xyz_m": self.candidate_points_map_xyz_m,
"projected_source_indices": self.projected_source_indices,
"projected_points_map_xyz_m": self.projected_points_map_xyz_m,
"projected_pixels_xy": self.projected_pixels_xy,
"projected_depth_m": self.projected_depth_m,
"projected_point_class": self.projected_point_class,
"projected_point_height_m": self.projected_point_height_m,
"projected_candidate_mask": self.projected_candidate_mask,
"projected_selected_mask": self.projected_selected_mask,
"sensor_position_map_xyz_m": self.sensor_position_map_xyz_m,
"sensor_orientation_map_from_lidar_xyzw": (
self.sensor_orientation_map_from_lidar_xyzw
),
}
def build_e30_materialization(
*,
review_pack_root: Path,
e29_root: Path,
source_result_root: Path,
source_pack_root: Path,
local_surface_root: Path,
output_root: Path,
camera_job_root: Path | None = None,
ffmpeg_path: Path | None = None,
profile: E30MaterializationProfile = DEFAULT_E30_MATERIALIZATION_PROFILE,
) -> E30Materialization:
"""Materialize every selected E30 item from its exact immutable sources."""
review = _read_review_pack(review_pack_root)
review_identity = _required_object(review.manifest, "identity")
review_source = _required_object(review_identity, "source")
e29_result_id = _required_string(review_source, "e29_result_id")
if _E29_RESULT_ID.fullmatch(e29_result_id) is None:
raise E30MaterializationError("E30 review source E29 id is invalid")
e29_result = _child_directory(e29_root, e29_result_id)
e29_manifest_path = _regular_file(e29_result, "manifest.json")
e29_manifest = _read_json(e29_manifest_path, "E29 manifest")
e29_identity = _required_object(e29_manifest, "identity")
e29_identity_sha256 = _required_string(e29_manifest, "identity_sha256")
if (
e29_manifest.get("schema_version") != CAMERA_GEOMETRY_FUSION_SCHEMA
or e29_manifest.get("result_id") != e29_result_id
or hashlib.sha256(_canonical_json(e29_identity)).hexdigest()
!= e29_identity_sha256
or e29_result_id != f"e29-camera-geometry-{e29_identity_sha256}"
or review_source.get("e29_identity_sha256") != e29_identity_sha256
):
raise E30MaterializationError("E29 materialization source identity is invalid")
_reject_authority(_required_object(e29_identity, "authority"), "E29 identity")
source_result_id = _required_string(e29_identity, "source_result_id")
source_pack_id = _required_string(e29_identity, "source_pack_id")
local_surface_model_id = _required_string(
e29_identity,
"local_surface_model_id",
)
if (
_SOURCE_RESULT_ID.fullmatch(source_result_id) is None
or review_source.get("camera_result_id") != source_result_id
or review_source.get("lidar_pack_id") != source_pack_id
or review_source.get("local_surface_model_id") != local_surface_model_id
):
raise E30MaterializationError("E30 linked source identities disagree")
source_result = _child_directory(source_result_root, source_result_id)
source_result_document_path = _regular_file(source_result, "result.json")
source_result_document = _read_json(
source_result_document_path,
"source perception result",
)
source_result_identity = _required_object(source_result_document, "identity")
source_result_identity_sha256 = _required_string(
source_result_document,
"identity_sha256",
)
if (
source_result_document.get("result_id") != source_result_id
or hashlib.sha256(_canonical_json(source_result_identity)).hexdigest()
!= source_result_identity_sha256
or source_result_id
!= f"e10-integrated-perception-{source_result_identity_sha256}"
):
raise E30MaterializationError("source perception result identity is invalid")
fusion_frames_path = _regular_file(source_result, "fusion-frames.jsonl")
fusion_frames_sha256 = _sha256_file(fusion_frames_path)
if (
fusion_frames_sha256
!= _required_string(e29_identity, "source_fusion_frames_sha256")
):
raise E30MaterializationError("source fusion frame digest changed")
source = E10LidarFieldSource(_child_directory(source_pack_root, source_pack_id))
surface = K1LocalSurfaceV1(
_child_directory(local_surface_root, local_surface_model_id)
)
try:
_validate_bound_sources(source, surface, e29_identity)
fusion_profile = _fusion_profile(e29_identity)
projection_profile = _projection_profile(source)
if (camera_job_root is None) != (ffmpeg_path is None):
raise E30MaterializationError(
"camera job and ffmpeg must be supplied together"
)
camera_source: E30CameraEvidenceSource | None = None
if camera_job_root is not None and ffmpeg_path is not None:
camera_source = open_e30_camera_evidence_source(
camera_job_root=camera_job_root,
ffmpeg_path=ffmpeg_path,
expected_session_id=_required_string(source.identity, "session_id"),
expected_source_id=projection_profile.source_id,
)
selected_frames = _review_items_by_frame(review.items)
fusion_frames = _read_selected_fusion_frames(
fusion_frames_path,
selected_frame_indices=set(selected_frames),
source=source,
)
identity: dict[str, object] = {
"schema_version": E30_MATERIALIZATION_SCHEMA,
"review_pack": {
"result_id": _required_string(review.manifest, "result_id"),
"identity_sha256": _required_string(
review.manifest,
"identity_sha256",
),
"items_sha256": review.items_sha256,
"item_count": len(review.items),
},
"source": {
"e29_result_id": e29_result_id,
"e29_manifest_sha256": _sha256_file(e29_manifest_path),
"source_result_id": source_result_id,
"source_result_sha256": _sha256_file(source_result_document_path),
"fusion_frames_sha256": fusion_frames_sha256,
"lidar_pack_id": source.pack_id,
"lidar_pack_sha256": _source_artifact_sha256(source.manifest),
"local_surface_model_id": surface.model_id,
"local_surface_sha256": _surface_artifact_sha256(surface.manifest),
"source_session_id": _required_string(source.identity, "session_id"),
},
"camera_evidence": (
camera_source.identity() if camera_source is not None else None
),
"fusion_profile": fusion_profile.to_dict(),
"materialization_profile": profile.to_dict(),
"projection": {
"source_id": projection_profile.source_id,
"calibration_slot": projection_profile.calibration_slot,
"width": projection_profile.width,
"height": projection_profile.height,
},
"producer_sha256": _sha256_file(Path(__file__).resolve(strict=True)),
"human_review_complete": False,
"authority": {
"commands_enabled": False,
"navigation_or_safety_accepted": False,
},
}
identity_sha256 = hashlib.sha256(_canonical_json(identity)).hexdigest()
result_id = f"e30-materialization-{identity_sha256}"
destination = output_root.expanduser().absolute()
destination.mkdir(mode=0o700, parents=True, exist_ok=True)
result_root = destination / result_id
if result_root.exists():
manifest = _read_existing_materialization(result_root, identity)
return E30Materialization(result_root, result_id, manifest)
staging = destination / f".{result_id}.{os.getpid()}.incomplete"
item_root = staging / "items"
item_root.mkdir(mode=0o700, parents=True, exist_ok=False)
index_path = staging / E30_MATERIALIZATION_INDEX_NAME
try:
camera_artifacts: dict[int, dict[str, object]] = {}
if camera_source is not None:
camera_artifacts = materialize_e30_camera_frames(
source=camera_source,
source_frame_indices=tuple(
_item_source_frame_index(item) for item in review.items
),
destination_root=staging / "frames",
width=projection_profile.width,
height=projection_profile.height,
)
with index_path.open("x", encoding="utf-8") as index_stream:
for item in review.items:
frame_index = _item_frame_index(item)
arrays, metadata = _materialize_item(
item=item,
fusion_frame=fusion_frames[frame_index],
source=source,
surface=surface,
fusion_profile=fusion_profile,
projection_profile=projection_profile,
maximum_context_points=(
profile.maximum_context_projection_points
),
)
item_id = _required_string(item, "item_id")
item_path = item_root / f"{item_id}.npz"
array_document = arrays.to_dict()
np.savez_compressed(
item_path,
selected_source_indices=arrays.selected_source_indices,
selected_points_map_xyz_m=arrays.selected_points_map_xyz_m,
candidate_source_indices=arrays.candidate_source_indices,
candidate_points_map_xyz_m=arrays.candidate_points_map_xyz_m,
projected_source_indices=arrays.projected_source_indices,
projected_points_map_xyz_m=arrays.projected_points_map_xyz_m,
projected_pixels_xy=arrays.projected_pixels_xy,
projected_depth_m=arrays.projected_depth_m,
projected_point_class=arrays.projected_point_class,
projected_point_height_m=arrays.projected_point_height_m,
projected_candidate_mask=arrays.projected_candidate_mask,
projected_selected_mask=arrays.projected_selected_mask,
sensor_position_map_xyz_m=arrays.sensor_position_map_xyz_m,
sensor_orientation_map_from_lidar_xyzw=(
arrays.sensor_orientation_map_from_lidar_xyzw
),
)
artifact = {
"path": f"items/{item_path.name}",
"media_type": "application/x-npz",
"byte_length": item_path.stat().st_size,
"sha256": _sha256_file(item_path),
"logical_sha256": _logical_arrays_sha256(array_document),
}
index_document = {
"schema_version": E30_MATERIALIZATION_ITEM_SCHEMA,
"item_id": item_id,
"sequence": _required_int(item, "sequence"),
"review_key": _required_string(item, "review_key"),
"stratum": _required_string(item, "stratum"),
"range_bucket": _required_string(item, "range_bucket"),
"evidence_binding": _required_object(
item,
"evidence_binding",
),
"e29_locator": _required_object(item, "e29_locator"),
"e29_snapshot": _required_object(item, "e29_snapshot"),
"materialization": metadata,
"artifact": artifact,
"camera_frame": camera_artifacts.get(
_item_source_frame_index(item)
),
"engineering_triage": _engineering_triage(
item=item,
metadata=metadata,
camera_available=(
_item_source_frame_index(item)
in camera_artifacts
),
),
"review": {
"state": "unreviewed",
"reason_code": None,
"notes": None,
},
"authority": {
"commands_enabled": False,
"navigation_or_safety_accepted": False,
},
}
index_stream.write(
_canonical_json(index_document).decode("utf-8") + "\n"
)
index_artifact = _artifact(
"materialized-items",
index_path,
"application/x-ndjson",
)
manifest = {
"schema_version": E30_MATERIALIZATION_SCHEMA,
"result_id": result_id,
"identity_sha256": identity_sha256,
"identity": identity,
"created_at_utc": datetime.now(UTC).isoformat(),
"classification": "private-derived-perception-review-materialization",
"item_count": len(review.items),
"camera_evidence_available": camera_source is not None,
"human_review_complete": False,
"lab_published": False,
"artifacts": [index_artifact],
"authority": {
"commands_enabled": False,
"navigation_or_safety_accepted": False,
},
}
_write_json(staging / E30_MATERIALIZATION_MANIFEST_NAME, manifest)
os.replace(staging, result_root)
except BaseException:
shutil.rmtree(staging, ignore_errors=True)
raise
return E30Materialization(result_root, result_id, manifest)
finally:
surface.close()
source.close()
def _materialize_item(
*,
item: dict[str, Any],
fusion_frame: dict[str, Any],
source: E10LidarFieldSource,
surface: K1LocalSurfaceV1,
fusion_profile: CameraGeometryFusionProfile,
projection_profile: Kb4ProjectionProfile,
maximum_context_points: int,
) -> tuple[_ItemArrays, dict[str, object]]:
frame_index = _item_frame_index(item)
start = int(source.arrays["cloud_offsets"][frame_index])
end = int(source.arrays["cloud_offsets"][frame_index + 1])
points_map = np.asarray(
source.arrays["cloud_points_map"][start:end],
dtype=np.float64,
)
point_class = np.asarray(
surface.arrays["point_class"][start:end],
dtype=np.uint8,
)
point_height = np.asarray(
surface.arrays["point_height_m"][start:end],
dtype=np.float32,
)
position = np.asarray(
source.arrays["pose_positions_map"][frame_index],
dtype=np.float64,
)
orientation = np.asarray(
source.arrays["pose_quaternions_map_from_lidar"][frame_index],
dtype=np.float64,
)
source_available = bool(source.arrays["sample_available"][frame_index])
surface_valid = bool(surface.arrays["frame_valid"][frame_index])
projected: ProjectedPointCloud | None = None
if source_available and surface_valid:
projected = project_map_points_kb4(
points_map,
position_map_xyz=(
float(position[0]),
float(position[1]),
float(position[2]),
),
orientation_map_from_lidar_xyzw=(
float(orientation[0]),
float(orientation[1]),
float(orientation[2]),
float(orientation[3]),
),
profile=projection_profile,
)
objects = _required_array(fusion_frame, "objects")
semantic_supports = [
_semantic_support(
_object(raw, "fusion object"),
projected=projected,
frame_points_map=points_map,
point_class=point_class,
point_height_m=point_height,
source_available=source_available,
surface_valid=surface_valid,
profile=fusion_profile,
)
for raw in objects
]
geometry_supports = _geometry_cluster_supports(
points_map=points_map,
point_class=point_class,
point_height_m=point_height,
sensor_position_map=position,
claimed_source_indices=_claimed_indices(semantic_supports),
profile=fusion_profile,
)
locator = _required_object(item, "e29_locator")
snapshot = _required_object(item, "e29_snapshot")
locator_kind = _required_string(locator, "kind")
if locator_kind == "semantic-observation":
observation_index = _required_int(locator, "observation_index")
if not 0 <= observation_index < len(semantic_supports):
raise E30MaterializationError("semantic observation locator is out of bounds")
semantic_support = semantic_supports[observation_index]
if semantic_support.document != snapshot:
raise E30MaterializationError(
"replayed semantic support differs from immutable E29"
)
original = _object(objects[observation_index], "fusion object")
detector_score: float | None = _required_float(original, "score")
selected_indices = semantic_support.occupied_source_indices
candidate_indices = _semantic_candidate_indices(
original,
projected,
fusion_profile,
)
elif locator_kind == "geometry-only-cluster":
cluster_index = _required_int(locator, "cluster_index")
if not 0 <= cluster_index < len(geometry_supports):
raise E30MaterializationError("geometry cluster locator is out of bounds")
geometry_support = geometry_supports[cluster_index]
detector_score = None
if geometry_support.document != snapshot:
raise E30MaterializationError(
"replayed geometry cluster differs from immutable E29"
)
selected_indices = geometry_support.occupied_source_indices
candidate_indices = selected_indices
else:
raise E30MaterializationError("E30 locator kind is incompatible")
if (
np.any(selected_indices < 0)
or np.any(selected_indices >= points_map.shape[0])
or np.any(candidate_indices < 0)
or np.any(candidate_indices >= points_map.shape[0])
or not set(int(value) for value in selected_indices).issubset(
int(value) for value in candidate_indices
)
):
raise E30MaterializationError("materialized point ownership is invalid")
projected_rows = _bounded_projection_rows(
projected,
selected_indices=selected_indices,
candidate_indices=candidate_indices,
maximum_context_points=maximum_context_points,
)
if projected is None:
projected_indices = np.empty(0, dtype=np.int64)
pixels = np.empty((0, 2), dtype=np.float32)
depths = np.empty(0, dtype=np.float32)
else:
projected_indices = projected.source_indices[projected_rows].astype(
np.int64,
copy=False,
)
pixels = projected.pixels_xy[projected_rows].astype(np.float32)
depths = projected.depths_m[projected_rows].astype(np.float32)
projected_candidate = np.isin(
projected_indices,
candidate_indices,
assume_unique=False,
).astype(np.uint8)
projected_selected = np.isin(
projected_indices,
selected_indices,
assume_unique=False,
).astype(np.uint8)
selected_indices = np.unique(selected_indices).astype(np.int64, copy=False)
candidate_indices = np.unique(candidate_indices).astype(np.int64, copy=False)
rejected_count = int(
np.count_nonzero(~np.isin(candidate_indices, selected_indices))
)
arrays = _ItemArrays(
selected_source_indices=selected_indices,
selected_points_map_xyz_m=points_map[selected_indices].astype(np.float32),
candidate_source_indices=candidate_indices,
candidate_points_map_xyz_m=points_map[candidate_indices].astype(np.float32),
projected_source_indices=projected_indices,
projected_points_map_xyz_m=points_map[projected_indices].astype(np.float32),
projected_pixels_xy=pixels,
projected_depth_m=depths,
projected_point_class=point_class[projected_indices].astype(np.uint8),
projected_point_height_m=point_height[projected_indices].astype(np.float32),
projected_candidate_mask=projected_candidate,
projected_selected_mask=projected_selected,
sensor_position_map_xyz_m=position,
sensor_orientation_map_from_lidar_xyzw=orientation,
)
metadata: dict[str, object] = {
"frame_point_count": int(points_map.shape[0]),
"camera_front_point_count": (
0 if projected is None else projected.camera_front_point_count
),
"projected_point_count": int(projected_indices.size),
"candidate_point_count": int(candidate_indices.size),
"selected_point_count": int(selected_indices.size),
"rejected_candidate_point_count": rejected_count,
"selected_and_candidate_lossless": True,
"context_projection_bounded": True,
"source_reprojection_required": False,
"projection_width": int(projection_profile.width),
"projection_height": int(projection_profile.height),
"free_space_valid": False,
"human_review_complete": False,
"detector_score": detector_score,
}
return arrays, metadata
def _engineering_triage(
*,
item: dict[str, Any],
metadata: dict[str, object],
camera_available: bool,
) -> dict[str, object]:
"""Route evidence without pretending that a rule is a semantic verdict."""
selected_count_value = metadata["selected_point_count"]
if (
not isinstance(selected_count_value, int)
or isinstance(selected_count_value, bool)
or selected_count_value < 0
):
raise E30MaterializationError("selected point count is invalid")
selected_count = selected_count_value
detector_score = metadata.get("detector_score")
stratum = _required_string(item, "stratum")
locator = _required_object(item, "e29_locator")
signals: list[str] = []
if selected_count <= 1:
signals.append("sparse_selected_support")
if isinstance(detector_score, float) and detector_score < 0.2:
signals.append("low_detector_confidence")
if locator.get("kind") == "geometry-only-cluster":
signals.append("no_semantic_observation")
if stratum == "unknown":
signals.append("source_observation_not_current")
return {
"schema_version": "missioncore.e30-engineering-triage/v1",
"provenance": "deterministic-evidence-readiness/v1",
"state": (
"ready-for-ai-review"
if camera_available
else "blocked-camera-frame-unavailable"
),
"attention": "elevated" if signals else "standard",
"signals": signals,
"semantic_verdict": None,
"human_exception_required": None,
}
def _semantic_candidate_indices(
item: dict[str, Any],
projected: ProjectedPointCloud | None,
profile: CameraGeometryFusionProfile,
) -> IntArray:
bbox = item.get("bbox_xyxy")
if projected is None or not isinstance(bbox, list) or len(bbox) != 4:
return np.empty(0, dtype=np.int64)
bounds = np.asarray(bbox, dtype=np.float64)
if (
not np.isfinite(bounds).all()
or bounds[2] <= bounds[0]
or bounds[3] <= bounds[1]
):
return np.empty(0, dtype=np.int64)
width = float(bounds[2] - bounds[0])
height = float(bounds[3] - bounds[1])
inset = profile.bbox_inset_fraction
inner = np.asarray(
[
bounds[0] + width * inset,
bounds[1] + height * inset,
bounds[2] - width * inset,
bounds[3] - height * inset,
],
dtype=np.float64,
)
pixels = projected.pixels_xy
rows = np.flatnonzero(
(pixels[:, 0] >= inner[0])
& (pixels[:, 0] <= inner[2])
& (pixels[:, 1] >= inner[1])
& (pixels[:, 1] <= inner[3])
)
return projected.source_indices[rows].astype(np.int64, copy=False)
def _bounded_projection_rows(
projected: ProjectedPointCloud | None,
*,
selected_indices: IntArray,
candidate_indices: IntArray,
maximum_context_points: int,
) -> IntArray:
if projected is None:
return np.empty(0, dtype=np.int64)
required = np.isin(
projected.source_indices,
np.union1d(selected_indices, candidate_indices),
)
required_rows = np.flatnonzero(required).astype(np.int64, copy=False)
context_rows = np.flatnonzero(~required).astype(np.int64, copy=False)
if context_rows.size > maximum_context_points:
positions = np.linspace(
0,
context_rows.size - 1,
maximum_context_points,
dtype=np.int64,
)
context_rows = context_rows[positions]
return np.sort(np.concatenate((required_rows, context_rows))).astype(
np.int64,
copy=False,
)
def _read_review_pack(root: Path) -> _ReviewPack:
candidate = root.expanduser()
if candidate.is_symlink():
raise E30MaterializationError("E30 review pack must not be a symlink")
candidate = candidate.resolve(strict=True)
if not candidate.is_dir() or _REVIEW_PACK_ID.fullmatch(candidate.name) is None:
raise E30MaterializationError("E30 review pack id is invalid")
manifest_path = _regular_file(candidate, "manifest.json")
manifest = _read_json(manifest_path, "E30 review manifest")
identity = _required_object(manifest, "identity")
identity_sha256 = _required_string(manifest, "identity_sha256")
if (
manifest.get("schema_version") != "missioncore.e30-evidence-review-pack/v1"
or manifest.get("result_id") != candidate.name
or hashlib.sha256(_canonical_json(identity)).hexdigest() != identity_sha256
or candidate.name != f"e30-review-pack-{identity_sha256}"
or manifest.get("human_review_complete") is not False
or manifest.get("lab_published") is not False
):
raise E30MaterializationError("E30 review pack identity is invalid")
_reject_authority(_required_object(manifest, "authority"), "E30 review pack")
artifact = _unique_artifact(manifest, "review-items")
items_path = _verified_relative_artifact(candidate, artifact)
items: list[dict[str, Any]] = []
with items_path.open("r", encoding="utf-8") as stream:
for expected_sequence, line in enumerate(stream):
try:
item = _object(json.loads(line), "E30 review item")
except json.JSONDecodeError as exc:
raise E30MaterializationError("E30 review item JSON is invalid") from exc
item_id = _required_string(item, "item_id")
if (
item.get("schema_version")
!= "missioncore.e30-evidence-review-item/v1"
or _REVIEW_ITEM_ID.fullmatch(item_id) is None
or _required_int(item, "sequence") != expected_sequence
or _required_object(item, "review").get("state") != "unreviewed"
):
raise E30MaterializationError("E30 review item is incompatible")
_reject_authority(
_required_object(item, "authority"),
"E30 review item",
)
items.append(item)
if (
len(items) != _required_int(manifest, "selected_item_count")
or len({item["item_id"] for item in items}) != len(items)
):
raise E30MaterializationError("E30 review item count is inconsistent")
return _ReviewPack(
root=candidate,
manifest=manifest,
items=tuple(items),
items_sha256=_required_string(artifact, "sha256"),
)
def _review_items_by_frame(
items: tuple[dict[str, Any], ...],
) -> dict[int, list[dict[str, Any]]]:
grouped: dict[int, list[dict[str, Any]]] = {}
for item in items:
grouped.setdefault(_item_frame_index(item), []).append(item)
return grouped
def _item_frame_index(item: dict[str, Any]) -> int:
binding = _required_object(item, "evidence_binding")
frame_index = _required_int(binding, "frame_index")
if frame_index < 0:
raise E30MaterializationError("E30 frame index is invalid")
return frame_index
def _item_source_frame_index(item: dict[str, Any]) -> int:
binding = _required_object(item, "evidence_binding")
frame_index = _required_int(binding, "source_frame_index")
if frame_index < 0:
raise E30MaterializationError("E30 source frame index is invalid")
return frame_index
def _read_selected_fusion_frames(
path: Path,
*,
selected_frame_indices: set[int],
source: E10LidarFieldSource,
) -> dict[int, dict[str, Any]]:
selected: dict[int, dict[str, Any]] = {}
with path.open("r", encoding="utf-8") as stream:
for frame_index, line in enumerate(stream):
if frame_index not in selected_frame_indices:
continue
selected[frame_index] = _fusion_frame(
line,
expected_frame_index=frame_index,
source=source,
)
if set(selected) != selected_frame_indices:
raise E30MaterializationError("source fusion frames are incomplete")
return selected
def _validate_bound_sources(
source: E10LidarFieldSource,
surface: K1LocalSurfaceV1,
e29_identity: dict[str, Any],
) -> None:
if (
e29_identity.get("source_pack_id") != source.pack_id
or e29_identity.get("local_surface_model_id") != surface.model_id
or surface.identity.get("source_pack_id") != source.pack_id
or surface.identity.get("frame_count") != source.frame_count
or surface.identity.get("point_count") != source.point_count
or e29_identity.get("frame_count") != source.frame_count
):
raise E30MaterializationError("E30 LiDAR/surface source binding is invalid")
def _fusion_profile(identity: dict[str, Any]) -> CameraGeometryFusionProfile:
value = _required_object(identity, "profile")
profile = CameraGeometryFusionProfile(
profile_id=_required_string(value, "profile_id"),
bbox_inset_fraction=_required_float(value, "bbox_inset_fraction"),
depth_cluster_minimum_gap_m=_required_float(
value,
"depth_cluster_minimum_gap_m",
),
depth_cluster_gap_fraction=_required_float(
value,
"depth_cluster_gap_fraction",
),
spatial_cluster_radius_m=_required_float(
value,
"spatial_cluster_radius_m",
),
semantic_minimum_occupied_points=_required_int(
value,
"semantic_minimum_occupied_points",
),
semantic_minimum_occupied_voxels=_required_int(
value,
"semantic_minimum_occupied_voxels",
),
semantic_voxel_size_m=_required_float(
value,
"semantic_voxel_size_m",
),
conflict_minimum_classified_points=_required_int(
value,
"conflict_minimum_classified_points",
),
conflict_surface_fraction=_required_float(
value,
"conflict_surface_fraction",
),
geometry_local_radius_m=_required_float(
value,
"geometry_local_radius_m",
),
geometry_voxel_size_m=_required_float(
value,
"geometry_voxel_size_m",
),
geometry_minimum_cluster_points=_required_int(
value,
"geometry_minimum_cluster_points",
),
geometry_minimum_cluster_voxels=_required_int(
value,
"geometry_minimum_cluster_voxels",
),
maximum_geometry_clusters_per_frame=_required_int(
value,
"maximum_geometry_clusters_per_frame",
),
)
if profile.to_dict() != value:
raise E30MaterializationError("E29 fusion profile cannot be reconstructed")
return profile
def _source_artifact_sha256(manifest: dict[str, Any]) -> str:
artifact = _required_object(manifest, "artifact")
return _required_sha256(artifact, "sha256")
def _surface_artifact_sha256(manifest: dict[str, Any]) -> str:
artifact = _unique_artifact(manifest, "local-surface")
return _required_sha256(artifact, "sha256")
def _read_existing_materialization(
root: Path,
identity: dict[str, object],
) -> dict[str, Any]:
manifest = _read_json(
_regular_file(root, E30_MATERIALIZATION_MANIFEST_NAME),
"E30 materialization manifest",
)
if (
manifest.get("schema_version") != E30_MATERIALIZATION_SCHEMA
or manifest.get("identity") != identity
or manifest.get("human_review_complete") is not False
or manifest.get("lab_published") is not False
):
raise E30MaterializationError("existing E30 materialization differs")
_reject_authority(
_required_object(manifest, "authority"),
"E30 materialization",
)
artifact = _unique_artifact(manifest, "materialized-items")
_verified_relative_artifact(root, artifact)
return manifest
def _logical_arrays_sha256(arrays: dict[str, npt.NDArray[Any]]) -> str:
digest = hashlib.sha256()
for name in sorted(arrays):
array = np.ascontiguousarray(arrays[name])
digest.update(name.encode())
digest.update(array.dtype.str.encode())
digest.update(_canonical_json(list(array.shape)))
digest.update(array.tobytes(order="C"))
return digest.hexdigest()
def _child_directory(root: Path, child: str) -> Path:
base = root.expanduser().absolute()
if base.is_symlink():
raise E30MaterializationError("evidence root must not be a symlink")
base = base.resolve(strict=True)
candidate = base / child
if candidate.is_symlink():
raise E30MaterializationError("evidence child must not be a symlink")
candidate = candidate.resolve(strict=True)
try:
candidate.relative_to(base)
except ValueError as exc:
raise E30MaterializationError("evidence child escaped its root") from exc
if not candidate.is_dir():
raise E30MaterializationError("evidence child must be a directory")
return candidate
def _regular_file(root: Path, relative: str) -> Path:
candidate = root / relative
if candidate.is_symlink():
raise E30MaterializationError("evidence artifact must not be a symlink")
candidate = candidate.resolve(strict=True)
try:
candidate.relative_to(root)
except ValueError as exc:
raise E30MaterializationError("evidence artifact escaped its root") from exc
if not candidate.is_file():
raise E30MaterializationError("evidence artifact must be a regular file")
return candidate
def _unique_artifact(manifest: dict[str, Any], role: str) -> dict[str, Any]:
matches = [
_object(item, "artifact")
for item in _required_array(manifest, "artifacts")
if isinstance(item, dict) and item.get("role") == role
]
if len(matches) != 1:
raise E30MaterializationError(f"no unique {role} artifact")
return matches[0]
def _verified_relative_artifact(
root: Path,
artifact: dict[str, Any],
) -> Path:
relative = _required_string(artifact, "path")
if Path(relative).is_absolute() or ".." in Path(relative).parts:
raise E30MaterializationError("artifact path is invalid")
path = _regular_file(root, relative)
if (
path.stat().st_size != _required_int(artifact, "byte_length")
or _sha256_file(path) != _required_sha256(artifact, "sha256")
):
raise E30MaterializationError("artifact content changed")
return path
def _artifact(role: str, path: Path, media_type: str) -> dict[str, object]:
return {
"role": role,
"path": path.name,
"media_type": media_type,
"byte_length": path.stat().st_size,
"sha256": _sha256_file(path),
}
def _reject_authority(authority: dict[str, Any], label: str) -> None:
if (
authority.get("commands_enabled") is not False
or authority.get("navigation_or_safety_accepted") is not False
):
raise E30MaterializationError(f"{label} must remain diagnostic-only")
def _read_json(path: Path, label: str) -> dict[str, Any]:
try:
return _object(json.loads(path.read_text(encoding="utf-8")), label)
except (OSError, UnicodeDecodeError, json.JSONDecodeError) as exc:
raise E30MaterializationError(f"{label} is invalid") from exc
def _write_json(path: Path, value: dict[str, Any]) -> None:
with path.open("x", encoding="utf-8") as stream:
stream.write(_canonical_json(value).decode("utf-8"))
stream.write("\n")
def _canonical_json(value: object) -> bytes:
return json.dumps(
value,
ensure_ascii=False,
sort_keys=True,
separators=(",", ":"),
allow_nan=False,
).encode()
def _sha256_file(path: Path) -> str:
digest = hashlib.sha256()
with path.open("rb") as stream:
while chunk := stream.read(1024 * 1024):
digest.update(chunk)
return digest.hexdigest()
def _object(value: object, label: str) -> dict[str, Any]:
if not isinstance(value, dict) or any(not isinstance(key, str) for key in value):
raise E30MaterializationError(f"{label} must be an object")
return value
def _required_object(document: dict[str, Any], key: str) -> dict[str, Any]:
return _object(document.get(key), key)
def _required_array(document: dict[str, Any], key: str) -> list[object]:
value = document.get(key)
if not isinstance(value, list):
raise E30MaterializationError(f"{key} must be an array")
return value
def _required_string(document: dict[str, Any], key: str) -> str:
value = document.get(key)
if not isinstance(value, str) or not value:
raise E30MaterializationError(f"{key} must be a nonempty string")
return value
def _required_sha256(document: dict[str, Any], key: str) -> str:
value = _required_string(document, key)
if _SHA256.fullmatch(value) is None:
raise E30MaterializationError(f"{key} must be a SHA-256 digest")
return value
def _required_int(document: dict[str, Any], key: str) -> int:
value = document.get(key)
if not isinstance(value, int) or isinstance(value, bool):
raise E30MaterializationError(f"{key} must be an integer")
return value
def _required_float(document: dict[str, Any], key: str) -> float:
value = document.get(key)
if not isinstance(value, int | float) or isinstance(value, bool):
raise E30MaterializationError(f"{key} must be numeric")
parsed = float(value)
if not math.isfinite(parsed):
raise E30MaterializationError(f"{key} must be finite")
return parsed