feat(perception): add E34 temporal occupied layer
This commit is contained in:
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -24,6 +24,11 @@ from k1link.compute.e33_worker_shadow import (
|
||||
E33WorkerShadowResult,
|
||||
read_e33_worker_shadow_result,
|
||||
)
|
||||
from k1link.compute.e34_temporal_occupied_replay import (
|
||||
E34TemporalOccupiedReplay,
|
||||
E34TemporalOccupiedReplayError,
|
||||
read_e34_temporal_occupied_replay,
|
||||
)
|
||||
|
||||
LABORATORY_ADVANCED_CATALOG_SCHEMA: Final = (
|
||||
"missioncore.laboratory-advanced-catalog/v1"
|
||||
@@ -32,6 +37,7 @@ LABORATORY_ADVANCED_CATALOG_SCHEMA: Final = (
|
||||
_E31_RESULT_ID = re.compile(r"^e31-source-qualification-[a-f0-9]{64}$")
|
||||
_E32_RESULT_ID = re.compile(r"^e32-track-geometry-[a-f0-9]{64}$")
|
||||
_E33_RESULT_ID = re.compile(r"^e33-worker-shadow-[a-f0-9]{64}$")
|
||||
_E34_RESULT_ID = re.compile(r"^e34-temporal-occupied-[a-f0-9]{64}$")
|
||||
|
||||
RootProvider = Callable[[], Path | None]
|
||||
|
||||
@@ -73,6 +79,15 @@ def _read_e33_cached(
|
||||
return read_e33_worker_shadow_result(Path(root_text))
|
||||
|
||||
|
||||
@lru_cache(maxsize=16)
|
||||
def _read_e34_cached(
|
||||
root_text: str,
|
||||
signature: tuple[int, ...],
|
||||
) -> E34TemporalOccupiedReplay:
|
||||
del signature
|
||||
return read_e34_temporal_occupied_replay(Path(root_text))
|
||||
|
||||
|
||||
def _configured_root(provider: RootProvider) -> Path | None:
|
||||
value = provider()
|
||||
if value is None:
|
||||
@@ -294,6 +309,113 @@ def _project_e33(
|
||||
}
|
||||
|
||||
|
||||
def _project_e34(result: E34TemporalOccupiedReplay) -> dict[str, object]:
|
||||
identity = _object(result.manifest.get("identity"), "E34 identity")
|
||||
profile = _object(identity.get("profile"), "E34 profile")
|
||||
layer = _object(profile.get("layer"), "E34 layer")
|
||||
association = _object(profile.get("association"), "E34 association")
|
||||
metrics = _object(result.report.get("metrics"), "E34 metrics")
|
||||
frames = _object(metrics.get("frames"), "E34 frames")
|
||||
components = _object(metrics.get("components"), "E34 components")
|
||||
occupancy = _object(metrics.get("occupancy"), "E34 occupancy")
|
||||
aging = _object(metrics.get("aging"), "E34 aging")
|
||||
map_frame = _object(metrics.get("map_frame"), "E34 map frame")
|
||||
runtime = _object(metrics.get("runtime"), "E34 runtime")
|
||||
frame_processing = _object(
|
||||
runtime.get("frame_processing_ms"),
|
||||
"E34 frame processing",
|
||||
)
|
||||
acceptance = _object(result.report.get("acceptance"), "E34 acceptance")
|
||||
if acceptance.get("accepted") is not True:
|
||||
raise ValueError("E34 result is not accepted")
|
||||
return {
|
||||
"result_id": result.result_id,
|
||||
"created_at_utc": result.manifest.get("created_at_utc"),
|
||||
"source_session_id": identity.get("source_session_id"),
|
||||
"status": result.manifest.get("acceptance_state"),
|
||||
"e32_result_id": identity.get("e32_result_id"),
|
||||
"e33_result_id": identity.get("e33_result_id"),
|
||||
"profile_id": profile.get("profile_id"),
|
||||
"pipeline_id": identity.get("pipeline"),
|
||||
"coordinate_frame": identity.get("coordinate_frame"),
|
||||
"configuration": {
|
||||
"voxel_size_m": layer.get("voxel_size_m"),
|
||||
"occupied_ttl_seconds": layer.get("occupied_ttl_seconds"),
|
||||
"maximum_active_components": layer.get(
|
||||
"maximum_active_components"
|
||||
),
|
||||
"maximum_cells_per_component": layer.get(
|
||||
"maximum_cells_per_component"
|
||||
),
|
||||
"geometry_maximum_gap_seconds": association.get(
|
||||
"geometry_maximum_gap_seconds"
|
||||
),
|
||||
"geometry_maximum_centroid_distance_m": association.get(
|
||||
"geometry_maximum_centroid_distance_m"
|
||||
),
|
||||
},
|
||||
"metrics": {
|
||||
"source_frames": frames.get("source"),
|
||||
"processed_frames": frames.get("processed"),
|
||||
"frames_with_current_layer": frames.get("with_current_layer"),
|
||||
"held_only_frames": frames.get("held_only"),
|
||||
"unknown_empty_frames": frames.get("unknown_empty"),
|
||||
"created_components": components.get("created"),
|
||||
"camera_created_components": components.get("camera_created"),
|
||||
"geometry_created_components": components.get("geometry_created"),
|
||||
"geometry_reassociated_components": components.get(
|
||||
"geometry_reassociated_components"
|
||||
),
|
||||
"exact_camera_associations": components.get(
|
||||
"exact_camera_associations"
|
||||
),
|
||||
"geometry_spatial_reassociations": components.get(
|
||||
"geometry_spatial_reassociations"
|
||||
),
|
||||
"held_publications": components.get("held_publications"),
|
||||
"expired_components": components.get("expired"),
|
||||
"peak_active_components": components.get("peak_active"),
|
||||
"maximum_observed_span_seconds": components.get(
|
||||
"maximum_observed_span_seconds"
|
||||
),
|
||||
"continuity_fraction": components.get("continuity_fraction"),
|
||||
"geometry_only_reassociation_fraction": components.get(
|
||||
"geometry_only_reassociation_fraction"
|
||||
),
|
||||
"e32_current_point_rows": occupancy.get(
|
||||
"e32_current_point_rows"
|
||||
),
|
||||
"e34_consumed_current_point_rows": occupancy.get(
|
||||
"e34_consumed_current_point_rows"
|
||||
),
|
||||
"current_cell_rows": occupancy.get("current_cell_rows"),
|
||||
"held_cell_rows": occupancy.get("held_cell_rows"),
|
||||
"stored_cell_rows": occupancy.get("stored_cell_rows"),
|
||||
"free_cell_rows": occupancy.get("free_cell_rows"),
|
||||
"peak_cells_per_component": occupancy.get(
|
||||
"peak_cells_per_component"
|
||||
),
|
||||
"maximum_held_age_seconds": aging.get(
|
||||
"maximum_held_age_seconds"
|
||||
),
|
||||
"maximum_expiry_delay_seconds": aging.get(
|
||||
"maximum_expiry_delay_seconds"
|
||||
),
|
||||
"maximum_replay_materialization_delay_seconds": aging.get(
|
||||
"maximum_replay_materialization_delay_seconds"
|
||||
),
|
||||
"map_frame_jump_candidates": map_frame.get("jump_candidates"),
|
||||
"frame_processing_p95_ms": frame_processing.get("p95"),
|
||||
"build_elapsed_ms": runtime.get("build_elapsed_ms"),
|
||||
},
|
||||
"review": copy.deepcopy(result.review),
|
||||
"acceptance": copy.deepcopy(acceptance),
|
||||
"decision": copy.deepcopy(result.report.get("decision")),
|
||||
"authority": copy.deepcopy(result.report.get("authority")),
|
||||
"access": "read-only",
|
||||
}
|
||||
|
||||
|
||||
def _empty_catalog(configured: bool) -> dict[str, object]:
|
||||
return {
|
||||
"schema_version": LABORATORY_ADVANCED_CATALOG_SCHEMA,
|
||||
@@ -310,6 +432,7 @@ def build_advanced_laboratory_router(
|
||||
e31_root_provider: RootProvider = lambda: None,
|
||||
e32_root_provider: RootProvider = lambda: None,
|
||||
e33_root_provider: RootProvider = lambda: None,
|
||||
e34_root_provider: RootProvider = lambda: None,
|
||||
) -> APIRouter:
|
||||
router = APIRouter(prefix="/api/v1/laboratory", tags=["laboratory"])
|
||||
|
||||
@@ -434,4 +557,39 @@ def build_advanced_laboratory_router(
|
||||
"invalid_total": invalid_total,
|
||||
}
|
||||
|
||||
@router.get("/e34/results")
|
||||
def list_e34_results(
|
||||
limit: int = Query(default=1, ge=1, le=10),
|
||||
) -> dict[str, object]:
|
||||
root = _configured_root(e34_root_provider)
|
||||
if root is None:
|
||||
return _empty_catalog(False)
|
||||
candidates = _candidates(root, _E34_RESULT_ID)
|
||||
items: list[dict[str, object]] = []
|
||||
invalid_total = 0
|
||||
for candidate in candidates:
|
||||
try:
|
||||
result = _read_e34_cached(
|
||||
str(candidate.resolve()),
|
||||
_result_signature(candidate),
|
||||
)
|
||||
if not result.accepted:
|
||||
raise ValueError("E34 result is not accepted")
|
||||
if len(items) < limit:
|
||||
items.append(_project_e34(result))
|
||||
except (
|
||||
E34TemporalOccupiedReplayError,
|
||||
KeyError,
|
||||
OSError,
|
||||
TypeError,
|
||||
ValueError,
|
||||
):
|
||||
invalid_total += 1
|
||||
return {
|
||||
**_empty_catalog(True),
|
||||
"items": items,
|
||||
"candidate_total": len(candidates),
|
||||
"invalid_total": invalid_total,
|
||||
}
|
||||
|
||||
return router
|
||||
|
||||
@@ -520,6 +520,13 @@ app.include_router(
|
||||
/ "e33"
|
||||
/ "results"
|
||||
),
|
||||
e34_root_provider=lambda: (
|
||||
REPOSITORY_ROOT
|
||||
/ ".runtime"
|
||||
/ "compute-experiments"
|
||||
/ "e34"
|
||||
/ "results"
|
||||
),
|
||||
)
|
||||
)
|
||||
app.include_router(
|
||||
|
||||
Reference in New Issue
Block a user