jabs-behavior-classifier 0.46.2__tar.gz → 0.46.3__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 (223) hide show
  1. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/PKG-INFO +11 -12
  2. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/README.md +7 -7
  3. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/pyproject.toml +4 -6
  4. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/feature_extraction/feature_base_class.py +26 -20
  5. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/feature_extraction/landmark_features/corner.py +12 -1
  6. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/feature_extraction/window_operations/signal_stats.py +13 -5
  7. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/feature_extraction/window_operations/window_stats.py +52 -23
  8. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/pose_estimation/__init__.py +17 -5
  9. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/pose_estimation/pose_est_v4.py +19 -4
  10. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/project/__init__.py +10 -0
  11. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/project/export_training.py +13 -3
  12. jabs_behavior_classifier-0.46.3/src/jabs/project/feature_cache_status.py +398 -0
  13. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/project/project.py +187 -45
  14. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/project/project_pruning.py +1 -1
  15. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/project/read_training.py +33 -2
  16. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/project/timeline_annotations.py +39 -34
  17. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/project/video_labels.py +0 -21
  18. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/project/video_manager.py +20 -1
  19. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/resources/docs/user_guide/cli-tools.md +78 -24
  20. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/resources/docs/user_guide/gui.md +7 -1
  21. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/scripts/cli/cli.py +2 -0
  22. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/scripts/cli/compute_features.py +1 -1
  23. jabs_behavior_classifier-0.46.3/src/jabs/scripts/cli/merge_projects.py +77 -0
  24. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/scripts/cli/postprocessing.py +46 -1
  25. jabs_behavior_classifier-0.46.3/src/jabs/scripts/generate_features.py +129 -0
  26. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/ui/dialogs/user_guide_dialog.py +2 -1
  27. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/ui/dialogs/video_info_dialog.py +100 -9
  28. jabs_behavior_classifier-0.46.3/src/jabs/ui/feature_cache_scan_thread.py +59 -0
  29. jabs_behavior_classifier-0.46.3/src/jabs/ui/feature_cache_text.py +66 -0
  30. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/ui/main_control_widget/main_control_widget.py +9 -0
  31. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/ui/main_window/central_widget.py +160 -2
  32. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/ui/main_window/main_window.py +169 -2
  33. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/ui/main_window/menu_builder.py +6 -3
  34. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/ui/main_window/menu_handlers.py +3 -0
  35. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/ui/main_window/video_list_widget.py +39 -3
  36. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/utils/__init__.py +6 -2
  37. jabs_behavior_classifier-0.46.2/src/jabs/scripts/generate_features.py +0 -119
  38. jabs_behavior_classifier-0.46.2/src/jabs/scripts/merge_projects.py +0 -87
  39. jabs_behavior_classifier-0.46.2/src/jabs/utils/update_checker.py +0 -53
  40. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/LICENSE +0 -0
  41. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/behavior_search/__init__.py +0 -0
  42. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/behavior_search/behavior_search_util.py +0 -0
  43. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/classifier/__init__.py +0 -0
  44. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/classifier/base.py +0 -0
  45. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/classifier/classifier.py +0 -0
  46. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/classifier/classifier_utils.py +0 -0
  47. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/classifier/cross_validation.py +0 -0
  48. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/classifier/factories.py +0 -0
  49. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/classifier/mlflow_logging.py +0 -0
  50. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/classifier/multi_class_classifier.py +0 -0
  51. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/classifier/protocols.py +0 -0
  52. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/classifier/training_report.py +0 -0
  53. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/feature_extraction/__init__.py +0 -0
  54. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/feature_extraction/angle_index.py +0 -0
  55. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/feature_extraction/base_features/__init__.py +0 -0
  56. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/feature_extraction/base_features/angles.py +0 -0
  57. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/feature_extraction/base_features/angular_velocity.py +0 -0
  58. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/feature_extraction/base_features/base_group.py +0 -0
  59. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/feature_extraction/base_features/centroid_velocity.py +0 -0
  60. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/feature_extraction/base_features/pairwise_distances.py +0 -0
  61. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/feature_extraction/base_features/point_speeds.py +0 -0
  62. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/feature_extraction/base_features/point_velocities.py +0 -0
  63. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/feature_extraction/feature_group_base_class.py +0 -0
  64. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/feature_extraction/features.py +0 -0
  65. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/feature_extraction/landmark_features/__init__.py +0 -0
  66. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/feature_extraction/landmark_features/food_hopper.py +0 -0
  67. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/feature_extraction/landmark_features/landmark_group.py +0 -0
  68. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/feature_extraction/landmark_features/lixit.py +0 -0
  69. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/feature_extraction/segmentation_features/__init__.py +0 -0
  70. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/feature_extraction/segmentation_features/hu_moments.py +0 -0
  71. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/feature_extraction/segmentation_features/moment_cache.py +0 -0
  72. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/feature_extraction/segmentation_features/moments.py +0 -0
  73. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/feature_extraction/segmentation_features/segment_group.py +0 -0
  74. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/feature_extraction/segmentation_features/shape_descriptors.py +0 -0
  75. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/feature_extraction/social_features/__init__.py +0 -0
  76. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/feature_extraction/social_features/closest_distances.py +0 -0
  77. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/feature_extraction/social_features/closest_fov_angles.py +0 -0
  78. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/feature_extraction/social_features/closest_fov_distances.py +0 -0
  79. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/feature_extraction/social_features/pairwise_social_distances.py +0 -0
  80. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/feature_extraction/social_features/social_distance.py +0 -0
  81. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/feature_extraction/social_features/social_group.py +0 -0
  82. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/feature_extraction/window_operations/__init__.py +0 -0
  83. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/pose_estimation/pose_est_v2.py +0 -0
  84. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/pose_estimation/pose_est_v3.py +0 -0
  85. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/pose_estimation/pose_est_v5.py +0 -0
  86. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/pose_estimation/pose_est_v6.py +0 -0
  87. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/pose_estimation/pose_est_v7.py +0 -0
  88. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/pose_estimation/pose_est_v8.py +0 -0
  89. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/project/feature_manager.py +0 -0
  90. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/project/parallel_workers.py +0 -0
  91. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/project/pose_attribute_cache.py +0 -0
  92. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/project/prediction_manager.py +0 -0
  93. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/project/project_merge.py +0 -0
  94. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/project/project_paths.py +0 -0
  95. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/project/project_utils.py +0 -0
  96. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/project/session_tracker.py +0 -0
  97. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/project/settings_manager.py +0 -0
  98. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/project/track_labels.py +0 -0
  99. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/resources/__init__.py +0 -0
  100. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/resources/docs/LICENSE +0 -0
  101. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/resources/docs/user_guide/behavior-search.md +0 -0
  102. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/resources/docs/user_guide/classifier-types.md +0 -0
  103. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/resources/docs/user_guide/features.md +0 -0
  104. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/resources/docs/user_guide/file-formats.md +0 -0
  105. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/resources/docs/user_guide/imgs/StackedImgs.svg +0 -0
  106. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/resources/docs/user_guide/imgs/bbox-identity-overlay.png +0 -0
  107. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/resources/docs/user_guide/imgs/centroid-identity-overlay.png +0 -0
  108. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/resources/docs/user_guide/imgs/classifier_controls.png +0 -0
  109. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/resources/docs/user_guide/imgs/floating-identity-overlay.png +0 -0
  110. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/resources/docs/user_guide/imgs/identity_gaps.png +0 -0
  111. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/resources/docs/user_guide/imgs/identity_gaps_with_label.png +0 -0
  112. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/resources/docs/user_guide/imgs/keypoint_legend.png +0 -0
  113. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/resources/docs/user_guide/imgs/label_viz.png +0 -0
  114. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/resources/docs/user_guide/imgs/main_window.png +0 -0
  115. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/resources/docs/user_guide/imgs/minimalist-identity-overlay.png +0 -0
  116. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/resources/docs/user_guide/imgs/pose_overlay.png +0 -0
  117. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/resources/docs/user_guide/imgs/search-dialog.png +0 -0
  118. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/resources/docs/user_guide/imgs/selecting_frames.png +0 -0
  119. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/resources/docs/user_guide/imgs/stacked_timeline.png +0 -0
  120. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/resources/docs/user_guide/imgs/timeline_menu.png +0 -0
  121. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/resources/docs/user_guide/imgs/track_overlay.png +0 -0
  122. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/resources/docs/user_guide/imgs/video-context-menu.png +0 -0
  123. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/resources/docs/user_guide/imgs/video-control-overlay.png +0 -0
  124. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/resources/docs/user_guide/imgs/video-control-overlay.svg +0 -0
  125. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/resources/docs/user_guide/keyboard-shortcuts.md +0 -0
  126. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/resources/docs/user_guide/labeling.md +0 -0
  127. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/resources/docs/user_guide/multi-class.md +0 -0
  128. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/resources/docs/user_guide/nwb-export.md +0 -0
  129. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/resources/docs/user_guide/overview.md +0 -0
  130. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/resources/docs/user_guide/postprocessing.md +0 -0
  131. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/resources/docs/user_guide/project-setup.md +0 -0
  132. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/resources/eartag_images/s2.svg +0 -0
  133. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/resources/eartag_images/s3.svg +0 -0
  134. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/resources/eartag_images/s4.svg +0 -0
  135. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/resources/fail_whale.png +0 -0
  136. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/resources/icon.png +0 -0
  137. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/schema/__init__.py +0 -0
  138. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/schema/metadata.py +0 -0
  139. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/scripts/__init__.py +0 -0
  140. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/scripts/classify.py +0 -0
  141. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/scripts/cli/__init__.py +0 -0
  142. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/scripts/cli/convert_parquet.py +0 -0
  143. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/scripts/cli/convert_to_nwb.py +0 -0
  144. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/scripts/cli/cross_validation.py +0 -0
  145. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/scripts/cli/sample_frames.py +0 -0
  146. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/scripts/cli/sample_pose_intervals.py +0 -0
  147. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/scripts/cli/update_labels.py +0 -0
  148. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/scripts/cli/update_pose.py +0 -0
  149. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/scripts/gui_entrypoint.py +0 -0
  150. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/scripts/initialize_project.py +0 -0
  151. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/ui/__init__.py +0 -0
  152. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/ui/behavior_timeline/__init__.py +0 -0
  153. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/ui/behavior_timeline/behavior_timeline_widget.py +0 -0
  154. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/ui/behavior_timeline/frame_ruler_widget.py +0 -0
  155. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/ui/behavior_timeline/track_widgets/__init__.py +0 -0
  156. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/ui/behavior_timeline/track_widgets/behavior_probability_detail_bar.py +0 -0
  157. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/ui/behavior_timeline/track_widgets/class_prediction_detail_bar.py +0 -0
  158. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/ui/behavior_timeline/track_widgets/label_detail_bar.py +0 -0
  159. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/ui/behavior_timeline/track_widgets/label_overview_bar.py +0 -0
  160. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/ui/behavior_timeline/track_widgets/label_track_widget.py +0 -0
  161. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/ui/behavior_timeline/track_widgets/per_class_prediction_track_widget.py +0 -0
  162. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/ui/behavior_timeline/track_widgets/prediction_track_widget.py +0 -0
  163. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/ui/behavior_timeline/track_widgets/timeline_util.py +0 -0
  164. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/ui/classification_thread.py +0 -0
  165. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/ui/classify_strategy.py +0 -0
  166. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/ui/colors.py +0 -0
  167. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/ui/constants.py +0 -0
  168. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/ui/dialogs/__init__.py +0 -0
  169. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/ui/dialogs/about_dialog.py +0 -0
  170. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/ui/dialogs/annotation_edit_dialog.py +0 -0
  171. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/ui/dialogs/annotation_info_dialog.py +0 -0
  172. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/ui/dialogs/archive_behavior_dialog.py +0 -0
  173. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/ui/dialogs/behavior_search_dialog.py +0 -0
  174. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/ui/dialogs/license_dialog.py +0 -0
  175. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/ui/dialogs/message_dialog.py +0 -0
  176. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/ui/dialogs/progress_dialog.py +0 -0
  177. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/ui/dialogs/project_pruning_dialog.py +0 -0
  178. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/ui/dialogs/training_report.py +0 -0
  179. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/ui/dialogs/update_check_dialog.py +0 -0
  180. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/ui/ear_tag_icons.py +0 -0
  181. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/ui/exceptions.py +0 -0
  182. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/ui/export_training_thread.py +0 -0
  183. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/ui/main_control_widget/__init__.py +0 -0
  184. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/ui/main_control_widget/k_fold_slider_widget.py +0 -0
  185. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/ui/main_control_widget/label_count_widget.py +0 -0
  186. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/ui/main_window/README.md +0 -0
  187. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/ui/main_window/__init__.py +0 -0
  188. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/ui/main_window/central_widget_mode.py +0 -0
  189. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/ui/main_window/constants.py +0 -0
  190. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/ui/player_widget/__init__.py +0 -0
  191. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/ui/player_widget/frame_with_overlays.py +0 -0
  192. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/ui/player_widget/overlays/__init__.py +0 -0
  193. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/ui/player_widget/overlays/annotation_overlay.py +0 -0
  194. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/ui/player_widget/overlays/bounding_box.py +0 -0
  195. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/ui/player_widget/overlays/control_overlay.py +0 -0
  196. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/ui/player_widget/overlays/floating_id_overlay.py +0 -0
  197. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/ui/player_widget/overlays/label_overlay.py +0 -0
  198. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/ui/player_widget/overlays/overlay.py +0 -0
  199. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/ui/player_widget/overlays/pose_overlay.py +0 -0
  200. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/ui/player_widget/player_thread.py +0 -0
  201. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/ui/player_widget/player_widget.py +0 -0
  202. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/ui/player_widget/pose_drawing.py +0 -0
  203. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/ui/project_loader_thread.py +0 -0
  204. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/ui/search_bar_widget.py +0 -0
  205. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/ui/settings_dialog/README.md +0 -0
  206. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/ui/settings_dialog/__init__.py +0 -0
  207. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/ui/settings_dialog/cache_format_settings_group.py +0 -0
  208. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/ui/settings_dialog/classifier_mode_settings_group.py +0 -0
  209. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/ui/settings_dialog/collapsible_section.py +0 -0
  210. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/ui/settings_dialog/cross_validation_settings_group.py +0 -0
  211. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/ui/settings_dialog/postprocessing_group.py +0 -0
  212. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/ui/settings_dialog/postprocessing_settings/__init__.py +0 -0
  213. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/ui/settings_dialog/session_tracking_group.py +0 -0
  214. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/ui/settings_dialog/settings_dialog.py +0 -0
  215. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/ui/settings_dialog/settings_group.py +0 -0
  216. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/ui/training_strategy.py +0 -0
  217. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/ui/training_thread.py +0 -0
  218. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/ui/util.py +0 -0
  219. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/version/__init__.py +0 -0
  220. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/video_reader/__init__.py +0 -0
  221. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/video_reader/frame_annotation.py +0 -0
  222. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/video_reader/utilities.py +0 -0
  223. {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/video_reader/video_reader.py +0 -0
@@ -1,13 +1,13 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: jabs-behavior-classifier
3
- Version: 0.46.2
3
+ Version: 0.46.3
4
4
  Summary:
5
5
  Author: Glen Beane, Brian Geuther, Keith Sheppard, Alexander Berger-Liedtka
6
6
  License-Expression: MIT
7
7
  License-File: LICENSE
8
- Requires-Dist: jabs-behavior==0.46.2
9
- Requires-Dist: jabs-core==0.46.2
10
- Requires-Dist: jabs-io==0.46.2
8
+ Requires-Dist: jabs-behavior==0.46.3
9
+ Requires-Dist: jabs-core==0.46.3
10
+ Requires-Dist: jabs-io==0.46.3
11
11
  Requires-Dist: h5py>=3.10.0,<4.0.0
12
12
  Requires-Dist: markdown2>=2.5.1,<3.0.0
13
13
  Requires-Dist: numpy>=2.0.0,<3.0.0
@@ -22,7 +22,6 @@ Requires-Dist: toml>=0.10.2,<0.11.0
22
22
  Requires-Dist: xgboost>=2.0.0,<3.0.0
23
23
  Requires-Dist: pyarrow>=23.0.1,<24.0.0
24
24
  Requires-Dist: rich>=14.0.0,<15.0.0
25
- Requires-Dist: rich-argparse>=1.7.1,<2.0.0
26
25
  Requires-Dist: intervaltree>=3.1.0,<4.0.0
27
26
  Requires-Dist: qt-material-icons>=0.2.0,<0.3.0
28
27
  Requires-Dist: jsonschema>=4.25.1,<5.0.0
@@ -51,14 +50,14 @@ Description-Content-Type: text/markdown
51
50
 
52
51
  [![Python 3.10-3.14](https://img.shields.io/badge/python-3.10--3.14-blue.svg)](https://www.python.org/downloads/)
53
52
  [![PyPI version](https://img.shields.io/pypi/v/jabs-behavior-classifier.svg)](https://pypi.org/project/jabs-behavior-classifier/)
54
- [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://github.com/KumarLabJax/JABS-behavior-classifier/blob/v0.46.2/LICENSE)
53
+ [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://github.com/KumarLabJax/JABS-behavior-classifier/blob/v0.46.3/LICENSE)
55
54
  [![DOI](https://img.shields.io/badge/DOI-10.7554%2FeLife.107259.2-green.svg)](https://doi.org/10.7554/eLife.107259.2)
56
55
 
57
- [Documentation](https://jabs-tutorial.readthedocs.io/) · [User Guide](https://github.com/KumarLabJax/JABS-behavior-classifier/blob/v0.46.2/docs/user-guide/overview.md) · [Sample Data](https://doi.org/10.5281/zenodo.16697331) · [Contact Us](mailto:jabs@jax.org)
56
+ [Documentation](https://jabs-tutorial.readthedocs.io/) · [User Guide](https://github.com/KumarLabJax/JABS-behavior-classifier/blob/v0.46.3/docs/user-guide/overview.md) · [Sample Data](https://doi.org/10.5281/zenodo.16697331) · [Contact Us](mailto:jabs@jax.org)
58
57
 
59
58
  ---
60
59
 
61
- ![JABS Screenshot](https://raw.githubusercontent.com/KumarLabJax/JABS-behavior-classifier/v0.46.2/docs/assets/images/jabs_screenshot.png)
60
+ ![JABS Screenshot](https://raw.githubusercontent.com/KumarLabJax/JABS-behavior-classifier/v0.46.3/docs/assets/images/jabs_screenshot.png)
62
61
 
63
62
  </div>
64
63
 
@@ -188,7 +187,7 @@ JABS requires pose files generated from the Kumar Lab's mouse pose estimation ne
188
187
 
189
188
  We provide Singularity/Apptainer definition files and SLURM batch scripts for running
190
189
  JABS on Linux compute clusters. See
191
- [vm/README.md](https://github.com/KumarLabJax/JABS-behavior-classifier/blob/v0.46.2/vm/README.md)
190
+ [vm/README.md](https://github.com/KumarLabJax/JABS-behavior-classifier/blob/v0.46.3/vm/README.md)
192
191
  for build instructions and usage details.
193
192
 
194
193
  ## Project Portability
@@ -224,14 +223,14 @@ JABS uses four version numbers to track compatibility:
224
223
  ## Documentation
225
224
 
226
225
  - **[ReadTheDocs Tutorial](https://jabs-tutorial.readthedocs.io/)** — Complete user guide and tutorials
227
- - **[User Guide](https://github.com/KumarLabJax/JABS-behavior-classifier/blob/v0.46.2/docs/user-guide/overview.md)** — Markdown documentation
226
+ - **[User Guide](https://github.com/KumarLabJax/JABS-behavior-classifier/blob/v0.46.3/docs/user-guide/overview.md)** — Markdown documentation
228
227
  - **[Sample Data](https://doi.org/10.5281/zenodo.16697331)** — Test datasets for demonstration
229
228
 
230
229
  ## Contributing
231
230
 
232
231
  Interested in contributing? Check out our:
233
- - [Contributing Guide](https://github.com/KumarLabJax/JABS-behavior-classifier/blob/v0.46.2/CONTRIBUTING.md)
234
- - [Development Guide](https://github.com/KumarLabJax/JABS-behavior-classifier/blob/v0.46.2/docs/development/development.md)
232
+ - [Contributing Guide](https://github.com/KumarLabJax/JABS-behavior-classifier/blob/v0.46.3/CONTRIBUTING.md)
233
+ - [Development Guide](https://github.com/KumarLabJax/JABS-behavior-classifier/blob/v0.46.3/docs/development/development.md)
235
234
 
236
235
  ## Citation
237
236
 
@@ -8,14 +8,14 @@
8
8
 
9
9
  [![Python 3.10-3.14](https://img.shields.io/badge/python-3.10--3.14-blue.svg)](https://www.python.org/downloads/)
10
10
  [![PyPI version](https://img.shields.io/pypi/v/jabs-behavior-classifier.svg)](https://pypi.org/project/jabs-behavior-classifier/)
11
- [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://github.com/KumarLabJax/JABS-behavior-classifier/blob/v0.46.2/LICENSE)
11
+ [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://github.com/KumarLabJax/JABS-behavior-classifier/blob/v0.46.3/LICENSE)
12
12
  [![DOI](https://img.shields.io/badge/DOI-10.7554%2FeLife.107259.2-green.svg)](https://doi.org/10.7554/eLife.107259.2)
13
13
 
14
- [Documentation](https://jabs-tutorial.readthedocs.io/) · [User Guide](https://github.com/KumarLabJax/JABS-behavior-classifier/blob/v0.46.2/docs/user-guide/overview.md) · [Sample Data](https://doi.org/10.5281/zenodo.16697331) · [Contact Us](mailto:jabs@jax.org)
14
+ [Documentation](https://jabs-tutorial.readthedocs.io/) · [User Guide](https://github.com/KumarLabJax/JABS-behavior-classifier/blob/v0.46.3/docs/user-guide/overview.md) · [Sample Data](https://doi.org/10.5281/zenodo.16697331) · [Contact Us](mailto:jabs@jax.org)
15
15
 
16
16
  ---
17
17
 
18
- ![JABS Screenshot](https://raw.githubusercontent.com/KumarLabJax/JABS-behavior-classifier/v0.46.2/docs/assets/images/jabs_screenshot.png)
18
+ ![JABS Screenshot](https://raw.githubusercontent.com/KumarLabJax/JABS-behavior-classifier/v0.46.3/docs/assets/images/jabs_screenshot.png)
19
19
 
20
20
  </div>
21
21
 
@@ -145,7 +145,7 @@ JABS requires pose files generated from the Kumar Lab's mouse pose estimation ne
145
145
 
146
146
  We provide Singularity/Apptainer definition files and SLURM batch scripts for running
147
147
  JABS on Linux compute clusters. See
148
- [vm/README.md](https://github.com/KumarLabJax/JABS-behavior-classifier/blob/v0.46.2/vm/README.md)
148
+ [vm/README.md](https://github.com/KumarLabJax/JABS-behavior-classifier/blob/v0.46.3/vm/README.md)
149
149
  for build instructions and usage details.
150
150
 
151
151
  ## Project Portability
@@ -181,14 +181,14 @@ JABS uses four version numbers to track compatibility:
181
181
  ## Documentation
182
182
 
183
183
  - **[ReadTheDocs Tutorial](https://jabs-tutorial.readthedocs.io/)** — Complete user guide and tutorials
184
- - **[User Guide](https://github.com/KumarLabJax/JABS-behavior-classifier/blob/v0.46.2/docs/user-guide/overview.md)** — Markdown documentation
184
+ - **[User Guide](https://github.com/KumarLabJax/JABS-behavior-classifier/blob/v0.46.3/docs/user-guide/overview.md)** — Markdown documentation
185
185
  - **[Sample Data](https://doi.org/10.5281/zenodo.16697331)** — Test datasets for demonstration
186
186
 
187
187
  ## Contributing
188
188
 
189
189
  Interested in contributing? Check out our:
190
- - [Contributing Guide](https://github.com/KumarLabJax/JABS-behavior-classifier/blob/v0.46.2/CONTRIBUTING.md)
191
- - [Development Guide](https://github.com/KumarLabJax/JABS-behavior-classifier/blob/v0.46.2/docs/development/development.md)
190
+ - [Contributing Guide](https://github.com/KumarLabJax/JABS-behavior-classifier/blob/v0.46.3/CONTRIBUTING.md)
191
+ - [Development Guide](https://github.com/KumarLabJax/JABS-behavior-classifier/blob/v0.46.3/docs/development/development.md)
192
192
 
193
193
  ## Citation
194
194
 
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "jabs-behavior-classifier"
3
- version = "0.46.2"
3
+ version = "0.46.3"
4
4
  description = ""
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.10,<3.15"
@@ -15,9 +15,9 @@ authors = [
15
15
  ]
16
16
 
17
17
  dependencies = [
18
- "jabs-behavior==0.46.2",
19
- "jabs-core==0.46.2",
20
- "jabs-io==0.46.2",
18
+ "jabs-behavior==0.46.3",
19
+ "jabs-core==0.46.3",
20
+ "jabs-io==0.46.3",
21
21
  "h5py>=3.10.0,<4.0.0",
22
22
  "markdown2>=2.5.1,<3.0.0",
23
23
  "numpy>=2.0.0,<3.0.0",
@@ -32,7 +32,6 @@ dependencies = [
32
32
  "xgboost>=2.0.0,<3.0.0",
33
33
  "pyarrow>=23.0.1,<24.0.0",
34
34
  "rich>=14.0.0,<15.0.0",
35
- "rich-argparse>=1.7.1,<2.0.0",
36
35
  "intervaltree>=3.1.0,<4.0.0",
37
36
  "qt-material-icons>=0.2.0,<0.3.0",
38
37
  "jsonschema>=4.25.1,<5.0.0",
@@ -87,7 +86,6 @@ jabs = "jabs.scripts.gui_entrypoint:main"
87
86
  "jabs-classify" = "jabs.scripts.classify:main"
88
87
  "jabs-init" = "jabs.scripts.initialize_project:main"
89
88
  "jabs-features" = "jabs.scripts.generate_features:main"
90
- "jabs-project-merge" = "jabs.scripts.merge_projects:main"
91
89
  "jabs-cli" = "jabs.scripts.cli:main"
92
90
 
93
91
  [tool.uv.workspace]
@@ -197,7 +197,7 @@ class Feature(abc.ABC):
197
197
  non_circular = per_frame_features
198
198
 
199
199
  # standard method for computing window features on non-circular values
200
- non_circular_features = self._window_standard(identity, window_size, non_circular)
200
+ non_circular_features = self._window_standard(window_size, non_circular)
201
201
 
202
202
  # non_circular_features and circular_features are both dicts of dicts, but they may have overlapping *top level* keys.
203
203
  merged = dict(non_circular_features) # start with dict1's keys/values
@@ -209,30 +209,45 @@ class Feature(abc.ABC):
209
209
 
210
210
  return merged
211
211
 
212
- def _window_standard(self, identity: int, window_size: int, per_frame_values: dict) -> dict:
212
+ def _window_standard(self, window_size: int, per_frame_values: dict) -> dict:
213
213
  """standard method for computing standard window feature values
214
214
 
215
+ This path does not take an identity mask: per-frame values are nan for frames
216
+ where the identity is not present, and the operations in
217
+ `window_operations.window_stats` already ignore nan values. Frames are only
218
+ masked explicitly on the circular path, which builds each window itself
219
+ (see `_compute_window_features_circular`).
220
+
215
221
  NOTE: some features may need to override this (for example, those with
216
222
  circular values such as angles)
223
+
224
+ Args:
225
+ window_size: number of frames (in each direction) to include in the
226
+ window. The actual number of frames is 2 * window_size + 1
227
+ per_frame_values: dict of per-frame values for this identity
228
+
229
+ Returns:
230
+ dict of window and signal processing feature values
217
231
  """
218
232
  values = {}
219
233
  for op in self._window_operations:
220
234
  values[op] = self._compute_window_feature(
221
235
  per_frame_values,
222
- self._poses.identity_mask(identity),
223
236
  window_size,
224
237
  self._window_operations[op],
225
238
  )
226
239
  # Also include signal features
227
- signal_features = self._window_signal(identity, window_size, per_frame_values)
240
+ signal_features = self._window_signal(window_size, per_frame_values)
228
241
  values.update(signal_features)
229
242
  return values
230
243
 
231
- def _window_signal(self, identity: int, window_size: int, per_frame_values: dict) -> dict:
244
+ def _window_signal(self, window_size: int, per_frame_values: dict) -> dict:
232
245
  """The standard method for computing signal processing window features.
233
246
 
247
+ As with `_window_standard`, this path does not take an identity mask: nan
248
+ per-frame values are zero-filled before the short-time Fourier transform.
249
+
234
250
  Args:
235
- identity: The identity of the mouse.
236
251
  window_size: The window size used for signal formation.
237
252
  per_frame_values: The values for a particular feature.
238
253
 
@@ -277,15 +292,12 @@ class Feature(abc.ABC):
277
292
  self._compute_signal_features(
278
293
  freqs,
279
294
  psd_data,
280
- self._poses.identity_mask(identity),
281
295
  op,
282
296
  **band,
283
297
  )
284
298
  )
285
299
  else:
286
- values[op_name] = self._compute_signal_features(
287
- freqs, psd_data, self._poses.identity_mask(identity), op
288
- )
300
+ values[op_name] = self._compute_signal_features(freqs, psd_data, op)
289
301
 
290
302
  return values
291
303
 
@@ -310,7 +322,6 @@ class Feature(abc.ABC):
310
322
  def _compute_window_feature(
311
323
  self,
312
324
  feature_values: dict,
313
- frame_mask: np.ndarray,
314
325
  window_size: int,
315
326
  op: typing.Callable,
316
327
  ) -> dict:
@@ -318,16 +329,15 @@ class Feature(abc.ABC):
318
329
 
319
330
  Args:
320
331
  feature_values: dict of per frame feature values
321
- frame_mask: array indicating which frames are valid for the current identity
322
332
  window_size: number of frames (in each direction) to include in the window. The actual number of frames is 2 * window_size + 1
323
333
  op: function to perform the actual computation
324
334
 
325
335
  Returns:
326
- dict containing feature values
336
+ dict mapping each per-frame feature name to its window feature values
327
337
  """
328
338
  values = {}
329
339
  for key, val in feature_values.items():
330
- values[f"{key}"] = op(val, window=window_size)
340
+ values[key] = op(val, window=window_size)
331
341
 
332
342
  return values
333
343
 
@@ -335,7 +345,6 @@ class Feature(abc.ABC):
335
345
  self,
336
346
  freqs: np.ndarray,
337
347
  psd: dict,
338
- frame_mask: np.ndarray,
339
348
  op: typing.Callable,
340
349
  **kwargs,
341
350
  ) -> dict:
@@ -344,18 +353,15 @@ class Feature(abc.ABC):
344
353
  Args:
345
354
  freqs: frequency values for psd matrices
346
355
  psd: dict of power spectral density
347
- frame_mask: array indicating which frames are valid for the current identity
348
356
  op: function to perform the actual computation. Operation must accept frequencies and psd as input
349
357
  **kwargs: additional keyword args used by op
350
358
 
351
-
352
-
353
359
  Returns:
354
- numpy nd array containing feature values
360
+ dict mapping each per-frame feature name to its signal feature values
355
361
  """
356
362
  values = {}
357
363
  for key, value in psd.items():
358
- values[f"{key}"] = op(freqs, value, **kwargs)
364
+ values[key] = op(freqs, value, **kwargs)
359
365
 
360
366
  return values
361
367
 
@@ -28,6 +28,11 @@ class CornerDistanceInfo:
28
28
  self._cached_bearings = {}
29
29
  self._all_wall_distances = {}
30
30
 
31
+ # None until cache_features() runs; it is then set to the arena's average
32
+ # wall length, or NaN when the pose file has no "corners" static object.
33
+ # get_avg_wall_length() relies on this None to know it must still compute.
34
+ self._avg_wall_length: float | None = None
35
+
31
36
  def cache_features(self, identity: int):
32
37
  """cache corner distances and bearings for a given identity
33
38
 
@@ -199,11 +204,17 @@ class CornerDistanceInfo:
199
204
  def get_avg_wall_length(self, identity: int = 0) -> float:
200
205
  """gets the average wall length
201
206
 
207
+ The average wall length is a property of the arena rather than of an
208
+ individual mouse, so a single instance-wide value is shared by every
209
+ identity. ``cache_features()`` derives it from the same static corners
210
+ every time it runs for a new identity, overwriting the stored value
211
+ with an identical one.
212
+
202
213
  Args:
203
214
  identity: identity to cache if not yet calculated
204
215
 
205
216
  Returns:
206
- average wall length
217
+ average wall length, or NaN if the pose file has no corners
207
218
  """
208
219
  if self._avg_wall_length is None:
209
220
  self.cache_features(identity)
@@ -64,14 +64,18 @@ def psd_mean_band(
64
64
  ) -> np.ndarray:
65
65
  """Calculates the mean power spectral density in a band
66
66
 
67
+ Unlike the other functions in this module, this one uses ``freqs`` -- it is
68
+ what selects the rows of ``psd`` that fall inside the band.
69
+
67
70
  Args:
68
- freqs: frequencies in the psd, ignored
71
+ freqs: frequencies in the psd, used to select the band
69
72
  psd: power spectral density matrix
70
- band_low: lower bound of the frequency band
71
- band_high: upper bound of the frequency band
73
+ band_low: inclusive lower bound of the frequency band
74
+ band_high: exclusive upper bound of the frequency band
72
75
 
73
76
  Returns:
74
- mean of power
77
+ mean of power over the frequencies in the band, or an array of nan if no
78
+ frequency falls inside the band
75
79
  """
76
80
  idx = np.logical_and(freqs >= band_low, freqs < band_high)
77
81
 
@@ -109,12 +113,16 @@ def psd_std_dev(freqs: np.ndarray, psd: np.ndarray) -> np.ndarray:
109
113
  def psd_kurtosis(freqs: np.ndarray, psd: np.ndarray) -> np.ndarray:
110
114
  """Calculates the kurtosis power spectral density
111
115
 
116
+ This uses scipy's default, which is Fisher (excess) kurtosis. The ``kurtosis``
117
+ window operation in ``window_operations.window_stats`` reports Pearson
118
+ (non-excess) kurtosis instead, so the two are offset by 3.0.
119
+
112
120
  Args:
113
121
  freqs: frequencies in the psd, ignored
114
122
  psd: power spectral density matrix
115
123
 
116
124
  Returns:
117
- kurtosis of power
125
+ excess kurtosis of power
118
126
  """
119
127
  with warnings.catch_warnings():
120
128
  warnings.simplefilter("ignore", category=RuntimeWarning)
@@ -8,13 +8,14 @@ def pad_sliding_window(arr: np.ndarray, window: int, pad_const: float | None = N
8
8
 
9
9
  Args:
10
10
  arr: 1d array to generate a sliding window
11
- window: half size of sliding window
11
+ window: number of frames to include on each side of the center frame. The
12
+ resulting window spans ``2 * window + 1`` frames.
12
13
  pad_const: Constant to pad the array with. None will pad with value at the edge.
13
14
 
14
15
  Returns:
15
16
  an unmodifiable 2d view of the input array where the first axis is time and the second axis is the window. Note that typical usage will use summary stats with axis=1.
16
17
  """
17
- if pad_const:
18
+ if pad_const is not None:
18
19
  arr_ext = np.concatenate([np.full(window, pad_const), arr, np.full(window, pad_const)])
19
20
  else:
20
21
  arr_ext = np.concatenate([np.full(window, arr[0]), arr, np.full(window, arr[-1])])
@@ -22,21 +23,25 @@ def pad_sliding_window(arr: np.ndarray, window: int, pad_const: float | None = N
22
23
 
23
24
 
24
25
  def get_window_masks(sliding_window_view: np.ndarray, const: float) -> np.ndarray:
25
- """Creates a mask for invalid values in a sliding window matrix.
26
+ """Creates a mask identifying the usable values in a sliding window matrix.
26
27
 
27
28
  Args:
28
29
  sliding_window_view: sliding window matrix from `pad_sliding_window`
29
30
  const: constant pad value
30
31
 
31
32
  Returns:
32
- matrix describing valid (0) and invalid (1) window values
33
+ boolean matrix that is True for valid window values and False for values
34
+ equal to the pad constant. Rows where every value is the pad constant are
35
+ returned as all True, since masking them entirely would leave the
36
+ downstream reduction with no data to operate on.
33
37
  """
34
38
  if np.isnan(const):
35
39
  window_masks = ~np.isnan(sliding_window_view)
36
40
  else:
37
41
  window_masks = sliding_window_view != const
38
- for no_data_row in np.where(np.all(~window_masks, axis=1)):
39
- window_masks[no_data_row] = True
42
+
43
+ no_data_rows = np.all(~window_masks, axis=1)
44
+ window_masks[no_data_rows] = True
40
45
 
41
46
  return window_masks
42
47
 
@@ -46,7 +51,8 @@ def window_mean(values: np.ndarray, window: int) -> np.ndarray:
46
51
 
47
52
  Args:
48
53
  values: 1d np.ndarray of values
49
- window: window size
54
+ window: number of frames to include on each side of the center frame. The
55
+ window used for each output value spans ``2 * window + 1`` frames.
50
56
 
51
57
  Returns:
52
58
  sliding window mean values
@@ -63,7 +69,8 @@ def window_median(values: np.ndarray, window: int) -> np.ndarray:
63
69
 
64
70
  Args:
65
71
  values: 1d np.ndarray of values
66
- window: window size
72
+ window: number of frames to include on each side of the center frame. The
73
+ window used for each output value spans ``2 * window + 1`` frames.
67
74
 
68
75
  Returns:
69
76
  sliding window median values
@@ -78,7 +85,8 @@ def window_std_dev(values: np.ndarray, window: int) -> np.ndarray:
78
85
 
79
86
  Args:
80
87
  values: 1d np.ndarray of values
81
- window: window size
88
+ window: number of frames to include on each side of the center frame. The
89
+ window used for each output value spans ``2 * window + 1`` frames.
82
90
 
83
91
  Returns:
84
92
  sliding window standard deviation values
@@ -93,14 +101,26 @@ def window_std_dev(values: np.ndarray, window: int) -> np.ndarray:
93
101
  def np_kurtosis(values: np.ndarray) -> np.ndarray:
94
102
  """Calculates kurtosis in a rolling window faster than scipy
95
103
 
104
+ This computes Pearson (non-excess) kurtosis, equivalent to
105
+ ``scipy.stats.kurtosis(values, axis=1, nan_policy="omit", fisher=False)``. It is
106
+ *not* equivalent to scipy's default, which subtracts 3.0 to give Fisher (excess)
107
+ kurtosis: values returned here are 3.0 larger than
108
+ ``scipy.stats.kurtosis(values, axis=1, nan_policy="omit")``.
109
+
110
+ Note that ``signal_stats.psd_kurtosis`` calls scipy with its default arguments, so
111
+ the ``kurtosis`` window feature and the ``psd_kurtosis`` signal feature do not use
112
+ the same convention.
113
+
96
114
  Args:
97
- values: 2d array of with time and a window
115
+ values: 2d array with time on the first axis and the window on the second
98
116
 
99
117
  Returns:
100
- kurtosis values that match scipy.stats.kurtosis(values, axis, nan_policy='omit')
118
+ Pearson kurtosis of the non-nan values in each window. A window that is
119
+ entirely nan yields nan.
101
120
 
102
- Raises:
103
- RuntimeWarning when an entire window is nans
121
+ Note:
122
+ numpy emits (does not raise) a RuntimeWarning when an entire window is nan.
123
+ Callers such as `window_kurtosis` suppress that warning.
104
124
  """
105
125
  mean = np.nanmean(values, axis=1)
106
126
  std = np.nanstd(values, axis=1)
@@ -115,7 +135,8 @@ def window_kurtosis(values: np.ndarray, window: int) -> np.ndarray:
115
135
 
116
136
  Args:
117
137
  values: 1d np.ndarray of values
118
- window: window size
138
+ window: number of frames to include on each side of the center frame. The
139
+ window used for each output value spans ``2 * window + 1`` frames.
119
140
 
120
141
  Returns:
121
142
  sliding window kurtosis values
@@ -130,14 +151,19 @@ def window_kurtosis(values: np.ndarray, window: int) -> np.ndarray:
130
151
  def np_skew(values: np.ndarray) -> np.ndarray:
131
152
  """Calculates skew in a rolling window faster than scipy
132
153
 
154
+ This computes the biased (population) skew, equivalent to
155
+ ``scipy.stats.skew(values, axis=1, nan_policy="omit")``, which is scipy's default.
156
+
133
157
  Args:
134
- values: 2d array of with time and a window
158
+ values: 2d array with time on the first axis and the window on the second
135
159
 
136
160
  Returns:
137
- skew values that match scipy.stats.skew(values, axis, nan_policy='omit')
161
+ skew of the non-nan values in each window. A window that is entirely nan
162
+ yields nan.
138
163
 
139
- Raises:
140
- RuntimeWarning when an entire window is nans
164
+ Note:
165
+ numpy emits (does not raise) a RuntimeWarning when an entire window is nan.
166
+ Callers such as `window_skew` suppress that warning.
141
167
  """
142
168
  mean = np.nanmean(values, axis=1)
143
169
  std = np.nanstd(values, axis=1)
@@ -152,7 +178,8 @@ def window_skew(values: np.ndarray, window: int) -> np.ndarray:
152
178
 
153
179
  Args:
154
180
  values: 1d np.ndarray of values
155
- window: window size
181
+ window: number of frames to include on each side of the center frame. The
182
+ window used for each output value spans ``2 * window + 1`` frames.
156
183
 
157
184
  Returns:
158
185
  sliding window skew values
@@ -165,14 +192,15 @@ def window_skew(values: np.ndarray, window: int) -> np.ndarray:
165
192
 
166
193
 
167
194
  def window_min(values: np.ndarray, window: int) -> np.ndarray:
168
- """Calculates a masked maximum of a window
195
+ """Calculates a masked minimum of a window
169
196
 
170
197
  Args:
171
198
  values: 1d np.ndarray of values
172
- window: window size
199
+ window: number of frames to include on each side of the center frame. The
200
+ window used for each output value spans ``2 * window + 1`` frames.
173
201
 
174
202
  Returns:
175
- sliding window maximum values
203
+ sliding window minimum values
176
204
  """
177
205
  window_values = pad_sliding_window(values, window, pad_const=np.nan)
178
206
  window_masks = get_window_masks(window_values, np.nan)
@@ -186,7 +214,8 @@ def window_max(values: np.ndarray, window: int) -> np.ndarray:
186
214
 
187
215
  Args:
188
216
  values: 1d np.ndarray of values
189
- window: window size
217
+ window: number of frames to include on each side of the center frame. The
218
+ window used for each output value spans ``2 * window + 1`` frames.
190
219
 
191
220
  Returns:
192
221
  sliding window maximum values
@@ -63,20 +63,32 @@ def get_pose_path(video_path: Path, pose_dir: Path | None = None):
63
63
  raise ValueError("Video does not have pose file")
64
64
 
65
65
 
66
- def get_pose_file_major_version(path: Path):
66
+ # matches the version suffix of a pose file name, e.g. "_v6.h5" in
67
+ # "video_pose_est_v6.h5". Anchored at the end so only the filename's suffix can
68
+ # supply the version.
69
+ _POSE_VERSION_RE = re.compile(r"_v(\d+)\.h5$")
70
+
71
+
72
+ def get_pose_file_major_version(path: Path) -> int:
67
73
  """get the major version of a pose file from the _filename_
68
74
 
69
- Note: does not inspect contents of file, assumes file name matches
70
- video_name_v[version number].h5
75
+ Note: does not inspect contents of file, assumes the file name follows the
76
+ JABS convention ``<video name>_pose_est_v<major version>.h5``.
71
77
 
72
78
  Args:
73
79
  path: path of pose file
74
80
 
75
81
  Returns:
76
82
  integer major version number
83
+
84
+ Raises:
85
+ ValueError: if the file name does not end with a ``_v<major version>.h5``
86
+ suffix
77
87
  """
78
- v = re.search(r"_v([0-9])+\.h5", str(path)).group(1)
79
- return int(v)
88
+ match = _POSE_VERSION_RE.search(path.name)
89
+ if match is None:
90
+ raise ValueError(f"'{path.name}' is not a valid pose file name")
91
+ return int(match.group(1))
80
92
 
81
93
 
82
94
  def get_frames_from_file(path: Path):
@@ -87,10 +87,16 @@ class PoseEstimationV4(PoseEstimation):
87
87
 
88
88
  self._num_frames = len(all_points)
89
89
 
90
- max_instance_id = (
91
- np.max(np.ma.array(instance_embed_id[...], mask=id_mask[...]))
90
+ valid_instance_embed_id = (
91
+ instance_embed_id[id_mask == 0]
92
92
  if instance_embed_id.shape[1] > 0
93
- else 0
93
+ else np.array([], dtype=instance_embed_id.dtype)
94
+ )
95
+ max_instance_id = (
96
+ valid_instance_embed_id.max() if valid_instance_embed_id.size > 0 else 0
97
+ )
98
+ min_instance_id = (
99
+ valid_instance_embed_id.min() if valid_instance_embed_id.size > 0 else 1
94
100
  )
95
101
 
96
102
  if "instance_id_center" in pose_grp:
@@ -101,12 +107,21 @@ class PoseEstimationV4(PoseEstimation):
101
107
  print(f"Warning: No identities found in pose file: {file_path}")
102
108
  self._num_identities = 0
103
109
 
104
- # Validate instance_embed_id range: must be in [0, self._num_identities]
110
+ # Validate instance_embed_id range for unmasked (id_mask == 0) data:
111
+ # must be in [1, self._num_identities].
105
112
  if max_instance_id > self._num_identities:
106
113
  raise PoseIdEmbeddingException(
107
114
  f"Invalid instance_embed_id, values out of range: {file_path.name}"
108
115
  )
109
116
 
117
+ # instance_embed_id values are 1-based; a value of 0 on unmasked
118
+ # data would wrap around to a large positive index when we
119
+ # subtract 1 to build a 0-based identity index below.
120
+ if min_instance_id < 1:
121
+ raise PoseIdEmbeddingException(
122
+ f"Invalid instance_embed_id, unmasked values must be >= 1: {file_path.name}"
123
+ )
124
+
110
125
  # generate list of identities based on the max number of instances
111
126
  # in the pose file
112
127
  if self._num_identities > 0:
@@ -1,6 +1,12 @@
1
1
  """jabs project module"""
2
2
 
3
3
  from .export_training import export_training_data, export_training_data_multiclass
4
+ from .feature_cache_status import (
5
+ VideoFeatureCacheStatus,
6
+ scan_project_feature_cache,
7
+ scan_project_video_feature_cache,
8
+ scan_video_feature_cache,
9
+ )
4
10
  from .project import Project
5
11
  from .project_pruning import get_videos_to_prune
6
12
  from .read_training import load_multiclass_training_data, load_training_data
@@ -12,10 +18,14 @@ __all__ = [
12
18
  "Project",
13
19
  "TimelineAnnotations",
14
20
  "TrackLabels",
21
+ "VideoFeatureCacheStatus",
15
22
  "VideoLabels",
16
23
  "export_training_data",
17
24
  "export_training_data_multiclass",
18
25
  "get_videos_to_prune",
19
26
  "load_multiclass_training_data",
20
27
  "load_training_data",
28
+ "scan_project_feature_cache",
29
+ "scan_project_video_feature_cache",
30
+ "scan_video_feature_cache",
21
31
  ]