opensportslib 0.2.0.dev4__tar.gz → 0.2.0.dev5__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 (171) hide show
  1. {opensportslib-0.2.0.dev4/opensportslib.egg-info → opensportslib-0.2.0.dev5}/PKG-INFO +2 -1
  2. {opensportslib-0.2.0.dev4 → opensportslib-0.2.0.dev5}/opensportslib/apis/classification.py +12 -1
  3. {opensportslib-0.2.0.dev4 → opensportslib-0.2.0.dev5}/opensportslib/apis/localization.py +6 -0
  4. opensportslib-0.2.0.dev5/opensportslib/configs/localization/h5_header_distance.yaml +93 -0
  5. opensportslib-0.2.0.dev5/opensportslib/configs/localization/h5_header_distance_angle.yaml +93 -0
  6. opensportslib-0.2.0.dev5/opensportslib/configs/localization/h5_header_distance_speed.yaml +93 -0
  7. opensportslib-0.2.0.dev5/opensportslib/configs/localization/h5_header_distance_speed_angle.yaml +93 -0
  8. opensportslib-0.2.0.dev5/opensportslib/configs/localization/h5_header_rule.yaml +99 -0
  9. {opensportslib-0.2.0.dev4 → opensportslib-0.2.0.dev5}/opensportslib/core/config/accessors.py +10 -0
  10. {opensportslib-0.2.0.dev4 → opensportslib-0.2.0.dev5}/opensportslib/core/trainer/classification_trainer.py +12 -2
  11. {opensportslib-0.2.0.dev4 → opensportslib-0.2.0.dev5}/opensportslib/core/trainer/localization_trainer.py +10 -1
  12. {opensportslib-0.2.0.dev4 → opensportslib-0.2.0.dev5}/opensportslib/core/utils/load_annotations.py +9 -1
  13. {opensportslib-0.2.0.dev4 → opensportslib-0.2.0.dev5}/opensportslib/datasets/classification_dataset.py +160 -0
  14. {opensportslib-0.2.0.dev4 → opensportslib-0.2.0.dev5}/opensportslib/datasets/localization_dataset.py +8 -0
  15. opensportslib-0.2.0.dev5/opensportslib/datasets/utils/h5_tracking.py +338 -0
  16. opensportslib-0.2.0.dev5/opensportslib/models/base/rule_based.py +579 -0
  17. {opensportslib-0.2.0.dev4 → opensportslib-0.2.0.dev5}/opensportslib/models/builder.py +7 -2
  18. {opensportslib-0.2.0.dev4 → opensportslib-0.2.0.dev5/opensportslib.egg-info}/PKG-INFO +2 -1
  19. {opensportslib-0.2.0.dev4 → opensportslib-0.2.0.dev5}/opensportslib.egg-info/SOURCES.txt +10 -0
  20. {opensportslib-0.2.0.dev4 → opensportslib-0.2.0.dev5}/opensportslib.egg-info/requires.txt +1 -0
  21. {opensportslib-0.2.0.dev4 → opensportslib-0.2.0.dev5}/pyproject.toml +2 -2
  22. opensportslib-0.2.0.dev5/scripts/run_h5_header_rule_inference.py +65 -0
  23. opensportslib-0.2.0.dev5/tests/test_h5_header_rule_spotter.py +540 -0
  24. opensportslib-0.2.0.dev5/tests/test_h5_tracking_dataset.py +196 -0
  25. {opensportslib-0.2.0.dev4 → opensportslib-0.2.0.dev5}/LICENSE +0 -0
  26. {opensportslib-0.2.0.dev4 → opensportslib-0.2.0.dev5}/LICENSE-COMMERCIAL +0 -0
  27. {opensportslib-0.2.0.dev4 → opensportslib-0.2.0.dev5}/MANIFEST.in +0 -0
  28. {opensportslib-0.2.0.dev4 → opensportslib-0.2.0.dev5}/README.md +0 -0
  29. {opensportslib-0.2.0.dev4 → opensportslib-0.2.0.dev5}/examples/quickstart/basic_classification.py +0 -0
  30. {opensportslib-0.2.0.dev4 → opensportslib-0.2.0.dev5}/examples/quickstart/basic_localization.py +0 -0
  31. {opensportslib-0.2.0.dev4 → opensportslib-0.2.0.dev5}/examples/quickstart/basic_vqa.py +0 -0
  32. {opensportslib-0.2.0.dev4 → opensportslib-0.2.0.dev5}/opensportslib/__init__.py +0 -0
  33. {opensportslib-0.2.0.dev4 → opensportslib-0.2.0.dev5}/opensportslib/apis/__init__.py +0 -0
  34. {opensportslib-0.2.0.dev4 → opensportslib-0.2.0.dev5}/opensportslib/apis/base_task_model.py +0 -0
  35. {opensportslib-0.2.0.dev4 → opensportslib-0.2.0.dev5}/opensportslib/apis/vqa.py +0 -0
  36. {opensportslib-0.2.0.dev4 → opensportslib-0.2.0.dev5}/opensportslib/cli.py +0 -0
  37. {opensportslib-0.2.0.dev4 → opensportslib-0.2.0.dev5}/opensportslib/configs/classification/default.yaml +0 -0
  38. {opensportslib-0.2.0.dev4 → opensportslib-0.2.0.dev5}/opensportslib/configs/classification/sngar_frames.yaml +0 -0
  39. {opensportslib-0.2.0.dev4 → opensportslib-0.2.0.dev5}/opensportslib/configs/classification/sngar_tracking.yaml +0 -0
  40. {opensportslib-0.2.0.dev4 → opensportslib-0.2.0.dev5}/opensportslib/configs/classification/video.yaml +0 -0
  41. {opensportslib-0.2.0.dev4 → opensportslib-0.2.0.dev5}/opensportslib/configs/default.yaml +0 -0
  42. {opensportslib-0.2.0.dev4 → opensportslib-0.2.0.dev5}/opensportslib/configs/localization/calf_resnetpca512.yaml +0 -0
  43. {opensportslib-0.2.0.dev4 → opensportslib-0.2.0.dev5}/opensportslib/configs/localization/default.yaml +0 -0
  44. {opensportslib-0.2.0.dev4 → opensportslib-0.2.0.dev5}/opensportslib/configs/localization/netvladpp_resnetpca512.yaml +0 -0
  45. {opensportslib-0.2.0.dev4 → opensportslib-0.2.0.dev5}/opensportslib/configs/localization/video_dali.yaml +0 -0
  46. {opensportslib-0.2.0.dev4 → opensportslib-0.2.0.dev5}/opensportslib/configs/localization/video_ocv.yaml +0 -0
  47. {opensportslib-0.2.0.dev4 → opensportslib-0.2.0.dev5}/opensportslib/configs/vqa/default.yaml +0 -0
  48. {opensportslib-0.2.0.dev4 → opensportslib-0.2.0.dev5}/opensportslib/configs/vqa/qwen.yaml +0 -0
  49. {opensportslib-0.2.0.dev4 → opensportslib-0.2.0.dev5}/opensportslib/configs/vqa/xvars.yaml +0 -0
  50. {opensportslib-0.2.0.dev4 → opensportslib-0.2.0.dev5}/opensportslib/core/__init__.py +0 -0
  51. {opensportslib-0.2.0.dev4 → opensportslib-0.2.0.dev5}/opensportslib/core/config/__init__.py +0 -0
  52. {opensportslib-0.2.0.dev4 → opensportslib-0.2.0.dev5}/opensportslib/core/config/conflicts.py +0 -0
  53. {opensportslib-0.2.0.dev4 → opensportslib-0.2.0.dev5}/opensportslib/core/config/loader.py +0 -0
  54. {opensportslib-0.2.0.dev4 → opensportslib-0.2.0.dev5}/opensportslib/core/config/migrate.py +0 -0
  55. {opensportslib-0.2.0.dev4 → opensportslib-0.2.0.dev5}/opensportslib/core/config/migrations/__init__.py +0 -0
  56. {opensportslib-0.2.0.dev4 → opensportslib-0.2.0.dev5}/opensportslib/core/config/migrations/legacy_to_canonical.py +0 -0
  57. {opensportslib-0.2.0.dev4 → opensportslib-0.2.0.dev5}/opensportslib/core/config/runtime_adapter.py +0 -0
  58. {opensportslib-0.2.0.dev4 → opensportslib-0.2.0.dev5}/opensportslib/core/config/schema.py +0 -0
  59. {opensportslib-0.2.0.dev4 → opensportslib-0.2.0.dev5}/opensportslib/core/config/schemas/__init__.py +0 -0
  60. {opensportslib-0.2.0.dev4 → opensportslib-0.2.0.dev5}/opensportslib/core/config/schemas/schema_canonical.py +0 -0
  61. {opensportslib-0.2.0.dev4 → opensportslib-0.2.0.dev5}/opensportslib/core/config/schemas/schema_legacy.py +0 -0
  62. {opensportslib-0.2.0.dev4 → opensportslib-0.2.0.dev5}/opensportslib/core/config/validate.py +0 -0
  63. {opensportslib-0.2.0.dev4 → opensportslib-0.2.0.dev5}/opensportslib/core/loss/__init__.py +0 -0
  64. {opensportslib-0.2.0.dev4 → opensportslib-0.2.0.dev5}/opensportslib/core/loss/builder.py +0 -0
  65. {opensportslib-0.2.0.dev4 → opensportslib-0.2.0.dev5}/opensportslib/core/loss/calf.py +0 -0
  66. {opensportslib-0.2.0.dev4 → opensportslib-0.2.0.dev5}/opensportslib/core/loss/ce.py +0 -0
  67. {opensportslib-0.2.0.dev4 → opensportslib-0.2.0.dev5}/opensportslib/core/loss/combine.py +0 -0
  68. {opensportslib-0.2.0.dev4 → opensportslib-0.2.0.dev5}/opensportslib/core/loss/nll.py +0 -0
  69. {opensportslib-0.2.0.dev4 → opensportslib-0.2.0.dev5}/opensportslib/core/optimizer/__init__.py +0 -0
  70. {opensportslib-0.2.0.dev4 → opensportslib-0.2.0.dev5}/opensportslib/core/optimizer/builder.py +0 -0
  71. {opensportslib-0.2.0.dev4 → opensportslib-0.2.0.dev5}/opensportslib/core/sampler/weighted_sampler.py +0 -0
  72. {opensportslib-0.2.0.dev4 → opensportslib-0.2.0.dev5}/opensportslib/core/scheduler/__init__.py +0 -0
  73. {opensportslib-0.2.0.dev4 → opensportslib-0.2.0.dev5}/opensportslib/core/scheduler/builder.py +0 -0
  74. {opensportslib-0.2.0.dev4 → opensportslib-0.2.0.dev5}/opensportslib/core/trainer/__init__.py +0 -0
  75. {opensportslib-0.2.0.dev4 → opensportslib-0.2.0.dev5}/opensportslib/core/trainer/vqa_trainer.py +0 -0
  76. {opensportslib-0.2.0.dev4 → opensportslib-0.2.0.dev5}/opensportslib/core/utils/checkpoint.py +0 -0
  77. {opensportslib-0.2.0.dev4 → opensportslib-0.2.0.dev5}/opensportslib/core/utils/config.py +0 -0
  78. {opensportslib-0.2.0.dev4 → opensportslib-0.2.0.dev5}/opensportslib/core/utils/config_normalize.py +0 -0
  79. {opensportslib-0.2.0.dev4 → opensportslib-0.2.0.dev5}/opensportslib/core/utils/data.py +0 -0
  80. {opensportslib-0.2.0.dev4 → opensportslib-0.2.0.dev5}/opensportslib/core/utils/ddp.py +0 -0
  81. {opensportslib-0.2.0.dev4 → opensportslib-0.2.0.dev5}/opensportslib/core/utils/default_args.py +0 -0
  82. {opensportslib-0.2.0.dev4 → opensportslib-0.2.0.dev5}/opensportslib/core/utils/hf_runtime.py +0 -0
  83. {opensportslib-0.2.0.dev4 → opensportslib-0.2.0.dev5}/opensportslib/core/utils/lightning.py +0 -0
  84. {opensportslib-0.2.0.dev4 → opensportslib-0.2.0.dev5}/opensportslib/core/utils/seed.py +0 -0
  85. {opensportslib-0.2.0.dev4 → opensportslib-0.2.0.dev5}/opensportslib/core/utils/video_processing.py +0 -0
  86. {opensportslib-0.2.0.dev4 → opensportslib-0.2.0.dev5}/opensportslib/core/utils/wandb.py +0 -0
  87. {opensportslib-0.2.0.dev4 → opensportslib-0.2.0.dev5}/opensportslib/datasets/__init__.py +0 -0
  88. {opensportslib-0.2.0.dev4 → opensportslib-0.2.0.dev5}/opensportslib/datasets/builder.py +0 -0
  89. {opensportslib-0.2.0.dev4 → opensportslib-0.2.0.dev5}/opensportslib/datasets/utils/__init__.py +0 -0
  90. {opensportslib-0.2.0.dev4 → opensportslib-0.2.0.dev5}/opensportslib/datasets/utils/tracking.py +0 -0
  91. {opensportslib-0.2.0.dev4 → opensportslib-0.2.0.dev5}/opensportslib/datasets/vqa_dataset.py +0 -0
  92. {opensportslib-0.2.0.dev4 → opensportslib-0.2.0.dev5}/opensportslib/legacy_config/classification.yaml +0 -0
  93. {opensportslib-0.2.0.dev4 → opensportslib-0.2.0.dev5}/opensportslib/legacy_config/localization-e2e-ocv.yaml +0 -0
  94. {opensportslib-0.2.0.dev4 → opensportslib-0.2.0.dev5}/opensportslib/legacy_config/localization-json_calf_resnetpca512.yaml +0 -0
  95. {opensportslib-0.2.0.dev4 → opensportslib-0.2.0.dev5}/opensportslib/legacy_config/localization-json_netvlad++_resnetpca512.yaml +0 -0
  96. {opensportslib-0.2.0.dev4 → opensportslib-0.2.0.dev5}/opensportslib/legacy_config/localization.yaml +0 -0
  97. {opensportslib-0.2.0.dev4 → opensportslib-0.2.0.dev5}/opensportslib/legacy_config/sngar-frames.yaml +0 -0
  98. {opensportslib-0.2.0.dev4 → opensportslib-0.2.0.dev5}/opensportslib/legacy_config/sngar-tracking.yaml +0 -0
  99. {opensportslib-0.2.0.dev4 → opensportslib-0.2.0.dev5}/opensportslib/metrics/classification_metric.py +0 -0
  100. {opensportslib-0.2.0.dev4 → opensportslib-0.2.0.dev5}/opensportslib/metrics/localization_metric.py +0 -0
  101. {opensportslib-0.2.0.dev4 → opensportslib-0.2.0.dev5}/opensportslib/metrics/vqa_metric.py +0 -0
  102. {opensportslib-0.2.0.dev4 → opensportslib-0.2.0.dev5}/opensportslib/models/__init__.py +0 -0
  103. {opensportslib-0.2.0.dev4 → opensportslib-0.2.0.dev5}/opensportslib/models/backbones/builder.py +0 -0
  104. {opensportslib-0.2.0.dev4 → opensportslib-0.2.0.dev5}/opensportslib/models/base/contextaware.py +0 -0
  105. {opensportslib-0.2.0.dev4 → opensportslib-0.2.0.dev5}/opensportslib/models/base/e2e.py +0 -0
  106. {opensportslib-0.2.0.dev4 → opensportslib-0.2.0.dev5}/opensportslib/models/base/learnablepooling.py +0 -0
  107. {opensportslib-0.2.0.dev4 → opensportslib-0.2.0.dev5}/opensportslib/models/base/qwen_xvars.py +0 -0
  108. {opensportslib-0.2.0.dev4 → opensportslib-0.2.0.dev5}/opensportslib/models/base/tracking.py +0 -0
  109. {opensportslib-0.2.0.dev4 → opensportslib-0.2.0.dev5}/opensportslib/models/base/vars.py +0 -0
  110. {opensportslib-0.2.0.dev4 → opensportslib-0.2.0.dev5}/opensportslib/models/base/video.py +0 -0
  111. {opensportslib-0.2.0.dev4 → opensportslib-0.2.0.dev5}/opensportslib/models/base/video_chatgpt_compat.py +0 -0
  112. {opensportslib-0.2.0.dev4 → opensportslib-0.2.0.dev5}/opensportslib/models/base/video_mae.py +0 -0
  113. {opensportslib-0.2.0.dev4 → opensportslib-0.2.0.dev5}/opensportslib/models/base/xvars_videochatgpt.py +0 -0
  114. {opensportslib-0.2.0.dev4 → opensportslib-0.2.0.dev5}/opensportslib/models/heads/builder.py +0 -0
  115. {opensportslib-0.2.0.dev4 → opensportslib-0.2.0.dev5}/opensportslib/models/neck/builder.py +0 -0
  116. {opensportslib-0.2.0.dev4 → opensportslib-0.2.0.dev5}/opensportslib/models/utils/common.py +0 -0
  117. {opensportslib-0.2.0.dev4 → opensportslib-0.2.0.dev5}/opensportslib/models/utils/impl/__init__.py +0 -0
  118. {opensportslib-0.2.0.dev4 → opensportslib-0.2.0.dev5}/opensportslib/models/utils/impl/asformer.py +0 -0
  119. {opensportslib-0.2.0.dev4 → opensportslib-0.2.0.dev5}/opensportslib/models/utils/impl/calf.py +0 -0
  120. {opensportslib-0.2.0.dev4 → opensportslib-0.2.0.dev5}/opensportslib/models/utils/impl/gsm.py +0 -0
  121. {opensportslib-0.2.0.dev4 → opensportslib-0.2.0.dev5}/opensportslib/models/utils/impl/gtad.py +0 -0
  122. {opensportslib-0.2.0.dev4 → opensportslib-0.2.0.dev5}/opensportslib/models/utils/impl/tsm.py +0 -0
  123. {opensportslib-0.2.0.dev4 → opensportslib-0.2.0.dev5}/opensportslib/models/utils/litebase.py +0 -0
  124. {opensportslib-0.2.0.dev4 → opensportslib-0.2.0.dev5}/opensportslib/models/utils/modules.py +0 -0
  125. {opensportslib-0.2.0.dev4 → opensportslib-0.2.0.dev5}/opensportslib/models/utils/shift.py +0 -0
  126. {opensportslib-0.2.0.dev4 → opensportslib-0.2.0.dev5}/opensportslib/models/utils/utils.py +0 -0
  127. {opensportslib-0.2.0.dev4 → opensportslib-0.2.0.dev5}/opensportslib/models/utils/vqa_prediction_priors.py +0 -0
  128. {opensportslib-0.2.0.dev4 → opensportslib-0.2.0.dev5}/opensportslib/models/utils/vqa_prompting.py +0 -0
  129. {opensportslib-0.2.0.dev4 → opensportslib-0.2.0.dev5}/opensportslib/models/utils/xvars_clip_index.py +0 -0
  130. {opensportslib-0.2.0.dev4 → opensportslib-0.2.0.dev5}/opensportslib/setup/setup.py +0 -0
  131. {opensportslib-0.2.0.dev4 → opensportslib-0.2.0.dev5}/opensportslib/tools/__init__.py +0 -0
  132. {opensportslib-0.2.0.dev4 → opensportslib-0.2.0.dev5}/opensportslib/tools/_common.py +0 -0
  133. {opensportslib-0.2.0.dev4 → opensportslib-0.2.0.dev5}/opensportslib/tools/hf_transfer.py +0 -0
  134. {opensportslib-0.2.0.dev4 → opensportslib-0.2.0.dev5}/opensportslib/tools/osl_json_to_parquet.py +0 -0
  135. {opensportslib-0.2.0.dev4 → opensportslib-0.2.0.dev5}/opensportslib/tools/parquet_to_osl_json.py +0 -0
  136. {opensportslib-0.2.0.dev4 → opensportslib-0.2.0.dev5}/opensportslib.egg-info/dependency_links.txt +0 -0
  137. {opensportslib-0.2.0.dev4 → opensportslib-0.2.0.dev5}/opensportslib.egg-info/entry_points.txt +0 -0
  138. {opensportslib-0.2.0.dev4 → opensportslib-0.2.0.dev5}/opensportslib.egg-info/top_level.txt +0 -0
  139. {opensportslib-0.2.0.dev4 → opensportslib-0.2.0.dev5}/setup.cfg +0 -0
  140. {opensportslib-0.2.0.dev4 → opensportslib-0.2.0.dev5}/tests/conftest.py +0 -0
  141. {opensportslib-0.2.0.dev4 → opensportslib-0.2.0.dev5}/tests/test_classification_dataset_paths.py +0 -0
  142. {opensportslib-0.2.0.dev4 → opensportslib-0.2.0.dev5}/tests/test_classification_trainer_dataloader.py +0 -0
  143. {opensportslib-0.2.0.dev4 → opensportslib-0.2.0.dev5}/tests/test_config_architecture.py +0 -0
  144. {opensportslib-0.2.0.dev4 → opensportslib-0.2.0.dev5}/tests/test_config_split_override_sync.py +0 -0
  145. {opensportslib-0.2.0.dev4 → opensportslib-0.2.0.dev5}/tests/test_config_utils_smoke.py +0 -0
  146. {opensportslib-0.2.0.dev4 → opensportslib-0.2.0.dev5}/tests/test_conversion_tools.py +0 -0
  147. {opensportslib-0.2.0.dev4 → opensportslib-0.2.0.dev5}/tests/test_extract_xvars_features.py +0 -0
  148. {opensportslib-0.2.0.dev4 → opensportslib-0.2.0.dev5}/tests/test_hf_transfer_tools.py +0 -0
  149. {opensportslib-0.2.0.dev4 → opensportslib-0.2.0.dev5}/tests/test_localization_dali_filenames.py +0 -0
  150. {opensportslib-0.2.0.dev4 → opensportslib-0.2.0.dev5}/tests/test_package_smoke.py +0 -0
  151. {opensportslib-0.2.0.dev4 → opensportslib-0.2.0.dev5}/tests/test_pretrained_config_merge_policy.py +0 -0
  152. {opensportslib-0.2.0.dev4 → opensportslib-0.2.0.dev5}/tests/test_public_apis_smoke.py +0 -0
  153. {opensportslib-0.2.0.dev4 → opensportslib-0.2.0.dev5}/tests/test_setup_cli.py +0 -0
  154. {opensportslib-0.2.0.dev4 → opensportslib-0.2.0.dev5}/tests/test_subset_train_infer_integration.py +0 -0
  155. {opensportslib-0.2.0.dev4 → opensportslib-0.2.0.dev5}/tests/test_task_model_api_contract.py +0 -0
  156. {opensportslib-0.2.0.dev4 → opensportslib-0.2.0.dev5}/tests/test_vqa_api.py +0 -0
  157. {opensportslib-0.2.0.dev4 → opensportslib-0.2.0.dev5}/tests/test_vqa_metrics_semantic.py +0 -0
  158. {opensportslib-0.2.0.dev4 → opensportslib-0.2.0.dev5}/tests/test_vqa_qwen_xvars.py +0 -0
  159. {opensportslib-0.2.0.dev4 → opensportslib-0.2.0.dev5}/tests/test_vqa_training_lora.py +0 -0
  160. {opensportslib-0.2.0.dev4 → opensportslib-0.2.0.dev5}/tests/test_vqa_xvars_videochatgpt.py +0 -0
  161. {opensportslib-0.2.0.dev4 → opensportslib-0.2.0.dev5}/tools/convert/build_soccernet_gar.py +0 -0
  162. {opensportslib-0.2.0.dev4 → opensportslib-0.2.0.dev5}/tools/convert/build_soccernet_gar_action_spotting.py +0 -0
  163. {opensportslib-0.2.0.dev4 → opensportslib-0.2.0.dev5}/tools/convert/build_xvars_indexes.py +0 -0
  164. {opensportslib-0.2.0.dev4 → opensportslib-0.2.0.dev5}/tools/convert/extract_xvars_clip_features.py +0 -0
  165. {opensportslib-0.2.0.dev4 → opensportslib-0.2.0.dev5}/tools/convert/osl_json_to_parquet_webdataset.py +0 -0
  166. {opensportslib-0.2.0.dev4 → opensportslib-0.2.0.dev5}/tools/convert/parquet_webdataset_to_osl_json.py +0 -0
  167. {opensportslib-0.2.0.dev4 → opensportslib-0.2.0.dev5}/tools/download/download_hf_repo.py +0 -0
  168. {opensportslib-0.2.0.dev4 → opensportslib-0.2.0.dev5}/tools/download/download_osl_hf.py +0 -0
  169. {opensportslib-0.2.0.dev4 → opensportslib-0.2.0.dev5}/tools/download/upload_osl_hf.py +0 -0
  170. {opensportslib-0.2.0.dev4 → opensportslib-0.2.0.dev5}/tools/training/classification.py +0 -0
  171. {opensportslib-0.2.0.dev4 → opensportslib-0.2.0.dev5}/tools/training/localization.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: opensportslib
