x4d-devkit 0.22.0rc2__tar.gz → 0.22.0rc3__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.
Files changed (98) hide show
  1. {x4d_devkit-0.22.0rc2 → x4d_devkit-0.22.0rc3}/PKG-INFO +2 -2
  2. {x4d_devkit-0.22.0rc2 → x4d_devkit-0.22.0rc3}/README.md +1 -1
  3. {x4d_devkit-0.22.0rc2 → x4d_devkit-0.22.0rc3}/pyproject.toml +1 -1
  4. {x4d_devkit-0.22.0rc2 → x4d_devkit-0.22.0rc3}/tests/test_nuscenes_converter.py +10 -0
  5. {x4d_devkit-0.22.0rc2 → x4d_devkit-0.22.0rc3}/tests/test_sdk_api.py +1 -1
  6. {x4d_devkit-0.22.0rc2 → x4d_devkit-0.22.0rc3}/tests/test_validation.py +29 -0
  7. {x4d_devkit-0.22.0rc2 → x4d_devkit-0.22.0rc3}/x4d_devkit/converters/nuscenes.py +6 -2
  8. {x4d_devkit-0.22.0rc2 → x4d_devkit-0.22.0rc3}/x4d_devkit/validation/validator.py +10 -3
  9. {x4d_devkit-0.22.0rc2 → x4d_devkit-0.22.0rc3}/x4d_devkit.egg-info/PKG-INFO +2 -2
  10. {x4d_devkit-0.22.0rc2 → x4d_devkit-0.22.0rc3}/LICENSE +0 -0
  11. {x4d_devkit-0.22.0rc2 → x4d_devkit-0.22.0rc3}/setup.cfg +0 -0
  12. {x4d_devkit-0.22.0rc2 → x4d_devkit-0.22.0rc3}/tests/test_assets_client.py +0 -0
  13. {x4d_devkit-0.22.0rc2 → x4d_devkit-0.22.0rc3}/tests/test_boundary.py +0 -0
  14. {x4d_devkit-0.22.0rc2 → x4d_devkit-0.22.0rc3}/tests/test_box.py +0 -0
  15. {x4d_devkit-0.22.0rc2 → x4d_devkit-0.22.0rc3}/tests/test_build_info.py +0 -0
  16. {x4d_devkit-0.22.0rc2 → x4d_devkit-0.22.0rc3}/tests/test_cli_auth.py +0 -0
  17. {x4d_devkit-0.22.0rc2 → x4d_devkit-0.22.0rc3}/tests/test_client_json_contract.py +0 -0
  18. {x4d_devkit-0.22.0rc2 → x4d_devkit-0.22.0rc3}/tests/test_client_projects.py +0 -0
  19. {x4d_devkit-0.22.0rc2 → x4d_devkit-0.22.0rc3}/tests/test_clip_archives.py +0 -0
  20. {x4d_devkit-0.22.0rc2 → x4d_devkit-0.22.0rc3}/tests/test_contract_validation.py +0 -0
  21. {x4d_devkit-0.22.0rc2 → x4d_devkit-0.22.0rc3}/tests/test_coordinate_frames.py +0 -0
  22. {x4d_devkit-0.22.0rc2 → x4d_devkit-0.22.0rc3}/tests/test_current_state.py +0 -0
  23. {x4d_devkit-0.22.0rc2 → x4d_devkit-0.22.0rc3}/tests/test_current_state_identity_consumers_example.py +0 -0
  24. {x4d_devkit-0.22.0rc2 → x4d_devkit-0.22.0rc3}/tests/test_dataset_contract.py +0 -0
  25. {x4d_devkit-0.22.0rc2 → x4d_devkit-0.22.0rc3}/tests/test_dataset_identity.py +0 -0
  26. {x4d_devkit-0.22.0rc2 → x4d_devkit-0.22.0rc3}/tests/test_detection_eval.py +0 -0
  27. {x4d_devkit-0.22.0rc2 → x4d_devkit-0.22.0rc3}/tests/test_evaluate.py +0 -0
  28. {x4d_devkit-0.22.0rc2 → x4d_devkit-0.22.0rc3}/tests/test_export_bundle.py +0 -0
  29. {x4d_devkit-0.22.0rc2 → x4d_devkit-0.22.0rc3}/tests/test_inference_builders.py +0 -0
  30. {x4d_devkit-0.22.0rc2 → x4d_devkit-0.22.0rc3}/tests/test_inference_schemas.py +0 -0
  31. {x4d_devkit-0.22.0rc2 → x4d_devkit-0.22.0rc3}/tests/test_inference_service.py +0 -0
  32. {x4d_devkit-0.22.0rc2 → x4d_devkit-0.22.0rc3}/tests/test_label_schemas.py +0 -0
  33. {x4d_devkit-0.22.0rc2 → x4d_devkit-0.22.0rc3}/tests/test_loader.py +0 -0
  34. {x4d_devkit-0.22.0rc2 → x4d_devkit-0.22.0rc3}/tests/test_matching.py +0 -0
  35. {x4d_devkit-0.22.0rc2 → x4d_devkit-0.22.0rc3}/tests/test_metrics.py +0 -0
  36. {x4d_devkit-0.22.0rc2 → x4d_devkit-0.22.0rc3}/tests/test_models.py +0 -0
  37. {x4d_devkit-0.22.0rc2 → x4d_devkit-0.22.0rc3}/tests/test_platform_pose.py +0 -0
  38. {x4d_devkit-0.22.0rc2 → x4d_devkit-0.22.0rc3}/tests/test_release_gate.py +0 -0
  39. {x4d_devkit-0.22.0rc2 → x4d_devkit-0.22.0rc3}/tests/test_token.py +0 -0
  40. {x4d_devkit-0.22.0rc2 → x4d_devkit-0.22.0rc3}/tests/test_training_identity.py +0 -0
  41. {x4d_devkit-0.22.0rc2 → x4d_devkit-0.22.0rc3}/tests/test_transform.py +0 -0
  42. {x4d_devkit-0.22.0rc2 → x4d_devkit-0.22.0rc3}/tests/test_transform_chain.py +0 -0
  43. {x4d_devkit-0.22.0rc2 → x4d_devkit-0.22.0rc3}/tests/test_work_session.py +0 -0
  44. {x4d_devkit-0.22.0rc2 → x4d_devkit-0.22.0rc3}/x4d_devkit/__init__.py +0 -0
  45. {x4d_devkit-0.22.0rc2 → x4d_devkit-0.22.0rc3}/x4d_devkit/build_info.py +0 -0
  46. {x4d_devkit-0.22.0rc2 → x4d_devkit-0.22.0rc3}/x4d_devkit/cli.py +0 -0
  47. {x4d_devkit-0.22.0rc2 → x4d_devkit-0.22.0rc3}/x4d_devkit/client/__init__.py +0 -0
  48. {x4d_devkit-0.22.0rc2 → x4d_devkit-0.22.0rc3}/x4d_devkit/client/_origin.py +0 -0
  49. {x4d_devkit-0.22.0rc2 → x4d_devkit-0.22.0rc3}/x4d_devkit/client/assets.py +0 -0
  50. {x4d_devkit-0.22.0rc2 → x4d_devkit-0.22.0rc3}/x4d_devkit/client/bags.py +0 -0
  51. {x4d_devkit-0.22.0rc2 → x4d_devkit-0.22.0rc3}/x4d_devkit/client/capabilities.py +0 -0
  52. {x4d_devkit-0.22.0rc2 → x4d_devkit-0.22.0rc3}/x4d_devkit/client/checkpoints.py +0 -0
  53. {x4d_devkit-0.22.0rc2 → x4d_devkit-0.22.0rc3}/x4d_devkit/client/client.py +0 -0
  54. {x4d_devkit-0.22.0rc2 → x4d_devkit-0.22.0rc3}/x4d_devkit/client/clip_work_sessions.py +0 -0
  55. {x4d_devkit-0.22.0rc2 → x4d_devkit-0.22.0rc3}/x4d_devkit/client/clips.py +0 -0
  56. {x4d_devkit-0.22.0rc2 → x4d_devkit-0.22.0rc3}/x4d_devkit/client/dataset_identity.py +0 -0
  57. {x4d_devkit-0.22.0rc2 → x4d_devkit-0.22.0rc3}/x4d_devkit/client/label_schemas.py +0 -0
  58. {x4d_devkit-0.22.0rc2 → x4d_devkit-0.22.0rc3}/x4d_devkit/client/projects.py +0 -0
  59. {x4d_devkit-0.22.0rc2 → x4d_devkit-0.22.0rc3}/x4d_devkit/client/services.py +0 -0
  60. {x4d_devkit-0.22.0rc2 → x4d_devkit-0.22.0rc3}/x4d_devkit/client/test_sets.py +0 -0
  61. {x4d_devkit-0.22.0rc2 → x4d_devkit-0.22.0rc3}/x4d_devkit/consumer_identity.py +0 -0
  62. {x4d_devkit-0.22.0rc2 → x4d_devkit-0.22.0rc3}/x4d_devkit/converters/__init__.py +0 -0
  63. {x4d_devkit-0.22.0rc2 → x4d_devkit-0.22.0rc3}/x4d_devkit/coordinate_contract.py +0 -0
  64. {x4d_devkit-0.22.0rc2 → x4d_devkit-0.22.0rc3}/x4d_devkit/core/__init__.py +0 -0
  65. {x4d_devkit-0.22.0rc2 → x4d_devkit-0.22.0rc3}/x4d_devkit/core/loader.py +0 -0
  66. {x4d_devkit-0.22.0rc2 → x4d_devkit-0.22.0rc3}/x4d_devkit/core/models.py +0 -0
  67. {x4d_devkit-0.22.0rc2 → x4d_devkit-0.22.0rc3}/x4d_devkit/core/token.py +0 -0
  68. {x4d_devkit-0.22.0rc2 → x4d_devkit-0.22.0rc3}/x4d_devkit/core/transform.py +0 -0
  69. {x4d_devkit-0.22.0rc2 → x4d_devkit-0.22.0rc3}/x4d_devkit/current_state.py +0 -0
  70. {x4d_devkit-0.22.0rc2 → x4d_devkit-0.22.0rc3}/x4d_devkit/dataset_contract.py +0 -0
  71. {x4d_devkit-0.22.0rc2 → x4d_devkit-0.22.0rc3}/x4d_devkit/dataset_identity.py +0 -0
  72. {x4d_devkit-0.22.0rc2 → x4d_devkit-0.22.0rc3}/x4d_devkit/eval/__init__.py +0 -0
  73. {x4d_devkit-0.22.0rc2 → x4d_devkit-0.22.0rc3}/x4d_devkit/eval/api.py +0 -0
  74. {x4d_devkit-0.22.0rc2 → x4d_devkit-0.22.0rc3}/x4d_devkit/eval/box.py +0 -0
  75. {x4d_devkit-0.22.0rc2 → x4d_devkit-0.22.0rc3}/x4d_devkit/eval/detection.py +0 -0
  76. {x4d_devkit-0.22.0rc2 → x4d_devkit-0.22.0rc3}/x4d_devkit/eval/matching.py +0 -0
  77. {x4d_devkit-0.22.0rc2 → x4d_devkit-0.22.0rc3}/x4d_devkit/eval/metrics.py +0 -0
  78. {x4d_devkit-0.22.0rc2 → x4d_devkit-0.22.0rc3}/x4d_devkit/export_bundle.py +0 -0
  79. {x4d_devkit-0.22.0rc2 → x4d_devkit-0.22.0rc3}/x4d_devkit/inference/__init__.py +0 -0
  80. {x4d_devkit-0.22.0rc2 → x4d_devkit-0.22.0rc3}/x4d_devkit/inference/builders.py +0 -0
  81. {x4d_devkit-0.22.0rc2 → x4d_devkit-0.22.0rc3}/x4d_devkit/inference/models.py +0 -0
  82. {x4d_devkit-0.22.0rc2 → x4d_devkit-0.22.0rc3}/x4d_devkit/inference/schemas.py +0 -0
  83. {x4d_devkit-0.22.0rc2 → x4d_devkit-0.22.0rc3}/x4d_devkit/inference/service.py +0 -0
  84. {x4d_devkit-0.22.0rc2 → x4d_devkit-0.22.0rc3}/x4d_devkit/inference/tasks.py +0 -0
  85. {x4d_devkit-0.22.0rc2 → x4d_devkit-0.22.0rc3}/x4d_devkit/json_contract.py +0 -0
  86. {x4d_devkit-0.22.0rc2 → x4d_devkit-0.22.0rc3}/x4d_devkit/label_schema.py +0 -0
  87. {x4d_devkit-0.22.0rc2 → x4d_devkit-0.22.0rc3}/x4d_devkit/materialize.py +0 -0
  88. {x4d_devkit-0.22.0rc2 → x4d_devkit-0.22.0rc3}/x4d_devkit/training_identity.py +0 -0
  89. {x4d_devkit-0.22.0rc2 → x4d_devkit-0.22.0rc3}/x4d_devkit/validation/__init__.py +0 -0
  90. {x4d_devkit-0.22.0rc2 → x4d_devkit-0.22.0rc3}/x4d_devkit/validation/contract.py +0 -0
  91. {x4d_devkit-0.22.0rc2 → x4d_devkit-0.22.0rc3}/x4d_devkit/validation/platform_pose.py +0 -0
  92. {x4d_devkit-0.22.0rc2 → x4d_devkit-0.22.0rc3}/x4d_devkit/validation/report.py +0 -0
  93. {x4d_devkit-0.22.0rc2 → x4d_devkit-0.22.0rc3}/x4d_devkit/work_session.py +0 -0
  94. {x4d_devkit-0.22.0rc2 → x4d_devkit-0.22.0rc3}/x4d_devkit.egg-info/SOURCES.txt +0 -0
  95. {x4d_devkit-0.22.0rc2 → x4d_devkit-0.22.0rc3}/x4d_devkit.egg-info/dependency_links.txt +0 -0
  96. {x4d_devkit-0.22.0rc2 → x4d_devkit-0.22.0rc3}/x4d_devkit.egg-info/entry_points.txt +0 -0
  97. {x4d_devkit-0.22.0rc2 → x4d_devkit-0.22.0rc3}/x4d_devkit.egg-info/requires.txt +0 -0
  98. {x4d_devkit-0.22.0rc2 → x4d_devkit-0.22.0rc3}/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.0rc2
