simba-uw-tf-dev 4.6.1__py3-none-any.whl → 4.6.3__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 (53) hide show
  1. simba/SimBA.py +2 -2
  2. simba/assets/icons/frames_2.png +0 -0
  3. simba/data_processors/agg_clf_counter_mp.py +52 -53
  4. simba/data_processors/cuda/image.py +3 -1
  5. simba/data_processors/cue_light_analyzer.py +5 -9
  6. simba/mixins/geometry_mixin.py +14 -28
  7. simba/mixins/image_mixin.py +10 -14
  8. simba/mixins/train_model_mixin.py +2 -2
  9. simba/plotting/ROI_feature_visualizer_mp.py +3 -5
  10. simba/plotting/clf_validator_mp.py +4 -5
  11. simba/plotting/cue_light_visualizer.py +6 -7
  12. simba/plotting/directing_animals_visualizer_mp.py +2 -3
  13. simba/plotting/distance_plotter_mp.py +378 -378
  14. simba/plotting/frame_mergerer_ffmpeg.py +137 -137
  15. simba/plotting/gantt_creator_mp.py +59 -31
  16. simba/plotting/geometry_plotter.py +270 -272
  17. simba/plotting/heat_mapper_clf_mp.py +2 -4
  18. simba/plotting/heat_mapper_location_mp.py +2 -2
  19. simba/plotting/light_dark_box_plotter.py +2 -2
  20. simba/plotting/path_plotter_mp.py +26 -29
  21. simba/plotting/plot_clf_results_mp.py +455 -454
  22. simba/plotting/pose_plotter_mp.py +27 -32
  23. simba/plotting/probability_plot_creator_mp.py +288 -288
  24. simba/plotting/roi_plotter_mp.py +29 -30
  25. simba/plotting/single_run_model_validation_video_mp.py +427 -427
  26. simba/plotting/spontaneous_alternation_plotter.py +2 -3
  27. simba/plotting/yolo_pose_track_visualizer.py +31 -27
  28. simba/plotting/yolo_pose_visualizer.py +32 -34
  29. simba/plotting/yolo_seg_visualizer.py +2 -3
  30. simba/roi_tools/roi_aggregate_stats_mp.py +4 -3
  31. simba/roi_tools/roi_clf_calculator_mp.py +3 -3
  32. simba/sandbox/cuda/egocentric_rotator.py +374 -0
  33. simba/sandbox/get_cpu_pool.py +5 -0
  34. simba/ui/pop_ups/clf_add_remove_print_pop_up.py +3 -1
  35. simba/ui/pop_ups/egocentric_alignment_pop_up.py +6 -3
  36. simba/ui/pop_ups/multiple_videos_to_frames_popup.py +10 -11
  37. simba/ui/pop_ups/single_video_to_frames_popup.py +10 -10
  38. simba/ui/pop_ups/video_processing_pop_up.py +63 -63
  39. simba/ui/tkinter_functions.py +7 -1
  40. simba/utils/data.py +89 -12
  41. simba/utils/enums.py +1 -0
  42. simba/utils/printing.py +9 -8
  43. simba/utils/read_write.py +3726 -3721
  44. simba/video_processors/clahe_ui.py +65 -22
  45. simba/video_processors/egocentric_video_rotator.py +6 -9
  46. simba/video_processors/video_processing.py +21 -10
  47. simba/video_processors/videos_to_frames.py +3 -2
  48. {simba_uw_tf_dev-4.6.1.dist-info → simba_uw_tf_dev-4.6.3.dist-info}/METADATA +1 -1
  49. {simba_uw_tf_dev-4.6.1.dist-info → simba_uw_tf_dev-4.6.3.dist-info}/RECORD +53 -50
  50. {simba_uw_tf_dev-4.6.1.dist-info → simba_uw_tf_dev-4.6.3.dist-info}/LICENSE +0 -0
  51. {simba_uw_tf_dev-4.6.1.dist-info → simba_uw_tf_dev-4.6.3.dist-info}/WHEEL +0 -0
  52. {simba_uw_tf_dev-4.6.1.dist-info → simba_uw_tf_dev-4.6.3.dist-info}/entry_points.txt +0 -0
  53. {simba_uw_tf_dev-4.6.1.dist-info → simba_uw_tf_dev-4.6.3.dist-info}/top_level.txt +0 -0
