simba-uw-tf-dev 4.5.8__py3-none-any.whl → 4.7.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (98) hide show
  1. simba/SimBA.py +2 -2
  2. simba/assets/.recent_projects.txt +1 -0
  3. simba/assets/icons/frames_2.png +0 -0
  4. simba/assets/lookups/tooptips.json +15 -1
  5. simba/data_processors/agg_clf_counter_mp.py +52 -53
  6. simba/data_processors/blob_location_computer.py +1 -1
  7. simba/data_processors/circling_detector.py +30 -13
  8. simba/data_processors/cuda/geometry.py +45 -27
  9. simba/data_processors/cuda/image.py +1648 -1598
  10. simba/data_processors/cuda/statistics.py +72 -26
  11. simba/data_processors/cuda/timeseries.py +1 -1
  12. simba/data_processors/cue_light_analyzer.py +5 -9
  13. simba/data_processors/egocentric_aligner.py +25 -7
  14. simba/data_processors/freezing_detector.py +55 -47
  15. simba/data_processors/kleinberg_calculator.py +61 -29
  16. simba/feature_extractors/feature_subsets.py +14 -7
  17. simba/feature_extractors/mitra_feature_extractor.py +2 -2
  18. simba/feature_extractors/straub_tail_analyzer.py +4 -6
  19. simba/labelling/standard_labeller.py +1 -1
  20. simba/mixins/config_reader.py +5 -2
  21. simba/mixins/geometry_mixin.py +22 -36
  22. simba/mixins/image_mixin.py +24 -28
  23. simba/mixins/plotting_mixin.py +28 -10
  24. simba/mixins/statistics_mixin.py +48 -11
  25. simba/mixins/timeseries_features_mixin.py +1 -1
  26. simba/mixins/train_model_mixin.py +67 -29
  27. simba/model/inference_batch.py +1 -1
  28. simba/model/yolo_seg_inference.py +3 -3
  29. simba/outlier_tools/skip_outlier_correction.py +1 -1
  30. simba/plotting/ROI_feature_visualizer_mp.py +3 -5
  31. simba/plotting/clf_validator_mp.py +4 -5
  32. simba/plotting/cue_light_visualizer.py +6 -7
  33. simba/plotting/directing_animals_visualizer_mp.py +2 -3
  34. simba/plotting/distance_plotter_mp.py +378 -378
  35. simba/plotting/frame_mergerer_ffmpeg.py +137 -196
  36. simba/plotting/gantt_creator.py +29 -10
  37. simba/plotting/gantt_creator_mp.py +96 -33
  38. simba/plotting/geometry_plotter.py +270 -272
  39. simba/plotting/heat_mapper_clf_mp.py +4 -6
  40. simba/plotting/heat_mapper_location_mp.py +2 -2
  41. simba/plotting/light_dark_box_plotter.py +2 -2
  42. simba/plotting/path_plotter_mp.py +26 -29
  43. simba/plotting/plot_clf_results_mp.py +455 -454
  44. simba/plotting/pose_plotter_mp.py +28 -29
  45. simba/plotting/probability_plot_creator_mp.py +288 -288
  46. simba/plotting/roi_plotter_mp.py +31 -31
  47. simba/plotting/single_run_model_validation_video_mp.py +427 -427
  48. simba/plotting/spontaneous_alternation_plotter.py +2 -3
  49. simba/plotting/yolo_pose_track_visualizer.py +32 -27
  50. simba/plotting/yolo_pose_visualizer.py +35 -36
  51. simba/plotting/yolo_seg_visualizer.py +2 -3
  52. simba/pose_importers/simba_blob_importer.py +3 -3
  53. simba/roi_tools/roi_aggregate_stats_mp.py +5 -4
  54. simba/roi_tools/roi_clf_calculator_mp.py +4 -4
  55. simba/sandbox/analyze_runtimes.py +30 -0
  56. simba/sandbox/cuda/egocentric_rotator.py +374 -0
  57. simba/sandbox/get_cpu_pool.py +5 -0
  58. simba/sandbox/proboscis_to_tip.py +28 -0
  59. simba/sandbox/test_directionality.py +47 -0
  60. simba/sandbox/test_nonstatic_directionality.py +27 -0
  61. simba/sandbox/test_pycharm_cuda.py +51 -0
  62. simba/sandbox/test_simba_install.py +41 -0
  63. simba/sandbox/test_static_directionality.py +26 -0
  64. simba/sandbox/test_static_directionality_2d.py +26 -0
  65. simba/sandbox/verify_env.py +42 -0
  66. simba/third_party_label_appenders/transform/coco_keypoints_to_yolo.py +3 -3
  67. simba/third_party_label_appenders/transform/coco_keypoints_to_yolo_bbox.py +2 -2
  68. simba/ui/pop_ups/clf_add_remove_print_pop_up.py +37 -30
  69. simba/ui/pop_ups/clf_plot_pop_up.py +2 -2
  70. simba/ui/pop_ups/egocentric_alignment_pop_up.py +20 -21
  71. simba/ui/pop_ups/fsttc_pop_up.py +27 -25
  72. simba/ui/pop_ups/gantt_pop_up.py +31 -6
  73. simba/ui/pop_ups/interpolate_pop_up.py +2 -4
  74. simba/ui/pop_ups/kleinberg_pop_up.py +39 -40
  75. simba/ui/pop_ups/multiple_videos_to_frames_popup.py +10 -11
  76. simba/ui/pop_ups/single_video_to_frames_popup.py +10 -10
  77. simba/ui/pop_ups/video_processing_pop_up.py +186 -174
  78. simba/ui/tkinter_functions.py +10 -1
  79. simba/utils/custom_feature_extractor.py +1 -1
  80. simba/utils/data.py +90 -14
  81. simba/utils/enums.py +1 -0
  82. simba/utils/errors.py +441 -440
  83. simba/utils/lookups.py +1203 -1203
  84. simba/utils/printing.py +124 -124
  85. simba/utils/read_write.py +3769 -3721
  86. simba/utils/yolo.py +10 -1
  87. simba/video_processors/blob_tracking_executor.py +2 -2
  88. simba/video_processors/clahe_ui.py +66 -23
  89. simba/video_processors/egocentric_video_rotator.py +46 -44
  90. simba/video_processors/multi_cropper.py +1 -1
  91. simba/video_processors/video_processing.py +5264 -5300
  92. simba/video_processors/videos_to_frames.py +43 -32
  93. {simba_uw_tf_dev-4.5.8.dist-info → simba_uw_tf_dev-4.7.1.dist-info}/METADATA +4 -3
  94. {simba_uw_tf_dev-4.5.8.dist-info → simba_uw_tf_dev-4.7.1.dist-info}/RECORD +98 -86
  95. {simba_uw_tf_dev-4.5.8.dist-info → simba_uw_tf_dev-4.7.1.dist-info}/LICENSE +0 -0
  96. {simba_uw_tf_dev-4.5.8.dist-info → simba_uw_tf_dev-4.7.1.dist-info}/WHEEL +0 -0
  97. {simba_uw_tf_dev-4.5.8.dist-info → simba_uw_tf_dev-4.7.1.dist-info}/entry_points.txt +0 -0
  98. {simba_uw_tf_dev-4.5.8.dist-info → simba_uw_tf_dev-4.7.1.dist-info}/top_level.txt +0 -0