3
+ Version: 0.22.0rc3
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.0rc2
69
+ pip install x4d-devkit==0.22.0rc3
70
70
  ```
71
71
 
72
72
  Devkit is released independently as an immutable wheel. X-4D, XPoints, and
@@ -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.0rc2
26
+ pip install x4d-devkit==0.22.0rc3
27
27
  ```
28
28
 
29
29
  Devkit is released independently as an immutable wheel. X-4D, XPoints, and
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "x4d-devkit"
7
- version = "0.22.0rc2"
7
+ version = "0.22.0rc3"
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"
@@ -416,6 +416,16 @@ class TestNuScenesConverterExtraction:
416
416
  assert meta["sensors"]["cam_front"]["modality"] == "camera"
417
417
  assert meta["schema_version"] == "0.11"
418
418
  assert meta["label_schema"] == _nuscenes_label_schema().identity.to_dict()
419
+ ego_poses = converter._extract_ego_poses(scene, clip_id)
420
+ ep_old_to_new = {
421
+ row["_original_token"]: row["ego_pose_token"] for row in ego_poses
422
+ }
423
+ sample_data = converter._extract_sample_data(scene, clip_id, ep_old_to_new)
424
+ assert meta["sweep_count"] == sum(
425
+ not row["is_keyframe"]
426
+ and row["channel"] == meta["annotation_source_channel"]
427
+ for row in sample_data
428
+ )
419
429
 
