x4d-devkit 0.22.0rc1__tar.gz → 0.22.0rc2__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.22.0rc1 → x4d_devkit-0.22.0rc2}/PKG-INFO +16 -2
- {x4d_devkit-0.22.0rc1 → x4d_devkit-0.22.0rc2}/README.md +15 -1
- {x4d_devkit-0.22.0rc1 → x4d_devkit-0.22.0rc2}/pyproject.toml +4 -1
- {x4d_devkit-0.22.0rc1 → x4d_devkit-0.22.0rc2}/tests/test_contract_validation.py +30 -0
- {x4d_devkit-0.22.0rc1 → x4d_devkit-0.22.0rc2}/tests/test_sdk_api.py +1 -1
- {x4d_devkit-0.22.0rc1 → x4d_devkit-0.22.0rc2}/tests/test_validation.py +31 -0
- {x4d_devkit-0.22.0rc1 → x4d_devkit-0.22.0rc2}/x4d_devkit/validation/contract.py +19 -2
- {x4d_devkit-0.22.0rc1 → x4d_devkit-0.22.0rc2}/x4d_devkit/validation/validator.py +31 -1
- {x4d_devkit-0.22.0rc1 → x4d_devkit-0.22.0rc2}/x4d_devkit.egg-info/PKG-INFO +16 -2
- {x4d_devkit-0.22.0rc1 → x4d_devkit-0.22.0rc2}/LICENSE +0 -0
- {x4d_devkit-0.22.0rc1 → x4d_devkit-0.22.0rc2}/setup.cfg +0 -0
- {x4d_devkit-0.22.0rc1 → x4d_devkit-0.22.0rc2}/tests/test_assets_client.py +0 -0
- {x4d_devkit-0.22.0rc1 → x4d_devkit-0.22.0rc2}/tests/test_boundary.py +0 -0
- {x4d_devkit-0.22.0rc1 → x4d_devkit-0.22.0rc2}/tests/test_box.py +0 -0
- {x4d_devkit-0.22.0rc1 → x4d_devkit-0.22.0rc2}/tests/test_build_info.py +0 -0
- {x4d_devkit-0.22.0rc1 → x4d_devkit-0.22.0rc2}/tests/test_cli_auth.py +0 -0
- {x4d_devkit-0.22.0rc1 → x4d_devkit-0.22.0rc2}/tests/test_client_json_contract.py +0 -0
- {x4d_devkit-0.22.0rc1 → x4d_devkit-0.22.0rc2}/tests/test_client_projects.py +0 -0
- {x4d_devkit-0.22.0rc1 → x4d_devkit-0.22.0rc2}/tests/test_clip_archives.py +0 -0
- {x4d_devkit-0.22.0rc1 → x4d_devkit-0.22.0rc2}/tests/test_coordinate_frames.py +0 -0
- {x4d_devkit-0.22.0rc1 → x4d_devkit-0.22.0rc2}/tests/test_current_state.py +0 -0
- {x4d_devkit-0.22.0rc1 → x4d_devkit-0.22.0rc2}/tests/test_current_state_identity_consumers_example.py +0 -0
- {x4d_devkit-0.22.0rc1 → x4d_devkit-0.22.0rc2}/tests/test_dataset_contract.py +0 -0
- {x4d_devkit-0.22.0rc1 → x4d_devkit-0.22.0rc2}/tests/test_dataset_identity.py +0 -0
- {x4d_devkit-0.22.0rc1 → x4d_devkit-0.22.0rc2}/tests/test_detection_eval.py +0 -0
- {x4d_devkit-0.22.0rc1 → x4d_devkit-0.22.0rc2}/tests/test_evaluate.py +0 -0
- {x4d_devkit-0.22.0rc1 → x4d_devkit-0.22.0rc2}/tests/test_export_bundle.py +0 -0
- {x4d_devkit-0.22.0rc1 → x4d_devkit-0.22.0rc2}/tests/test_inference_builders.py +0 -0
- {x4d_devkit-0.22.0rc1 → x4d_devkit-0.22.0rc2}/tests/test_inference_schemas.py +0 -0
- {x4d_devkit-0.22.0rc1 → x4d_devkit-0.22.0rc2}/tests/test_inference_service.py +0 -0
- {x4d_devkit-0.22.0rc1 → x4d_devkit-0.22.0rc2}/tests/test_label_schemas.py +0 -0
- {x4d_devkit-0.22.0rc1 → x4d_devkit-0.22.0rc2}/tests/test_loader.py +0 -0
- {x4d_devkit-0.22.0rc1 → x4d_devkit-0.22.0rc2}/tests/test_matching.py +0 -0
- {x4d_devkit-0.22.0rc1 → x4d_devkit-0.22.0rc2}/tests/test_metrics.py +0 -0
- {x4d_devkit-0.22.0rc1 → x4d_devkit-0.22.0rc2}/tests/test_models.py +0 -0
- {x4d_devkit-0.22.0rc1 → x4d_devkit-0.22.0rc2}/tests/test_nuscenes_converter.py +0 -0
- {x4d_devkit-0.22.0rc1 → x4d_devkit-0.22.0rc2}/tests/test_platform_pose.py +0 -0
- {x4d_devkit-0.22.0rc1 → x4d_devkit-0.22.0rc2}/tests/test_release_gate.py +0 -0
- {x4d_devkit-0.22.0rc1 → x4d_devkit-0.22.0rc2}/tests/test_token.py +0 -0
- {x4d_devkit-0.22.0rc1 → x4d_devkit-0.22.0rc2}/tests/test_training_identity.py +0 -0
- {x4d_devkit-0.22.0rc1 → x4d_devkit-0.22.0rc2}/tests/test_transform.py +0 -0
- {x4d_devkit-0.22.0rc1 → x4d_devkit-0.22.0rc2}/tests/test_transform_chain.py +0 -0
- {x4d_devkit-0.22.0rc1 → x4d_devkit-0.22.0rc2}/tests/test_work_session.py +0 -0
- {x4d_devkit-0.22.0rc1 → x4d_devkit-0.22.0rc2}/x4d_devkit/__init__.py +0 -0
- {x4d_devkit-0.22.0rc1 → x4d_devkit-0.22.0rc2}/x4d_devkit/build_info.py +0 -0
- {x4d_devkit-0.22.0rc1 → x4d_devkit-0.22.0rc2}/x4d_devkit/cli.py +0 -0
- {x4d_devkit-0.22.0rc1 → x4d_devkit-0.22.0rc2}/x4d_devkit/client/__init__.py +0 -0
- {x4d_devkit-0.22.0rc1 → x4d_devkit-0.22.0rc2}/x4d_devkit/client/_origin.py +0 -0
- {x4d_devkit-0.22.0rc1 → x4d_devkit-0.22.0rc2}/x4d_devkit/client/assets.py +0 -0
- {x4d_devkit-0.22.0rc1 → x4d_devkit-0.22.0rc2}/x4d_devkit/client/bags.py +0 -0
- {x4d_devkit-0.22.0rc1 → x4d_devkit-0.22.0rc2}/x4d_devkit/client/capabilities.py +0 -0
- {x4d_devkit-0.22.0rc1 → x4d_devkit-0.22.0rc2}/x4d_devkit/client/checkpoints.py +0 -0
- {x4d_devkit-0.22.0rc1 → x4d_devkit-0.22.0rc2}/x4d_devkit/client/client.py +0 -0
- {x4d_devkit-0.22.0rc1 → x4d_devkit-0.22.0rc2}/x4d_devkit/client/clip_work_sessions.py +0 -0
- {x4d_devkit-0.22.0rc1 → x4d_devkit-0.22.0rc2}/x4d_devkit/client/clips.py +0 -0
- {x4d_devkit-0.22.0rc1 → x4d_devkit-0.22.0rc2}/x4d_devkit/client/dataset_identity.py +0 -0
- {x4d_devkit-0.22.0rc1 → x4d_devkit-0.22.0rc2}/x4d_devkit/client/label_schemas.py +0 -0
- {x4d_devkit-0.22.0rc1 → x4d_devkit-0.22.0rc2}/x4d_devkit/client/projects.py +0 -0
- {x4d_devkit-0.22.0rc1 → x4d_devkit-0.22.0rc2}/x4d_devkit/client/services.py +0 -0
- {x4d_devkit-0.22.0rc1 → x4d_devkit-0.22.0rc2}/x4d_devkit/client/test_sets.py +0 -0
- {x4d_devkit-0.22.0rc1 → x4d_devkit-0.22.0rc2}/x4d_devkit/consumer_identity.py +0 -0
- {x4d_devkit-0.22.0rc1 → x4d_devkit-0.22.0rc2}/x4d_devkit/converters/__init__.py +0 -0
- {x4d_devkit-0.22.0rc1 → x4d_devkit-0.22.0rc2}/x4d_devkit/converters/nuscenes.py +0 -0
- {x4d_devkit-0.22.0rc1 → x4d_devkit-0.22.0rc2}/x4d_devkit/coordinate_contract.py +0 -0
- {x4d_devkit-0.22.0rc1 → x4d_devkit-0.22.0rc2}/x4d_devkit/core/__init__.py +0 -0
- {x4d_devkit-0.22.0rc1 → x4d_devkit-0.22.0rc2}/x4d_devkit/core/loader.py +0 -0
- {x4d_devkit-0.22.0rc1 → x4d_devkit-0.22.0rc2}/x4d_devkit/core/models.py +0 -0
- {x4d_devkit-0.22.0rc1 → x4d_devkit-0.22.0rc2}/x4d_devkit/core/token.py +0 -0
- {x4d_devkit-0.22.0rc1 → x4d_devkit-0.22.0rc2}/x4d_devkit/core/transform.py +0 -0
- {x4d_devkit-0.22.0rc1 → x4d_devkit-0.22.0rc2}/x4d_devkit/current_state.py +0 -0
- {x4d_devkit-0.22.0rc1 → x4d_devkit-0.22.0rc2}/x4d_devkit/dataset_contract.py +0 -0
- {x4d_devkit-0.22.0rc1 → x4d_devkit-0.22.0rc2}/x4d_devkit/dataset_identity.py +0 -0
- {x4d_devkit-0.22.0rc1 → x4d_devkit-0.22.0rc2}/x4d_devkit/eval/__init__.py +0 -0
- {x4d_devkit-0.22.0rc1 → x4d_devkit-0.22.0rc2}/x4d_devkit/eval/api.py +0 -0
- {x4d_devkit-0.22.0rc1 → x4d_devkit-0.22.0rc2}/x4d_devkit/eval/box.py +0 -0
- {x4d_devkit-0.22.0rc1 → x4d_devkit-0.22.0rc2}/x4d_devkit/eval/detection.py +0 -0
- {x4d_devkit-0.22.0rc1 → x4d_devkit-0.22.0rc2}/x4d_devkit/eval/matching.py +0 -0
- {x4d_devkit-0.22.0rc1 → x4d_devkit-0.22.0rc2}/x4d_devkit/eval/metrics.py +0 -0
- {x4d_devkit-0.22.0rc1 → x4d_devkit-0.22.0rc2}/x4d_devkit/export_bundle.py +0 -0
- {x4d_devkit-0.22.0rc1 → x4d_devkit-0.22.0rc2}/x4d_devkit/inference/__init__.py +0 -0
- {x4d_devkit-0.22.0rc1 → x4d_devkit-0.22.0rc2}/x4d_devkit/inference/builders.py +0 -0
- {x4d_devkit-0.22.0rc1 → x4d_devkit-0.22.0rc2}/x4d_devkit/inference/models.py +0 -0
- {x4d_devkit-0.22.0rc1 → x4d_devkit-0.22.0rc2}/x4d_devkit/inference/schemas.py +0 -0
- {x4d_devkit-0.22.0rc1 → x4d_devkit-0.22.0rc2}/x4d_devkit/inference/service.py +0 -0
- {x4d_devkit-0.22.0rc1 → x4d_devkit-0.22.0rc2}/x4d_devkit/inference/tasks.py +0 -0
- {x4d_devkit-0.22.0rc1 → x4d_devkit-0.22.0rc2}/x4d_devkit/json_contract.py +0 -0
- {x4d_devkit-0.22.0rc1 → x4d_devkit-0.22.0rc2}/x4d_devkit/label_schema.py +0 -0
- {x4d_devkit-0.22.0rc1 → x4d_devkit-0.22.0rc2}/x4d_devkit/materialize.py +0 -0
- {x4d_devkit-0.22.0rc1 → x4d_devkit-0.22.0rc2}/x4d_devkit/training_identity.py +0 -0
- {x4d_devkit-0.22.0rc1 → x4d_devkit-0.22.0rc2}/x4d_devkit/validation/__init__.py +0 -0
- {x4d_devkit-0.22.0rc1 → x4d_devkit-0.22.0rc2}/x4d_devkit/validation/platform_pose.py +0 -0
- {x4d_devkit-0.22.0rc1 → x4d_devkit-0.22.0rc2}/x4d_devkit/validation/report.py +0 -0
- {x4d_devkit-0.22.0rc1 → x4d_devkit-0.22.0rc2}/x4d_devkit/work_session.py +0 -0
- {x4d_devkit-0.22.0rc1 → x4d_devkit-0.22.0rc2}/x4d_devkit.egg-info/SOURCES.txt +0 -0
- {x4d_devkit-0.22.0rc1 → x4d_devkit-0.22.0rc2}/x4d_devkit.egg-info/dependency_links.txt +0 -0
- {x4d_devkit-0.22.0rc1 → x4d_devkit-0.22.0rc2}/x4d_devkit.egg-info/entry_points.txt +0 -0
- {x4d_devkit-0.22.0rc1 → x4d_devkit-0.22.0rc2}/x4d_devkit.egg-info/requires.txt +0 -0
- {x4d_devkit-0.22.0rc1 → x4d_devkit-0.22.0rc2}/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.22.
|
|
3
|
+
Version: 0.22.0rc2
|
|
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
|
|
@@ -66,7 +66,7 @@ Design decisions for this boundary are tracked in GitHub issues, starting with:
|
|
|
66
66
|
## Installation
|
|
67
67
|
|
|
68
68
|
```bash
|
|
69
|
-
pip install x4d-devkit==0.22.
|
|
69
|
+
pip install x4d-devkit==0.22.0rc2
|
|
70
70
|
```
|
|
71
71
|
|
|
72
72
|
Devkit is released independently as an immutable wheel. X-4D, XPoints, and
|
|
@@ -473,6 +473,20 @@ converter = NuScenesConverter("/path/to/nuscenes")
|
|
|
473
473
|
converter.convert_scene("scene-0001", output_dir="/path/to/output")
|
|
474
474
|
```
|
|
475
475
|
|
|
476
|
+
## Development
|
|
477
|
+
|
|
478
|
+
Development and verification run in the repository-owned Docker environment.
|
|
479
|
+
A host Python installation is not part of the project workflow.
|
|
480
|
+
|
|
481
|
+
```bash
|
|
482
|
+
make verify
|
|
483
|
+
```
|
|
484
|
+
|
|
485
|
+
Use `make test`, `make lint`, `make docs`, `make package`, or `make shell` for
|
|
486
|
+
individual tasks. Dependency changes are resolved and locked with `make lock`.
|
|
487
|
+
See [the development environment guide](docs/development.md) for the ownership
|
|
488
|
+
boundary and complete workflow.
|
|
489
|
+
|
|
476
490
|
## Modules
|
|
477
491
|
|
|
478
492
|
| Module | Description |
|
|
@@ -23,7 +23,7 @@ Design decisions for this boundary are tracked in GitHub issues, starting with:
|
|
|
23
23
|
## Installation
|
|
24
24
|
|
|
25
25
|
```bash
|
|
26
|
-
pip install x4d-devkit==0.22.
|
|
26
|
+
pip install x4d-devkit==0.22.0rc2
|
|
27
27
|
```
|
|
28
28
|
|
|
29
29
|
Devkit is released independently as an immutable wheel. X-4D, XPoints, and
|
|
@@ -430,6 +430,20 @@ converter = NuScenesConverter("/path/to/nuscenes")
|
|
|
430
430
|
converter.convert_scene("scene-0001", output_dir="/path/to/output")
|
|
431
431
|
```
|
|
432
432
|
|
|
433
|
+
## Development
|
|
434
|
+
|
|
435
|
+
Development and verification run in the repository-owned Docker environment.
|
|
436
|
+
A host Python installation is not part of the project workflow.
|
|
437
|
+
|
|
438
|
+
```bash
|
|
439
|
+
make verify
|
|
440
|
+
```
|
|
441
|
+
|
|
442
|
+
Use `make test`, `make lint`, `make docs`, `make package`, or `make shell` for
|
|
443
|
+
individual tasks. Dependency changes are resolved and locked with `make lock`.
|
|
444
|
+
See [the development environment guide](docs/development.md) for the ownership
|
|
445
|
+
boundary and complete workflow.
|
|
446
|
+
|
|
433
447
|
## Modules
|
|
434
448
|
|
|
435
449
|
| Module | Description |
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "x4d-devkit"
|
|
7
|
-
version = "0.22.
|
|
7
|
+
version = "0.22.0rc2"
|
|
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"
|
|
@@ -58,3 +58,6 @@ exclude = ["site*", "tests*", "docs*", "examples*"]
|
|
|
58
58
|
|
|
59
59
|
[tool.pytest.ini_options]
|
|
60
60
|
testpaths = ["tests"]
|
|
61
|
+
|
|
62
|
+
[tool.uv]
|
|
63
|
+
required-version = "==0.9.20"
|
|
@@ -291,6 +291,36 @@ def test_final_sensor_coverage_requires_every_declared_channel():
|
|
|
291
291
|
assert "incomplete_sensor_coverage" in _codes(report)
|
|
292
292
|
|
|
293
293
|
|
|
294
|
+
def test_final_sensor_coverage_does_not_count_sweeps():
|
|
295
|
+
meta = _meta()
|
|
296
|
+
meta["sensors"]["cam_front"] = {"modality": "camera", "frame_id": "cam_front"}
|
|
297
|
+
sweep = _sample_data()
|
|
298
|
+
sweep.update(
|
|
299
|
+
sample_data_token="cam-sweep",
|
|
300
|
+
calibrated_sensor_token="cs-camera",
|
|
301
|
+
channel="cam_front",
|
|
302
|
+
file_path="sweeps/cam_front/1.jpg",
|
|
303
|
+
is_keyframe=False,
|
|
304
|
+
width=640,
|
|
305
|
+
height=480,
|
|
306
|
+
)
|
|
307
|
+
|
|
308
|
+
report = validate_clip_contract(_context(meta=meta, sample_data=[_sample_data(), sweep]))
|
|
309
|
+
|
|
310
|
+
assert "incomplete_sensor_coverage" in _codes(report)
|
|
311
|
+
|
|
312
|
+
|
|
313
|
+
def test_annotation_must_reference_a_keyframe_sample():
|
|
314
|
+
context = _context()
|
|
315
|
+
context.samples[0]["is_keyframe"] = False
|
|
316
|
+
context.sample_data[0]["is_keyframe"] = False
|
|
317
|
+
context.sample_data[0]["file_path"] = "sweeps/lidar/1.bin"
|
|
318
|
+
|
|
319
|
+
report = validate_clip_contract(context)
|
|
320
|
+
|
|
321
|
+
assert "annotation_sample_not_keyframe" in _codes(report)
|
|
322
|
+
|
|
323
|
+
|
|
294
324
|
def test_context_rejects_non_list_payloads_and_invalid_meta():
|
|
295
325
|
with pytest.raises(TypeError):
|
|
296
326
|
validate_annotation_payload(_context(), annotations=(), instances=[])
|
|
@@ -12,7 +12,7 @@ from x4d_devkit.eval.matching import MetricData
|
|
|
12
12
|
|
|
13
13
|
|
|
14
14
|
def test_package_version_is_current_release():
|
|
15
|
-
assert x4d_devkit.__version__ == "0.22.
|
|
15
|
+
assert x4d_devkit.__version__ == "0.22.0rc2"
|
|
16
16
|
|
|
17
17
|
|
|
18
18
|
def test_loader_exposes_and_enforces_only_current_schema(tmp_path):
|
|
@@ -223,3 +223,34 @@ def test_explicit_schema_context_must_match_meta_identity():
|
|
|
223
223
|
|
|
224
224
|
assert not report.ok
|
|
225
225
|
assert "label_schema_identity_mismatch" in _codes(report)
|
|
226
|
+
|
|
227
|
+
|
|
228
|
+
def test_camera_frame_must_not_be_shared_with_point_cloud_sensor():
|
|
229
|
+
payload = current_clip_tables(include_camera=True, include_fused=True)
|
|
230
|
+
payload["meta.json"]["sensors"]["cam_front"]["frame_id"] = "base_link"
|
|
231
|
+
payload["calibrated_sensor.json"] = [
|
|
232
|
+
row
|
|
233
|
+
for row in payload["calibrated_sensor.json"]
|
|
234
|
+
if row["channel"] != "cam_front"
|
|
235
|
+
]
|
|
236
|
+
for row in payload["sample_data.json"]:
|
|
237
|
+
if row["channel"] == "cam_front":
|
|
238
|
+
row["calibrated_sensor_token"] = "cs-root"
|
|
239
|
+
|
|
240
|
+
report = _validate_payload(payload)
|
|
241
|
+
|
|
242
|
+
assert not report.ok
|
|
243
|
+
assert "calibration_shape" in _codes(report)
|
|
244
|
+
|
|
245
|
+
|
|
246
|
+
def test_camera_sample_dimensions_must_match_calibration_intrinsics():
|
|
247
|
+
payload = current_clip_tables(include_camera=True)
|
|
248
|
+
camera = next(
|
|
249
|
+
row for row in payload["sample_data.json"] if row["channel"] == "cam_front"
|
|
250
|
+
)
|
|
251
|
+
camera["width"] = 320
|
|
252
|
+
|
|
253
|
+
report = _validate_payload(payload)
|
|
254
|
+
|
|
255
|
+
assert not report.ok
|
|
256
|
+
assert "sample_data_shape" in _codes(report)
|
|
@@ -370,9 +370,15 @@ def validate_annotation_payload(
|
|
|
370
370
|
_validate_context(context, builder)
|
|
371
371
|
|
|
372
372
|
sample_tokens = {
|
|
373
|
-
|
|
373
|
+
token
|
|
374
374
|
for row in context.samples
|
|
375
|
-
if _strict_token(row.get("sample_token"))
|
|
375
|
+
if (token := _strict_token(row.get("sample_token"))) is not None
|
|
376
|
+
}
|
|
377
|
+
keyframe_sample_tokens = {
|
|
378
|
+
token
|
|
379
|
+
for row in context.samples
|
|
380
|
+
if row.get("is_keyframe") is True
|
|
381
|
+
if (token := _strict_token(row.get("sample_token"))) is not None
|
|
376
382
|
}
|
|
377
383
|
class_map = class_rule_map(context.label_schema)
|
|
378
384
|
|
|
@@ -428,6 +434,15 @@ def validate_annotation_payload(
|
|
|
428
434
|
related_token=sample_token,
|
|
429
435
|
details={"sample_token": sample_token},
|
|
430
436
|
)
|
|
437
|
+
elif sample_token not in keyframe_sample_tokens:
|
|
438
|
+
builder.issue(
|
|
439
|
+
"annotation_sample_not_keyframe",
|
|
440
|
+
f"{path}.sample_token",
|
|
441
|
+
"annotation sample_token must identify a keyframe sample",
|
|
442
|
+
row=ann,
|
|
443
|
+
related_token=sample_token,
|
|
444
|
+
details={"sample_token": sample_token},
|
|
445
|
+
)
|
|
431
446
|
|
|
432
447
|
if not instance_token:
|
|
433
448
|
builder.issue(
|
|
@@ -1401,6 +1416,8 @@ def _validate_sensor_coverage(builder: _ReportBuilder, context: ClipValidationCo
|
|
|
1401
1416
|
|
|
1402
1417
|
channels_by_sample: dict[str, set[str]] = {}
|
|
1403
1418
|
for row in context.sample_data:
|
|
1419
|
+
if row.get("is_keyframe") is not True:
|
|
1420
|
+
continue
|
|
1404
1421
|
sample_token = _strict_token(row.get("sample_token"))
|
|
1405
1422
|
channel = _strict_token(row.get("channel"))
|
|
1406
1423
|
if sample_token and channel:
|
|
@@ -401,7 +401,14 @@ def _validate_calibrated_sensors(
|
|
|
401
401
|
intrinsics = row.get("intrinsics")
|
|
402
402
|
distortion = row.get("distortion")
|
|
403
403
|
frame_modality = _modality_for_frame(meta, channel)
|
|
404
|
-
if frame_modality == "
|
|
404
|
+
if frame_modality == "ambiguous":
|
|
405
|
+
_append_error(
|
|
406
|
+
issues,
|
|
407
|
+
"calibration_shape",
|
|
408
|
+
"a camera frame must not be shared with a non-camera sensor",
|
|
409
|
+
f"{path}.channel",
|
|
410
|
+
)
|
|
411
|
+
elif frame_modality == "camera":
|
|
405
412
|
_validate_camera_calibration(
|
|
406
413
|
intrinsics,
|
|
407
414
|
distortion,
|
|
@@ -612,6 +619,29 @@ def _validate_sample_data(
|
|
|
612
619
|
f"camera {field} must be a positive integer",
|
|
613
620
|
f"{path}.{field}",
|
|
614
621
|
)
|
|
622
|
+
calibration = calibrated_sensors.get(calibrated_token)
|
|
623
|
+
intrinsics = (
|
|
624
|
+
calibration.get("intrinsics")
|
|
625
|
+
if isinstance(calibration, dict)
|
|
626
|
+
else None
|
|
627
|
+
)
|
|
628
|
+
if isinstance(intrinsics, dict):
|
|
629
|
+
expected_dimensions = {
|
|
630
|
+
"width": intrinsics.get("image_width"),
|
|
631
|
+
"height": intrinsics.get("image_height"),
|
|
632
|
+
}
|
|
633
|
+
actual_dimensions = {"width": width, "height": height}
|
|
634
|
+
if actual_dimensions != expected_dimensions:
|
|
635
|
+
_append_error(
|
|
636
|
+
issues,
|
|
637
|
+
"sample_data_shape",
|
|
638
|
+
"camera dimensions must match resolved calibration intrinsics",
|
|
639
|
+
path,
|
|
640
|
+
{
|
|
641
|
+
"expected": expected_dimensions,
|
|
642
|
+
"actual": actual_dimensions,
|
|
643
|
+
},
|
|
644
|
+
)
|
|
615
645
|
elif width is not None or height is not None:
|
|
616
646
|
_append_error(
|
|
617
647
|
issues,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: x4d-devkit
|
|
3
|
-
Version: 0.22.
|
|
3
|
+
Version: 0.22.0rc2
|
|
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
|
|
@@ -66,7 +66,7 @@ Design decisions for this boundary are tracked in GitHub issues, starting with:
|
|
|
66
66
|
## Installation
|
|
67
67
|
|
|
68
68
|
```bash
|
|
69
|
-
pip install x4d-devkit==0.22.
|
|
69
|
+
pip install x4d-devkit==0.22.0rc2
|
|
70
70
|
```
|
|
71
71
|
|
|
72
72
|
Devkit is released independently as an immutable wheel. X-4D, XPoints, and
|
|
@@ -473,6 +473,20 @@ converter = NuScenesConverter("/path/to/nuscenes")
|
|
|
473
473
|
converter.convert_scene("scene-0001", output_dir="/path/to/output")
|
|
474
474
|
```
|
|
475
475
|
|
|
476
|
+
## Development
|
|
477
|
+
|
|
478
|
+
Development and verification run in the repository-owned Docker environment.
|
|
479
|
+
A host Python installation is not part of the project workflow.
|
|
480
|
+
|
|
481
|
+
```bash
|
|
482
|
+
make verify
|
|
483
|
+
```
|
|
484
|
+
|
|
485
|
+
Use `make test`, `make lint`, `make docs`, `make package`, or `make shell` for
|
|
486
|
+
individual tasks. Dependency changes are resolved and locked with `make lock`.
|
|
487
|
+
See [the development environment guide](docs/development.md) for the ownership
|
|
488
|
+
boundary and complete workflow.
|
|
489
|
+
|
|
476
490
|
## Modules
|
|
477
491
|
|
|
478
492
|
| Module | Description |
|
|
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.22.0rc1 → x4d_devkit-0.22.0rc2}/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
|