3
- Version: 0.2.0.dev4
3
+ Version: 0.2.0.dev5
4
4
  Summary: OpenSportsLib is the professional library, designed for advanced video understanding in sports. It provides state-of-the-art tools for action recognition, spotting, retrieval, and captioning, making it ideal for researchers, analysts, and developers working with sports video data.
5
5
  Author: Jeet Vora
6
6
  Requires-Python: >=3.12
@@ -26,6 +26,7 @@ Requires-Dist: tabulate
26
26
  Requires-Dist: pytorch-lightning
27
27
  Requires-Dist: pandas
28
28
  Requires-Dist: pyarrow
29
+ Requires-Dist: h5py
29
30
  Requires-Dist: huggingface_hub
30
31
  Requires-Dist: easydict
31
32
  Provides-Extra: test
@@ -17,6 +17,17 @@ from opensportslib.core.config.accessors import (
17
17
  )
18
18
  from opensportslib.core.utils.config import expand
19
19
 
20
+
21
+ def _is_tracking_graph_modality(modality):
22
+ return str(modality).lower() in {
23
+ "tracking",
24
+ "tracking_parquet",
25
+ "tracking_h5",
26
+ "player_centroids_h5",
27
+ "player_joints_h5",
28
+ }
29
+
30
+
20
31
  class ClassificationModel(BaseTaskModel):
