x4d-devkit 0.43.0rc3__tar.gz → 0.43.0rc4__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {x4d_devkit-0.43.0rc3/x4d_devkit.egg-info → x4d_devkit-0.43.0rc4}/PKG-INFO +1 -1
- {x4d_devkit-0.43.0rc3 → x4d_devkit-0.43.0rc4}/pyproject.toml +1 -1
- {x4d_devkit-0.43.0rc3 → x4d_devkit-0.43.0rc4}/tests/test_clean_basemap.py +5 -0
- x4d_devkit-0.43.0rc4/tests/test_clean_basemap_preannotation.py +96 -0
- {x4d_devkit-0.43.0rc3 → x4d_devkit-0.43.0rc4}/tests/test_sdk_api.py +1 -1
- {x4d_devkit-0.43.0rc3 → x4d_devkit-0.43.0rc4}/x4d_devkit/clean_basemap.py +125 -4
- {x4d_devkit-0.43.0rc3 → x4d_devkit-0.43.0rc4/x4d_devkit.egg-info}/PKG-INFO +1 -1
- {x4d_devkit-0.43.0rc3 → x4d_devkit-0.43.0rc4}/x4d_devkit.egg-info/SOURCES.txt +1 -0
- {x4d_devkit-0.43.0rc3 → x4d_devkit-0.43.0rc4}/LICENSE +0 -0
- {x4d_devkit-0.43.0rc3 → x4d_devkit-0.43.0rc4}/README.md +0 -0
- {x4d_devkit-0.43.0rc3 → x4d_devkit-0.43.0rc4}/setup.cfg +0 -0
- {x4d_devkit-0.43.0rc3 → x4d_devkit-0.43.0rc4}/tests/test_annotation_contract.py +0 -0
- {x4d_devkit-0.43.0rc3 → x4d_devkit-0.43.0rc4}/tests/test_annotation_reference.py +0 -0
- {x4d_devkit-0.43.0rc3 → x4d_devkit-0.43.0rc4}/tests/test_assets_client.py +0 -0
- {x4d_devkit-0.43.0rc3 → x4d_devkit-0.43.0rc4}/tests/test_boundary.py +0 -0
- {x4d_devkit-0.43.0rc3 → x4d_devkit-0.43.0rc4}/tests/test_box.py +0 -0
- {x4d_devkit-0.43.0rc3 → x4d_devkit-0.43.0rc4}/tests/test_build_info.py +0 -0
- {x4d_devkit-0.43.0rc3 → x4d_devkit-0.43.0rc4}/tests/test_clean_basemap_client.py +0 -0
- {x4d_devkit-0.43.0rc3 → x4d_devkit-0.43.0rc4}/tests/test_cli_auth.py +0 -0
- {x4d_devkit-0.43.0rc3 → x4d_devkit-0.43.0rc4}/tests/test_client_json_contract.py +0 -0
- {x4d_devkit-0.43.0rc3 → x4d_devkit-0.43.0rc4}/tests/test_client_projects.py +0 -0
- {x4d_devkit-0.43.0rc3 → x4d_devkit-0.43.0rc4}/tests/test_clip_archives.py +0 -0
- {x4d_devkit-0.43.0rc3 → x4d_devkit-0.43.0rc4}/tests/test_contract_validation.py +0 -0
- {x4d_devkit-0.43.0rc3 → x4d_devkit-0.43.0rc4}/tests/test_coordinate_frames.py +0 -0
- {x4d_devkit-0.43.0rc3 → x4d_devkit-0.43.0rc4}/tests/test_current_state.py +0 -0
- {x4d_devkit-0.43.0rc3 → x4d_devkit-0.43.0rc4}/tests/test_current_state_identity_consumers_example.py +0 -0
- {x4d_devkit-0.43.0rc3 → x4d_devkit-0.43.0rc4}/tests/test_dataset_contract.py +0 -0
- {x4d_devkit-0.43.0rc3 → x4d_devkit-0.43.0rc4}/tests/test_dataset_identity.py +0 -0
- {x4d_devkit-0.43.0rc3 → x4d_devkit-0.43.0rc4}/tests/test_detection_eval.py +0 -0
- {x4d_devkit-0.43.0rc3 → x4d_devkit-0.43.0rc4}/tests/test_evaluate.py +0 -0
- {x4d_devkit-0.43.0rc3 → x4d_devkit-0.43.0rc4}/tests/test_export_bundle.py +0 -0
- {x4d_devkit-0.43.0rc3 → x4d_devkit-0.43.0rc4}/tests/test_image_review.py +0 -0
- {x4d_devkit-0.43.0rc3 → x4d_devkit-0.43.0rc4}/tests/test_inference_input.py +0 -0
- {x4d_devkit-0.43.0rc3 → x4d_devkit-0.43.0rc4}/tests/test_inference_schemas.py +0 -0
- {x4d_devkit-0.43.0rc3 → x4d_devkit-0.43.0rc4}/tests/test_inference_service.py +0 -0
- {x4d_devkit-0.43.0rc3 → x4d_devkit-0.43.0rc4}/tests/test_label_schemas.py +0 -0
- {x4d_devkit-0.43.0rc3 → x4d_devkit-0.43.0rc4}/tests/test_lidar_materialization.py +0 -0
- {x4d_devkit-0.43.0rc3 → x4d_devkit-0.43.0rc4}/tests/test_loader.py +0 -0
- {x4d_devkit-0.43.0rc3 → x4d_devkit-0.43.0rc4}/tests/test_matching.py +0 -0
- {x4d_devkit-0.43.0rc3 → x4d_devkit-0.43.0rc4}/tests/test_metrics.py +0 -0
- {x4d_devkit-0.43.0rc3 → x4d_devkit-0.43.0rc4}/tests/test_models.py +0 -0
- {x4d_devkit-0.43.0rc3 → x4d_devkit-0.43.0rc4}/tests/test_platform_pose.py +0 -0
- {x4d_devkit-0.43.0rc3 → x4d_devkit-0.43.0rc4}/tests/test_preannotation_client.py +0 -0
- {x4d_devkit-0.43.0rc3 → x4d_devkit-0.43.0rc4}/tests/test_reconstruction_client.py +0 -0
- {x4d_devkit-0.43.0rc3 → x4d_devkit-0.43.0rc4}/tests/test_release_gate.py +0 -0
- {x4d_devkit-0.43.0rc3 → x4d_devkit-0.43.0rc4}/tests/test_roadmark_preview.py +0 -0
- {x4d_devkit-0.43.0rc3 → x4d_devkit-0.43.0rc4}/tests/test_semantic_scene_authoring.py +0 -0
- {x4d_devkit-0.43.0rc3 → x4d_devkit-0.43.0rc4}/tests/test_semantic_scene_client.py +0 -0
- {x4d_devkit-0.43.0rc3 → x4d_devkit-0.43.0rc4}/tests/test_semantic_scene_contract.py +0 -0
- {x4d_devkit-0.43.0rc3 → x4d_devkit-0.43.0rc4}/tests/test_semantic_scene_native_clip.py +0 -0
- {x4d_devkit-0.43.0rc3 → x4d_devkit-0.43.0rc4}/tests/test_time_contract.py +0 -0
- {x4d_devkit-0.43.0rc3 → x4d_devkit-0.43.0rc4}/tests/test_token.py +0 -0
- {x4d_devkit-0.43.0rc3 → x4d_devkit-0.43.0rc4}/tests/test_tracking_eval.py +0 -0
- {x4d_devkit-0.43.0rc3 → x4d_devkit-0.43.0rc4}/tests/test_training_identity.py +0 -0
- {x4d_devkit-0.43.0rc3 → x4d_devkit-0.43.0rc4}/tests/test_transform.py +0 -0
- {x4d_devkit-0.43.0rc3 → x4d_devkit-0.43.0rc4}/tests/test_transform_chain.py +0 -0
- {x4d_devkit-0.43.0rc3 → x4d_devkit-0.43.0rc4}/tests/test_validation.py +0 -0
- {x4d_devkit-0.43.0rc3 → x4d_devkit-0.43.0rc4}/tests/test_work_session.py +0 -0
- {x4d_devkit-0.43.0rc3 → x4d_devkit-0.43.0rc4}/x4d_devkit/__init__.py +0 -0
- {x4d_devkit-0.43.0rc3 → x4d_devkit-0.43.0rc4}/x4d_devkit/annotation_contract.py +0 -0
- {x4d_devkit-0.43.0rc3 → x4d_devkit-0.43.0rc4}/x4d_devkit/annotation_reference.py +0 -0
- {x4d_devkit-0.43.0rc3 → x4d_devkit-0.43.0rc4}/x4d_devkit/build_info.py +0 -0
- {x4d_devkit-0.43.0rc3 → x4d_devkit-0.43.0rc4}/x4d_devkit/cli.py +0 -0
- {x4d_devkit-0.43.0rc3 → x4d_devkit-0.43.0rc4}/x4d_devkit/client/__init__.py +0 -0
- {x4d_devkit-0.43.0rc3 → x4d_devkit-0.43.0rc4}/x4d_devkit/client/_origin.py +0 -0
- {x4d_devkit-0.43.0rc3 → x4d_devkit-0.43.0rc4}/x4d_devkit/client/annotation_reference.py +0 -0
- {x4d_devkit-0.43.0rc3 → x4d_devkit-0.43.0rc4}/x4d_devkit/client/assets.py +0 -0
- {x4d_devkit-0.43.0rc3 → x4d_devkit-0.43.0rc4}/x4d_devkit/client/bags.py +0 -0
- {x4d_devkit-0.43.0rc3 → x4d_devkit-0.43.0rc4}/x4d_devkit/client/capabilities.py +0 -0
- {x4d_devkit-0.43.0rc3 → x4d_devkit-0.43.0rc4}/x4d_devkit/client/checkpoints.py +0 -0
- {x4d_devkit-0.43.0rc3 → x4d_devkit-0.43.0rc4}/x4d_devkit/client/clean_basemap.py +0 -0
- {x4d_devkit-0.43.0rc3 → x4d_devkit-0.43.0rc4}/x4d_devkit/client/client.py +0 -0
- {x4d_devkit-0.43.0rc3 → x4d_devkit-0.43.0rc4}/x4d_devkit/client/clip_work_sessions.py +0 -0
- {x4d_devkit-0.43.0rc3 → x4d_devkit-0.43.0rc4}/x4d_devkit/client/clips.py +0 -0
- {x4d_devkit-0.43.0rc3 → x4d_devkit-0.43.0rc4}/x4d_devkit/client/dataset_identity.py +0 -0
- {x4d_devkit-0.43.0rc3 → x4d_devkit-0.43.0rc4}/x4d_devkit/client/image_review.py +0 -0
- {x4d_devkit-0.43.0rc3 → x4d_devkit-0.43.0rc4}/x4d_devkit/client/label_schemas.py +0 -0
- {x4d_devkit-0.43.0rc3 → x4d_devkit-0.43.0rc4}/x4d_devkit/client/preannotation.py +0 -0
- {x4d_devkit-0.43.0rc3 → x4d_devkit-0.43.0rc4}/x4d_devkit/client/projects.py +0 -0
- {x4d_devkit-0.43.0rc3 → x4d_devkit-0.43.0rc4}/x4d_devkit/client/reconstruction.py +0 -0
- {x4d_devkit-0.43.0rc3 → x4d_devkit-0.43.0rc4}/x4d_devkit/client/semantic_scene.py +0 -0
- {x4d_devkit-0.43.0rc3 → x4d_devkit-0.43.0rc4}/x4d_devkit/client/semantic_scene_authoring.py +0 -0
- {x4d_devkit-0.43.0rc3 → x4d_devkit-0.43.0rc4}/x4d_devkit/client/services.py +0 -0
- {x4d_devkit-0.43.0rc3 → x4d_devkit-0.43.0rc4}/x4d_devkit/client/test_sets.py +0 -0
- {x4d_devkit-0.43.0rc3 → x4d_devkit-0.43.0rc4}/x4d_devkit/consumer_identity.py +0 -0
- {x4d_devkit-0.43.0rc3 → x4d_devkit-0.43.0rc4}/x4d_devkit/coordinate_contract.py +0 -0
- {x4d_devkit-0.43.0rc3 → x4d_devkit-0.43.0rc4}/x4d_devkit/core/__init__.py +0 -0
- {x4d_devkit-0.43.0rc3 → x4d_devkit-0.43.0rc4}/x4d_devkit/core/loader.py +0 -0
- {x4d_devkit-0.43.0rc3 → x4d_devkit-0.43.0rc4}/x4d_devkit/core/models.py +0 -0
- {x4d_devkit-0.43.0rc3 → x4d_devkit-0.43.0rc4}/x4d_devkit/core/token.py +0 -0
- {x4d_devkit-0.43.0rc3 → x4d_devkit-0.43.0rc4}/x4d_devkit/core/transform.py +0 -0
- {x4d_devkit-0.43.0rc3 → x4d_devkit-0.43.0rc4}/x4d_devkit/current_state.py +0 -0
- {x4d_devkit-0.43.0rc3 → x4d_devkit-0.43.0rc4}/x4d_devkit/dataset_contract.py +0 -0
- {x4d_devkit-0.43.0rc3 → x4d_devkit-0.43.0rc4}/x4d_devkit/dataset_identity.py +0 -0
- {x4d_devkit-0.43.0rc3 → x4d_devkit-0.43.0rc4}/x4d_devkit/eval/__init__.py +0 -0
- {x4d_devkit-0.43.0rc3 → x4d_devkit-0.43.0rc4}/x4d_devkit/eval/api.py +0 -0
- {x4d_devkit-0.43.0rc3 → x4d_devkit-0.43.0rc4}/x4d_devkit/eval/box.py +0 -0
- {x4d_devkit-0.43.0rc3 → x4d_devkit-0.43.0rc4}/x4d_devkit/eval/detection.py +0 -0
- {x4d_devkit-0.43.0rc3 → x4d_devkit-0.43.0rc4}/x4d_devkit/eval/matching.py +0 -0
- {x4d_devkit-0.43.0rc3 → x4d_devkit-0.43.0rc4}/x4d_devkit/eval/metrics.py +0 -0
- {x4d_devkit-0.43.0rc3 → x4d_devkit-0.43.0rc4}/x4d_devkit/eval/tracking.py +0 -0
- {x4d_devkit-0.43.0rc3 → x4d_devkit-0.43.0rc4}/x4d_devkit/export_bundle.py +0 -0
- {x4d_devkit-0.43.0rc3 → x4d_devkit-0.43.0rc4}/x4d_devkit/image_review.py +0 -0
- {x4d_devkit-0.43.0rc3 → x4d_devkit-0.43.0rc4}/x4d_devkit/inference/__init__.py +0 -0
- {x4d_devkit-0.43.0rc3 → x4d_devkit-0.43.0rc4}/x4d_devkit/inference/input.py +0 -0
- {x4d_devkit-0.43.0rc3 → x4d_devkit-0.43.0rc4}/x4d_devkit/inference/models.py +0 -0
- {x4d_devkit-0.43.0rc3 → x4d_devkit-0.43.0rc4}/x4d_devkit/inference/schemas.py +0 -0
- {x4d_devkit-0.43.0rc3 → x4d_devkit-0.43.0rc4}/x4d_devkit/inference/service.py +0 -0
- {x4d_devkit-0.43.0rc3 → x4d_devkit-0.43.0rc4}/x4d_devkit/inference/tasks.py +0 -0
- {x4d_devkit-0.43.0rc3 → x4d_devkit-0.43.0rc4}/x4d_devkit/json_contract.py +0 -0
- {x4d_devkit-0.43.0rc3 → x4d_devkit-0.43.0rc4}/x4d_devkit/label_schema.py +0 -0
- {x4d_devkit-0.43.0rc3 → x4d_devkit-0.43.0rc4}/x4d_devkit/lidar_materialization.py +0 -0
- {x4d_devkit-0.43.0rc3 → x4d_devkit-0.43.0rc4}/x4d_devkit/materialize.py +0 -0
- {x4d_devkit-0.43.0rc3 → x4d_devkit-0.43.0rc4}/x4d_devkit/roadmark_preview.py +0 -0
- {x4d_devkit-0.43.0rc3 → x4d_devkit-0.43.0rc4}/x4d_devkit/semantic_scene_authoring.py +0 -0
- {x4d_devkit-0.43.0rc3 → x4d_devkit-0.43.0rc4}/x4d_devkit/semantic_scene_contract.py +0 -0
- {x4d_devkit-0.43.0rc3 → x4d_devkit-0.43.0rc4}/x4d_devkit/time_contract.py +0 -0
- {x4d_devkit-0.43.0rc3 → x4d_devkit-0.43.0rc4}/x4d_devkit/training_identity.py +0 -0
- {x4d_devkit-0.43.0rc3 → x4d_devkit-0.43.0rc4}/x4d_devkit/validation/__init__.py +0 -0
- {x4d_devkit-0.43.0rc3 → x4d_devkit-0.43.0rc4}/x4d_devkit/validation/contract.py +0 -0
- {x4d_devkit-0.43.0rc3 → x4d_devkit-0.43.0rc4}/x4d_devkit/validation/platform_pose.py +0 -0
- {x4d_devkit-0.43.0rc3 → x4d_devkit-0.43.0rc4}/x4d_devkit/validation/report.py +0 -0
- {x4d_devkit-0.43.0rc3 → x4d_devkit-0.43.0rc4}/x4d_devkit/validation/validator.py +0 -0
- {x4d_devkit-0.43.0rc3 → x4d_devkit-0.43.0rc4}/x4d_devkit/work_session.py +0 -0
- {x4d_devkit-0.43.0rc3 → x4d_devkit-0.43.0rc4}/x4d_devkit.egg-info/dependency_links.txt +0 -0
- {x4d_devkit-0.43.0rc3 → x4d_devkit-0.43.0rc4}/x4d_devkit.egg-info/entry_points.txt +0 -0
- {x4d_devkit-0.43.0rc3 → x4d_devkit-0.43.0rc4}/x4d_devkit.egg-info/requires.txt +0 -0
- {x4d_devkit-0.43.0rc3 → x4d_devkit-0.43.0rc4}/x4d_devkit.egg-info/top_level.txt +0 -0
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "x4d-devkit"
|
|
7
|
-
version = "0.43.
|
|
7
|
+
version = "0.43.0rc4"
|
|
8
8
|
description = "Official X-4D external SDK and CLI for datasets, platform APIs, training bridges, and automation"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
license = "Apache-2.0"
|
|
@@ -25,6 +25,7 @@ from x4d_devkit.clean_basemap import (
|
|
|
25
25
|
validate_clean_basemap_annotation,
|
|
26
26
|
validate_clean_basemap_native_binding,
|
|
27
27
|
validate_clean_basemap_resource,
|
|
28
|
+
compute_clean_basemap_preannotation_revision,
|
|
28
29
|
)
|
|
29
30
|
from x4d_devkit.semantic_scene_contract import (
|
|
30
31
|
compute_annotation_dependency_revisions,
|
|
@@ -97,6 +98,9 @@ def fixture():
|
|
|
97
98
|
},
|
|
98
99
|
}
|
|
99
100
|
inputs = {key: "sha256:" + "b" * 64 for key in CLEAN_BASEMAP_INPUT_FIELDS}
|
|
101
|
+
inputs["preannotation_revision"] = compute_clean_basemap_preannotation_revision(
|
|
102
|
+
None
|
|
103
|
+
)
|
|
100
104
|
dependencies = compute_annotation_dependency_revisions(native["annotation"])
|
|
101
105
|
for key in inputs:
|
|
102
106
|
if key in dependencies:
|
|
@@ -110,6 +114,7 @@ def fixture():
|
|
|
110
114
|
inputs, profile
|
|
111
115
|
),
|
|
112
116
|
"input_identity": inputs,
|
|
117
|
+
"preannotation_evidence": None,
|
|
113
118
|
"profile": profile,
|
|
114
119
|
"point_count": 4,
|
|
115
120
|
"bounds": [xyz.min(0).tolist(), xyz.max(0).tolist()],
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import copy
|
|
2
|
+
|
|
3
|
+
import pytest
|
|
4
|
+
|
|
5
|
+
from tests.test_clean_basemap import fixture
|
|
6
|
+
from x4d_devkit.clean_basemap import (
|
|
7
|
+
CLEAN_BASEMAP_PREANNOTATION_CONTRACT_VERSION,
|
|
8
|
+
clean_basemap_preannotation_reference,
|
|
9
|
+
compute_clean_basemap_dependency_identity,
|
|
10
|
+
compute_clean_basemap_preannotation_revision,
|
|
11
|
+
compute_clean_basemap_revision,
|
|
12
|
+
parse_clean_basemap_manifest,
|
|
13
|
+
validate_clean_basemap_preannotation_evidence,
|
|
14
|
+
)
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def evidence_fixture():
|
|
18
|
+
manifest, _, native = fixture()
|
|
19
|
+
evidence = {
|
|
20
|
+
"contract_version": CLEAN_BASEMAP_PREANNOTATION_CONTRACT_VERSION,
|
|
21
|
+
"clip_id": manifest["clip_id"],
|
|
22
|
+
"candidate_id": "sha256:" + "c" * 64,
|
|
23
|
+
"profile_id": "detector-profile-1",
|
|
24
|
+
"pipeline_identity": "sha256:" + "d" * 64,
|
|
25
|
+
"checkpoint_identity": "sha256:" + "e" * 64,
|
|
26
|
+
"source_identity": {
|
|
27
|
+
key: manifest["input_identity"][key]
|
|
28
|
+
for key in (
|
|
29
|
+
"samples_revision",
|
|
30
|
+
"sweeps_revision",
|
|
31
|
+
"calibration_revision",
|
|
32
|
+
"pose_revision",
|
|
33
|
+
)
|
|
34
|
+
},
|
|
35
|
+
"annotation": native["annotation"],
|
|
36
|
+
}
|
|
37
|
+
manifest["preannotation_evidence"] = clean_basemap_preannotation_reference(evidence)
|
|
38
|
+
manifest["input_identity"]["preannotation_revision"] = (
|
|
39
|
+
compute_clean_basemap_preannotation_revision(evidence)
|
|
40
|
+
)
|
|
41
|
+
manifest["dependency_identity"] = compute_clean_basemap_dependency_identity(
|
|
42
|
+
manifest["input_identity"], manifest["profile"]
|
|
43
|
+
)
|
|
44
|
+
manifest["basemap_revision"] = compute_clean_basemap_revision(manifest)
|
|
45
|
+
return manifest, evidence
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
def test_evidence_is_bound_separately_and_does_not_add_native_instances():
|
|
49
|
+
manifest, evidence = evidence_fixture()
|
|
50
|
+
before = copy.deepcopy(manifest["instance_sources"])
|
|
51
|
+
parsed = parse_clean_basemap_manifest(manifest)
|
|
52
|
+
assert (
|
|
53
|
+
validate_clean_basemap_preannotation_evidence(
|
|
54
|
+
evidence, clip_id=parsed.clip_id, input_identity=manifest["input_identity"]
|
|
55
|
+
)
|
|
56
|
+
== evidence
|
|
57
|
+
)
|
|
58
|
+
assert parsed.to_dict()["instance_sources"] == before
|
|
59
|
+
assert "annotation" not in parsed.to_dict()["preannotation_evidence"]
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
@pytest.mark.parametrize(
|
|
63
|
+
"field",
|
|
64
|
+
["samples_revision", "sweeps_revision", "calibration_revision", "pose_revision"],
|
|
65
|
+
)
|
|
66
|
+
def test_evidence_from_different_geometry_cannot_bind(field):
|
|
67
|
+
manifest, evidence = evidence_fixture()
|
|
68
|
+
evidence["source_identity"][field] = "sha256:" + "f" * 64
|
|
69
|
+
with pytest.raises(ValueError, match="source differs"):
|
|
70
|
+
validate_clean_basemap_preannotation_evidence(
|
|
71
|
+
evidence,
|
|
72
|
+
clip_id=manifest["clip_id"],
|
|
73
|
+
input_identity=manifest["input_identity"],
|
|
74
|
+
)
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
def test_different_candidate_or_absent_evidence_requires_new_identity():
|
|
78
|
+
manifest, evidence = evidence_fixture()
|
|
79
|
+
evidence["candidate_id"] = "sha256:" + "f" * 64
|
|
80
|
+
with pytest.raises(ValueError, match="revision differs"):
|
|
81
|
+
validate_clean_basemap_preannotation_evidence(
|
|
82
|
+
evidence,
|
|
83
|
+
clip_id=manifest["clip_id"],
|
|
84
|
+
input_identity=manifest["input_identity"],
|
|
85
|
+
)
|
|
86
|
+
with pytest.raises(ValueError, match="revision differs"):
|
|
87
|
+
validate_clean_basemap_preannotation_evidence(
|
|
88
|
+
None, clip_id=manifest["clip_id"], input_identity=manifest["input_identity"]
|
|
89
|
+
)
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
def test_historical_v2_is_rejected_even_with_current_fields():
|
|
93
|
+
manifest, _ = evidence_fixture()
|
|
94
|
+
manifest["contract_version"] = "x4d-clean-static-basemap-v2"
|
|
95
|
+
with pytest.raises(ValueError, match="current contract"):
|
|
96
|
+
parse_clean_basemap_manifest(manifest)
|
|
@@ -11,7 +11,7 @@ from x4d_devkit.eval.matching import MetricData
|
|
|
11
11
|
|
|
12
12
|
|
|
13
13
|
def test_package_version_is_current_release():
|
|
14
|
-
assert x4d_devkit.__version__ == "0.43.
|
|
14
|
+
assert x4d_devkit.__version__ == "0.43.0rc4"
|
|
15
15
|
|
|
16
16
|
|
|
17
17
|
def test_loader_exposes_and_enforces_only_current_schema(tmp_path):
|
|
@@ -36,7 +36,11 @@ from x4d_devkit.semantic_scene_contract import (
|
|
|
36
36
|
)
|
|
37
37
|
from x4d_devkit.time_contract import parse_time_ns
|
|
38
38
|
|
|
39
|
-
CLEAN_BASEMAP_CONTRACT_VERSION = "x4d-clean-static-basemap-
|
|
39
|
+
CLEAN_BASEMAP_CONTRACT_VERSION = "x4d-clean-static-basemap-v3"
|
|
40
|
+
CLEAN_BASEMAP_PREANNOTATION_CONTRACT_VERSION = "x4d-clean-basemap-preannotation-v1"
|
|
41
|
+
_GEOMETRY_INPUT_FIELDS = frozenset(
|
|
42
|
+
{"samples_revision", "sweeps_revision", "calibration_revision", "pose_revision"}
|
|
43
|
+
)
|
|
40
44
|
CLEAN_BASEMAP_OPERATION = "reconstruction.prepare_clean_static_basemap"
|
|
41
45
|
CLEAN_BASEMAP_MAPPING_FORMAT = "x4d-clean-static-basemap-mapping-v1"
|
|
42
46
|
CLEAN_BASEMAP_DECISION_FORMAT = "x4d-clean-static-basemap-decisions-v2"
|
|
@@ -49,6 +53,7 @@ CLEAN_BASEMAP_INPUT_FIELDS = frozenset(
|
|
|
49
53
|
"scene_ownership_revision",
|
|
50
54
|
"instance_shape_input_revision",
|
|
51
55
|
"image_input_revision",
|
|
56
|
+
"preannotation_revision",
|
|
52
57
|
}
|
|
53
58
|
)
|
|
54
59
|
KEEP_STATIC = 0
|
|
@@ -183,6 +188,117 @@ def compute_clean_basemap_revision(value: Mapping[str, Any]) -> str:
|
|
|
183
188
|
return canonical_json_sha256(data)
|
|
184
189
|
|
|
185
190
|
|
|
191
|
+
def parse_clean_basemap_preannotation_evidence(value: Any) -> dict | None:
|
|
192
|
+
"""Validate supplemental hypotheses without granting native ownership."""
|
|
193
|
+
if value is None:
|
|
194
|
+
return None
|
|
195
|
+
data = _thaw(value)
|
|
196
|
+
_object(
|
|
197
|
+
data,
|
|
198
|
+
{
|
|
199
|
+
"contract_version",
|
|
200
|
+
"clip_id",
|
|
201
|
+
"candidate_id",
|
|
202
|
+
"profile_id",
|
|
203
|
+
"pipeline_identity",
|
|
204
|
+
"checkpoint_identity",
|
|
205
|
+
"source_identity",
|
|
206
|
+
"annotation",
|
|
207
|
+
},
|
|
208
|
+
"preannotation_evidence",
|
|
209
|
+
)
|
|
210
|
+
ensure_i_json(data, path="preannotation_evidence")
|
|
211
|
+
if data["contract_version"] != CLEAN_BASEMAP_PREANNOTATION_CONTRACT_VERSION:
|
|
212
|
+
raise ValueError("preannotation evidence requires the current contract")
|
|
213
|
+
parse_portable_token(data["clip_id"], path="preannotation_evidence.clip_id")
|
|
214
|
+
parse_portable_token(data["profile_id"], path="preannotation_evidence.profile_id")
|
|
215
|
+
for key in ("candidate_id", "pipeline_identity", "checkpoint_identity"):
|
|
216
|
+
_hash(data[key], f"preannotation_evidence.{key}")
|
|
217
|
+
_object(
|
|
218
|
+
data["source_identity"], _GEOMETRY_INPUT_FIELDS, "preannotation source_identity"
|
|
219
|
+
)
|
|
220
|
+
for key, identity in data["source_identity"].items():
|
|
221
|
+
_hash(identity, f"preannotation source_identity.{key}")
|
|
222
|
+
annotation = parse_clip_annotations(data["annotation"])
|
|
223
|
+
if annotation.clip_id != data["clip_id"]:
|
|
224
|
+
raise ValueError("preannotation evidence annotation belongs to another Clip")
|
|
225
|
+
data["annotation"] = annotation.to_dict()
|
|
226
|
+
return data
|
|
227
|
+
|
|
228
|
+
|
|
229
|
+
def clean_basemap_preannotation_reference(value: Any) -> dict | None:
|
|
230
|
+
data = parse_clean_basemap_preannotation_evidence(value)
|
|
231
|
+
if data is None:
|
|
232
|
+
return None
|
|
233
|
+
annotation = data.pop("annotation")
|
|
234
|
+
return {**data, "annotation_revision": annotation["annotation_revision"]}
|
|
235
|
+
|
|
236
|
+
|
|
237
|
+
def compute_clean_basemap_preannotation_revision(value: Any) -> str:
|
|
238
|
+
return canonical_json_sha256(
|
|
239
|
+
{"evidence": clean_basemap_preannotation_reference(value)}
|
|
240
|
+
)
|
|
241
|
+
|
|
242
|
+
|
|
243
|
+
def _validate_preannotation_reference(reference, *, clip_id, input_identity):
|
|
244
|
+
if reference is not None:
|
|
245
|
+
_object(
|
|
246
|
+
reference,
|
|
247
|
+
{
|
|
248
|
+
"contract_version",
|
|
249
|
+
"clip_id",
|
|
250
|
+
"candidate_id",
|
|
251
|
+
"profile_id",
|
|
252
|
+
"pipeline_identity",
|
|
253
|
+
"checkpoint_identity",
|
|
254
|
+
"source_identity",
|
|
255
|
+
"annotation_revision",
|
|
256
|
+
},
|
|
257
|
+
"preannotation_evidence",
|
|
258
|
+
)
|
|
259
|
+
if (
|
|
260
|
+
reference["contract_version"]
|
|
261
|
+
!= CLEAN_BASEMAP_PREANNOTATION_CONTRACT_VERSION
|
|
262
|
+
or reference["clip_id"] != clip_id
|
|
263
|
+
):
|
|
264
|
+
raise ValueError("preannotation evidence contract or Clip differs")
|
|
265
|
+
parse_portable_token(
|
|
266
|
+
reference["profile_id"], path="preannotation_evidence.profile_id"
|
|
267
|
+
)
|
|
268
|
+
for key in (
|
|
269
|
+
"candidate_id",
|
|
270
|
+
"pipeline_identity",
|
|
271
|
+
"checkpoint_identity",
|
|
272
|
+
"annotation_revision",
|
|
273
|
+
):
|
|
274
|
+
_hash(reference[key], f"preannotation_evidence.{key}")
|
|
275
|
+
_object(
|
|
276
|
+
reference["source_identity"],
|
|
277
|
+
_GEOMETRY_INPUT_FIELDS,
|
|
278
|
+
"preannotation source_identity",
|
|
279
|
+
)
|
|
280
|
+
if reference["source_identity"] != {
|
|
281
|
+
key: input_identity[key] for key in _GEOMETRY_INPUT_FIELDS
|
|
282
|
+
}:
|
|
283
|
+
raise ValueError("preannotation evidence source differs from clean basemap")
|
|
284
|
+
if (
|
|
285
|
+
canonical_json_sha256({"evidence": reference})
|
|
286
|
+
!= input_identity["preannotation_revision"]
|
|
287
|
+
):
|
|
288
|
+
raise ValueError("preannotation evidence revision differs from clean basemap")
|
|
289
|
+
|
|
290
|
+
|
|
291
|
+
def validate_clean_basemap_preannotation_evidence(value, *, clip_id, input_identity):
|
|
292
|
+
"""Validate the full frozen evidence against its manifest dependency."""
|
|
293
|
+
data = parse_clean_basemap_preannotation_evidence(value)
|
|
294
|
+
_validate_preannotation_reference(
|
|
295
|
+
clean_basemap_preannotation_reference(data),
|
|
296
|
+
clip_id=clip_id,
|
|
297
|
+
input_identity=input_identity,
|
|
298
|
+
)
|
|
299
|
+
return data
|
|
300
|
+
|
|
301
|
+
|
|
186
302
|
def compute_clean_basemap_dependency_identity(
|
|
187
303
|
input_identity: Mapping[str, str], profile: Mapping[str, Any]
|
|
188
304
|
) -> str:
|
|
@@ -285,6 +401,7 @@ def parse_clean_basemap_manifest(
|
|
|
285
401
|
"basemap_revision",
|
|
286
402
|
"dependency_identity",
|
|
287
403
|
"input_identity",
|
|
404
|
+
"preannotation_evidence",
|
|
288
405
|
"profile",
|
|
289
406
|
"point_count",
|
|
290
407
|
"bounds",
|
|
@@ -303,6 +420,11 @@ def parse_clean_basemap_manifest(
|
|
|
303
420
|
):
|
|
304
421
|
raise ValueError("clean basemap requires the current contract in clip_world")
|
|
305
422
|
parse_portable_token(data["clip_id"], path="clean_basemap.clip_id")
|
|
423
|
+
_validate_preannotation_reference(
|
|
424
|
+
data["preannotation_evidence"],
|
|
425
|
+
clip_id=data["clip_id"],
|
|
426
|
+
input_identity=data["input_identity"],
|
|
427
|
+
)
|
|
306
428
|
_hash(data["basemap_revision"], "basemap_revision")
|
|
307
429
|
if data["dependency_identity"] != compute_clean_basemap_dependency_identity(
|
|
308
430
|
data["input_identity"], data["profile"]
|
|
@@ -528,9 +650,8 @@ def encode_clean_basemap_mapping(
|
|
|
528
650
|
}
|
|
529
651
|
count = len(vectors["sweep_index"])
|
|
530
652
|
_integer(count, 1, SEMANTIC_SCENE_MAX_SCENE_POINTS_PER_CHUNK, "point_count")
|
|
531
|
-
if (
|
|
532
|
-
|
|
533
|
-
or np.any(~np.isin(vectors["decision"], tuple(KEEP_CODES)))
|
|
653
|
+
if any(len(vector) != count for vector in vectors.values()) or np.any(
|
|
654
|
+
~np.isin(vectors["decision"], tuple(KEEP_CODES))
|
|
534
655
|
):
|
|
535
656
|
raise ValueError(
|
|
536
657
|
"mapping must have one retained decision and address per geometry point"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{x4d_devkit-0.43.0rc3 → x4d_devkit-0.43.0rc4}/tests/test_current_state_identity_consumers_example.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|