@@ -1,196 +1,137 @@
1
- __author__ = "Simon Nilsson; sronilsson@gmail.com"
2
-
3
- import os
4
- import shutil
5
- from datetime import datetime
6
- from typing import List, Optional, Union
7
-
8
- try:
9
- from typing import Literal
10
- except ImportError:
11
- from typing_extensions import Literal
12
-
13
- from simba.mixins.config_reader import ConfigReader
14
- from simba.utils.checks import (check_ffmpeg_available,
15
- check_file_exist_and_readable, check_int,
16
- check_nvidea_gpu_available, check_str,
17
- check_valid_lst)
18
- from simba.utils.enums import Paths, TagNames
19
- from simba.utils.errors import FFMPEGCodecGPUError
20
- from simba.utils.printing import SimbaTimer, log_event, stdout_success
21
- from simba.utils.read_write import copy_files_to_directory, get_fn_ext
22
- from simba.video_processors.video_processing import (
23
- horizontal_video_concatenator, mixed_mosaic_concatenator,
24
- mosaic_concatenator, vertical_video_concatenator)
25
-
26
- HORIZONTAL = "horizontal"
27
- VERTICAL = "vertical"
28
- MOSAIC = "mosaic"
29
- MIXED_MOSAIC = "mixed_mosaic"
30
- ACCEPTED_TYPES = [HORIZONTAL, VERTICAL, MOSAIC, MIXED_MOSAIC]
31
-
32
-
33
- class FrameMergererFFmpeg(ConfigReader):
34
- """
35
- Merge separate visualizations of classifications, descriptive statistics etc., into single video mosaic.
36
-
37
- .. note::
38
- `GitHub tutorial <https://github.com/sgoldenlab/simba/blob/master/docs/tutorial.md#step-12-merge-frames>`_.
39
-
40
- .. image:: _static/img/mosaic_videos.gif
41
- :width: 600
42
- :align: center
43
-
44
- :parameter str config_path: Optional path to SimBA project config file in Configparser format.
45
- :parameter Literal["horizontal", "vertical", "mosaic", "mixed_mosaic"] concat_type: Type of concatenation. OPTIONS: 'horizontal', 'vertical', 'mosaic', 'mixed_mosaic'.
46
- :parameter List[Union[str, os.PathLike]] video_paths: List with videos to concatenate.
47
- :parameter Optional[int] video_height: Optional height of the canatenated videos. Required if concat concat_type is not mixed_mosaic.
48
- :parameter int video_width: Optional wisth of the canatenated videos. Required if concat concat_type is not mixed_mosaic.
49
- :parameter Optional[bool] gpu: If True, use NVIDEA FFMpeg GPU codecs. Default False.
50
-
51
- :example:
52
- >>> video_paths = ['/Users/simon/Desktop/envs/simba/troubleshooting/mouse_open_field/project_folder/videos/SI_DAY3_308_CD1_PRESENT_downsampled.mp4', '/Users/simon/Desktop/envs/simba/troubleshooting/mouse_open_field/project_folder/videos/SI_DAY3_308_CD1_PRESENT_downsampled.mp4']
53
- >>> merger = FrameMergererFFmpeg(config_path='/Users/simon/Desktop/envs/simba/troubleshooting/two_black_animals_14bp/project_folder/project_config.ini', video_paths=videos, video_height=600, video_width=600, concat_type='mosaic')
54
- >>> merger.run()
55
- """
56
-
57
- def __init__(
58
- self,
59
- concat_type: Literal["horizontal", "vertical", "mosaic", "mixed_mosaic"],
60
- video_paths: List[Union[str, os.PathLike]],
61
- video_height: Optional[int] = None,
62
- video_width: Optional[int] = None,
63
- config_path: Optional[str] = None,
64
- gpu: Optional[bool] = False,
65
- ):
66
-
67
- if gpu and not check_nvidea_gpu_available():
68
- raise FFMPEGCodecGPUError(
69
- msg="NVIDEA GPU not available (as evaluated by nvidea-smi returning None",
70
- source=self.__class__.__name__,
71
- )
72
- check_ffmpeg_available()
73
- check_str(
74
- name=f"{FrameMergererFFmpeg.__name__} concat_type",
75
- value=concat_type,
76
- options=ACCEPTED_TYPES,
77
- )
78
- check_valid_lst(
79
- data=video_paths,
80
- source=f"{self.__class__.__name__} video_paths",
81
- valid_dtypes=(str,),
82
- min_len=2,
83
- )
84
- for i in video_paths:
85
- check_file_exist_and_readable(file_path=i)
86
- if concat_type != MIXED_MOSAIC:
87
- check_int(
88
- name=f"{FrameMergererFFmpeg.__name__} video_height",
89
- value=video_height,
90
- min_value=0,
91
- )
92
- check_int(
93
- name=f"{FrameMergererFFmpeg.__name__} video_width",
94
- value=video_height,
95
- min_value=0,
96
- )
97
- if config_path is not None:
98
- ConfigReader.__init__(self, config_path=config_path)
99
- log_event(
100
- logger_name=str(__class__.__name__),
101
- log_type=TagNames.CLASS_INIT.value,
102
- msg=self.create_log_msg_from_init_args(locals=locals()),
103
- )
104
- self.output_dir = os.path.join(
105
- self.project_path, Paths.CONCAT_VIDEOS_DIR.value
106
- )
107
- self.output_path = os.path.join(
108
- self.project_path,
109
- Paths.CONCAT_VIDEOS_DIR.value,
110
- f"merged_video_{self.datetime}.mp4",
111
- )
112
- else:
113
- self.timer = SimbaTimer(start=True)
114
- self.datetime = datetime.now().strftime("%Y%m%d%H%M%S")
115
- self.output_dir, _, _ = get_fn_ext(filepath=video_paths[0])
116
- self.output_path = os.path.join(
117
- self.output_dir, f"merged_video_{self.datetime}.mp4"
118
- )
119
-
120
- self.video_height, self.video_width, self.gpu = video_height, video_width, gpu
121
- self.video_paths, self.concat_type = video_paths, concat_type
122
- if not os.path.exists(self.output_dir):
123
- os.makedirs(self.output_dir)
124
-
125
- def run(self):
126
- if self.concat_type == HORIZONTAL:
127
- _ = horizontal_video_concatenator(
128
- video_paths=self.video_paths,
129
- save_path=self.output_path,
130
- height_px=self.video_height,
131
- gpu=self.gpu,
132
- verbose=True,
133
- )
134
- elif self.concat_type == VERTICAL:
135
- _ = vertical_video_concatenator(
136
- video_paths=self.video_paths,
137
- save_path=self.output_path,
138
- width_px=self.video_width,
139
- gpu=self.gpu,
140
- verbose=True,
141
- )
142
- elif self.concat_type == MOSAIC:
143
- _ = mosaic_concatenator(
144
- video_paths=self.video_paths,
145
- save_path=self.output_path,
146
- width_px=self.video_width,
147
- height_px=self.video_height,
148
- gpu=self.gpu,
149
- verbose=True,
150
- )
151
- else:
152
- _ = mixed_mosaic_concatenator(
153
- video_paths=self.video_paths,
154
- save_path=self.output_path,
155
- gpu=self.gpu,
156
- verbose=True,
157
- )
158
- self.timer.stop_timer()
159
- stdout_success(
160
- msg=f"Merged video saved at {self.output_path}",
161
- source=self.__class__.__name__,
162
- elapsed_time=self.timer.elapsed_time_str,
163
- )
164
-
165
-
166
- # videos = ['/Users/simon/Desktop/envs/simba/troubleshooting/mouse_open_field/project_folder/videos/SI_DAY3_308_CD1_PRESENT_downsampled.mp4', '/Users/simon/Desktop/envs/simba/troubleshooting/mouse_open_field/project_folder/videos/SI_DAY3_308_CD1_PRESENT_downsampled.mp4']
167
- #
168
- # merger = FrameMergererFFmpeg(config_path='/Users/simon/Desktop/envs/simba/troubleshooting/two_black_animals_14bp/project_folder/project_config.ini',
169
- # video_paths=videos,
170
- # video_height=600,
171
- # video_width=600,
172
- # concat_type='vertical') #horizontal, vertical, mosaic, mixed_mosaic
173
- # merger.run()
174
-
175
-
176
- #
177
- # FrameMergererFFmpeg(config_path=None,
178
- # frame_types={'Video 1': '/Users/simon/Desktop/envs/troubleshooting/two_black_animals_14bp/project_folder/videos/Together_1.avi',
179
- # 'Video 2': '/Users/simon/Desktop/envs/troubleshooting/two_black_animals_14bp/project_folder/videos/Together_1.avi'},
180
- # video_height=640,
181
- # video_width=480,
182
- # concat_type='vertical') #horizontal, vertical, mosaic, mixed_mosaic
183
- #
184
- #
185
-
186
-
187
- # FrameMergererFFmpeg(config_path=None,
188
- # frame_types={'Video 1': r'C:\Users\Nape_Computer_2\Desktop\test_videos\Box1_PM2_day_5_20211104T171021.mp4',
189
- # 'Video 2': r'C:\Users\Nape_Computer_2\Desktop\test_videos\Box1_PM2_day_5_20211104T171021.mp4',
190
- # 'Video 3': r'C:\Users\Nape_Computer_2\Desktop\test_videos\Box1_PM2_day_5_20211104T171021.mp4',
191
- # 'Video 4': r'C:\Users\Nape_Computer_2\Desktop\test_videos\Box1_PM2_day_5_20211104T171021.mp4'},
192
- # video_height=640,
193
- # video_width=480,
194
- # concat_type='mixed_mosaic',
195
- # gpu=False) #horizontal, vertical, mosaic, mixed_mosaic
196
- #
1
+ __author__ = "Simon Nilsson; sronilsson@gmail.com"
2
+
3
+ import os
4
+ import shutil
5
+ from datetime import datetime
6
+ from typing import List, Optional, Union
7
+
8
+ try:
9
+ from typing import Literal
10
+ except ImportError:
11
+ from typing_extensions import Literal
12
+
13
+ from simba.mixins.config_reader import ConfigReader
14
+ from simba.utils.checks import (check_ffmpeg_available,
15
+ check_file_exist_and_readable, check_int,
16
+ check_nvidea_gpu_available, check_str,
17
+ check_valid_boolean, check_valid_lst)
18
+ from simba.utils.enums import Paths, TagNames
19
+ from simba.utils.errors import FFMPEGCodecGPUError
20
+ from simba.utils.printing import SimbaTimer, log_event, stdout_success
21
+ from simba.utils.read_write import copy_files_to_directory, get_fn_ext
22
+ from simba.video_processors.video_processing import (
23
+ horizontal_video_concatenator, mixed_mosaic_concatenator,
24
+ mosaic_concatenator, vertical_video_concatenator)
25
+
26
+ HORIZONTAL = "horizontal"
27
+ VERTICAL = "vertical"
28
+ MOSAIC = "mosaic"
29
+ MIXED_MOSAIC = "mixed_mosaic"
30
+ ACCEPTED_TYPES = [HORIZONTAL, VERTICAL, MOSAIC, MIXED_MOSAIC]
31
+
32
+
33
+ class FrameMergererFFmpeg(ConfigReader):
34
+ """
35
+ Merge separate visualizations of classifications, descriptive statistics etc., into single video mosaic.
36
+
37
+ .. note::
38
+ `GitHub tutorial <https://github.com/sgoldenlab/simba/blob/master/docs/tutorial.md#step-12-merge-frames>`_.
39
+
40
+ .. image:: _static/img/mosaic_videos.gif
41
+ :width: 600
42
+ :align: center
43
+
44
+ :parameter str config_path: Optional path to SimBA project config file in Configparser format.
45
+ :parameter Literal["horizontal", "vertical", "mosaic", "mixed_mosaic"] concat_type: Type of concatenation. OPTIONS: 'horizontal', 'vertical', 'mosaic', 'mixed_mosaic'.
46
+ :parameter List[Union[str, os.PathLike]] video_paths: List with videos to concatenate.
47
+ :param int quality: Video quality (CRF value). Lower values = higher quality. Range 0-52. Default 23.
48
+ :parameter Optional[int] video_height: Optional height of the canatenated videos. Required if concat concat_type is not mixed_mosaic.
49
+ :parameter int video_width: Optional wisth of the canatenated videos. Required if concat concat_type is not mixed_mosaic.
50
+ :parameter Optional[bool] gpu: If True, use NVIDEA FFMpeg GPU codecs. Default False.
51
+
52
+ :example:
53
+ >>> video_paths = ['/Users/simon/Desktop/envs/simba/troubleshooting/mouse_open_field/project_folder/videos/SI_DAY3_308_CD1_PRESENT_downsampled.mp4', '/Users/simon/Desktop/envs/simba/troubleshooting/mouse_open_field/project_folder/videos/SI_DAY3_308_CD1_PRESENT_downsampled.mp4']
54
+ >>> merger = FrameMergererFFmpeg(config_path='/Users/simon/Desktop/envs/simba/troubleshooting/two_black_animals_14bp/project_folder/project_config.ini', video_paths=videos, video_height=600, video_width=600, concat_type='mosaic')
55
+ >>> merger.run()
56
+ """
57
+
58
+ def __init__( self,
59
+ concat_type: Literal["horizontal", "vertical", "mosaic", "mixed_mosaic"],
60
+ video_paths: List[Union[str, os.PathLike]],
61
+ video_height: Optional[int] = None,
62
+ video_width: Optional[int] = None,
63
+ config_path: Optional[str] = None,
64
+ quality: int = 23,
65
+ gpu: bool = False):
66
+
67
+ if gpu and not check_nvidea_gpu_available():
68
+ raise FFMPEGCodecGPUError(msg="NVIDEA GPU not available (as evaluated by nvidea-smi returning None", source=self.__class__.__name__)
69
+ check_ffmpeg_available()
70
+ check_str(name=f"{FrameMergererFFmpeg.__name__} concat_type", value=concat_type, options=ACCEPTED_TYPES)
71
+ check_valid_lst(data=video_paths, source=f"{self.__class__.__name__} video_paths", valid_dtypes=(str,), min_len=2)
72
+ check_valid_boolean(value=gpu, source=f'{self.__class__.__name__} gpu', raise_error=True)
73
+ self.quality = 23 if not check_int(name='quality', value=quality, min_value=0, max_value=52, raise_error=False)[0] else int(quality)
74
+ for i in video_paths:
75
+ check_file_exist_and_readable(file_path=i)
76
+ if concat_type != MIXED_MOSAIC:
77
+ check_int(name=f"{FrameMergererFFmpeg.__name__} video_height", value=video_height, min_value=0)
78
+ check_int(name=f"{FrameMergererFFmpeg.__name__} video_width", value=video_height, min_value=0)
79
+ if config_path is not None:
80
+ ConfigReader.__init__(self, config_path=config_path)
81
+ log_event(logger_name=str(__class__.__name__), log_type=TagNames.CLASS_INIT.value, msg=self.create_log_msg_from_init_args(locals=locals()))
82
+ self.output_dir = os.path.join(self.project_path, Paths.CONCAT_VIDEOS_DIR.value)
83
+ self.output_path = os.path.join(self.project_path, Paths.CONCAT_VIDEOS_DIR.value, f"merged_video_{self.datetime}.mp4")
84
+ else:
85
+ self.timer = SimbaTimer(start=True)
86
+ self.datetime = datetime.now().strftime("%Y%m%d%H%M%S")
87
+ self.output_dir, _, _ = get_fn_ext(filepath=video_paths[0])
88
+ self.output_path = os.path.join(self.output_dir, f"merged_video_{self.datetime}.mp4")
89
+
90
+ self.video_height, self.video_width, self.gpu = video_height, video_width, gpu
91
+ self.video_paths, self.concat_type = video_paths, concat_type
92
+ if not os.path.exists(self.output_dir): os.makedirs(self.output_dir)
93
+
94
+ def run(self):
95
+ if self.concat_type == HORIZONTAL:
96
+ _ = horizontal_video_concatenator(video_paths=self.video_paths, save_path=self.output_path, height_px=self.video_height, gpu=self.gpu, quality=self.quality, verbose=True)
97
+ elif self.concat_type == VERTICAL:
98
+ _ = vertical_video_concatenator(video_paths=self.video_paths, save_path=self.output_path, width_px=self.video_width, gpu=self.gpu, quality=self.quality, verbose=True)
99
+ elif self.concat_type == MOSAIC:
100
+ _ = mosaic_concatenator(video_paths=self.video_paths, save_path=self.output_path, width_px=self.video_width, height_px=self.video_height, gpu=self.gpu, quality=self.quality, verbose=True)
101
+ else:
102
+ _ = mixed_mosaic_concatenator(video_paths=self.video_paths, save_path=self.output_path, gpu=self.gpu, verbose=True)
103
+ self.timer.stop_timer()
104
+ stdout_success(msg=f"Merged video saved at {self.output_path}", source=self.__class__.__name__, elapsed_time=self.timer.elapsed_time_str)
105
+
106
+
107
+ # videos = ['/Users/simon/Desktop/envs/simba/troubleshooting/mouse_open_field/project_folder/videos/SI_DAY3_308_CD1_PRESENT_downsampled.mp4', '/Users/simon/Desktop/envs/simba/troubleshooting/mouse_open_field/project_folder/videos/SI_DAY3_308_CD1_PRESENT_downsampled.mp4']
108
+ #
109
+ # merger = FrameMergererFFmpeg(config_path='/Users/simon/Desktop/envs/simba/troubleshooting/two_black_animals_14bp/project_folder/project_config.ini',
110
+ # video_paths=videos,
111
+ # video_height=600,
112
+ # video_width=600,
113
+ # concat_type='vertical') #horizontal, vertical, mosaic, mixed_mosaic
114
+ # merger.run()
115
+
116
+
117
+ #
118
+ # FrameMergererFFmpeg(config_path=None,
119
+ # frame_types={'Video 1': '/Users/simon/Desktop/envs/troubleshooting/two_black_animals_14bp/project_folder/videos/Together_1.avi',
120
+ # 'Video 2': '/Users/simon/Desktop/envs/troubleshooting/two_black_animals_14bp/project_folder/videos/Together_1.avi'},
121
+ # video_height=640,
122
+ # video_width=480,
123
+ # concat_type='vertical') #horizontal, vertical, mosaic, mixed_mosaic
124
+ #
125
+ #
126
+
127
+
128
+ # FrameMergererFFmpeg(config_path=None,
129
+ # frame_types={'Video 1': r'C:\Users\Nape_Computer_2\Desktop\test_videos\Box1_PM2_day_5_20211104T171021.mp4',
130
+ # 'Video 2': r'C:\Users\Nape_Computer_2\Desktop\test_videos\Box1_PM2_day_5_20211104T171021.mp4',
131
+ # 'Video 3': r'C:\Users\Nape_Computer_2\Desktop\test_videos\Box1_PM2_day_5_20211104T171021.mp4',
132
+ # 'Video 4': r'C:\Users\Nape_Computer_2\Desktop\test_videos\Box1_PM2_day_5_20211104T171021.mp4'},
133
+ # video_height=640,
134
+ # video_width=480,
135
+ # concat_type='mixed_mosaic',
136
+ # gpu=False) #horizontal, vertical, mosaic, mixed_mosaic
137
+ #
@@ -2,6 +2,7 @@ __author__ = "Simon Nilsson; sronilsson@gmail.com"
2
2
 
