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.
- {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/PKG-INFO +11 -12
- {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/README.md +7 -7
- {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/pyproject.toml +4 -6
- {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/feature_extraction/feature_base_class.py +26 -20
- {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/feature_extraction/landmark_features/corner.py +12 -1
- {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/feature_extraction/window_operations/signal_stats.py +13 -5
- {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/feature_extraction/window_operations/window_stats.py +52 -23
- {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/pose_estimation/__init__.py +17 -5
- {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/pose_estimation/pose_est_v4.py +19 -4
- {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/project/__init__.py +10 -0
- {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/project/export_training.py +13 -3
- jabs_behavior_classifier-0.46.3/src/jabs/project/feature_cache_status.py +398 -0
- {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/project/project.py +187 -45
- {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/project/project_pruning.py +1 -1
- {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/project/read_training.py +33 -2
- {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/project/timeline_annotations.py +39 -34
- {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/project/video_labels.py +0 -21
- {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/project/video_manager.py +20 -1
- {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/resources/docs/user_guide/cli-tools.md +78 -24
- {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/resources/docs/user_guide/gui.md +7 -1
- {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/scripts/cli/cli.py +2 -0
- {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/scripts/cli/compute_features.py +1 -1
- jabs_behavior_classifier-0.46.3/src/jabs/scripts/cli/merge_projects.py +77 -0
- {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/scripts/cli/postprocessing.py +46 -1
- jabs_behavior_classifier-0.46.3/src/jabs/scripts/generate_features.py +129 -0
- {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/ui/dialogs/user_guide_dialog.py +2 -1
- {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/ui/dialogs/video_info_dialog.py +100 -9
- jabs_behavior_classifier-0.46.3/src/jabs/ui/feature_cache_scan_thread.py +59 -0
- jabs_behavior_classifier-0.46.3/src/jabs/ui/feature_cache_text.py +66 -0
- {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/ui/main_control_widget/main_control_widget.py +9 -0
- {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/ui/main_window/central_widget.py +160 -2
- {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/ui/main_window/main_window.py +169 -2
- {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/ui/main_window/menu_builder.py +6 -3
- {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/ui/main_window/menu_handlers.py +3 -0
- {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/ui/main_window/video_list_widget.py +39 -3
- {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/utils/__init__.py +6 -2
- jabs_behavior_classifier-0.46.2/src/jabs/scripts/generate_features.py +0 -119
- jabs_behavior_classifier-0.46.2/src/jabs/scripts/merge_projects.py +0 -87
- jabs_behavior_classifier-0.46.2/src/jabs/utils/update_checker.py +0 -53
- {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/LICENSE +0 -0
- {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/behavior_search/__init__.py +0 -0
- {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/behavior_search/behavior_search_util.py +0 -0
- {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/classifier/__init__.py +0 -0
- {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/classifier/base.py +0 -0
- {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/classifier/classifier.py +0 -0
- {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/classifier/classifier_utils.py +0 -0
- {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/classifier/cross_validation.py +0 -0
- {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/classifier/factories.py +0 -0
- {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/classifier/mlflow_logging.py +0 -0
- {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/classifier/multi_class_classifier.py +0 -0
- {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/classifier/protocols.py +0 -0
- {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/classifier/training_report.py +0 -0
- {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/feature_extraction/__init__.py +0 -0
- {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/feature_extraction/angle_index.py +0 -0
- {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/feature_extraction/base_features/__init__.py +0 -0
- {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/feature_extraction/base_features/angles.py +0 -0
- {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/feature_extraction/base_features/angular_velocity.py +0 -0
- {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/feature_extraction/base_features/base_group.py +0 -0
- {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/feature_extraction/base_features/centroid_velocity.py +0 -0
- {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/feature_extraction/base_features/pairwise_distances.py +0 -0
- {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/feature_extraction/base_features/point_speeds.py +0 -0
- {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/feature_extraction/base_features/point_velocities.py +0 -0
- {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/feature_extraction/feature_group_base_class.py +0 -0
- {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/feature_extraction/features.py +0 -0
- {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/feature_extraction/landmark_features/__init__.py +0 -0
- {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/feature_extraction/landmark_features/food_hopper.py +0 -0
- {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/feature_extraction/landmark_features/landmark_group.py +0 -0
- {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/feature_extraction/landmark_features/lixit.py +0 -0
- {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/feature_extraction/segmentation_features/__init__.py +0 -0
- {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/feature_extraction/segmentation_features/hu_moments.py +0 -0
- {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/feature_extraction/segmentation_features/moment_cache.py +0 -0
- {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/feature_extraction/segmentation_features/moments.py +0 -0
- {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/feature_extraction/segmentation_features/segment_group.py +0 -0
- {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/feature_extraction/segmentation_features/shape_descriptors.py +0 -0
- {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/feature_extraction/social_features/__init__.py +0 -0
- {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/feature_extraction/social_features/closest_distances.py +0 -0
- {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/feature_extraction/social_features/closest_fov_angles.py +0 -0
- {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/feature_extraction/social_features/closest_fov_distances.py +0 -0
- {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/feature_extraction/social_features/pairwise_social_distances.py +0 -0
- {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/feature_extraction/social_features/social_distance.py +0 -0
- {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/feature_extraction/social_features/social_group.py +0 -0
- {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/feature_extraction/window_operations/__init__.py +0 -0
- {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/pose_estimation/pose_est_v2.py +0 -0
- {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/pose_estimation/pose_est_v3.py +0 -0
- {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/pose_estimation/pose_est_v5.py +0 -0
- {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/pose_estimation/pose_est_v6.py +0 -0
- {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/pose_estimation/pose_est_v7.py +0 -0
- {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/pose_estimation/pose_est_v8.py +0 -0
- {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/project/feature_manager.py +0 -0
- {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/project/parallel_workers.py +0 -0
- {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/project/pose_attribute_cache.py +0 -0
- {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/project/prediction_manager.py +0 -0
- {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/project/project_merge.py +0 -0
- {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/project/project_paths.py +0 -0
- {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/project/project_utils.py +0 -0
- {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/project/session_tracker.py +0 -0
- {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/project/settings_manager.py +0 -0
- {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/project/track_labels.py +0 -0
- {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/resources/__init__.py +0 -0
- {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/resources/docs/LICENSE +0 -0
- {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/resources/docs/user_guide/behavior-search.md +0 -0
- {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/resources/docs/user_guide/classifier-types.md +0 -0
- {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/resources/docs/user_guide/features.md +0 -0
- {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/resources/docs/user_guide/file-formats.md +0 -0
- {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/resources/docs/user_guide/imgs/StackedImgs.svg +0 -0
- {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
- {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
- {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/resources/docs/user_guide/imgs/classifier_controls.png +0 -0
- {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
- {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/resources/docs/user_guide/imgs/identity_gaps.png +0 -0
- {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
- {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/resources/docs/user_guide/imgs/keypoint_legend.png +0 -0
- {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/resources/docs/user_guide/imgs/label_viz.png +0 -0
- {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/resources/docs/user_guide/imgs/main_window.png +0 -0
- {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
- {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/resources/docs/user_guide/imgs/pose_overlay.png +0 -0
- {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/resources/docs/user_guide/imgs/search-dialog.png +0 -0
- {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/resources/docs/user_guide/imgs/selecting_frames.png +0 -0
- {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/resources/docs/user_guide/imgs/stacked_timeline.png +0 -0
- {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/resources/docs/user_guide/imgs/timeline_menu.png +0 -0
- {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/resources/docs/user_guide/imgs/track_overlay.png +0 -0
- {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
- {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
- {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
- {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/resources/docs/user_guide/keyboard-shortcuts.md +0 -0
- {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/resources/docs/user_guide/labeling.md +0 -0
- {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/resources/docs/user_guide/multi-class.md +0 -0
- {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/resources/docs/user_guide/nwb-export.md +0 -0
- {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/resources/docs/user_guide/overview.md +0 -0
- {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/resources/docs/user_guide/postprocessing.md +0 -0
- {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/resources/docs/user_guide/project-setup.md +0 -0
- {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/resources/eartag_images/s2.svg +0 -0
- {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/resources/eartag_images/s3.svg +0 -0
- {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/resources/eartag_images/s4.svg +0 -0
- {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/resources/fail_whale.png +0 -0
- {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/resources/icon.png +0 -0
- {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/schema/__init__.py +0 -0
- {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/schema/metadata.py +0 -0
- {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/scripts/__init__.py +0 -0
- {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/scripts/classify.py +0 -0
- {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/scripts/cli/__init__.py +0 -0
- {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/scripts/cli/convert_parquet.py +0 -0
- {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/scripts/cli/convert_to_nwb.py +0 -0
- {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/scripts/cli/cross_validation.py +0 -0
- {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/scripts/cli/sample_frames.py +0 -0
- {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/scripts/cli/sample_pose_intervals.py +0 -0
- {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/scripts/cli/update_labels.py +0 -0
- {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/scripts/cli/update_pose.py +0 -0
- {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/scripts/gui_entrypoint.py +0 -0
- {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/scripts/initialize_project.py +0 -0
- {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/ui/__init__.py +0 -0
- {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/ui/behavior_timeline/__init__.py +0 -0
- {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/ui/behavior_timeline/behavior_timeline_widget.py +0 -0
- {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/ui/behavior_timeline/frame_ruler_widget.py +0 -0
- {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/ui/behavior_timeline/track_widgets/__init__.py +0 -0
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/ui/behavior_timeline/track_widgets/timeline_util.py +0 -0
- {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/ui/classification_thread.py +0 -0
- {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/ui/classify_strategy.py +0 -0
- {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/ui/colors.py +0 -0
- {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/ui/constants.py +0 -0
- {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/ui/dialogs/__init__.py +0 -0
- {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/ui/dialogs/about_dialog.py +0 -0
- {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/ui/dialogs/annotation_edit_dialog.py +0 -0
- {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/ui/dialogs/annotation_info_dialog.py +0 -0
- {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/ui/dialogs/archive_behavior_dialog.py +0 -0
- {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/ui/dialogs/behavior_search_dialog.py +0 -0
- {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/ui/dialogs/license_dialog.py +0 -0
- {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/ui/dialogs/message_dialog.py +0 -0
- {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/ui/dialogs/progress_dialog.py +0 -0
- {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/ui/dialogs/project_pruning_dialog.py +0 -0
- {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/ui/dialogs/training_report.py +0 -0
- {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/ui/dialogs/update_check_dialog.py +0 -0
- {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/ui/ear_tag_icons.py +0 -0
- {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/ui/exceptions.py +0 -0
- {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/ui/export_training_thread.py +0 -0
- {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/ui/main_control_widget/__init__.py +0 -0
- {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
- {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/ui/main_control_widget/label_count_widget.py +0 -0
- {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/ui/main_window/README.md +0 -0
- {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/ui/main_window/__init__.py +0 -0
- {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/ui/main_window/central_widget_mode.py +0 -0
- {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/ui/main_window/constants.py +0 -0
- {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/ui/player_widget/__init__.py +0 -0
- {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/ui/player_widget/frame_with_overlays.py +0 -0
- {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/ui/player_widget/overlays/__init__.py +0 -0
- {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/ui/player_widget/overlays/annotation_overlay.py +0 -0
- {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/ui/player_widget/overlays/bounding_box.py +0 -0
- {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/ui/player_widget/overlays/control_overlay.py +0 -0
- {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/ui/player_widget/overlays/floating_id_overlay.py +0 -0
- {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/ui/player_widget/overlays/label_overlay.py +0 -0
- {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/ui/player_widget/overlays/overlay.py +0 -0
- {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/ui/player_widget/overlays/pose_overlay.py +0 -0
- {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/ui/player_widget/player_thread.py +0 -0
- {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/ui/player_widget/player_widget.py +0 -0
- {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/ui/player_widget/pose_drawing.py +0 -0
- {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/ui/project_loader_thread.py +0 -0
- {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/ui/search_bar_widget.py +0 -0
- {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/ui/settings_dialog/README.md +0 -0
- {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/ui/settings_dialog/__init__.py +0 -0
- {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/ui/settings_dialog/cache_format_settings_group.py +0 -0
- {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/ui/settings_dialog/classifier_mode_settings_group.py +0 -0
- {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/ui/settings_dialog/collapsible_section.py +0 -0
- {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/ui/settings_dialog/cross_validation_settings_group.py +0 -0
- {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/ui/settings_dialog/postprocessing_group.py +0 -0
- {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/ui/settings_dialog/postprocessing_settings/__init__.py +0 -0
- {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/ui/settings_dialog/session_tracking_group.py +0 -0
- {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/ui/settings_dialog/settings_dialog.py +0 -0
- {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/ui/settings_dialog/settings_group.py +0 -0
- {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/ui/training_strategy.py +0 -0
- {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/ui/training_thread.py +0 -0
- {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/ui/util.py +0 -0
- {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/version/__init__.py +0 -0
- {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/video_reader/__init__.py +0 -0
- {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/video_reader/frame_annotation.py +0 -0
- {jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/video_reader/utilities.py +0 -0
- {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.
|
|
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.
|
|
9
|
-
Requires-Dist: jabs-core==0.46.
|
|
10
|
-
Requires-Dist: jabs-io==0.46.
|
|
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
|
[](https://www.python.org/downloads/)
|
|
53
52
|
[](https://pypi.org/project/jabs-behavior-classifier/)
|
|
54
|
-
[](https://github.com/KumarLabJax/JABS-behavior-classifier/blob/v0.46.
|
|
53
|
+
[](https://github.com/KumarLabJax/JABS-behavior-classifier/blob/v0.46.3/LICENSE)
|
|
55
54
|
[](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.
|
|
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
|
-

|
|
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.
|
|
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.
|
|
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.
|
|
234
|
-
- [Development Guide](https://github.com/KumarLabJax/JABS-behavior-classifier/blob/v0.46.
|
|
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
|
[](https://www.python.org/downloads/)
|
|
10
10
|
[](https://pypi.org/project/jabs-behavior-classifier/)
|
|
11
|
-
[](https://github.com/KumarLabJax/JABS-behavior-classifier/blob/v0.46.
|
|
11
|
+
[](https://github.com/KumarLabJax/JABS-behavior-classifier/blob/v0.46.3/LICENSE)
|
|
12
12
|
[](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.
|
|
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
|
-

|
|
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.
|
|
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.
|
|
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.
|
|
191
|
-
- [Development Guide](https://github.com/KumarLabJax/JABS-behavior-classifier/blob/v0.46.
|
|
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.
|
|
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.
|
|
19
|
-
"jabs-core==0.46.
|
|
20
|
-
"jabs-io==0.46.
|
|
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(
|
|
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,
|
|
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(
|
|
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,
|
|
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
|
|
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[
|
|
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
|
-
|
|
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[
|
|
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,
|
|
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:
|
|
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
|
|
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
|
|
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
|
-
|
|
39
|
-
|
|
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:
|
|
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:
|
|
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:
|
|
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
|
|
115
|
+
values: 2d array with time on the first axis and the window on the second
|
|
98
116
|
|
|
99
117
|
Returns:
|
|
100
|
-
kurtosis values
|
|
118
|
+
Pearson kurtosis of the non-nan values in each window. A window that is
|
|
119
|
+
entirely nan yields nan.
|
|
101
120
|
|
|
102
|
-
|
|
103
|
-
RuntimeWarning when an entire window is
|
|
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:
|
|
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
|
|
158
|
+
values: 2d array with time on the first axis and the window on the second
|
|
135
159
|
|
|
136
160
|
Returns:
|
|
137
|
-
skew values
|
|
161
|
+
skew of the non-nan values in each window. A window that is entirely nan
|
|
162
|
+
yields nan.
|
|
138
163
|
|
|
139
|
-
|
|
140
|
-
RuntimeWarning when an entire window is
|
|
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:
|
|
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
|
|
195
|
+
"""Calculates a masked minimum of a window
|
|
169
196
|
|
|
170
197
|
Args:
|
|
171
198
|
values: 1d np.ndarray of values
|
|
172
|
-
window:
|
|
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
|
|
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:
|
|
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
|
-
|
|
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
|
|
70
|
-
|
|
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
|
-
|
|
79
|
-
|
|
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
|
-
|
|
91
|
-
|
|
90
|
+
valid_instance_embed_id = (
|
|
91
|
+
instance_embed_id[id_mask == 0]
|
|
92
92
|
if instance_embed_id.shape[1] > 0
|
|
93
|
-
else
|
|
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
|
|
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:
|
{jabs_behavior_classifier-0.46.2 → jabs_behavior_classifier-0.46.3}/src/jabs/project/__init__.py
RENAMED
|
@@ -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
|
]
|