21
32
  """Top-level task wrapper for classification."""
22
33
 
@@ -100,7 +111,7 @@ class ClassificationModel(BaseTaskModel):
100
111
  trainer.model = model
101
112
 
102
113
  modality = get_data_modality(config)
103
- use_tracking_collate = modality in {"tracking", "tracking_parquet"}
114
+ use_tracking_collate = _is_tracking_graph_modality(modality)
104
115
  logging.info(
105
116
  "Worker setup | mode=%s | modality=%s | tracking_collate=%s",
106
117
  mode,
@@ -14,6 +14,7 @@ from opensportslib.core.config.accessors import (
14
14
  get_split_annotation_path,
15
15
  get_split_cfg,
16
16
  set_split_annotation_path,
17
+ get_model_family,
17
18
  )
18
19
  from opensportslib.core.utils.config import expand
19
20
 
@@ -170,6 +171,11 @@ class LocalizationModel(BaseTaskModel):
170
171
 
171
172
  del kwargs
172
173
 
174
+ if str(get_model_family(self.config)).lower() == "rulebased":
175
+ raise NotImplementedError(
176
+ "RuleBased localization models are inference-only; call infer() instead of train()."
177
+ )
178
+
173
179
  train_set = self._resolve_split_path("train", train_set)
174
180
  valid_set = self._resolve_split_path("valid", valid_set)
175
181
  self._set_split_path("train", train_set)
@@ -0,0 +1,93 @@
1
+ TASK: localization
2
+ VERSION: 2
3
+
4
+ SYSTEM:
5
+ paths:
6
+ work_dir: ./outputs/header_spotting_distance
7
+ device: cpu
8
+ gpu:
9
+ count: 0
10
+
11
+ DATA:
12
+ common:
13
+ dataset_name: h5_headers
14
+ data_root: ./data
15
+ classes:
16
+ - header
17
+ splits:
18
+ test:
19
+ type: H5OSLJsonSpotting
20
+ annotation_path: ./data/h5.json
21
+ source_path: ./data
22
+ dataloader:
23
+ batch_size: 1
24
+ shuffle: false
25
+ num_workers: 0
26
+ pin_memory: false
27
+ inputs:
28
+ tracking:
29
+ modality: player_joints_h5
30
+ representation: raw
31
+ source:
32
+ format: h5
33
+ sampling: {}
34
+ transform: {}
35
+ augmentations: {}
36
+ params: {}
37
+
38
+ MODEL:
39
+ metadata:
40
+ family: RuleBased
41
+ runner:
42
+ type: runner_h5_header_rule
43
+ components:
44
+ rule:
45
+ kind: algorithm
46
+ source:
47
+ provider: opensportslib
48
+ registry: rule_based
49
+ name: h5_header_distance
50
+ params:
51
+ label: header
52
+ head_name: action
53
+ distance_threshold_m: 0.5
54
+ min_confidence: 0.5
55
+ confidence_mode: linear_inverse_distance
56
+ confidence_power: 1.0
57
+ nms_window_ms: 1000
58
+ nms_scope: sample
59
+ ball_tolerance_ms: 60
60
+ chunk_size: 100000
61
+ head_joints: [nose, neck, l_eye, r_eye, l_ear, r_ear]
62
+ required_input_type: player_joints_h5
63
+ ball_path_field: ball_path
64
+ timestamp_field: timestamp_utc
65
+ output_task: action_spotting
66
+ include_diagnostics: true
67
+ position_ms_origin: joint_h5_start
68
+ metadata_start_field: start_utc
69
+ metadata_end_field: end_utc
70
+ ball_coordinate_fields: [x, y, z]
71
+ joint_coordinate_suffixes: [x, y, z]
72
+ identity_fields: [player_id, jersey_number, team_id, is_home]
73
+ invalid_coordinate_values: [-200.0]
74
+ sideline_filter_enabled: true
75
+ pitch_half_width_m: 50.0
76
+ sideline_exclusion_m: 1.0
77
+ sideline_reference: ball_y
78
+ trajectory_filter_enabled: false
79
+ trajectory_change_mode: either_angle_or_speed
80
+ trajectory_pre_window_ms: 200
81
+ trajectory_post_window_ms: 200
82
+ trajectory_min_angle_deg: 25.0
83
+ trajectory_min_speed_delta_ratio: 0.25
84
+ trajectory_min_vector_norm_m: 0.05
85
+ trajectory_use_xy_only: false
86
+ confidence_output_key: confidence_score
87
+ topology: []
88
+
89
+ TRAIN:
90
+ trainer:
91
+ type: trainer_rule_based
92
+ execution:
93
+ enabled: false
@@ -0,0 +1,93 @@
1
+ TASK: localization
2
+ VERSION: 2
3
+
4
+ SYSTEM:
5
+ paths:
6
+ work_dir: ./outputs/header_spotting_distance_angle
7
+ device: cpu
8
+ gpu:
9
+ count: 0
10
+
11
+ DATA:
12
+ common:
13
+ dataset_name: h5_headers
14
+ data_root: ./data
15
+ classes:
16
+ - header
17
+ splits:
18
+ test:
19
+ type: H5OSLJsonSpotting
20
+ annotation_path: ./data/h5.json
21
+ source_path: ./data
22
+ dataloader:
23
+ batch_size: 1
24
+ shuffle: false
25
+ num_workers: 0
26
+ pin_memory: false
27
+ inputs:
28
+ tracking:
29
+ modality: player_joints_h5
30
+ representation: raw
31
+ source:
32
+ format: h5
33
+ sampling: {}
34
+ transform: {}
35
+ augmentations: {}
36
+ params: {}
37
+
38
+ MODEL:
39
+ metadata:
40
+ family: RuleBased
41
+ runner:
42
+ type: runner_h5_header_rule
43
+ components:
44
+ rule:
45
+ kind: algorithm
46
+ source:
47
+ provider: opensportslib
48
+ registry: rule_based
49
+ name: h5_header_distance_angle
50
+ params:
51
+ label: header
52
+ head_name: action
53
+ distance_threshold_m: 0.5
54
+ min_confidence: 0.5
55
+ confidence_mode: linear_inverse_distance
56
+ confidence_power: 1.0
57
+ nms_window_ms: 1000
58
+ nms_scope: sample
59
+ ball_tolerance_ms: 60
60
+ chunk_size: 100000
61
+ head_joints: [nose, neck, l_eye, r_eye, l_ear, r_ear]
62
+ required_input_type: player_joints_h5
63
+ ball_path_field: ball_path
64
+ timestamp_field: timestamp_utc
65
+ output_task: action_spotting
66
+ include_diagnostics: true
67
+ position_ms_origin: joint_h5_start
68
+ metadata_start_field: start_utc
69
+ metadata_end_field: end_utc
70
+ ball_coordinate_fields: [x, y, z]
71
+ joint_coordinate_suffixes: [x, y, z]
72
+ identity_fields: [player_id, jersey_number, team_id, is_home]
73
+ invalid_coordinate_values: [-200.0]
74
+ sideline_filter_enabled: true
75
+ pitch_half_width_m: 50.0
76
+ sideline_exclusion_m: 1.0
77
+ sideline_reference: ball_y
78
+ trajectory_filter_enabled: true
79
+ trajectory_change_mode: angle
80
+ trajectory_pre_window_ms: 200
81
+ trajectory_post_window_ms: 200
82
+ trajectory_min_angle_deg: 25.0
83
+ trajectory_min_speed_delta_ratio: 0.25
84
+ trajectory_min_vector_norm_m: 0.05
85
+ trajectory_use_xy_only: false
86
+ confidence_output_key: confidence_score
87
+ topology: []
88
+
89
+ TRAIN:
90
+ trainer:
91
+ type: trainer_rule_based
92
+ execution:
93
+ enabled: false
@@ -0,0 +1,93 @@
1
+ TASK: localization
2
+ VERSION: 2
3
+
4
+ SYSTEM:
5
+ paths:
6
+ work_dir: ./outputs/header_spotting_distance_speed
7
+ device: cpu
8
+ gpu:
9
+ count: 0
10
+
11
+ DATA:
12
+ common:
13
+ dataset_name: h5_headers
14
+ data_root: ./data
15
+ classes:
16
+ - header
17
+ splits:
18
+ test:
19
+ type: H5OSLJsonSpotting
20
+ annotation_path: ./data/h5.json
21
+ source_path: ./data
22
+ dataloader:
23
+ batch_size: 1
24
+ shuffle: false
25
+ num_workers: 0
26
+ pin_memory: false
27
+ inputs:
28
+ tracking:
29
+ modality: player_joints_h5
30
+ representation: raw
31
+ source:
32
+ format: h5
33
+ sampling: {}
34
+ transform: {}
35
+ augmentations: {}
36
+ params: {}
37
+
38
+ MODEL:
39
+ metadata:
40
+ family: RuleBased
41
+ runner:
42
+ type: runner_h5_header_rule
43
+ components:
44
+ rule:
45
+ kind: algorithm
46
+ source:
47
+ provider: opensportslib
48
+ registry: rule_based
49
+ name: h5_header_distance_speed
50
+ params:
51
+ label: header
52
+ head_name: action
53
+ distance_threshold_m: 0.5
54
+ min_confidence: 0.5
55
+ confidence_mode: linear_inverse_distance
56
+ confidence_power: 1.0
57
+ nms_window_ms: 1000
58
+ nms_scope: sample
59
+ ball_tolerance_ms: 60
60
+ chunk_size: 100000
61
+ head_joints: [nose, neck, l_eye, r_eye, l_ear, r_ear]
62
+ required_input_type: player_joints_h5
63
+ ball_path_field: ball_path
64
+ timestamp_field: timestamp_utc
65
+ output_task: action_spotting
66
+ include_diagnostics: true
67
+ position_ms_origin: joint_h5_start
68
+ metadata_start_field: start_utc
69
+ metadata_end_field: end_utc
70
+ ball_coordinate_fields: [x, y, z]
71
+ joint_coordinate_suffixes: [x, y, z]
72
+ identity_fields: [player_id, jersey_number, team_id, is_home]
73
+ invalid_coordinate_values: [-200.0]
74
+ sideline_filter_enabled: true
75
+ pitch_half_width_m: 50.0
76
+ sideline_exclusion_m: 1.0
77
+ sideline_reference: ball_y
78
+ trajectory_filter_enabled: true
79
+ trajectory_change_mode: speed
80
+ trajectory_pre_window_ms: 200
81
+ trajectory_post_window_ms: 200
82
+ trajectory_min_angle_deg: 25.0
83
+ trajectory_min_speed_delta_ratio: 0.25
84
+ trajectory_min_vector_norm_m: 0.05
85
+ trajectory_use_xy_only: false
86
+ confidence_output_key: confidence_score
87
+ topology: []
88
+
89
+ TRAIN:
90
+ trainer:
91
+ type: trainer_rule_based
92
+ execution:
93
+ enabled: false
@@ -0,0 +1,93 @@
1
+ TASK: localization
2
+ VERSION: 2
3
+
4
+ SYSTEM:
5
+ paths:
6
+ work_dir: ./outputs/header_spotting_distance_speed_angle
7
+ device: cpu
8
+ gpu:
9
+ count: 0
10
+
11
+ DATA:
12
+ common:
13
+ dataset_name: h5_headers
14
+ data_root: ./data
15
+ classes:
16
+ - header
17
+ splits:
18
+ test:
19
+ type: H5OSLJsonSpotting
20
+ annotation_path: ./data/h5.json
21
+ source_path: ./data
22
+ dataloader:
23
+ batch_size: 1
24
+ shuffle: false
25
+ num_workers: 0
26
+ pin_memory: false
27
+ inputs:
28
+ tracking:
29
+ modality: player_joints_h5
30
+ representation: raw
31
+ source:
32
+ format: h5
33
+ sampling: {}
34
+ transform: {}
35
+ augmentations: {}
36
+ params: {}
37
+
38
+ MODEL:
39
+ metadata:
40
+ family: RuleBased
41
+ runner:
42
+ type: runner_h5_header_rule
43
+ components:
44
+ rule:
45
+ kind: algorithm
46
+ source:
47
+ provider: opensportslib
48
+ registry: rule_based
49
+ name: h5_header_distance_speed_angle
50
+ params:
51
+ label: header
52
+ head_name: action
53
+ distance_threshold_m: 0.5
54
+ min_confidence: 0.5
55
+ confidence_mode: linear_inverse_distance
56
+ confidence_power: 1.0
57
+ nms_window_ms: 1000
58
+ nms_scope: sample
59
+ ball_tolerance_ms: 60
60
+ chunk_size: 100000
61
+ head_joints: [nose, neck, l_eye, r_eye, l_ear, r_ear]
62
+ required_input_type: player_joints_h5
63
+ ball_path_field: ball_path
64
+ timestamp_field: timestamp_utc
65
+ output_task: action_spotting
66
+ include_diagnostics: true
67
+ position_ms_origin: joint_h5_start
68
+ metadata_start_field: start_utc
69
+ metadata_end_field: end_utc
70
+ ball_coordinate_fields: [x, y, z]
71
+ joint_coordinate_suffixes: [x, y, z]
72
+ identity_fields: [player_id, jersey_number, team_id, is_home]
73
+ invalid_coordinate_values: [-200.0]
74
+ sideline_filter_enabled: true
75
+ pitch_half_width_m: 50.0
76
+ sideline_exclusion_m: 1.0
77
+ sideline_reference: ball_y
78
+ trajectory_filter_enabled: true
79
+ trajectory_change_mode: both_angle_and_speed
80
+ trajectory_pre_window_ms: 200
81
+ trajectory_post_window_ms: 200
82
+ trajectory_min_angle_deg: 25.0
83
+ trajectory_min_speed_delta_ratio: 0.25
84
+ trajectory_min_vector_norm_m: 0.05
85
+ trajectory_use_xy_only: false
86
+ confidence_output_key: confidence_score
87
+ topology: []
88
+
89
+ TRAIN:
90
+ trainer:
91
+ type: trainer_rule_based
92
+ execution:
93
+ enabled: false
@@ -0,0 +1,99 @@
1
+ TASK: localization
2
+ VERSION: 2
3
+
4
+ SYSTEM:
5
+ paths:
6
+ work_dir: ./outputs/header_spotting
7
+ device: cpu
8
+ gpu:
9
+ count: 0
10
+
11
+ DATA:
12
+ common:
13
+ dataset_name: h5_headers
14
+ data_root: ./data
15
+ classes:
16
+ - header
17
+ splits:
18
+ test:
19
+ type: H5OSLJsonSpotting
20
+ annotation_path: ./data/h5.json
21
+ source_path: ./data
22
+ dataloader:
23
+ batch_size: 1
24
+ shuffle: false
25
+ num_workers: 0
26
+ pin_memory: false
27
+ inputs:
28
+ tracking:
29
+ modality: player_joints_h5
30
+ representation: raw
31
+ source:
32
+ format: h5
33
+ sampling: {}
34
+ transform: {}
35
+ augmentations: {}
36
+ params: {}
37
+
38
+ MODEL:
39
+ metadata:
40
+ family: RuleBased
41
+ runner:
42
+ type: runner_h5_header_rule
43
+ components:
44
+ rule:
45
+ kind: algorithm
46
+ source:
47
+ provider: opensportslib
48
+ registry: rule_based
49
+ # Available models:
50
+ # - h5_header_distance
51
+ # - h5_header_distance_speed
52
+ # - h5_header_distance_angle
53
+ # - h5_header_distance_speed_angle
54
+ name: h5_header_distance_speed_angle
55
+ params:
56
+ label: header
57
+ head_name: action
58
+ distance_threshold_m: 0.20
59
+ min_confidence: 0.5
60
+ confidence_mode: linear_inverse_distance
61
+ confidence_power: 1.0
62
+ nms_window_ms: 1000
63
+ nms_scope: sample
64
+ ball_tolerance_ms: 60
65
+ chunk_size: 100000
66
+ head_joints: [nose, neck, l_eye, r_eye, l_ear, r_ear]
67
+ required_input_type: player_joints_h5
68
+ ball_path_field: ball_path
69
+ timestamp_field: timestamp_utc
70
+ output_task: action_spotting
71
+ include_diagnostics: true
72
+ created_by: h5_header_distance_speed_angle_rule
73
+ position_ms_origin: joint_h5_start
74
+ metadata_start_field: start_utc
75
+ metadata_end_field: end_utc
76
+ ball_coordinate_fields: [x, y, z]
77
+ joint_coordinate_suffixes: [x, y, z]
78
+ identity_fields: [player_id, jersey_number, team_id, is_home]
79
+ invalid_coordinate_values: [-200.0]
80
+ sideline_filter_enabled: true
81
+ pitch_half_width_m: 50.0
82
+ sideline_exclusion_m: 1.0
83
+ sideline_reference: ball_y
84
+ trajectory_filter_enabled: true
85
+ trajectory_change_mode: both_angle_and_speed
86
+ trajectory_pre_window_ms: 200
87
+ trajectory_post_window_ms: 200
88
+ trajectory_min_angle_deg: 25.0
89
+ trajectory_min_speed_delta_ratio: 0.25
90
+ trajectory_min_vector_norm_m: 0.05
91
+ trajectory_use_xy_only: false
92
+ confidence_output_key: confidence_score
93
+ topology: []
94
+
95
+ TRAIN:
96
+ trainer:
97
+ type: trainer_rule_based
98
+ execution:
99
+ enabled: false
@@ -6,10 +6,17 @@ import os
6
6
  from types import SimpleNamespace
7
7
  from typing import Any
8
8
 
9
+ try:
10
+ from omegaconf import OmegaConf
11
+ except Exception: # pragma: no cover - omegaconf is a runtime dependency
12
+ OmegaConf = None
13
+
9
14
 
10
15
  def _to_plain(obj: Any) -> Any:
11
16
  if obj is None:
12
17
  return None
18
+ if OmegaConf is not None and OmegaConf.is_config(obj):
19
+ return OmegaConf.to_container(obj, resolve=True)
13
20
  if isinstance(obj, dict):
14
21
  return {k: _to_plain(v) for k, v in obj.items()}
15
22
  if isinstance(obj, list):
@@ -24,6 +31,9 @@ def _to_plain(obj: Any) -> Any:
24
31
  def _as_dict(obj: Any) -> dict[str, Any]:
25
32
  if obj is None:
26
33
  return {}
34
+ if OmegaConf is not None and OmegaConf.is_config(obj):
35
+ plain = OmegaConf.to_container(obj, resolve=True)
36
+ return plain if isinstance(plain, dict) else {}
27
37
  if isinstance(obj, dict):
28
38
  return {k: _to_plain(v) for k, v in obj.items()}
29
39
  if hasattr(obj, "__dict__"):
@@ -69,6 +69,16 @@ def _is_frames_npy_modality(config, modality=None):
69
69
  representation = str(input_cfg.get("representation", "")).lower()
70
70
  return source_format == "npy" or representation == "frames"
71
71
 
72
+
73
+ def _is_tracking_graph_modality(modality):
74
+ return str(modality).lower() in {
75
+ "tracking",
76
+ "tracking_parquet",
77
+ "tracking_h5",
78
+ "player_centroids_h5",
79
+ "player_joints_h5",
80
+ }
81
+
72
82
  # -------------------------------------------------------------------
73
83
  # base classification trainer
74
84
  # -------------------------------------------------------------------
@@ -815,7 +825,7 @@ class Trainer_Classification:
815
825
 
816
826
  is_ddp = world_size > 1
817
827
  modality = get_data_modality(self.config)
818
- is_tracking_modality = modality in {"tracking", "tracking_parquet"}
828
+ is_tracking_modality = _is_tracking_graph_modality(modality)
819
829
  is_frames_modality = _is_frames_npy_modality(self.config, modality)
820
830
  seed = get_system_seed(self.config)
821
831
 
@@ -1128,7 +1138,7 @@ class Trainer_Classification:
1128
1138
  test_sampler = None
1129
1139
 
1130
1140
  modality = get_data_modality(self.config)
1131
- is_tracking_modality = modality in {"tracking", "tracking_parquet"}
1141
+ is_tracking_modality = _is_tracking_graph_modality(modality)
1132
1142
  is_frames_modality = _is_frames_npy_modality(self.config, modality)
1133
1143
  collate_fn = tracking_collate_fn if is_tracking_modality else None
1134
1144
  test_dataloader_cfg = get_split_dataloader_cfg(self.config, "test")
@@ -510,6 +510,8 @@ def build_inferer(cfg, model, default_args=None):
510
510
  return Inferer(cfg=cfg, model=model, infer_Spotting="infer_SN")
511
511
  if runner_type == "runner_e2e":
512
512
  return Inferer(cfg=cfg, model=model, infer_Spotting="infer_E2E")
513
+ if runner_type == "runner_h5_header_rule":
514
+ return Inferer(cfg=cfg, model=model, infer_Spotting="infer_H5HeaderRule")
513
515
  raise ValueError(f"Unsupported localization runner type: {runner_type}")
514
516
 
515
517
  class Inferer:
@@ -542,7 +544,9 @@ class Inferer:
542
544
  return self.infer_SN(cfg, self.model, data, dataloader)
543
545
  elif self.infer_Spotting=="infer_E2E":
544
546
  return self.infer_E2E(cfg, self.model, data, dataloader)
545
-
547
+ elif self.infer_Spotting=="infer_H5HeaderRule":
548
+ return self.infer_H5HeaderRule(cfg, self.model, data, dataloader)
549
+ raise ValueError(f"Unsupported infer_Spotting method: {self.infer_Spotting}")
546
550
 
547
551
  def infer_common(self, cfg, model, data, dataloader=None):
548
552
  """Infer actions from data using a given model.
@@ -644,6 +648,11 @@ class Inferer:
644
648
 
645
649
  return predictions
646
650
 
651
+ def infer_H5HeaderRule(self, cfg, model, data, dataloader=None):
652
+ """Run rule-based H5 header spotting without Lightning or weights."""
653
+ del cfg, dataloader
654
+ return model.predict(data)
655
+
647
656
 
648
657
  def build_evaluator(cfg, default_args=None):
649
658
  """Build a evaluator from config dict.
@@ -66,7 +66,8 @@ def load_annotations(
66
66
  # Group by action id (without view suffix)
67
67
  grouped = defaultdict(lambda: {
68
68
  "video_paths": [],
69
- "label": None
69
+ "label": None,
70
+ "inputs": [],
70
71
  })
71
72
 
72
73
  for item in data["data"]:
@@ -101,9 +102,14 @@ def load_annotations(
101
102
  continue
102
103
 
103
104
  grouped[group_id]["video_paths"].extend(clips)
105
+ grouped[group_id]["inputs"].extend(
106
+ dict(inp) for inp in item.get("inputs", [])
107
+ if inp.get("type") == input_type and "path" in inp
108
+ )
104
109
  if label_idx is not None:
105
110
  grouped[group_id]["label"] = label_idx
106
111
  grouped[group_id]["id"] = group_id
112
+ grouped[group_id].setdefault("metadata", dict(item.get("metadata", {}) or {}))
107
113
 
108
114
  return list(grouped.values()), label_map
109
115
 
@@ -587,5 +593,7 @@ def whether_infer_split(cfg):
587
593
  return True
588
594
  else:
589
595
  return False
596
+ elif split_type == "H5OSLJsonSpotting":
597
+ return bool(annotation_path and annotation_path.endswith(".json"))
590
598
  else:
591
599
  raise ValueError(f"Unknown dataset type {split_type}")