3
3
  import os
4
4
  import shutil
5
+ from copy import deepcopy
5
6
  from typing import List, Optional, Union
6
7
 
7
8
  import cv2
@@ -16,7 +17,7 @@ from simba.utils.checks import (
16
17
  from simba.utils.data import create_color_palette, detect_bouts
17
18
  from simba.utils.enums import Formats, Options
18
19
  from simba.utils.errors import NoSpecifiedOutputError
19
- from simba.utils.lookups import get_named_colors
20
+ from simba.utils.lookups import get_fonts, get_named_colors
20
21
  from simba.utils.printing import stdout_success
21
22
  from simba.utils.read_write import get_fn_ext, read_df
22
23
 
@@ -60,16 +61,18 @@ class GanttCreatorSingleProcess(ConfigReader, PlottingMixin):
60
61
 
61
62
  def __init__(self,
62
63
  config_path: Union[str, os.PathLike],
63
- data_paths: List[Union[str, os.PathLike]],
64
+ data_paths: Optional[Union[Union[str, os.PathLike], List[Union[str, os.PathLike]]]] = None,
64
65
  width: int = 640,
65
66
  height: int = 480,
66
67
  font_size: int = 8,
67
68
  font_rotation: int = 45,
69
+ font: Optional[str] = None,
68
70
  palette: str = 'Set1',
69
- frame_setting: Optional[bool] = False,
70
- video_setting: Optional[bool] = False,
71
- last_frm_setting: Optional[bool] = True,
72
- hhmmss: Optional[bool] = True):
71
+ frame_setting: bool = False,
72
+ video_setting: bool = False,
73
+ last_frm_setting: bool = True,
74
+ hhmmss: bool = True,
75
+ clf_names: Optional[List[str]] = None):
73
76
 