@@ -14,7 +14,7 @@ from simba.data_processors.spontaneous_alternation_calculator import \
14
14
  from simba.mixins.config_reader import ConfigReader
15
15
  from simba.utils.checks import (check_file_exist_and_readable, check_float,
16
16
  check_int, check_str, check_valid_lst)
17
- from simba.utils.data import detect_bouts
17
+ from simba.utils.data import detect_bouts, terminate_cpu_pool
18
18
  from simba.utils.enums import Formats, Paths, TextOptions
19
19
  from simba.utils.errors import AnimalNumberError, InvalidInputError
20
20
  from simba.utils.printing import stdout_success
@@ -296,8 +296,7 @@ class SpontaneousAlternationsPlotter(ConfigReader):
296
296
  pool.imap(constants, frm_index, chunksize=self.multiprocess_chunksize)
297
297
  ):
298
298
  print(f"Section {cnt} complete...")
299
- pool.terminate()
300
- pool.join()
299
+ terminate_cpu_pool(pool=pool, force=False)
301
300
  print(f"Joining {sa_computer.video_name} multiprocessed video...")
302
301
  concatenate_videos_in_folder(in_folder=self.temp_folder, save_path=save_path)
303
302
  self.timer.stop_timer()
@@ -13,9 +13,10 @@ from simba.mixins.plotting_mixin import PlottingMixin
13
13
  from simba.utils.checks import (check_file_exist_and_readable, check_float,
14
14
  check_if_dir_exists, check_int,
15
15
  check_valid_boolean, check_valid_dataframe)
16
+ from simba.utils.data import terminate_cpu_pool, get_cpu_pool
16
17
  from simba.utils.enums import Defaults, Formats
17
18
  from simba.utils.errors import InvalidFilepathError, NoFilesFoundError
18
- from simba.utils.lookups import get_random_color_palette, intermittent_palette
19
+ from simba.utils.lookups import get_random_color_palette, intermittent_palette, get_current_time
19
20
  from simba.utils.printing import SimbaTimer, stdout_success