420
430
  def test_extract_calibrated_sensors(self, converter):
421
431
  scene = converter.nusc.scene[0]
@@ -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.0rc2"
15
+ assert x4d_devkit.__version__ == "0.22.0rc3"
16
16
 
17
17
 
18
18
  def test_loader_exposes_and_enforces_only_current_schema(tmp_path):
@@ -57,6 +57,35 @@ def test_remote_asset_inventory_uses_the_same_current_contract():
57
57
  assert valid.ok, str(valid)
58
58
 
59
59
 
60
+ def test_sweep_count_uses_only_the_annotation_source_channel():
61
+ payload = current_clip_tables(include_camera=True)
62
+ payload["meta.json"]["sweep_count"] = 1
63
+ for channel in ("lidar_top", "cam_front"):
64
+ keyframe = next(
65
+ row for row in payload["sample_data.json"] if row["channel"] == channel
66
+ )
67
+ sweep_token = f"data-{channel}-sweep"
68
+ keyframe["next"] = sweep_token
69
+ sweep = dict(keyframe)
70
+ sweep.update(
71
+ sample_data_token=sweep_token,
72
+ file_path=f"sweeps/{channel}/1100000.{'jpg' if channel == 'cam_front' else 'bin'}",
73
+ timestamp_us=1_100_000,
74
+ is_keyframe=False,
75
+ prev=keyframe["sample_data_token"],
76
+ next=None,
77
+ )
78
+ payload["sample_data.json"].append(sweep)
79
+
80
+ report = _validate_payload(payload)
81
+
82
+ assert report.ok, str(report)
83
+
84
+ payload["meta.json"]["sweep_count"] = 2
85
+ report = _validate_payload(payload)
86
+ assert "meta_count_mismatch" in _codes(report)
87
+
88
+
60
89
  def test_remote_asset_inventory_rejects_noncanonical_input():