74
77
  if ((frame_setting != True) and (video_setting != True) and (last_frm_setting != True)):
75
78
  raise NoSpecifiedOutputError(msg="SIMBA ERROR: Please select gantt videos, frames, and/or last frame.")
@@ -78,7 +81,13 @@ class GanttCreatorSingleProcess(ConfigReader, PlottingMixin):
78
81
  check_int(value=height, min_value=1, name=f'{self.__class__.__name__} height')
79
82
  check_int(value=font_size, min_value=1, name=f'{self.__class__.__name__} font_size')
80
83
  check_int(value=font_rotation, min_value=0, max_value=180, name=f'{self.__class__.__name__} font_rotation')
81
- check_valid_lst(data=data_paths, source=f'{self.__class__.__name__} data_paths', valid_dtypes=(str,), min_len=1)
84
+ if isinstance(data_paths, list):
85
+ check_valid_lst(data=data_paths, source=f'{self.__class__.__name__} data_paths', valid_dtypes=(str,), min_len=1)
86
+ elif isinstance(data_paths, str):
87
+ check_file_exist_and_readable(file_path=data_paths)
88
+ data_paths = [data_paths]
89
+ else:
90
+ data_paths = deepcopy(self.machine_results_paths)
82
91
  check_valid_boolean(value=hhmmss, source=f'{self.__class__.__name__} hhmmss', raise_error=False)