20
21
  from simba.utils.read_write import (concatenate_videos_in_folder,
21
22
  create_directory,
@@ -53,13 +54,12 @@ def _yolo_keypoint_track_visualizer(frm_ids: np.ndarray,
53
54
  video_save_path = os.path.join(save_dir, f'{batch_id}.mp4')
54
55
  video_writer = cv2.VideoWriter(video_save_path, fourcc, video_meta_data["fps"], (video_meta_data["width"], video_meta_data["height"]))
55
56
  while current_frm <= end_frm:
56
- print(f'Processing frame {current_frm}/{video_meta_data["frame_count"]} (batch: {batch_id})...')
57
+ print(f'[{get_current_time()}] Processing frame {current_frm}/{video_meta_data["frame_count"]} (batch: {batch_id}, video name: {video_meta_data["video_name"]})...')
57
58
  img = read_frm_of_video(video_path=video_path, frame_index=current_frm, raise_error=False)
58
59
  if img is not None:
59
60
  frm_data = data.loc[data[FRAME] == current_frm]
60
61
  frm_data = frm_data[frm_data[CONFIDENCE] > threshold]
61
62
  for cnt, (row, row_data) in enumerate(frm_data.iterrows()):
62
-
63
63
  clrs = np.array(palettes[int(row_data[TRACK])]).astype(np.int32)
64
64
  bbox_cords = row_data[BOX_CORD_FIELDS].values.astype(np.int32).reshape(-1, 2)
65
65
  kp_coords = row_data.drop(EXPECTED_COLS).values.astype(np.int32).reshape(-1, 3)[:, :-1]
@@ -159,6 +159,8 @@ class YOLOPoseTrackVisualizer():
159
159
  self.threshold, self.circle_size, self.thickness, self.show_bbox, self.overwrite = threshold, circle_size, thickness, bbox, overwrite
160
160
 
161
161
  def run(self):
162
+ self.pool = get_cpu_pool(core_cnt=self.core_cnt, maxtasksperchild=Defaults.MAXIMUM_MAX_TASK_PER_CHILD.value, source=self.__class__.__name__)
163
+ self.timer = SimbaTimer(start=True)
162
164
  for video_cnt, (video_name, data_path) in enumerate(self.data_paths.items()):
163
165
  print(f'Visualizing YOLO pose tracks in video {video_name} ({video_cnt+1}/{len(self.data_paths.keys())}) ...')
164
166
  video_timer = SimbaTimer(start=True)
@@ -189,23 +191,25 @@ class YOLOPoseTrackVisualizer():
189
191
 
190
192
  frm_batches = np.array_split(np.array(list(range(0, df_frm_cnt))), self.core_cnt)
191
193
  frm_batches = [(i, j) for i, j in enumerate(frm_batches)]
192
- with multiprocessing.Pool(self.core_cnt, maxtasksperchild=Defaults.MAXIMUM_MAX_TASK_PER_CHILD.value) as pool:
193
- constants = functools.partial(_yolo_keypoint_track_visualizer,
194
- data=self.data_df,
195
- threshold=self.threshold,
196
- video_path=self.video_paths[video_name],
197
- save_dir=video_temp_dir,
198
- circle_size=video_circle_size,
199
- thickness=video_thickness,
200
- palettes=video_palettes,
201
- show_bbox=self.show_bbox)
202
- for cnt, result in enumerate(pool.imap(constants, frm_batches, chunksize=1)):
203
- print(f'Video batch {result+1}/{self.core_cnt} complete...')
204
- pool.terminate()
205
- pool.join()
194
+ constants = functools.partial(_yolo_keypoint_track_visualizer,
195
+ data=self.data_df,
196
+ threshold=self.threshold,
197
+ video_path=self.video_paths[video_name],
198
+ save_dir=video_temp_dir,
199
+ circle_size=video_circle_size,
200
+ thickness=video_thickness,
201
+ palettes=video_palettes,
202
+ show_bbox=self.show_bbox)
203
+ for cnt, result in enumerate(self.pool.imap(constants, frm_batches, chunksize=1)):
204
+ print(f'[{get_current_time()}] Video batch {result+1}/{self.core_cnt} complete...')
206
205
  video_timer.stop_timer()
207
206
  concatenate_videos_in_folder(in_folder=video_temp_dir, save_path=save_path, gpu=True)
208
207
  stdout_success(msg=f'YOLO track pose video saved at {save_path}', source=self.__class__.__name__, elapsed_time=video_timer.elapsed_time_str)
208
+ terminate_cpu_pool(pool=self.pool, force=False, source=self.__class__.__name__)
209
+ self.timer.stop_timer()
210
+ stdout_success(msg=f'YOLO track pose video data for {len(self.data_paths.keys())} videos saved in {self.save_dir}', source=self.__class__.__name__, elapsed_time=self.timer.elapsed_time_str)
211
+
212
+
209
213
  #
210
214
  # if __name__ == "__main__" and not hasattr(sys, 'ps1'):
211
215
  # parser = argparse.ArgumentParser(description="Visualize YOLO pose tracking CSV outputs on their source videos.")
@@ -247,13 +251,13 @@ class YOLOPoseTrackVisualizer():
247
251
  # #kp_vis.run()
248
252
 
249
253
 
250
- if __name__ == "__main__":
251
- VIDEO_PATH = r"E:\netholabs_videos\primeintellect_100_videos"
252
- DATA_PATH = r"E:\netholabs_videos\primeintellect_100_largest"
253
- SAVE_DIR = r"E:\netholabs_videos\primeintellect_100_videos\out"
254
- kp_vis = YOLOPoseTrackVisualizer(data_path=DATA_PATH,
255
- video_path=VIDEO_PATH,
256
- save_dir=SAVE_DIR,
257
- core_cnt=8,
258
- bbox=True)
259
- kp_vis.run()
254
+ # if __name__ == "__main__":
255
+ # VIDEO_PATH = r"E:\netholabs_videos\primeintellect_100_videos"
256
+ # DATA_PATH = r"E:\netholabs_videos\primeintellect_100_largest"
257
+ # SAVE_DIR = r"E:\netholabs_videos\primeintellect_100_videos\out"
258
+ # kp_vis = YOLOPoseTrackVisualizer(data_path=DATA_PATH,
259
+ # video_path=VIDEO_PATH,
260
+ # save_dir=SAVE_DIR,
261
+ # core_cnt=8,
262
+ # bbox=True)
263
+ # kp_vis.run()
@@ -14,7 +14,7 @@ from simba.utils.checks import (check_file_exist_and_readable, check_float,
14
14
  check_if_dir_exists, check_int,
15
15
  check_valid_boolean, check_valid_dataframe,
16
16
  check_valid_lst, check_valid_tuple)
17
- from simba.utils.data import create_color_palette
17
+ from simba.utils.data import create_color_palette, terminate_cpu_pool, get_cpu_pool
18
18
  from simba.utils.enums import Defaults, Options
19
19
  from simba.utils.errors import (CountError, DataHeaderError, FrameRangeError,
20
20
  InvalidInputError, NoDataError)
@@ -24,8 +24,7 @@ from simba.utils.read_write import (concatenate_videos_in_folder,
24
24
  find_files_of_filetypes_in_directory,
25
25
  get_fn_ext, get_video_meta_data,
26
26
  read_frm_of_video, recursive_file_search,
27
- remove_a_folder)
28
- from simba.utils.warnings import InvalidValueWarning
27
+ remove_a_folder, get_current_time)
29
28
 
30
29
  FRAME = 'FRAME'
31
30
  CLASS_ID = 'CLASS_ID'
@@ -58,7 +57,7 @@ def _yolo_keypoint_visualizer(frm_ids: np.ndarray,
58
57
  if TRACK in data.columns:
59
58
  data = data.drop([TRACK], axis=1)
60
59
  while current_frm <= end_frm:
61
- print(f'Processing frame {current_frm}/{video_meta_data["frame_count"]} (batch: {batch_id}, video: {video_meta_data["video_name"]})...')
60
+ print(f'[{get_current_time()}] Processing frame {current_frm}/{video_meta_data["frame_count"]} (batch: {batch_id}, video: {video_meta_data["video_name"]})...')
62
61
  img = read_frm_of_video(video_path=video_path, frame_index=current_frm)
63
62
  frm_data = data.loc[data[FRAME] == current_frm]
64
63
  frm_data = frm_data[frm_data[CONFIDENCE] > threshold]
@@ -206,6 +205,7 @@ class YOLOPoseVisualizer():
206
205
  self.timer = SimbaTimer(start=True)
207
206
 
208
207
  def run(self):
208
+ self.pool = get_cpu_pool(core_cnt=self.core_cnt, maxtasksperchild=Defaults.MAXIMUM_MAX_TASK_PER_CHILD.value, verbose=True, source=self.__class__.__name__)
209
209
  for video_cnt, (video_name, data_path) in enumerate(self.data_paths.items()):
210
210
  video_timer = SimbaTimer(start=True)
211
211
  self.video_temp_dir = os.path.join(self.save_dir, video_name, "temp")
@@ -248,26 +248,24 @@ class YOLOPoseVisualizer():
248
248
  thickness = deepcopy(self.thickness)
249
249
  frm_batches = np.array_split(np.array(list(range(0, self.df_frm_cnt))), self.core_cnt)
250
250
  frm_batches = [(i, j) for i, j in enumerate(frm_batches)]
251
- if self.verbose: print(f'Visualizing video {self.video_meta_data["video_name"]} (frame count: {self.video_meta_data["frame_count"]})...')
252
- with multiprocessing.Pool(self.core_cnt, maxtasksperchild=Defaults.MAXIMUM_MAX_TASK_PER_CHILD.value) as pool:
253
- constants = functools.partial(_yolo_keypoint_visualizer,
254
- data=self.data_df,
255
- threshold=self.threshold,
256
- video_path=self.video_paths[video_name],
257
- save_dir=self.video_temp_dir,
258
- circle_size=circle_size,
259
- thickness=thickness,
260
- palettes=self.clrs,
261
- bbox=self.bbox,
262
- skeleton=self.skeleton)
263
- for cnt, result in enumerate(pool.imap(constants, frm_batches, chunksize=1)):
264
- print(f'Video batch {result+1}/{self.core_cnt} complete...')
265
- pool.terminate()
266
- pool.join()
251
+ if self.verbose: print(f'[{get_current_time()}] Visualizing video {self.video_meta_data["video_name"]} (frame count: {self.video_meta_data["frame_count"]})...')
252
+ constants = functools.partial(_yolo_keypoint_visualizer,
253
+ data=self.data_df,
254
+ threshold=self.threshold,
255
+ video_path=self.video_paths[video_name],
256
+ save_dir=self.video_temp_dir,
257
+ circle_size=circle_size,
258
+ thickness=thickness,
259
+ palettes=self.clrs,
260
+ bbox=self.bbox,
261
+ skeleton=self.skeleton)
262
+ for cnt, result in enumerate(self.pool.imap(constants, frm_batches, chunksize=1)):
263
+ print(f'[{get_current_time()}] Video batch {result+1}/{self.core_cnt} complete...')
267
264
  video_timer.stop_timer()
268
265
  concatenate_videos_in_folder(in_folder=self.video_temp_dir, save_path=self.save_path, gpu=True)
269
266
  stdout_success(msg=f'YOLO pose video saved at {self.save_path} (Video {video_cnt+1}/{len(list(self.data_paths.keys()))})', source=self.__class__.__name__, elapsed_time=video_timer.elapsed_time_str)
270
267
 
268
+ terminate_cpu_pool(pool=self.pool, force=False, source=self.__class__.__name__)
271
269
  self.timer.stop_timer()
272
270
  stdout_success(msg=f'{len(list(self.data_paths.keys()))} YOLO pose video saved in directory {self.save_dir}', source=self.__class__.__name__, elapsed_time=self.timer.elapsed_time_str)
273
271
 
@@ -413,18 +411,18 @@ class YOLOPoseVisualizer():
413
411
  # kp_vis.run()
414
412
 
415
413
 
416
- # if __name__ == "__main__":
417
- # video_path = r"E:\netholabs_videos\primeintellect_100_videos\cage_1_date_2025_08_28_hour_20_minute_21.avi"
418
- # data_path = r"E:\netholabs_videos\primeintellect_100_largest\cage_1_date_2025_08_28_hour_20_minute_21.csv"
419
- # save_dir = r'E:\netholabs_videos\test_order'
420
- # kp_vis = YOLOPoseVisualizer(data_path=data_path,
421
- # video_path=video_path,
422
- # save_dir=save_dir,
423
- # core_cnt=14,
424
- # palettes=('tab20',),
425
- # recursive=True,
426
- # sample_n=None)
427
- #
428
- #
429
- # kp_vis.run()
414
+ if __name__ == "__main__":
415
+ video_path = r"E:\netholabs_videos\primeintellect_100_videos\cage_1_date_2025_08_28_hour_20_minute_21.avi"
416
+ data_path = r"E:\netholabs_videos\primeintellect_100_largest\cage_1_date_2025_08_28_hour_20_minute_21.csv"
417
+ save_dir = r'E:\netholabs_videos\test_order'
418
+ kp_vis = YOLOPoseVisualizer(data_path=data_path,
419
+ video_path=video_path,
420
+ save_dir=save_dir,
421
+ core_cnt=14,
422
+ palettes=('tab20',),
423
+ recursive=True,
424
+ sample_n=None)
425
+
426
+
427
+ kp_vis.run()
430
428
 
@@ -12,7 +12,7 @@ from simba.utils.checks import (check_file_exist_and_readable, check_float,
12
12
  check_int, check_valid_boolean,
13
13
  check_valid_dataframe, check_valid_lst,
14
14
  check_valid_tuple)
15
- from simba.utils.data import create_color_palette
15
+ from simba.utils.data import create_color_palette, terminate_cpu_pool
16
16
  from simba.utils.enums import Defaults, Options
17
17
  from simba.utils.errors import CountError, DataHeaderError, FrameRangeError
18
18
  from simba.utils.printing import SimbaTimer, stdout_success
@@ -140,8 +140,7 @@ class YOLOSegmentationVisualizer():
140
140
  shape_opacity=self.shape_opacity)
141
141
  for cnt, result in enumerate(pool.imap(constants, frm_batches, chunksize=1)):
142
142
  print(f'Video batch {result+1}/{self.core_cnt} complete...')
143
- pool.terminate()
144
- pool.join()
143
+ terminate_cpu_pool(pool=pool, force=False)
145
144
  video_timer.stop_timer()
146
145
  concatenate_videos_in_folder(in_folder=self.video_temp_dir, save_path=self.save_path, gpu=True)
147
146
  stdout_success(msg=f'YOLO pose video saved at {self.save_path}', source=self.__class__.__name__, elapsed_time=video_timer.elapsed_time_str)
@@ -17,7 +17,8 @@ from simba.utils.checks import (
17
17
  check_all_file_names_are_represented_in_video_log,
18
18
  check_file_exist_and_readable, check_float, check_if_dir_exists, check_int,
19
19
  check_that_column_exist, check_valid_boolean, check_valid_lst)
20
- from simba.utils.data import detect_bouts, slice_roi_dict_for_video
20
+ from simba.utils.data import (detect_bouts, slice_roi_dict_for_video,
21
+ terminate_cpu_pool)
21
22
  from simba.utils.enums import ROI_SETTINGS, Formats, Keys
22
23
  from simba.utils.errors import CountError, ROICoordinatesNotFoundError
23
24
  from simba.utils.printing import SimbaTimer, stdout_success
@@ -297,8 +298,8 @@ class ROIAggregateStatisticsAnalyzerMultiprocess(ConfigReader, FeatureExtraction
297
298
  self.results.append(result); self.detailed_dfs.append(detailed_dfs)
298
299
  print(f"Data batch core {batch_id} / {self.core_cnt} complete...")
299
300
  self.results = pd.concat(self.results, axis=0).reset_index(drop=True)
300
- pool.join()
301
- pool.terminate()
301
+ terminate_cpu_pool(pool=pool, force=False)
302
+
302
303
 
303
304
  def save(self):
304
305
  self.__clean_results()
@@ -16,7 +16,8 @@ from simba.utils.checks import (
16
16
  check_all_file_names_are_represented_in_video_log,
17
17
  check_file_exist_and_readable, check_if_dir_exists, check_int,
18
18
  check_valid_boolean, check_valid_dataframe, check_valid_lst)
19
- from simba.utils.data import detect_bouts, slice_roi_dict_for_video
19
+ from simba.utils.data import (detect_bouts, slice_roi_dict_for_video,
20
+ terminate_cpu_pool)
20
21
  from simba.utils.enums import ROI_SETTINGS, Keys
21
22
  from simba.utils.errors import InvalidInputError, NoROIDataError
22
23
  from simba.utils.lookups import get_current_time
@@ -237,8 +238,7 @@ class ROIClfCalculatorMultiprocess(ConfigReader):
237
238
  self.bouts_results.append(batch_bout_results)
238
239
  print(f"Data batch core {batch_id + 1} / {self.core_cnt} complete...")
239
240
  self.bouts_results = pd.concat(self.bouts_results, axis=0).reset_index(drop=True) if len(self.bouts_results) > 0 else None
240
- pool.join()
241
- pool.terminate()
241
+ terminate_cpu_pool(pool=pool, force=False)
242
242
 
243
243
  def save(self):
244
244
  self.timer.stop_timer()