61
90
  payload = current_clip_tables()
62
91
  for inventory in (
@@ -312,7 +312,10 @@ class NuScenesConverter:
312
312
  # Count keyframes
313
313
  keyframe_count = scene["nbr_samples"]
314
314
 
315
- # Count sweeps
315
+ # nuScenes annotates from LIDAR_TOP. A clip-level sweep count follows
316
+ # that one explicit temporal source instead of summing asynchronous
317
+ # records from every sensor channel.
318
+ anchor_channel = _normalize_channel("LIDAR_TOP")
316
319
  sweep_count = 0
317
320
  sample_token = scene["first_sample_token"]
318
321
  while sample_token:
@@ -320,6 +323,8 @@ class NuScenesConverter:
320
323
  for channel, sd_token in sample["data"].items():
321
324
  if channel not in TARGET_CHANNELS:
322
325
  continue
326
+ if _normalize_channel(channel) != anchor_channel:
327
+ continue
323
328
  sd = self.nusc.get("sample_data", sd_token)
324
329
  cur = sd["next"]
325
330
  while cur:
@@ -338,7 +343,6 @@ class NuScenesConverter:
338
343
  # nuScenes annotates from the LIDAR_TOP point cloud; SLAM also runs
339
344
  # there, so ego_pose is also expressed for that frame in clip-local
340
345
  # world. After normalization, the source channel is "lidar_top".
341
- anchor_channel = _normalize_channel("LIDAR_TOP")
342
346
  meta = {
343
347
  "clip_id": clip_id,
344
348
  "session_id": log["logfile"],
@@ -338,8 +338,11 @@ def _validate_tables(
338
338
  )
339
339
 
340
340
  actual_keyframes = sum(row.get("is_keyframe") is True for row in tables["samples"])
341
+ annotation_source_channel = meta["annotation_source_channel"]
341
342
  actual_sweeps = sum(
342
- row.get("is_keyframe") is False for row in tables["sample_data"]
343
+ row.get("is_keyframe") is False
344
+ and row.get("channel") == annotation_source_channel
345
+ for row in tables["sample_data"]
343
346
  )
344
347
  if meta["keyframe_count"] != actual_keyframes:
345
348
  _append_error(
@@ -353,9 +356,13 @@ def _validate_tables(
353
356
  _append_error(
354
357
  issues,
355
358
  "meta_count_mismatch",
356
- "meta.sweep_count does not match non-keyframe sample_data records",
359
+ "meta.sweep_count does not match annotation-source sweep records",
357
360
  "meta.sweep_count",
358
- {"declared": meta["sweep_count"], "actual": actual_sweeps},
361
+ {
362
+ "declared": meta["sweep_count"],
363
+ "actual": actual_sweeps,
364
+ "annotation_source_channel": annotation_source_channel,
365
+ },
359
366
  )
360
367
  return tables
361
368
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: x4d-devkit
3
- Version: 0.22.0rc2
3
+ Version: 0.22.0rc3
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.0rc2
69
+ pip install x4d-devkit==0.22.0rc3
70
70
  ```
71
71
 
72
72
  Devkit is released independently as an immutable wheel. X-4D, XPoints, and
File without changes
File without changes