83
92
  palettes = Options.PALETTE_OPTIONS_CATEGORICAL.value + Options.PALETTE_OPTIONS.value
84
93
  check_str(name=f'{self.__class__.__name__} palette', value=palette, options=palettes)
@@ -90,7 +99,12 @@ class GanttCreatorSingleProcess(ConfigReader, PlottingMixin):
90
99
  if not os.path.exists(self.gantt_plot_dir): os.makedirs(self.gantt_plot_dir)
91
100
  self.frame_setting, self.video_setting, self.last_frm_setting = frame_setting, video_setting, last_frm_setting
92
101
  self.width, self.height, self.font_size, self.font_rotation = width, height, font_size, font_rotation
93
- self.data_paths, self.hhmmss = data_paths, hhmmss
102
+ if font is not None:
103
+ check_str(name=f'{self.__class__.__name__} font', value=font, options=list(get_fonts().keys()), raise_error=True)
104
+ if clf_names is not None:
105
+ check_valid_lst(data=clf_names, source=f'{self.__class__.__name__} clf_names', valid_dtypes=(str,), valid_values=self.clf_names, min_len=1, raise_error=True)
106
+ self.clf_names = clf_names
107
+ self.data_paths, self.hhmmss, self.font = data_paths, hhmmss, font
94
108
  self.colours = get_named_colors()
