x4d-devkit 0.44.0rc1__tar.gz → 0.45.0__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.44.0rc1/x4d_devkit.egg-info → x4d_devkit-0.45.0}/PKG-INFO +8 -8
- {x4d_devkit-0.44.0rc1 → x4d_devkit-0.45.0}/README.md +7 -7
- {x4d_devkit-0.44.0rc1 → x4d_devkit-0.45.0}/pyproject.toml +1 -1
- {x4d_devkit-0.44.0rc1 → x4d_devkit-0.45.0}/tests/test_contract_validation.py +3 -4
- {x4d_devkit-0.44.0rc1 → x4d_devkit-0.45.0}/tests/test_current_state.py +2 -2
- {x4d_devkit-0.44.0rc1 → x4d_devkit-0.45.0}/tests/test_dataset_identity.py +1 -1
- {x4d_devkit-0.44.0rc1 → x4d_devkit-0.45.0}/tests/test_export_bundle.py +2 -2
- {x4d_devkit-0.44.0rc1 → x4d_devkit-0.45.0}/tests/test_inference_input.py +2 -2
- {x4d_devkit-0.44.0rc1 → x4d_devkit-0.45.0}/tests/test_inference_schemas.py +3 -3
- {x4d_devkit-0.44.0rc1 → x4d_devkit-0.45.0}/tests/test_inference_service.py +1 -1
- {x4d_devkit-0.44.0rc1 → x4d_devkit-0.45.0}/tests/test_label_schemas.py +2 -2
- {x4d_devkit-0.44.0rc1 → x4d_devkit-0.45.0}/tests/test_loader.py +1 -1
- {x4d_devkit-0.44.0rc1 → x4d_devkit-0.45.0}/tests/test_models.py +2 -3
- {x4d_devkit-0.44.0rc1 → x4d_devkit-0.45.0}/tests/test_preannotation_client.py +1 -1
- {x4d_devkit-0.44.0rc1 → x4d_devkit-0.45.0}/tests/test_sdk_api.py +4 -4
- x4d_devkit-0.45.0/tests/test_source_attributes.py +54 -0
- {x4d_devkit-0.44.0rc1 → x4d_devkit-0.45.0}/tests/test_training_identity.py +3 -3
- {x4d_devkit-0.44.0rc1 → x4d_devkit-0.45.0}/tests/test_work_session.py +4 -5
- {x4d_devkit-0.44.0rc1 → x4d_devkit-0.45.0}/x4d_devkit/annotation_contract.py +2 -2
- {x4d_devkit-0.44.0rc1 → x4d_devkit-0.45.0}/x4d_devkit/cli.py +1 -1
- {x4d_devkit-0.44.0rc1 → x4d_devkit-0.45.0}/x4d_devkit/core/loader.py +5 -5
- {x4d_devkit-0.44.0rc1 → x4d_devkit-0.45.0}/x4d_devkit/core/models.py +6 -6
- {x4d_devkit-0.44.0rc1 → x4d_devkit-0.45.0}/x4d_devkit/dataset_contract.py +16 -8
- {x4d_devkit-0.44.0rc1 → x4d_devkit-0.45.0}/x4d_devkit/dataset_identity.py +1 -1
- {x4d_devkit-0.44.0rc1 → x4d_devkit-0.45.0}/x4d_devkit/eval/tracking.py +4 -4
- {x4d_devkit-0.44.0rc1 → x4d_devkit-0.45.0}/x4d_devkit/export_bundle.py +1 -1
- {x4d_devkit-0.44.0rc1 → x4d_devkit-0.45.0}/x4d_devkit/inference/input.py +1 -1
- {x4d_devkit-0.44.0rc1 → x4d_devkit-0.45.0}/x4d_devkit/inference/schemas.py +2 -2
- {x4d_devkit-0.44.0rc1 → x4d_devkit-0.45.0}/x4d_devkit/label_schema.py +1 -1
- {x4d_devkit-0.44.0rc1 → x4d_devkit-0.45.0}/x4d_devkit/lidar_materialization.py +1 -1
- {x4d_devkit-0.44.0rc1 → x4d_devkit-0.45.0}/x4d_devkit/materialize.py +5 -5
- {x4d_devkit-0.44.0rc1 → x4d_devkit-0.45.0}/x4d_devkit/semantic_scene_contract.py +3 -3
- {x4d_devkit-0.44.0rc1 → x4d_devkit-0.45.0}/x4d_devkit/time_contract.py +1 -1
- {x4d_devkit-0.44.0rc1 → x4d_devkit-0.45.0}/x4d_devkit/validation/platform_pose.py +1 -1
- {x4d_devkit-0.44.0rc1 → x4d_devkit-0.45.0}/x4d_devkit/validation/validator.py +6 -6
- {x4d_devkit-0.44.0rc1 → x4d_devkit-0.45.0/x4d_devkit.egg-info}/PKG-INFO +8 -8
- {x4d_devkit-0.44.0rc1 → x4d_devkit-0.45.0}/x4d_devkit.egg-info/SOURCES.txt +1 -0
- {x4d_devkit-0.44.0rc1 → x4d_devkit-0.45.0}/LICENSE +0 -0
- {x4d_devkit-0.44.0rc1 → x4d_devkit-0.45.0}/setup.cfg +0 -0
- {x4d_devkit-0.44.0rc1 → x4d_devkit-0.45.0}/tests/test_annotation_contract.py +0 -0
- {x4d_devkit-0.44.0rc1 → x4d_devkit-0.45.0}/tests/test_annotation_reference.py +0 -0
- {x4d_devkit-0.44.0rc1 → x4d_devkit-0.45.0}/tests/test_assets_client.py +0 -0
- {x4d_devkit-0.44.0rc1 → x4d_devkit-0.45.0}/tests/test_boundary.py +0 -0
- {x4d_devkit-0.44.0rc1 → x4d_devkit-0.45.0}/tests/test_box.py +0 -0
- {x4d_devkit-0.44.0rc1 → x4d_devkit-0.45.0}/tests/test_build_info.py +0 -0
- {x4d_devkit-0.44.0rc1 → x4d_devkit-0.45.0}/tests/test_clean_basemap.py +0 -0
- {x4d_devkit-0.44.0rc1 → x4d_devkit-0.45.0}/tests/test_clean_basemap_client.py +0 -0
- {x4d_devkit-0.44.0rc1 → x4d_devkit-0.45.0}/tests/test_clean_basemap_preannotation.py +0 -0
- {x4d_devkit-0.44.0rc1 → x4d_devkit-0.45.0}/tests/test_cli_auth.py +0 -0
- {x4d_devkit-0.44.0rc1 → x4d_devkit-0.45.0}/tests/test_client_json_contract.py +0 -0
- {x4d_devkit-0.44.0rc1 → x4d_devkit-0.45.0}/tests/test_client_projects.py +0 -0
- {x4d_devkit-0.44.0rc1 → x4d_devkit-0.45.0}/tests/test_clip_archives.py +0 -0
- {x4d_devkit-0.44.0rc1 → x4d_devkit-0.45.0}/tests/test_coordinate_frames.py +0 -0
- {x4d_devkit-0.44.0rc1 → x4d_devkit-0.45.0}/tests/test_current_state_identity_consumers_example.py +0 -0
- {x4d_devkit-0.44.0rc1 → x4d_devkit-0.45.0}/tests/test_dataset_contract.py +0 -0
- {x4d_devkit-0.44.0rc1 → x4d_devkit-0.45.0}/tests/test_detection_eval.py +0 -0
- {x4d_devkit-0.44.0rc1 → x4d_devkit-0.45.0}/tests/test_evaluate.py +0 -0
- {x4d_devkit-0.44.0rc1 → x4d_devkit-0.45.0}/tests/test_image_review.py +0 -0
- {x4d_devkit-0.44.0rc1 → x4d_devkit-0.45.0}/tests/test_lidar_materialization.py +0 -0
- {x4d_devkit-0.44.0rc1 → x4d_devkit-0.45.0}/tests/test_matching.py +0 -0
- {x4d_devkit-0.44.0rc1 → x4d_devkit-0.45.0}/tests/test_metrics.py +0 -0
- {x4d_devkit-0.44.0rc1 → x4d_devkit-0.45.0}/tests/test_platform_pose.py +0 -0
- {x4d_devkit-0.44.0rc1 → x4d_devkit-0.45.0}/tests/test_reconstruction_client.py +0 -0
- {x4d_devkit-0.44.0rc1 → x4d_devkit-0.45.0}/tests/test_release_gate.py +0 -0
- {x4d_devkit-0.44.0rc1 → x4d_devkit-0.45.0}/tests/test_roadmark_preview.py +0 -0
- {x4d_devkit-0.44.0rc1 → x4d_devkit-0.45.0}/tests/test_semantic_scene_authoring.py +0 -0
- {x4d_devkit-0.44.0rc1 → x4d_devkit-0.45.0}/tests/test_semantic_scene_client.py +0 -0
- {x4d_devkit-0.44.0rc1 → x4d_devkit-0.45.0}/tests/test_semantic_scene_contract.py +0 -0
- {x4d_devkit-0.44.0rc1 → x4d_devkit-0.45.0}/tests/test_semantic_scene_native_clip.py +0 -0
- {x4d_devkit-0.44.0rc1 → x4d_devkit-0.45.0}/tests/test_time_contract.py +0 -0
- {x4d_devkit-0.44.0rc1 → x4d_devkit-0.45.0}/tests/test_token.py +0 -0
- {x4d_devkit-0.44.0rc1 → x4d_devkit-0.45.0}/tests/test_tracking_eval.py +0 -0
- {x4d_devkit-0.44.0rc1 → x4d_devkit-0.45.0}/tests/test_transform.py +0 -0
- {x4d_devkit-0.44.0rc1 → x4d_devkit-0.45.0}/tests/test_transform_chain.py +0 -0
- {x4d_devkit-0.44.0rc1 → x4d_devkit-0.45.0}/tests/test_validation.py +0 -0
- {x4d_devkit-0.44.0rc1 → x4d_devkit-0.45.0}/tests/test_vector_map.py +0 -0
- {x4d_devkit-0.44.0rc1 → x4d_devkit-0.45.0}/tests/test_vector_map_geometry.py +0 -0
- {x4d_devkit-0.44.0rc1 → x4d_devkit-0.45.0}/tests/test_vector_map_session.py +0 -0
- {x4d_devkit-0.44.0rc1 → x4d_devkit-0.45.0}/x4d_devkit/__init__.py +0 -0
- {x4d_devkit-0.44.0rc1 → x4d_devkit-0.45.0}/x4d_devkit/annotation_reference.py +0 -0
- {x4d_devkit-0.44.0rc1 → x4d_devkit-0.45.0}/x4d_devkit/build_info.py +0 -0
- {x4d_devkit-0.44.0rc1 → x4d_devkit-0.45.0}/x4d_devkit/clean_basemap.py +0 -0
- {x4d_devkit-0.44.0rc1 → x4d_devkit-0.45.0}/x4d_devkit/client/__init__.py +0 -0
- {x4d_devkit-0.44.0rc1 → x4d_devkit-0.45.0}/x4d_devkit/client/_origin.py +0 -0
- {x4d_devkit-0.44.0rc1 → x4d_devkit-0.45.0}/x4d_devkit/client/annotation_reference.py +0 -0
- {x4d_devkit-0.44.0rc1 → x4d_devkit-0.45.0}/x4d_devkit/client/assets.py +0 -0
- {x4d_devkit-0.44.0rc1 → x4d_devkit-0.45.0}/x4d_devkit/client/bags.py +0 -0
- {x4d_devkit-0.44.0rc1 → x4d_devkit-0.45.0}/x4d_devkit/client/capabilities.py +0 -0
- {x4d_devkit-0.44.0rc1 → x4d_devkit-0.45.0}/x4d_devkit/client/checkpoints.py +0 -0
- {x4d_devkit-0.44.0rc1 → x4d_devkit-0.45.0}/x4d_devkit/client/clean_basemap.py +0 -0
- {x4d_devkit-0.44.0rc1 → x4d_devkit-0.45.0}/x4d_devkit/client/client.py +0 -0
- {x4d_devkit-0.44.0rc1 → x4d_devkit-0.45.0}/x4d_devkit/client/clip_work_sessions.py +0 -0
- {x4d_devkit-0.44.0rc1 → x4d_devkit-0.45.0}/x4d_devkit/client/clips.py +0 -0
- {x4d_devkit-0.44.0rc1 → x4d_devkit-0.45.0}/x4d_devkit/client/dataset_identity.py +0 -0
- {x4d_devkit-0.44.0rc1 → x4d_devkit-0.45.0}/x4d_devkit/client/image_review.py +0 -0
- {x4d_devkit-0.44.0rc1 → x4d_devkit-0.45.0}/x4d_devkit/client/label_schemas.py +0 -0
- {x4d_devkit-0.44.0rc1 → x4d_devkit-0.45.0}/x4d_devkit/client/preannotation.py +0 -0
- {x4d_devkit-0.44.0rc1 → x4d_devkit-0.45.0}/x4d_devkit/client/projects.py +0 -0
- {x4d_devkit-0.44.0rc1 → x4d_devkit-0.45.0}/x4d_devkit/client/reconstruction.py +0 -0
- {x4d_devkit-0.44.0rc1 → x4d_devkit-0.45.0}/x4d_devkit/client/semantic_scene.py +0 -0
- {x4d_devkit-0.44.0rc1 → x4d_devkit-0.45.0}/x4d_devkit/client/semantic_scene_authoring.py +0 -0
- {x4d_devkit-0.44.0rc1 → x4d_devkit-0.45.0}/x4d_devkit/client/services.py +0 -0
- {x4d_devkit-0.44.0rc1 → x4d_devkit-0.45.0}/x4d_devkit/client/test_sets.py +0 -0
- {x4d_devkit-0.44.0rc1 → x4d_devkit-0.45.0}/x4d_devkit/consumer_identity.py +0 -0
- {x4d_devkit-0.44.0rc1 → x4d_devkit-0.45.0}/x4d_devkit/coordinate_contract.py +0 -0
- {x4d_devkit-0.44.0rc1 → x4d_devkit-0.45.0}/x4d_devkit/core/__init__.py +0 -0
- {x4d_devkit-0.44.0rc1 → x4d_devkit-0.45.0}/x4d_devkit/core/token.py +0 -0
- {x4d_devkit-0.44.0rc1 → x4d_devkit-0.45.0}/x4d_devkit/core/transform.py +0 -0
- {x4d_devkit-0.44.0rc1 → x4d_devkit-0.45.0}/x4d_devkit/current_state.py +0 -0
- {x4d_devkit-0.44.0rc1 → x4d_devkit-0.45.0}/x4d_devkit/eval/__init__.py +0 -0
- {x4d_devkit-0.44.0rc1 → x4d_devkit-0.45.0}/x4d_devkit/eval/api.py +0 -0
- {x4d_devkit-0.44.0rc1 → x4d_devkit-0.45.0}/x4d_devkit/eval/box.py +0 -0
- {x4d_devkit-0.44.0rc1 → x4d_devkit-0.45.0}/x4d_devkit/eval/detection.py +0 -0
- {x4d_devkit-0.44.0rc1 → x4d_devkit-0.45.0}/x4d_devkit/eval/matching.py +0 -0
- {x4d_devkit-0.44.0rc1 → x4d_devkit-0.45.0}/x4d_devkit/eval/metrics.py +0 -0
- {x4d_devkit-0.44.0rc1 → x4d_devkit-0.45.0}/x4d_devkit/image_review.py +0 -0
- {x4d_devkit-0.44.0rc1 → x4d_devkit-0.45.0}/x4d_devkit/inference/__init__.py +0 -0
- {x4d_devkit-0.44.0rc1 → x4d_devkit-0.45.0}/x4d_devkit/inference/models.py +0 -0
- {x4d_devkit-0.44.0rc1 → x4d_devkit-0.45.0}/x4d_devkit/inference/service.py +0 -0
- {x4d_devkit-0.44.0rc1 → x4d_devkit-0.45.0}/x4d_devkit/inference/tasks.py +0 -0
- {x4d_devkit-0.44.0rc1 → x4d_devkit-0.45.0}/x4d_devkit/json_contract.py +0 -0
- {x4d_devkit-0.44.0rc1 → x4d_devkit-0.45.0}/x4d_devkit/roadmark_preview.py +0 -0
- {x4d_devkit-0.44.0rc1 → x4d_devkit-0.45.0}/x4d_devkit/semantic_scene_authoring.py +0 -0
- {x4d_devkit-0.44.0rc1 → x4d_devkit-0.45.0}/x4d_devkit/training_identity.py +0 -0
- {x4d_devkit-0.44.0rc1 → x4d_devkit-0.45.0}/x4d_devkit/validation/__init__.py +0 -0
- {x4d_devkit-0.44.0rc1 → x4d_devkit-0.45.0}/x4d_devkit/validation/contract.py +0 -0
- {x4d_devkit-0.44.0rc1 → x4d_devkit-0.45.0}/x4d_devkit/validation/report.py +0 -0
- {x4d_devkit-0.44.0rc1 → x4d_devkit-0.45.0}/x4d_devkit/vector_map.py +0 -0
- {x4d_devkit-0.44.0rc1 → x4d_devkit-0.45.0}/x4d_devkit/vector_map_geometry.py +0 -0
- {x4d_devkit-0.44.0rc1 → x4d_devkit-0.45.0}/x4d_devkit/work_session.py +0 -0
- {x4d_devkit-0.44.0rc1 → x4d_devkit-0.45.0}/x4d_devkit.egg-info/dependency_links.txt +0 -0
- {x4d_devkit-0.44.0rc1 → x4d_devkit-0.45.0}/x4d_devkit.egg-info/entry_points.txt +0 -0
- {x4d_devkit-0.44.0rc1 → x4d_devkit-0.45.0}/x4d_devkit.egg-info/requires.txt +0 -0
- {x4d_devkit-0.44.0rc1 → x4d_devkit-0.45.0}/x4d_devkit.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: x4d-devkit
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.45.0
|
|
4
4
|
Summary: Official X-4D external SDK and CLI for datasets, platform APIs, training bridges, and automation
|
|
5
5
|
Author: windzu
|
|
6
6
|
License-Expression: Apache-2.0
|
|
@@ -97,18 +97,18 @@ platform-to-platform data flow. See
|
|
|
97
97
|
generic identity model, and
|
|
98
98
|
[docs/training-current-state-data.md](docs/training-current-state-data.md) for
|
|
99
99
|
work-session materialization and conditional annotation writeback. Every
|
|
100
|
-
Dataset 0.
|
|
100
|
+
Dataset 0.18 Clip carries its authoritative Label Schema snapshot at root
|
|
101
101
|
`label_schema.json`.
|
|
102
102
|
Shared validation rules for platform submit, X-Points preflight, local clip
|
|
103
103
|
validation, and training consumers are documented in
|
|
104
104
|
[docs/shared-contract-validation.md](docs/shared-contract-validation.md).
|
|
105
|
-
The Dataset 0.
|
|
105
|
+
The Dataset 0.18 native contract, exact nanosecond time, Multi-LiDAR layout,
|
|
106
106
|
and model materialization are documented in
|
|
107
|
-
[docs/dataset-0.
|
|
107
|
+
[docs/dataset-0.18.md](docs/dataset-0.18.md). The single-file annotation
|
|
108
108
|
authority, semantic revision, and
|
|
109
109
|
derived track views are documented in
|
|
110
110
|
[docs/annotation-contract.md](docs/annotation-contract.md).
|
|
111
|
-
Portable export producers and consumers share the exact `0.
|
|
111
|
+
Portable export producers and consumers share the exact `0.18` manifest
|
|
112
112
|
parser documented in
|
|
113
113
|
[docs/export-bundle-contract.md](docs/export-bundle-contract.md).
|
|
114
114
|
`examples/current_state_identity_consumers.py` provides an offline downstream
|
|
@@ -133,7 +133,7 @@ Included:
|
|
|
133
133
|
- Typed point-level semantic-scene authoring sessions, dirty semantic-chunk upload, and
|
|
134
134
|
complete compare-and-set submit without a per-point mutation API.
|
|
135
135
|
- Strict validation of `x4d-training-identity-v5` manifests.
|
|
136
|
-
- Strict producer-option and manifest parsing for export bundle `0.
|
|
136
|
+
- Strict producer-option and manifest parsing for export bundle `0.18`.
|
|
137
137
|
- Clip preannotation protocol, source-only inference adapter, and service
|
|
138
138
|
wrapper for algorithm projects.
|
|
139
139
|
|
|
@@ -247,7 +247,7 @@ comparison = compare_project_label_schema_snapshots(project_schema, current)
|
|
|
247
247
|
assert comparison.status == "same"
|
|
248
248
|
```
|
|
249
249
|
|
|
250
|
-
The native Dataset 0.
|
|
250
|
+
The native Dataset 0.18 Clip stores the immutable identity in
|
|
251
251
|
`meta.label_schema` and the complete authoritative snapshot in root
|
|
252
252
|
`label_schema.json`. Registry records are used when creating/binding Clips, not
|
|
253
253
|
when loading or validating their current contents.
|
|
@@ -402,7 +402,7 @@ asset existence and point-cloud layout checks without downloading the assets.
|
|
|
402
402
|
|
|
403
403
|
Third-party model projects should use `x4d-devkit[inference]` instead of
|
|
404
404
|
hand-writing the X-4D preannotation protocol. The pipeline receives an
|
|
405
|
-
annotation-isolated `InferenceClip` and returns one complete Dataset 0.
|
|
405
|
+
annotation-isolated `InferenceClip` and returns one complete Dataset 0.18
|
|
406
406
|
annotation document.
|
|
407
407
|
|
|
408
408
|
```python
|
|
@@ -54,18 +54,18 @@ platform-to-platform data flow. See
|
|
|
54
54
|
generic identity model, and
|
|
55
55
|
[docs/training-current-state-data.md](docs/training-current-state-data.md) for
|
|
56
56
|
work-session materialization and conditional annotation writeback. Every
|
|
57
|
-
Dataset 0.
|
|
57
|
+
Dataset 0.18 Clip carries its authoritative Label Schema snapshot at root
|
|
58
58
|
`label_schema.json`.
|
|
59
59
|
Shared validation rules for platform submit, X-Points preflight, local clip
|
|
60
60
|
validation, and training consumers are documented in
|
|
61
61
|
[docs/shared-contract-validation.md](docs/shared-contract-validation.md).
|
|
62
|
-
The Dataset 0.
|
|
62
|
+
The Dataset 0.18 native contract, exact nanosecond time, Multi-LiDAR layout,
|
|
63
63
|
and model materialization are documented in
|
|
64
|
-
[docs/dataset-0.
|
|
64
|
+
[docs/dataset-0.18.md](docs/dataset-0.18.md). The single-file annotation
|
|
65
65
|
authority, semantic revision, and
|
|
66
66
|
derived track views are documented in
|
|
67
67
|
[docs/annotation-contract.md](docs/annotation-contract.md).
|
|
68
|
-
Portable export producers and consumers share the exact `0.
|
|
68
|
+
Portable export producers and consumers share the exact `0.18` manifest
|
|
69
69
|
parser documented in
|
|
70
70
|
[docs/export-bundle-contract.md](docs/export-bundle-contract.md).
|
|
71
71
|
`examples/current_state_identity_consumers.py` provides an offline downstream
|
|
@@ -90,7 +90,7 @@ Included:
|
|
|
90
90
|
- Typed point-level semantic-scene authoring sessions, dirty semantic-chunk upload, and
|
|
91
91
|
complete compare-and-set submit without a per-point mutation API.
|
|
92
92
|
- Strict validation of `x4d-training-identity-v5` manifests.
|
|
93
|
-
- Strict producer-option and manifest parsing for export bundle `0.
|
|
93
|
+
- Strict producer-option and manifest parsing for export bundle `0.18`.
|
|
94
94
|
- Clip preannotation protocol, source-only inference adapter, and service
|
|
95
95
|
wrapper for algorithm projects.
|
|
96
96
|
|
|
@@ -204,7 +204,7 @@ comparison = compare_project_label_schema_snapshots(project_schema, current)
|
|
|
204
204
|
assert comparison.status == "same"
|
|
205
205
|
```
|
|
206
206
|
|
|
207
|
-
The native Dataset 0.
|
|
207
|
+
The native Dataset 0.18 Clip stores the immutable identity in
|
|
208
208
|
`meta.label_schema` and the complete authoritative snapshot in root
|
|
209
209
|
`label_schema.json`. Registry records are used when creating/binding Clips, not
|
|
210
210
|
when loading or validating their current contents.
|
|
@@ -359,7 +359,7 @@ asset existence and point-cloud layout checks without downloading the assets.
|
|
|
359
359
|
|
|
360
360
|
Third-party model projects should use `x4d-devkit[inference]` instead of
|
|
361
361
|
hand-writing the X-4D preannotation protocol. The pipeline receives an
|
|
362
|
-
annotation-isolated `InferenceClip` and returns one complete Dataset 0.
|
|
362
|
+
annotation-isolated `InferenceClip` and returns one complete Dataset 0.18
|
|
363
363
|
annotation document.
|
|
364
364
|
|
|
365
365
|
```python
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "x4d-devkit"
|
|
7
|
-
version = "0.
|
|
7
|
+
version = "0.45.0"
|
|
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"
|
|
@@ -24,9 +24,8 @@ def _time(value: int) -> dict[str, int]:
|
|
|
24
24
|
def _meta(*, keyframe_count: int = 1) -> dict:
|
|
25
25
|
return {
|
|
26
26
|
"clip_id": "clip-a",
|
|
27
|
-
"schema_version": "0.
|
|
27
|
+
"schema_version": "0.18",
|
|
28
28
|
"session_id": "session-a",
|
|
29
|
-
"vehicle_id": "vehicle-a",
|
|
30
29
|
"capture_time": _time(1),
|
|
31
30
|
"duration_s": float(max(0, keyframe_count - 1)),
|
|
32
31
|
"keyframe_count": keyframe_count,
|
|
@@ -152,7 +151,7 @@ def _context(
|
|
|
152
151
|
) -> ClipValidationContext:
|
|
153
152
|
return ClipValidationContext(
|
|
154
153
|
clip_id="clip-a",
|
|
155
|
-
clip_schema_version="0.
|
|
154
|
+
clip_schema_version="0.18",
|
|
156
155
|
label_schema=_schema(),
|
|
157
156
|
samples=[_sample()] if samples is None else samples,
|
|
158
157
|
sample_data=[_sample_data()] if sample_data is None else sample_data,
|
|
@@ -423,7 +422,7 @@ def test_context_rejects_non_list_payloads_and_invalid_meta():
|
|
|
423
422
|
with pytest.raises(TypeError):
|
|
424
423
|
ClipValidationContext(
|
|
425
424
|
clip_id="clip-a",
|
|
426
|
-
clip_schema_version="0.
|
|
425
|
+
clip_schema_version="0.18",
|
|
427
426
|
label_schema=_schema(),
|
|
428
427
|
samples=(),
|
|
429
428
|
sample_data=[],
|
|
@@ -34,7 +34,7 @@ def _identity(**overrides):
|
|
|
34
34
|
"vector_map_revision": None,
|
|
35
35
|
"label_schema": schema_identity(),
|
|
36
36
|
"business_metadata_revision": "business-metadata",
|
|
37
|
-
"clip_schema_version": "0.
|
|
37
|
+
"clip_schema_version": "0.18",
|
|
38
38
|
"ready": True,
|
|
39
39
|
"blockers": [],
|
|
40
40
|
}
|
|
@@ -233,5 +233,5 @@ def test_normalize_clip_identity_rejects_removed_source_granularity(field):
|
|
|
233
233
|
|
|
234
234
|
|
|
235
235
|
def test_normalize_clip_identity_rejects_non_current_clip_schema_version():
|
|
236
|
-
with pytest.raises(ValueError, match="clip_schema_version must be '0.
|
|
236
|
+
with pytest.raises(ValueError, match="clip_schema_version must be '0.18'"):
|
|
237
237
|
normalize_clip_identity(_identity(clip_schema_version="0.10"))
|
|
@@ -49,7 +49,7 @@ def _identity(clip_id: str = "clip-a", **overrides):
|
|
|
49
49
|
"vector_map_revision": None,
|
|
50
50
|
"label_schema": schema_identity(),
|
|
51
51
|
"business_metadata_revision": "sha256:business-metadata",
|
|
52
|
-
"clip_schema_version": "0.
|
|
52
|
+
"clip_schema_version": "0.18",
|
|
53
53
|
"ready": True,
|
|
54
54
|
"blockers": [],
|
|
55
55
|
}
|
|
@@ -20,7 +20,7 @@ def _manifest(*, include_sweeps: bool = True) -> dict:
|
|
|
20
20
|
return {
|
|
21
21
|
"export_id": "exp_20260711_a3f8c1d2",
|
|
22
22
|
"exported_at": {"sec": 1_783_735_200, "nanosec": 123_456_000},
|
|
23
|
-
"schema_version": "0.
|
|
23
|
+
"schema_version": "0.18",
|
|
24
24
|
"options": {
|
|
25
25
|
"include_sweeps": include_sweeps,
|
|
26
26
|
"pointcloud_format": "pcd_binary",
|
|
@@ -31,7 +31,7 @@ def _manifest(*, include_sweeps: bool = True) -> dict:
|
|
|
31
31
|
"clips": [
|
|
32
32
|
{
|
|
33
33
|
"clip_id": "20260711_G150-002_003",
|
|
34
|
-
"schema_version": "0.
|
|
34
|
+
"schema_version": "0.18",
|
|
35
35
|
"label_schema": schema_identity(),
|
|
36
36
|
"annotation_frame_id": "base_link",
|
|
37
37
|
"channels": ["cam_front", "lidar"],
|
|
@@ -30,7 +30,7 @@ def _inference_clip(tmp_path) -> tuple[ClipLoader, InferenceClip]:
|
|
|
30
30
|
sweeps_revision=_digest("b"),
|
|
31
31
|
calibration_revision="calibration-1",
|
|
32
32
|
pose_revision="pose-1",
|
|
33
|
-
clip_schema_version="0.
|
|
33
|
+
clip_schema_version="0.18",
|
|
34
34
|
)
|
|
35
35
|
access = PreannotationClipAccess(
|
|
36
36
|
project_id=7,
|
|
@@ -174,7 +174,7 @@ def test_inference_clip_rejects_a_mismatched_source_identity(tmp_path):
|
|
|
174
174
|
sweeps_revision=clip.source_identity.sweeps_revision,
|
|
175
175
|
calibration_revision=clip.source_identity.calibration_revision,
|
|
176
176
|
pose_revision=clip.source_identity.pose_revision,
|
|
177
|
-
clip_schema_version="0.
|
|
177
|
+
clip_schema_version="0.18",
|
|
178
178
|
)
|
|
179
179
|
|
|
180
180
|
with pytest.raises(ValueError, match="source identity"):
|
|
@@ -37,7 +37,7 @@ def _request_payload() -> dict:
|
|
|
37
37
|
"sweeps_revision": _digest("f"),
|
|
38
38
|
"calibration_revision": "calibration-1",
|
|
39
39
|
"pose_revision": "pose-1",
|
|
40
|
-
"clip_schema_version": "0.
|
|
40
|
+
"clip_schema_version": "0.18",
|
|
41
41
|
},
|
|
42
42
|
"label_schema": schema_identity(),
|
|
43
43
|
"base_annotation_revision": _digest("a"),
|
|
@@ -108,7 +108,7 @@ def test_source_identity_projects_only_pure_inference_dependencies():
|
|
|
108
108
|
"semantic_scene_revision": _digest("d"),
|
|
109
109
|
"vector_map_revision": None,
|
|
110
110
|
"label_schema": schema_identity(),
|
|
111
|
-
"clip_schema_version": "0.
|
|
111
|
+
"clip_schema_version": "0.18",
|
|
112
112
|
"ready": True,
|
|
113
113
|
"blockers": [],
|
|
114
114
|
}
|
|
@@ -120,7 +120,7 @@ def test_source_identity_projects_only_pure_inference_dependencies():
|
|
|
120
120
|
"sweeps_revision": _digest("f"),
|
|
121
121
|
"calibration_revision": "calibration-1",
|
|
122
122
|
"pose_revision": "pose-1",
|
|
123
|
-
"clip_schema_version": "0.
|
|
123
|
+
"clip_schema_version": "0.18",
|
|
124
124
|
}
|
|
125
125
|
|
|
126
126
|
|
|
@@ -83,7 +83,7 @@ def _fixture(tmp_path, pipeline=None, *, run_inline=True):
|
|
|
83
83
|
sweeps_revision=_digest("e"),
|
|
84
84
|
calibration_revision="calibration-1",
|
|
85
85
|
pose_revision="pose-1",
|
|
86
|
-
clip_schema_version="0.
|
|
86
|
+
clip_schema_version="0.18",
|
|
87
87
|
)
|
|
88
88
|
selected = pipeline or FakePipeline()
|
|
89
89
|
|
|
@@ -285,7 +285,7 @@ def test_batch_resolution_deduplicates_by_task_free_binding():
|
|
|
285
285
|
"vector_map_revision": None,
|
|
286
286
|
"business_metadata_revision": "business-a",
|
|
287
287
|
"label_schema": identity,
|
|
288
|
-
"clip_schema_version": "0.
|
|
288
|
+
"clip_schema_version": "0.18",
|
|
289
289
|
"ready": True,
|
|
290
290
|
"blockers": [],
|
|
291
291
|
},
|
|
@@ -302,7 +302,7 @@ def test_batch_resolution_deduplicates_by_task_free_binding():
|
|
|
302
302
|
"vector_map_revision": None,
|
|
303
303
|
"business_metadata_revision": "business-b",
|
|
304
304
|
"label_schema": identity,
|
|
305
|
-
"clip_schema_version": "0.
|
|
305
|
+
"clip_schema_version": "0.18",
|
|
306
306
|
"ready": True,
|
|
307
307
|
"blockers": [],
|
|
308
308
|
},
|
|
@@ -28,7 +28,7 @@ def loader(tmp_path):
|
|
|
28
28
|
|
|
29
29
|
def test_loader_builds_current_typed_models_and_indexes(loader):
|
|
30
30
|
assert isinstance(loader.meta, ClipMeta)
|
|
31
|
-
assert loader.schema_version == "0.
|
|
31
|
+
assert loader.schema_version == "0.18"
|
|
32
32
|
assert loader.annotation_revision.startswith("sha256:")
|
|
33
33
|
assert all(isinstance(item, Sample) for item in loader.samples)
|
|
34
34
|
assert all(isinstance(item, Annotation) for item in loader.annotations)
|
|
@@ -82,9 +82,8 @@ def test_clip_meta_serializes_exact_current_metadata():
|
|
|
82
82
|
sensors = {"cam_front": SensorInfo("camera", "cam_front")}
|
|
83
83
|
meta = ClipMeta(
|
|
84
84
|
clip_id="clip-a",
|
|
85
|
-
schema_version="0.
|
|
85
|
+
schema_version="0.18",
|
|
86
86
|
session_id="session-a",
|
|
87
|
-
vehicle_id="vehicle-a",
|
|
88
87
|
capture_time=TimeNs(1, 2),
|
|
89
88
|
duration_s=1.0,
|
|
90
89
|
num_keyframes=1,
|
|
@@ -96,7 +95,7 @@ def test_clip_meta_serializes_exact_current_metadata():
|
|
|
96
95
|
scene_tags=["urban"],
|
|
97
96
|
)
|
|
98
97
|
wire = meta.to_dict()
|
|
99
|
-
assert wire["schema_version"] == "0.
|
|
98
|
+
assert wire["schema_version"] == "0.18"
|
|
100
99
|
assert wire["capture_time"] == {"sec": 1, "nanosec": 2}
|
|
101
100
|
assert wire["scene_tags"] == ["urban"]
|
|
102
101
|
assert "route_tag" not in wire
|
|
@@ -117,7 +117,7 @@ def _portable_candidate() -> dict:
|
|
|
117
117
|
"sweeps_revision": _digest("f"),
|
|
118
118
|
"calibration_revision": "calibration-1",
|
|
119
119
|
"pose_revision": "pose-1",
|
|
120
|
-
"clip_schema_version": "0.
|
|
120
|
+
"clip_schema_version": "0.18",
|
|
121
121
|
},
|
|
122
122
|
"label_schema": schema_identity(),
|
|
123
123
|
"base_annotation_revision": _digest("0"),
|
|
@@ -11,14 +11,14 @@ 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.
|
|
14
|
+
assert x4d_devkit.__version__ == "0.45.0"
|
|
15
15
|
|
|
16
16
|
|
|
17
17
|
def test_loader_exposes_and_enforces_only_current_schema(tmp_path):
|
|
18
18
|
loader = ClipLoader(write_current_clip(tmp_path / "current"))
|
|
19
|
-
assert loader.schema_version == "0.
|
|
20
|
-
loader.require_schema_version("0.
|
|
21
|
-
loader.require_schema_version({"0.
|
|
19
|
+
assert loader.schema_version == "0.18"
|
|
20
|
+
loader.require_schema_version("0.18")
|
|
21
|
+
loader.require_schema_version({"0.18"})
|
|
22
22
|
with pytest.raises(SchemaVersionMismatch):
|
|
23
23
|
loader.require_schema_version("0.10")
|
|
24
24
|
with pytest.raises(SchemaVersionMismatch):
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
"""Vehicle-free metadata and the independent business-metadata boundary."""
|
|
2
|
+
|
|
3
|
+
import copy
|
|
4
|
+
|
|
5
|
+
import pytest
|
|
6
|
+
|
|
7
|
+
from tests.current_clip_fixtures import current_clip_tables, write_current_clip
|
|
8
|
+
from x4d_devkit.core.loader import ClipLoader
|
|
9
|
+
from x4d_devkit.dataset_contract import (
|
|
10
|
+
DatasetContractError,
|
|
11
|
+
parse_clip_meta,
|
|
12
|
+
project_business_metadata,
|
|
13
|
+
project_source_metadata,
|
|
14
|
+
)
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def test_vehicle_free_clip_loads_and_roundtrips(tmp_path):
|
|
18
|
+
tables = current_clip_tables()
|
|
19
|
+
clip_dir = write_current_clip(tmp_path / "test-clip")
|
|
20
|
+
clip = ClipLoader(clip_dir)
|
|
21
|
+
assert clip.meta.source_attributes is None
|
|
22
|
+
assert clip.meta.to_dict() == tables["meta.json"]
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def test_source_attributes_change_only_business_metadata():
|
|
26
|
+
meta = current_clip_tables()["meta.json"]
|
|
27
|
+
candidate = copy.deepcopy(meta)
|
|
28
|
+
candidate["source_attributes"] = {"vehicle_id": "V01", "vehicle_model": "车型 A"}
|
|
29
|
+
parsed = parse_clip_meta(candidate, include_label_schema=True)
|
|
30
|
+
assert parsed == candidate
|
|
31
|
+
assert project_source_metadata(meta) == project_source_metadata(candidate)
|
|
32
|
+
assert project_business_metadata(meta) == {}
|
|
33
|
+
assert project_business_metadata(candidate) == {
|
|
34
|
+
"source_attributes": candidate["source_attributes"]
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
@pytest.mark.parametrize("attributes", [{}, [], {"a": None}, {"a": 1}, {"a": " x"}, {"a": ""}, {"Bad key": "x"}])
|
|
39
|
+
def test_source_attributes_reject_inexact_values(attributes):
|
|
40
|
+
meta = current_clip_tables()["meta.json"]
|
|
41
|
+
meta["source_attributes"] = attributes
|
|
42
|
+
with pytest.raises(DatasetContractError):
|
|
43
|
+
parse_clip_meta(meta, include_label_schema=True)
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
def test_previous_vehicle_field_and_dataset_version_are_rejected():
|
|
47
|
+
meta = current_clip_tables()["meta.json"]
|
|
48
|
+
meta["vehicle_id"] = "V01"
|
|
49
|
+
with pytest.raises(DatasetContractError):
|
|
50
|
+
parse_clip_meta(meta, include_label_schema=True)
|
|
51
|
+
del meta["vehicle_id"]
|
|
52
|
+
meta["schema_version"] = "0.17"
|
|
53
|
+
with pytest.raises(DatasetContractError):
|
|
54
|
+
parse_clip_meta(meta, include_label_schema=True)
|
|
@@ -38,7 +38,7 @@ def _clip(**overrides):
|
|
|
38
38
|
"annotation_revision": "ann",
|
|
39
39
|
"semantic_scene_revision": None,
|
|
40
40
|
"label_schema": schema_identity(),
|
|
41
|
-
"clip_schema_version": "0.
|
|
41
|
+
"clip_schema_version": "0.18",
|
|
42
42
|
"materialization_policy": "keyframes_only",
|
|
43
43
|
}
|
|
44
44
|
data.update(overrides)
|
|
@@ -133,7 +133,7 @@ def test_training_identity_file_rejects_duplicate_json_fields(tmp_path):
|
|
|
133
133
|
|
|
134
134
|
|
|
135
135
|
def test_training_identity_rejects_non_current_clip_schema_version():
|
|
136
|
-
with pytest.raises(ValueError, match="clip_schema_version must be '0.
|
|
136
|
+
with pytest.raises(ValueError, match="clip_schema_version must be '0.18'"):
|
|
137
137
|
build_training_identity_manifest(
|
|
138
138
|
projects=_projects(),
|
|
139
139
|
clips=[_clip(clip_schema_version="0.10")]
|
|
@@ -251,7 +251,7 @@ def test_project_training_identities_are_dataset_diff_ready(tmp_path):
|
|
|
251
251
|
"annotation_revision": "ann",
|
|
252
252
|
"semantic_scene_revision": None,
|
|
253
253
|
"label_schema": schema_identity(),
|
|
254
|
-
"clip_schema_version": "0.
|
|
254
|
+
"clip_schema_version": "0.18",
|
|
255
255
|
}]
|
|
256
256
|
|
|
257
257
|
|
|
@@ -51,9 +51,8 @@ def _manifest() -> dict:
|
|
|
51
51
|
"label_schema": clip_schema_snapshot(),
|
|
52
52
|
"meta": {
|
|
53
53
|
"clip_id": "clip-a",
|
|
54
|
-
"schema_version": "0.
|
|
54
|
+
"schema_version": "0.18",
|
|
55
55
|
"session_id": "session-a",
|
|
56
|
-
"vehicle_id": "vehicle-a",
|
|
57
56
|
"capture_time": {"sec": 0, "nanosec": 1000},
|
|
58
57
|
"duration_s": 0.0,
|
|
59
58
|
"keyframe_count": 1,
|
|
@@ -327,7 +326,7 @@ class _FakeX4DClient:
|
|
|
327
326
|
|
|
328
327
|
def test_work_session_wire_has_one_meta_source_for_version_and_frames():
|
|
329
328
|
manifest = parse_clip_work_session(_manifest())
|
|
330
|
-
assert manifest.clip_schema_version == "0.
|
|
329
|
+
assert manifest.clip_schema_version == "0.18"
|
|
331
330
|
assert manifest.annotation_frame_id == "base_link"
|
|
332
331
|
assert manifest.ego_pose_frame_id == "base_link"
|
|
333
332
|
assert manifest.instances == [
|
|
@@ -372,7 +371,7 @@ def test_loader_from_work_session_supports_current_transforms_and_assets():
|
|
|
372
371
|
parse_clip_work_session(_manifest()),
|
|
373
372
|
api_url="http://x4d.local",
|
|
374
373
|
)
|
|
375
|
-
assert loader.schema_version == "0.
|
|
374
|
+
assert loader.schema_version == "0.18"
|
|
376
375
|
assert loader.annotation_frame_id == "base_link"
|
|
377
376
|
assert loader.frame_id_for_channel("lidar") == "base_link"
|
|
378
377
|
assert loader.point_format("lidar").bytes_per_point == 24
|
|
@@ -634,7 +633,7 @@ def test_adopt_work_session_cache_fails_closed_without_changing_markers(
|
|
|
634
633
|
else:
|
|
635
634
|
meta_path = tmp_path / "meta.json"
|
|
636
635
|
meta = json.loads(meta_path.read_text())
|
|
637
|
-
meta["
|
|
636
|
+
meta["source_attributes"] = {"vehicle_id": "different"}
|
|
638
637
|
meta_path.write_text(json.dumps(meta))
|
|
639
638
|
|
|
640
639
|
with pytest.raises(ValueError, match="cache adoption"):
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
"""Strict Dataset 0.
|
|
1
|
+
"""Strict Dataset 0.18 annotation document and derived track views."""
|
|
2
2
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
@@ -115,7 +115,7 @@ def build_clip_annotations(
|
|
|
115
115
|
annotation_frame_id: str,
|
|
116
116
|
annotations: list[Mapping[str, Any]],
|
|
117
117
|
) -> ClipAnnotationDocument:
|
|
118
|
-
"""Build the only canonical Dataset 0.
|
|
118
|
+
"""Build the only canonical Dataset 0.18 annotation document."""
|
|
119
119
|
|
|
120
120
|
canonical = _canonical_annotation_rows(annotations)
|
|
121
121
|
parsed_clip_id = _portable_token(clip_id, path="annotation.clip_id")
|
|
@@ -242,7 +242,7 @@ def cmd_screening_plan(args):
|
|
|
242
242
|
for clip in result["valid_clips"]:
|
|
243
243
|
print(
|
|
244
244
|
f" bags={clip['bag_ids']} duration={clip['duration_s']:.1f}s "
|
|
245
|
-
f"
|
|
245
|
+
f"session={clip['session_id']}"
|
|
246
246
|
)
|
|
247
247
|
for flagged in result["flagged"]:
|
|
248
248
|
print(f" flagged bag={flagged['bag_id']} reason={flagged['reason']}")
|
|
@@ -342,7 +342,6 @@ class ClipLoader:
|
|
|
342
342
|
clip_id=d["clip_id"],
|
|
343
343
|
schema_version=d["schema_version"],
|
|
344
344
|
session_id=d["session_id"],
|
|
345
|
-
vehicle_id=d["vehicle_id"],
|
|
346
345
|
capture_time=TimeNs.from_dict(d["capture_time"]),
|
|
347
346
|
duration_s=d["duration_s"],
|
|
348
347
|
num_keyframes=d["keyframe_count"],
|
|
@@ -351,6 +350,7 @@ class ClipLoader:
|
|
|
351
350
|
annotation_frame_id=d["annotation_frame_id"],
|
|
352
351
|
ego_pose_frame_id=d["ego_pose_frame_id"],
|
|
353
352
|
label_schema=dict(d["label_schema"]),
|
|
353
|
+
source_attributes=d.get("source_attributes"),
|
|
354
354
|
route_tag=d.get("route_tag"),
|
|
355
355
|
weather=d.get("weather"),
|
|
356
356
|
time_of_day=d.get("time_of_day"),
|
|
@@ -493,7 +493,7 @@ class ClipLoader:
|
|
|
493
493
|
|
|
494
494
|
@property
|
|
495
495
|
def has_semantic_scene(self) -> bool:
|
|
496
|
-
"""Whether this local Dataset 0.
|
|
496
|
+
"""Whether this local Dataset 0.18 Clip contains a semantic scene."""
|
|
497
497
|
|
|
498
498
|
return (self._clip_dir / "semantic_scene" / "manifest.json").is_file()
|
|
499
499
|
|
|
@@ -550,7 +550,7 @@ class ClipLoader:
|
|
|
550
550
|
Example::
|
|
551
551
|
|
|
552
552
|
loader = ClipLoader(path)
|
|
553
|
-
loader.require_schema_version("0.
|
|
553
|
+
loader.require_schema_version("0.18") # raises if not 0.18
|
|
554
554
|
"""
|
|
555
555
|
actual = self._meta.schema_version
|
|
556
556
|
if isinstance(expected, str):
|
|
@@ -798,14 +798,14 @@ class ClipLoader:
|
|
|
798
798
|
) -> np.ndarray:
|
|
799
799
|
"""Reject the removed homogeneous point-cloud representation.
|
|
800
800
|
|
|
801
|
-
Dataset 0.
|
|
801
|
+
Dataset 0.18 mixes ``float32`` spatial fields with an absolute
|
|
802
802
|
``uint64 timestamp_ns``. A homogeneous NumPy matrix cannot preserve
|
|
803
803
|
both contracts. Use :meth:`load_point_records` for native data or the
|
|
804
804
|
explicit model materialization API for derived ``float32 xyzit``.
|
|
805
805
|
"""
|
|
806
806
|
|
|
807
807
|
raise ValueError(
|
|
808
|
-
"load_point_cloud() is unavailable for Dataset 0.
|
|
808
|
+
"load_point_cloud() is unavailable for Dataset 0.18 because a "
|
|
809
809
|
"homogeneous array loses uint64 timestamp_ns precision; use "
|
|
810
810
|
"load_point_records() or transform_concat_v1()"
|
|
811
811
|
)
|
|
@@ -120,7 +120,7 @@ class PointFormat:
|
|
|
120
120
|
|
|
121
121
|
@dataclass(frozen=True)
|
|
122
122
|
class PointTime:
|
|
123
|
-
"""Exact Dataset 0.
|
|
123
|
+
"""Exact Dataset 0.18 per-point time semantics."""
|
|
124
124
|
|
|
125
125
|
field: str
|
|
126
126
|
representation: str
|
|
@@ -136,7 +136,7 @@ class PointTime:
|
|
|
136
136
|
"epoch": "unix",
|
|
137
137
|
"timescale": "posix",
|
|
138
138
|
}:
|
|
139
|
-
raise ValueError("PointTime must match the Dataset 0.
|
|
139
|
+
raise ValueError("PointTime must match the Dataset 0.18 contract")
|
|
140
140
|
|
|
141
141
|
@classmethod
|
|
142
142
|
def from_dict(cls, value: dict[str, Any]) -> PointTime:
|
|
@@ -195,7 +195,7 @@ class SensorInfo:
|
|
|
195
195
|
or self.point_format.bytes_per_point != CANONICAL_POINT_BYTES
|
|
196
196
|
):
|
|
197
197
|
raise ValueError(
|
|
198
|
-
"point-cloud SensorInfo requires canonical Dataset 0.
|
|
198
|
+
"point-cloud SensorInfo requires canonical Dataset 0.18 layout"
|
|
199
199
|
)
|
|
200
200
|
if not isinstance(self.point_time, PointTime):
|
|
201
201
|
raise TypeError("point-cloud SensorInfo requires PointTime")
|
|
@@ -241,7 +241,7 @@ class ClipMeta:
|
|
|
241
241
|
clip_id: Unique clip identifier (e.g. "20180724_n015_scene-0061_000").
|
|
242
242
|
schema_version: X4D format version (e.g. "0.5").
|
|
243
243
|
session_id: Recording session identifier.
|
|
244
|
-
|
|
244
|
+
source_attributes: Optional descriptive provenance, independent of identity.
|
|
245
245
|
capture_time: Exact capture timestamp.
|
|
246
246
|
duration_s: Clip duration in seconds.
|
|
247
247
|
num_keyframes: Number of keyframes (annotated frames).
|
|
@@ -260,7 +260,6 @@ class ClipMeta:
|
|
|
260
260
|
clip_id: str
|
|
261
261
|
schema_version: str
|
|
262
262
|
session_id: str
|
|
263
|
-
vehicle_id: str
|
|
264
263
|
capture_time: TimeNs
|
|
265
264
|
duration_s: float
|
|
266
265
|
num_keyframes: int
|
|
@@ -269,6 +268,7 @@ class ClipMeta:
|
|
|
269
268
|
annotation_frame_id: str
|
|
270
269
|
ego_pose_frame_id: str
|
|
271
270
|
label_schema: dict[str, Any]
|
|
271
|
+
source_attributes: dict[str, str] | None = None
|
|
272
272
|
route_tag: str | None = None
|
|
273
273
|
weather: str | None = None
|
|
274
274
|
time_of_day: str | None = None
|
|
@@ -281,7 +281,6 @@ class ClipMeta:
|
|
|
281
281
|
"clip_id": self.clip_id,
|
|
282
282
|
"schema_version": self.schema_version,
|
|
283
283
|
"session_id": self.session_id,
|
|
284
|
-
"vehicle_id": self.vehicle_id,
|
|
285
284
|
"capture_time": self.capture_time.to_dict(),
|
|
286
285
|
"duration_s": self.duration_s,
|
|
287
286
|
"keyframe_count": self.num_keyframes,
|
|
@@ -294,6 +293,7 @@ class ClipMeta:
|
|
|
294
293
|
"label_schema": copy.deepcopy(self.label_schema),
|
|
295
294
|
}
|
|
296
295
|
for key in (
|
|
296
|
+
"source_attributes",
|
|
297
297
|
"route_tag",
|
|
298
298
|
"weather",
|
|
299
299
|
"time_of_day",
|