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
simba/SimBA.py CHANGED
@@ -966,8 +966,8 @@ class App(object):
966
966
  video_process_menu.add_cascade(label="Drop body-parts from tracking data", compound="left", image=self.menu_icons["trash"]["img"], command=DropTrackingDataPopUp, font=Formats.FONT_REGULAR.value)
967
967
  extract_frames_menu = Menu(video_process_menu, font=Formats.FONT_REGULAR.value)
968
968
  extract_frames_menu.add_command(label="Extract defined frames", command=ExtractSpecificFramesPopUp, font=Formats.FONT_REGULAR.value, image=self.menu_icons["frames"]["img"], compound="left")
969
- extract_frames_menu.add_command(label="Extract frames from single video", command=SingleVideo2FramesPopUp, font=Formats.FONT_REGULAR.value, image=self.menu_icons["video"]["img"], compound="left")
970
- extract_frames_menu.add_command(label="Extract frames from multiple video", command=MultipleVideos2FramesPopUp, font=Formats.FONT_REGULAR.value, image=self.menu_icons["stack"]["img"], compound="left")
969
+ extract_frames_menu.add_command(label="Extract frames from single video", command=SingleVideo2FramesPopUp, font=Formats.FONT_REGULAR.value, image=self.menu_icons["frames_2"]["img"], compound="left")
970
+ extract_frames_menu.add_command(label="Extract frames from multiple videos", command=MultipleVideos2FramesPopUp, font=Formats.FONT_REGULAR.value, image=self.menu_icons["stack"]["img"], compound="left")
971
971
  extract_frames_menu.add_command(label="Extract frames from seq files", command=ExtractSEQFramesPopUp, font=Formats.FONT_REGULAR.value, image=self.menu_icons["fire"]["img"], compound="left")
972
972
  video_process_menu.add_cascade(label="Extract frames...", compound="left", image=self.menu_icons["frames"]["img"], menu=extract_frames_menu, font=Formats.FONT_REGULAR.value)
973
973
 
Binary file
@@ -20,7 +20,7 @@ from simba.utils.checks import (
20
20
  check_all_file_names_are_represented_in_video_log,
21
21
  check_file_exist_and_readable, check_if_dir_exists, check_int,
22
22
  check_valid_boolean, check_valid_dataframe, check_valid_lst)
23
- from simba.utils.data import detect_bouts
23
+ from simba.utils.data import detect_bouts, terminate_cpu_pool
24
24
  from simba.utils.enums import TagNames
25
25
  from simba.utils.errors import NoChoosenMeasurementError
26
26
  from simba.utils.printing import SimbaTimer, log_event, stdout_success
@@ -210,8 +210,7 @@ class AggregateClfCalculatorMultiprocess(ConfigReader):
210
210
  self.bouts_df_lst.append(batch_bouts_df_lst)
211
211
  print(f"Data batch core {batch_id+1} / {self.core_cnt} complete...")
212
212
  self.bouts_df_lst = [df for sub in self.bouts_df_lst for df in sub]
213
- pool.join()
214
- pool.terminate()
213
+ terminate_cpu_pool(pool=pool, force=False)
215
214
 
216
215
  def save(self) -> None:
217
216
  """
@@ -242,56 +241,56 @@ class AggregateClfCalculatorMultiprocess(ConfigReader):
242
241
  self.timer.stop_timer()
243
242
  stdout_success(msg=f"Data aggregate log saved at {self.save_path}", elapsed_time=self.timer.elapsed_time_str, source=self.__class__.__name__)
244
243
 
245
- if __name__ == "__main__" and not hasattr(sys, 'ps1'):
246
- parser = argparse.ArgumentParser(description='Compute aggregate descriptive statistics from classification data.')
247
- parser.add_argument('--config_path', type=str, required=True, help='Path to SimBA project config file')
248
- parser.add_argument('--classifiers', type=str, nargs='+', required=True, help='List of classifier names to analyze')
249
- parser.add_argument('--data_dir', type=str, default=None, help='Directory containing machine results CSV files (default: project machine_results directory)')
250
- parser.add_argument('--detailed_bout_data', action='store_true', help='Save detailed bout data for each bout')
251
- parser.add_argument('--transpose', action='store_true', help='Create output with one video per row')
252
- parser.add_argument('--no_first_occurrence', action='store_true', help='Disable first occurrence calculation')
253
- parser.add_argument('--no_event_count', action='store_true', help='Disable event count calculation')
254
- parser.add_argument('--no_total_event_duration', action='store_true', help='Disable total event duration calculation')
255
- parser.add_argument('--no_mean_event_duration', action='store_true', help='Disable mean event duration calculation')
256
- parser.add_argument('--no_median_event_duration', action='store_true', help='Disable median event duration calculation')
257
- parser.add_argument('--no_mean_interval_duration', action='store_true', help='Disable mean interval duration calculation')
258
- parser.add_argument('--no_median_interval_duration', action='store_true', help='Disable median interval duration calculation')
259
- parser.add_argument('--frame_count', action='store_true', help='Include frame count in output')
260
- parser.add_argument('--video_length', action='store_true', help='Include video length in output')
261
-
262
- args = parser.parse_args()
263
-
264
- clf_calculator = AggregateClfCalculatorMultiprocess(
265
- config_path=args.config_path,
266
- classifiers=args.classifiers,
267
- data_dir=args.data_dir,
268
- detailed_bout_data=args.detailed_bout_data,
269
- transpose=args.transpose,
270
- first_occurrence=not args.no_first_occurrence,
271
- event_count=not args.no_event_count,
272
- total_event_duration=not args.no_total_event_duration,
273
- mean_event_duration=not args.no_mean_event_duration,
274
- median_event_duration=not args.no_median_event_duration,
275
- mean_interval_duration=not args.no_mean_interval_duration,
276
- median_interval_duration=not args.no_median_interval_duration,
277
- frame_count=args.frame_count,
278
- video_length=args.video_length
279
- )
280
- clf_calculator.run()
281
- clf_calculator.save()
282
-
283
- # if __name__ == "__main__":
284
- # test = AggregateClfCalculatorMultiprocess(config_path=r"D:\troubleshooting\maplight_ri\project_folder\project_config.ini",
285
- # classifiers=['attack'],
286
- # transpose=True,
287
- # mean_event_duration = True,
288
- # median_event_duration = True,
289
- # mean_interval_duration = True,
290
- # median_interval_duration = True,
291
- # detailed_bout_data=True,
292
- # core_cnt=12)
293
- # test.run()
294
- # test.save()
244
+ # if __name__ == "__main__" and not hasattr(sys, 'ps1'):
245
+ # parser = argparse.ArgumentParser(description='Compute aggregate descriptive statistics from classification data.')
246
+ # parser.add_argument('--config_path', type=str, required=True, help='Path to SimBA project config file')
247
+ # parser.add_argument('--classifiers', type=str, nargs='+', required=True, help='List of classifier names to analyze')
248
+ # parser.add_argument('--data_dir', type=str, default=None, help='Directory containing machine results CSV files (default: project machine_results directory)')
249
+ # parser.add_argument('--detailed_bout_data', action='store_true', help='Save detailed bout data for each bout')
250
+ # parser.add_argument('--transpose', action='store_true', help='Create output with one video per row')
251
+ # parser.add_argument('--no_first_occurrence', action='store_true', help='Disable first occurrence calculation')
252
+ # parser.add_argument('--no_event_count', action='store_true', help='Disable event count calculation')
253
+ # parser.add_argument('--no_total_event_duration', action='store_true', help='Disable total event duration calculation')
254
+ # parser.add_argument('--no_mean_event_duration', action='store_true', help='Disable mean event duration calculation')
255
+ # parser.add_argument('--no_median_event_duration', action='store_true', help='Disable median event duration calculation')
256
+ # parser.add_argument('--no_mean_interval_duration', action='store_true', help='Disable mean interval duration calculation')
257
+ # parser.add_argument('--no_median_interval_duration', action='store_true', help='Disable median interval duration calculation')
258
+ # parser.add_argument('--frame_count', action='store_true', help='Include frame count in output')
259
+ # parser.add_argument('--video_length', action='store_true', help='Include video length in output')
260
+ #
261
+ # args = parser.parse_args()
262
+ #
263
+ # clf_calculator = AggregateClfCalculatorMultiprocess(
264
+ # config_path=args.config_path,
265
+ # classifiers=args.classifiers,
266
+ # data_dir=args.data_dir,
267
+ # detailed_bout_data=args.detailed_bout_data,
268
+ # transpose=args.transpose,
269
+ # first_occurrence=not args.no_first_occurrence,
270
+ # event_count=not args.no_event_count,
271
+ # total_event_duration=not args.no_total_event_duration,
272
+ # mean_event_duration=not args.no_mean_event_duration,
273
+ # median_event_duration=not args.no_median_event_duration,
274
+ # mean_interval_duration=not args.no_mean_interval_duration,
275
+ # median_interval_duration=not args.no_median_interval_duration,
276
+ # frame_count=args.frame_count,
277
+ # video_length=args.video_length
278
+ # )
279
+ # clf_calculator.run()
280
+ # clf_calculator.save()
281
+
282
+ if __name__ == "__main__":
283
+ test = AggregateClfCalculatorMultiprocess(config_path=r"D:\troubleshooting\maplight_ri\project_folder\project_config.ini",
284
+ classifiers=['attack'],
285
+ transpose=True,
286
+ mean_event_duration = True,
287
+ median_event_duration = True,
288
+ mean_interval_duration = True,
289
+ median_interval_duration = True,
290
+ detailed_bout_data=True,
291
+ core_cnt=12)
292
+ test.run()
293
+ test.save()
295
294
 
296
295
 
297
296
  # test = AggregateClfCalculator(config_path=r"C:\troubleshooting\mitra\project_folder\project_config.ini",
@@ -213,7 +213,6 @@ def _average_3d_stack_cuda(image_stack: np.ndarray) -> np.ndarray:
213
213
  return results
214
214
 
215
215
 
216
-
217
216
  def create_average_frm_cuda(video_path: Union[str, os.PathLike],
218
217
  start_frm: Optional[int] = None,
219
218
  end_frm: Optional[int] = None,
@@ -1512,6 +1511,9 @@ def pose_plotter(data: Union[str, os.PathLike, np.ndarray],
1512
1511
  stdout_success(msg=f'Pose-estimation video saved at {save_path}.', elapsed_time=total_timer.elapsed_time_str)
1513
1512
 
1514
1513
 
1514
+
1515
+ #x = create_average_frm_cuda(video_path=r"D:\troubleshooting\mitra\project_folder\videos\average_cpu_test\20min.mp4", verbose=True, batch_size=500, async_frame_read=False)
1516
+
1515
1517
  # VIDEO_PATH = "/mnt/d/troubleshooting/maplight_ri/project_folder/blob/videos/Trial_1_C24_D1_1.mp4"
1516
1518
  # #
1517
1519
  #
@@ -1,13 +1,9 @@
1
1
  __author__ = "Simon Nilsson; sronilsson@gmail.com"
2
2
 
3
3
  import functools
4
- import glob
5
- import itertools
6
4
  import multiprocessing
7
5
  import os
8
- import platform
9
- import time
10
- from typing import Dict, List, Optional, Union
6
+ from typing import Dict, List, Union
11
7
 
12
8
  import cv2
13
9
  import numpy as np
@@ -17,9 +13,9 @@ from simba.mixins.config_reader import ConfigReader
17
13
  from simba.mixins.statistics_mixin import Statistics
18
14
  from simba.utils.checks import (
19
15
  check_all_file_names_are_represented_in_video_log, check_if_dir_exists,
20
- check_if_valid_img, check_int, check_nvidea_gpu_available,
21
- check_valid_boolean, check_valid_lst)
22
- from simba.utils.data import detect_bouts, slice_roi_dict_from_attribute
16
+ check_if_valid_img, check_int, check_valid_boolean, check_valid_lst)
17
+ from simba.utils.data import (detect_bouts, slice_roi_dict_from_attribute,
18
+ terminate_cpu_pool)
23
19
  from simba.utils.enums import Defaults, Keys
24
20
  from simba.utils.errors import NoROIDataError
25
21
  from simba.utils.printing import SimbaTimer, stdout_success
@@ -220,7 +216,7 @@ class CueLightAnalyzer(ConfigReader):
220
216
  else: self.intensities[key] = subdict
221
217
  if self.verbose:
222
218
  print(f'Batch {int(np.ceil(cnt + 1 / self.core_cnt))} complete...')
223
- pool.terminate(); pool.join()
219
+ terminate_cpu_pool(pool=pool, force=False)
224
220
  kmeans = self._get_kmeans(intensities=self.intensities)
225
221
  self.data_df = self._append_light_data(data_df=self.data_df, kmeans_data=kmeans)
226
222
  self.data_df = self._remove_outlier_events(data_df=self.data_df)
@@ -1339,8 +1339,7 @@ class GeometryMixin(object):
1339
1339
  )
1340
1340
  for cnt, result in enumerate(pool.imap(constants, data, chunksize=1)):
1341
1341
  results.append(result)
1342
- pool.join()
1343
- pool.terminate()
1342
+ terminate_cpu_pool(pool=pool, force=False)
1344
1343
  if data_ndim == 2:
1345
1344
  return [i for s in results for i in s]
1346
1345
  else:
@@ -1370,8 +1369,7 @@ class GeometryMixin(object):
1370
1369
  cap_style=cap_style)
1371
1370
  for cnt, mp_return in enumerate(pool.imap(constants, geomety_lst, chunksize=1)):
1372
1371
  results.append(mp_return)
1373
- pool.join()
1374
- pool.terminate()
1372
+ terminate_cpu_pool(pool=pool, force=False)
1375
1373
  return [l for ll in results for l in ll]
1376
1374
 
1377
1375
  def multiframe_bodyparts_to_circle(self,
@@ -1524,8 +1522,7 @@ class GeometryMixin(object):
1524
1522
  )
1525
1523
  for cnt, result in enumerate(pool.imap(constants, data, chunksize=1)):
1526
1524
  results.append(result)
1527
- pool.join()
1528
- pool.terminate()
1525
+ terminate_cpu_pool(pool=pool, force=False)
1529
1526
  return results
1530
1527
 
1531
1528
  def multiframe_compute_pct_shape_overlap(self,
@@ -1798,8 +1795,7 @@ class GeometryMixin(object):
1798
1795
  timer.stop_timer()
1799
1796
  if verbose:
1800
1797
  stdout_success(msg="Rotated rectangles complete.", elapsed_time=timer.elapsed_time_str)
1801
- pool.join()
1802
- pool.terminate()
1798
+ terminate_cpu_pool(pool=pool, force=False)
1803
1799
  return results
1804
1800
 
1805
1801
  @staticmethod
@@ -2003,8 +1999,7 @@ class GeometryMixin(object):
2003
1999
  )
2004
2000
  for cnt, result in enumerate(pool.imap(constants, shapes, chunksize=1)):
2005
2001
  results.append(result)
2006
- pool.join()
2007
- pool.terminate()
2002
+ terminate_cpu_pool(pool=pool, force=False)
2008
2003
  return results
2009
2004
 
2010
2005
  def multiframe_union(self, shapes: Iterable[Union[LineString, MultiLineString, Polygon]], core_cnt: int = -1) -> \
@@ -2043,8 +2038,7 @@ class GeometryMixin(object):
2043
2038
  with multiprocessing.Pool(core_cnt, maxtasksperchild=Defaults.LARGE_MAX_TASK_PER_CHILD.value) as pool:
2044
2039
  for cnt, result in enumerate(pool.imap(GeometryMixin().union, shapes, chunksize=1)):
2045
2040
  results.append(result)
2046
- pool.join()
2047
- pool.terminate()
2041
+ terminate_cpu_pool(pool=pool, force=False)
2048
2042
  return results
2049
2043
 
2050
2044
  def multiframe_symmetric_difference(self, shapes: Iterable[Union[LineString, MultiLineString, Polygon]],
@@ -2084,8 +2078,7 @@ class GeometryMixin(object):
2084
2078
  pool.imap(GeometryMixin().symmetric_difference, shapes, chunksize=1)
2085
2079
  ):
2086
2080
  results.append(result)
2087
- pool.join()
2088
- pool.terminate()
2081
+ terminate_cpu_pool(pool=pool, force=False)
2089
2082
  return results
2090
2083
 
2091
2084
  def multiframe_delaunay_triangulate_keypoints(self, data: np.ndarray, core_cnt: int = -1) -> List[List[Polygon]]:
@@ -2132,8 +2125,7 @@ class GeometryMixin(object):
2132
2125
  ):
2133
2126
  results.append(result)
2134
2127
 
2135
- pool.join()
2136
- pool.terminate()
2128
+ terminate_cpu_pool(pool=pool, force=False)
2137
2129
  return results
2138
2130
 
2139
2131
  def multiframe_difference(
@@ -2221,8 +2213,7 @@ class GeometryMixin(object):
2221
2213
  msg="Multi-frame difference compute complete",
2222
2214
  elapsed_time=timer.elapsed_time_str,
2223
2215
  )
2224
- pool.join()
2225
- pool.terminate()
2216
+ terminate_cpu_pool(pool=pool, force=False)
2226
2217
  return results
2227
2218
 
2228
2219
  def multiframe_area(self,
@@ -2276,8 +2267,7 @@ class GeometryMixin(object):
2276
2267
 
2277
2268
  timer.stop_timer()
2278
2269
  stdout_success(msg="Multi-frame area compute complete", elapsed_time=timer.elapsed_time_str)
2279
- pool.join()
2280
- pool.terminate()
2270
+ terminate_cpu_pool(pool=pool, force=False)
2281
2271
  return results
2282
2272
 
2283
2273
  def multiframe_bodyparts_to_multistring_skeleton(
@@ -2619,8 +2609,7 @@ class GeometryMixin(object):
2619
2609
  pool.imap(GeometryMixin.is_shape_covered, shapes, chunksize=1)
2620
2610
  ):
2621
2611
  results.append(mp_return)
2622
- pool.join()
2623
- pool.terminate()
2612
+ terminate_cpu_pool(pool=pool, force=False)
2624
2613
  return results
2625
2614
 
2626
2615
  @staticmethod
@@ -3321,8 +3310,7 @@ class GeometryMixin(object):
3321
3310
  for cnt, result in enumerate(pool.imap(constants, data, chunksize=1)):
3322
3311
  if result[1] != -1:
3323
3312
  img_arr[result[0], result[2] - 1, result[1] - 1] = 1
3324
- pool.join()
3325
- pool.terminate()
3313
+ terminate_cpu_pool(pool=pool, force=False)
3326
3314
  timer.stop_timer()
3327
3315
  stdout_success(
3328
3316
  msg="Cumulative coordinates in geometries complete",
@@ -3415,8 +3403,7 @@ class GeometryMixin(object):
3415
3403
  for cnt, result in enumerate(pool.imap(constants, data, chunksize=1)):
3416
3404
  if result[1] != -1:
3417
3405
  img_arr[result[0], result[2] - 1, result[1] - 1] = 1
3418
- pool.join()
3419
- pool.terminate()
3406
+ terminate_cpu_pool(pool=pool, force=False)
3420
3407
  if fps is None:
3421
3408
  return np.cumsum(img_arr, axis=0)
3422
3409
  else:
@@ -3559,8 +3546,7 @@ class GeometryMixin(object):
3559
3546
  constants = functools.partial(GeometryMixin._compute_framewise_geometry_idx, grid=grid, verbose=verbose)
3560
3547
  for cnt, result in enumerate(pool.imap(constants, data, chunksize=1)):
3561
3548
  results.append(result)
3562
- pool.join();
3563
- pool.terminate();
3549
+ terminate_cpu_pool(pool=pool, force=False)
3564
3550
  del data
3565
3551
 
3566
3552
  results = np.vstack(results)[:, 1:].astype(np.int32)
@@ -18,7 +18,7 @@ from collections import ChainMap
18
18
  import cv2
19
19
  import pandas as pd
20
20
  from numba import float64, int64, jit, njit, prange, uint8
21
- from shapely.geometry import MultiPolygon, Polygon
21
+ from shapely.geometry import Polygon
22
22
  from skimage.metrics import structural_similarity
23
23
 
24
24
  from simba.utils.checks import (check_file_exist_and_readable, check_float,
@@ -27,16 +27,14 @@ from simba.utils.checks import (check_file_exist_and_readable, check_float,
27
27
  check_int, check_str, check_valid_array,
28
28
  check_valid_boolean, check_valid_lst,
29
29
  check_valid_tuple, is_img_bw, is_img_greyscale)
30
+ from simba.utils.data import terminate_cpu_pool
30
31
  from simba.utils.enums import Defaults, Formats, GeometryEnum, Options
31
- from simba.utils.errors import (ArrayError, FFMPEGCodecGPUError,
32
- FrameRangeError, InvalidInputError,
33
- NotDirectoryError)
32
+ from simba.utils.errors import ArrayError, FrameRangeError, InvalidInputError
34
33
  from simba.utils.printing import SimbaTimer, stdout_success
35
34
  from simba.utils.read_write import (find_core_cnt,
36
35
  find_files_of_filetypes_in_directory,
37
36
  get_fn_ext, get_video_meta_data,
38
- read_frm_of_video,
39
- read_img_batch_from_video_gpu, write_df)
37
+ read_frm_of_video)
40
38
 
41
39
 
42
40
  class ImageMixin(object):
@@ -546,8 +544,8 @@ class ImageMixin(object):
546
544
  pool.imap(constants, split_frm_idx, chunksize=1)
547
545
  ):
548
546
  results.append(result)
549
- pool.terminate()
550
- pool.join()
547
+
548
+ terminate_cpu_pool(pool=pool, force=False)
551
549
  results = dict(ChainMap(*results))
552
550
 
553
551
  max_value, max_frm = -np.inf, None
@@ -876,8 +874,7 @@ class ImageMixin(object):
876
874
  pool.imap(ImageMixin()._image_reader_helper, file_paths, chunksize=1)
877
875
  ):
878
876
  imgs.update(result)
879
- pool.join()
880
- pool.terminate()
877
+ terminate_cpu_pool(pool=pool, force=False)
881
878
  return imgs
882
879
 
883
880
  @staticmethod
@@ -1027,8 +1024,7 @@ class ImageMixin(object):
1027
1024
  for cnt, result in enumerate(pool.imap(constants, frm_lst, chunksize=1)):
1028
1025
  results.update(result)
1029
1026
 
1030
- pool.join()
1031
- pool.terminate()
1027
+ terminate_cpu_pool(pool=pool, force=False)
1032
1028
  return results
1033
1029
 
1034
1030
  @staticmethod
@@ -1509,8 +1505,8 @@ class ImageMixin(object):
1509
1505
  for cnt, result in enumerate(pool.imap(constants, shapes, chunksize=1)):
1510
1506
  results.append(result)
1511
1507
  results = dict(ChainMap(*results))
1512
- pool.join()
1513
- pool.terminate()
1508
+
1509
+ terminate_cpu_pool(pool=pool, force=False)
1514
1510
  results = dict(sorted(results.items(), key=lambda item: int(item[0])))
1515
1511
  timer.stop_timer()
1516
1512
  stdout_success(msg="Geometry image slicing complete.", elapsed_time=timer.elapsed_time_str, source=self.__class__.__name__)
@@ -67,7 +67,7 @@ from simba.utils.checks import (check_all_dfs_in_list_has_same_cols,
67
67
  check_valid_boolean, check_valid_dataframe,
68
68
  check_valid_lst, is_lxc_container)
69
69
  from simba.utils.data import (detect_bouts, detect_bouts_multiclass,
70
- get_library_version)
70
+ get_library_version, terminate_cpu_pool)
71
71
  from simba.utils.enums import (OS, ConfigKey, Defaults, Dtypes, Formats, Links,
72
72
  Methods, MLParamKeys, Options)
73
73
  from simba.utils.errors import (ClassifierInferenceError, CorruptedFileError,
@@ -1859,7 +1859,7 @@ class TrainModelMixin(object):
1859
1859
  shap_raw.append(shap_data[result[1]][1].drop(clf_name, axis=1))
1860
1860
  if verbose: print(f"Completed SHAP care batch (Batch {result[1] + 1}/{len(shap_data)}).")
1861
1861
 
1862
- pool.terminate(); pool.join()
1862
+ terminate_cpu_pool(pool=pool, force=False)
1863
1863
  shap_df = pd.DataFrame(data=np.row_stack(shap_results), columns=list(x_names) + ["Expected_value", "Sum", "Prediction_probability", clf_name])
1864
1864
  raw_df = pd.DataFrame(data=np.row_stack(shap_raw), columns=list(x_names))
1865
1865
  out_shap_path, out_raw_path, img_save_path, df_save_paths, summary_dfs, img = None, None, None, None, None, None
@@ -24,10 +24,9 @@ from simba.utils.checks import (check_file_exist_and_readable,
24
24
  check_if_valid_rgb_tuple, check_int, check_str,
25
25
  check_valid_boolean, check_valid_lst,
26
26
  check_video_and_data_frm_count_align)
27
- from simba.utils.data import slice_roi_dict_for_video
27
+ from simba.utils.data import slice_roi_dict_for_video, terminate_cpu_pool
28
28
  from simba.utils.enums import Formats, TextOptions
29
- from simba.utils.errors import (BodypartColumnNotFoundError, NoFilesFoundError,
30
- ROICoordinatesNotFoundError)
29
+ from simba.utils.errors import BodypartColumnNotFoundError, NoFilesFoundError
31
30
  from simba.utils.printing import stdout_success
32
31
  from simba.utils.read_write import (concatenate_videos_in_folder,
33
32
  find_core_cnt, get_fn_ext,
@@ -315,8 +314,7 @@ class ROIfeatureVisualizerMultiprocess(ConfigReader):
315
314
  print(f"Joining {self.video_name} multi-processed video...")
316
315
  concatenate_videos_in_folder(in_folder=self.save_temp_dir, save_path=self.save_path, video_format="mp4", remove_splits=True, gpu=self.gpu)
317
316
  self.timer.stop_timer()
318
- pool.terminate()
319
- pool.join()
317
+ terminate_cpu_pool(pool=pool, force=False)
320
318
  stdout_success(msg=f"Video {self.video_name} complete. Video saved in directory {self.roi_features_save_dir}.", elapsed_time=self.timer.elapsed_time_str)
321
319
 
322
320
 
@@ -14,9 +14,9 @@ from simba.mixins.plotting_mixin import PlottingMixin
14
14
  from simba.utils.checks import (check_float, check_if_valid_rgb_tuple,
15
15
  check_int, check_str, check_that_column_exist,
16
16
  check_valid_lst)
17
- from simba.utils.data import detect_bouts
18
- from simba.utils.enums import Formats, TagNames, TextOptions
19
- from simba.utils.errors import NoFilesFoundError, NoSpecifiedOutputError
17
+ from simba.utils.data import detect_bouts, terminate_cpu_pool
18
+ from simba.utils.enums import Formats, TextOptions
19
+ from simba.utils.errors import NoSpecifiedOutputError
20
20
  from simba.utils.printing import SimbaTimer, log_event, stdout_success
21
21
  from simba.utils.read_write import (concatenate_videos_in_folder,
22
22
  find_core_cnt, get_fn_ext,
@@ -218,8 +218,7 @@ class ClassifierValidationClipsMultiprocess(ConfigReader):
218
218
  for cnt, result in enumerate(
219
219
  pool.imap(constants, clip_data, chunksize=self.multiprocess_chunksize)):
220
220
  print(f"Bout {cnt+1} complete...")
221
- pool.terminate()
222
- pool.join()
221
+ terminate_cpu_pool(pool=pool, force=False)
223
222
 
224
223
  if self.concat_video:
225
224
  print(f"Joining {file_name} multiprocessed video...")
@@ -1,10 +1,9 @@
1
1
  __author__ = "Simon Nilsson; sronilsson@gmail.com"
2
2
 
3
3
  import functools
4
- import itertools
5
4
  import multiprocessing
6
5
  import os
7
- from typing import List, Optional, Union
6
+ from typing import List, Union
8
7
 
9
8
  import cv2
10
9
  import numpy as np
@@ -16,14 +15,15 @@ from simba.utils.checks import (check_file_exist_and_readable, check_int,
16
15
  check_valid_boolean, check_valid_dataframe,
17
16
  check_valid_lst)
18
17
  from simba.utils.data import (create_color_palettes, detect_bouts,
19
- slice_roi_dict_from_attribute)
20
- from simba.utils.enums import Defaults, Formats, Keys, TextOptions
18
+ slice_roi_dict_from_attribute,
19
+ terminate_cpu_pool)
20
+ from simba.utils.enums import Defaults, Formats, TextOptions
21
21
  from simba.utils.errors import NoROIDataError, NoSpecifiedOutputError
22
22
  from simba.utils.printing import stdout_success
23
23
  from simba.utils.read_write import (concatenate_videos_in_folder,
24
24
  create_directory, find_core_cnt,
25
25
  get_fn_ext, get_video_meta_data, read_df,
26
- read_frm_of_video, remove_a_folder)
26
+ read_frm_of_video)
27
27
 
28
28
 
29
29
  def _plot_cue_light_data(frm_idxs: list,
@@ -197,8 +197,7 @@ class CueLightVisualizer(ConfigReader):
197
197
  for cnt, result in enumerate(pool.imap(constants, self.frame_chunks, chunksize=self.multiprocess_chunksize)):
198
198
  if self.verbose:
199
199
  print(f'Batch {int(result+1/self.core_cnt)} complete...')
200
- pool.terminate()
201
- pool.join()
200
+ terminate_cpu_pool(pool=pool, force=False)
202
201
  self.timer.stop_timer()
203
202
  if self.video_setting:
204
203
  print(f"Joining {self.video_name} multiprocessed video...")
@@ -19,7 +19,7 @@ from simba.utils.checks import (check_file_exist_and_readable,
19
19
  check_if_valid_rgb_tuple, check_int,
20
20
  check_valid_lst,
21
21
  check_video_and_data_frm_count_align)
22
- from simba.utils.data import create_color_palettes
22
+ from simba.utils.data import create_color_palettes, terminate_cpu_pool
23
23
  from simba.utils.enums import OS, Formats, Keys, TextOptions
24
24
  from simba.utils.errors import (AnimalNumberError, InvalidInputError,
25
25
  NoFilesFoundError)
@@ -226,8 +226,7 @@ class DirectingOtherAnimalsVisualizerMultiprocess(ConfigReader, PlottingMixin):
226
226
  print(f"Joining {self.video_name} multi-processed video...")
227
227
  concatenate_videos_in_folder(in_folder=self.save_temp_path, save_path=self.save_path, video_format="mp4", remove_splits=True)
228
228
  self.timer.stop_timer()
229
- pool.terminate()
230
- pool.join()
229
+ terminate_cpu_pool(pool=pool, force=False)
231
230
  stdout_success(msg=f"Video {self.video_name} complete. Video saved in {self.directing_animals_video_output_path} directory", elapsed_time=self.timer.elapsed_time_str)
232
231
 
233
232