95
109
  self.colour_tuple_x = list(np.arange(3.5, 203.5, 5))
96
110
 
@@ -121,6 +135,7 @@ class GanttCreatorSingleProcess(ConfigReader, PlottingMixin):
121
135
  font_size=self.font_size,
122
136
  font_rotation=self.font_rotation,
123
137
  video_name=self.video_name,
138
+ font=self.font,
124
139
  save_path=os.path.join(self.gantt_plot_dir, f"{self.video_name }_final_image.png"),
125
140
  palette=self.clr_lst,
126
141
  hhmmss=self.hhmmss)
@@ -135,6 +150,7 @@ class GanttCreatorSingleProcess(ConfigReader, PlottingMixin):
135
150
  width=self.width,
136
151
  height=self.height,
137
152
  font_size=self.font_size,
153
+ font=self.font,
138
154
  font_rotation=self.font_rotation,
139
155
  video_name=self.video_name,
140
156
  palette=self.clr_lst,
@@ -156,13 +172,16 @@ class GanttCreatorSingleProcess(ConfigReader, PlottingMixin):
156
172
  # test = GanttCreatorSingleProcess(config_path=r"C:\troubleshooting\mitra\project_folder\project_config.ini",
157
173
  # frame_setting=False,
158
174
  # video_setting=False,
159
- # data_paths=[r"C:\troubleshooting\mitra\project_folder\csv\machine_results\592_MA147_Gq_CNO_0515.csv"],
175
+ # data_paths=[r"C:\troubleshooting\mitra\project_folder\csv\machine_results\501_MA142_Gi_CNO_0516.csv"],
160
176
  # last_frm_setting=True,
161
177
  # width=640,
162
178
  # height= 480,
163
179
  # font_size=10,
180
+ # font=None,
164
181
  # font_rotation=45,
165
- # palette='Set1')
182
+ # hhmmss=False,
183
+ # palette='Set1',
184
+ # clf_names=['straub_tail'])
166
185
  # test.run()
167
186
 
168
187