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.
- simba/SimBA.py +2 -2
- simba/assets/.recent_projects.txt +1 -0
- simba/assets/icons/frames_2.png +0 -0
- simba/assets/lookups/tooptips.json +15 -1
- simba/data_processors/agg_clf_counter_mp.py +52 -53
- simba/data_processors/blob_location_computer.py +1 -1
- simba/data_processors/circling_detector.py +30 -13
- simba/data_processors/cuda/geometry.py +45 -27
- simba/data_processors/cuda/image.py +1648 -1598
- simba/data_processors/cuda/statistics.py +72 -26
- simba/data_processors/cuda/timeseries.py +1 -1
- simba/data_processors/cue_light_analyzer.py +5 -9
- simba/data_processors/egocentric_aligner.py +25 -7
- simba/data_processors/freezing_detector.py +55 -47
- simba/data_processors/kleinberg_calculator.py +61 -29
- simba/feature_extractors/feature_subsets.py +14 -7
- simba/feature_extractors/mitra_feature_extractor.py +2 -2
- simba/feature_extractors/straub_tail_analyzer.py +4 -6
- simba/labelling/standard_labeller.py +1 -1
- simba/mixins/config_reader.py +5 -2
- simba/mixins/geometry_mixin.py +22 -36
- simba/mixins/image_mixin.py +24 -28
- simba/mixins/plotting_mixin.py +28 -10
- simba/mixins/statistics_mixin.py +48 -11
- simba/mixins/timeseries_features_mixin.py +1 -1
- simba/mixins/train_model_mixin.py +67 -29
- simba/model/inference_batch.py +1 -1
- simba/model/yolo_seg_inference.py +3 -3
- simba/outlier_tools/skip_outlier_correction.py +1 -1
- simba/plotting/ROI_feature_visualizer_mp.py +3 -5
- simba/plotting/clf_validator_mp.py +4 -5
- simba/plotting/cue_light_visualizer.py +6 -7
- simba/plotting/directing_animals_visualizer_mp.py +2 -3
- simba/plotting/distance_plotter_mp.py +378 -378
- simba/plotting/frame_mergerer_ffmpeg.py +137 -196
- simba/plotting/gantt_creator.py +29 -10
- simba/plotting/gantt_creator_mp.py +96 -33
- simba/plotting/geometry_plotter.py +270 -272
- simba/plotting/heat_mapper_clf_mp.py +4 -6
- simba/plotting/heat_mapper_location_mp.py +2 -2
- simba/plotting/light_dark_box_plotter.py +2 -2
- simba/plotting/path_plotter_mp.py +26 -29
- simba/plotting/plot_clf_results_mp.py +455 -454
- simba/plotting/pose_plotter_mp.py +28 -29
- simba/plotting/probability_plot_creator_mp.py +288 -288
- simba/plotting/roi_plotter_mp.py +31 -31
- simba/plotting/single_run_model_validation_video_mp.py +427 -427
- simba/plotting/spontaneous_alternation_plotter.py +2 -3
- simba/plotting/yolo_pose_track_visualizer.py +32 -27
- simba/plotting/yolo_pose_visualizer.py +35 -36
- simba/plotting/yolo_seg_visualizer.py +2 -3
- simba/pose_importers/simba_blob_importer.py +3 -3
- simba/roi_tools/roi_aggregate_stats_mp.py +5 -4
- simba/roi_tools/roi_clf_calculator_mp.py +4 -4
- simba/sandbox/analyze_runtimes.py +30 -0
- simba/sandbox/cuda/egocentric_rotator.py +374 -0
- simba/sandbox/get_cpu_pool.py +5 -0
- simba/sandbox/proboscis_to_tip.py +28 -0
- simba/sandbox/test_directionality.py +47 -0
- simba/sandbox/test_nonstatic_directionality.py +27 -0
- simba/sandbox/test_pycharm_cuda.py +51 -0
- simba/sandbox/test_simba_install.py +41 -0
- simba/sandbox/test_static_directionality.py +26 -0
- simba/sandbox/test_static_directionality_2d.py +26 -0
- simba/sandbox/verify_env.py +42 -0
- simba/third_party_label_appenders/transform/coco_keypoints_to_yolo.py +3 -3
- simba/third_party_label_appenders/transform/coco_keypoints_to_yolo_bbox.py +2 -2
- simba/ui/pop_ups/clf_add_remove_print_pop_up.py +37 -30
- simba/ui/pop_ups/clf_plot_pop_up.py +2 -2
- simba/ui/pop_ups/egocentric_alignment_pop_up.py +20 -21
- simba/ui/pop_ups/fsttc_pop_up.py +27 -25
- simba/ui/pop_ups/gantt_pop_up.py +31 -6
- simba/ui/pop_ups/interpolate_pop_up.py +2 -4
- simba/ui/pop_ups/kleinberg_pop_up.py +39 -40
- simba/ui/pop_ups/multiple_videos_to_frames_popup.py +10 -11
- simba/ui/pop_ups/single_video_to_frames_popup.py +10 -10
- simba/ui/pop_ups/video_processing_pop_up.py +186 -174
- simba/ui/tkinter_functions.py +10 -1
- simba/utils/custom_feature_extractor.py +1 -1
- simba/utils/data.py +90 -14
- simba/utils/enums.py +1 -0
- simba/utils/errors.py +441 -440
- simba/utils/lookups.py +1203 -1203
- simba/utils/printing.py +124 -124
- simba/utils/read_write.py +3769 -3721
- simba/utils/yolo.py +10 -1
- simba/video_processors/blob_tracking_executor.py +2 -2
- simba/video_processors/clahe_ui.py +66 -23
- simba/video_processors/egocentric_video_rotator.py +46 -44
- simba/video_processors/multi_cropper.py +1 -1
- simba/video_processors/video_processing.py +5264 -5300
- simba/video_processors/videos_to_frames.py +43 -32
- {simba_uw_tf_dev-4.5.8.dist-info → simba_uw_tf_dev-4.7.1.dist-info}/METADATA +4 -3
- {simba_uw_tf_dev-4.5.8.dist-info → simba_uw_tf_dev-4.7.1.dist-info}/RECORD +98 -86
- {simba_uw_tf_dev-4.5.8.dist-info → simba_uw_tf_dev-4.7.1.dist-info}/LICENSE +0 -0
- {simba_uw_tf_dev-4.5.8.dist-info → simba_uw_tf_dev-4.7.1.dist-info}/WHEEL +0 -0
- {simba_uw_tf_dev-4.5.8.dist-info → simba_uw_tf_dev-4.7.1.dist-info}/entry_points.txt +0 -0
- {simba_uw_tf_dev-4.5.8.dist-info → simba_uw_tf_dev-4.7.1.dist-info}/top_level.txt +0 -0
simba/ui/tkinter_functions.py
CHANGED
|
@@ -156,6 +156,7 @@ class SimBAScaleBar(Frame):
|
|
|
156
156
|
def __init__(self,
|
|
157
157
|
parent: Union[Frame, Canvas, LabelFrame, Toplevel, Tk],
|
|
158
158
|
label: Optional[str] = None,
|
|
159
|
+
label_width: Optional[int] = None,
|
|
159
160
|
orient: Literal['horizontal', 'vertical'] = HORIZONTAL,
|
|
160
161
|
length: int = 200,
|
|
161
162
|
value: Optional[int] = 95,
|
|
@@ -194,7 +195,7 @@ class SimBAScaleBar(Frame):
|
|
|
194
195
|
showvalue=showvalue)
|
|
195
196
|
|
|
196
197
|
if label is not None:
|
|
197
|
-
self.lbl = SimBALabel(parent=self, txt=label, font=lbl_font, txt_clr=label_clr)
|
|
198
|
+
self.lbl = SimBALabel(parent=self, txt=label, font=lbl_font, txt_clr=label_clr, width=label_width)
|
|
198
199
|
self.lbl.grid(row=0, column=1, sticky=SW)
|
|
199
200
|
|
|
200
201
|
self.scale.grid(row=0, column=2, sticky=NW)
|
|
@@ -207,6 +208,11 @@ class SimBAScaleBar(Frame):
|
|
|
207
208
|
def get_value(self) -> Union[int, float]:
|
|
208
209
|
return self.scale.get()
|
|
209
210
|
|
|
211
|
+
def get(self) -> Union[int, float]:
|
|
212
|
+
## Alternative for ``get_value`` for legacy reasons.
|
|
213
|
+
return self.scale.get()
|
|
214
|
+
|
|
215
|
+
|
|
210
216
|
|
|
211
217
|
|
|
212
218
|
class Entry_Box(Frame):
|
|
@@ -223,6 +229,7 @@ class Entry_Box(Frame):
|
|
|
223
229
|
value: Optional[Any] = None,
|
|
224
230
|
label_font: tuple = Formats.FONT_REGULAR.value,
|
|
225
231
|
entry_font: tuple = Formats.FONT_REGULAR.value,
|
|
232
|
+
tooltip_key: Optional[str] = None,
|
|
226
233
|
justify: Literal["left", "center", "right"] = 'left',
|
|
227
234
|
cmd: Optional[Callable] = None,
|
|
228
235
|
**kw):
|
|
@@ -243,6 +250,8 @@ class Entry_Box(Frame):
|
|
|
243
250
|
self.filePath = StringVar()
|
|
244
251
|
self.lblName = Label(self, text=fileDescription, width=labelwidth, anchor=W, font=label_font, bg=label_bg_clr)
|
|
245
252
|
self.lblName.grid(row=0, column=1)
|
|
253
|
+
if tooltip_key in TOOLTIPS.keys():
|
|
254
|
+
CreateToolTip(widget=self.lblName, text=TOOLTIPS[tooltip_key])
|
|
246
255
|
if not entry_box_width:
|
|
247
256
|
self.entPath = Entry(self, textvariable=self.filePath, state=self.status, validate="key", validatecommand=self.validation_methods.get(validation, None), font=entry_font, justify=justify, bg=entry_box_clr)
|
|
248
257
|
else:
|
|
@@ -30,7 +30,7 @@ class CustomFeatureExtractor(ConfigReader):
|
|
|
30
30
|
4. Handle cases of multiple classes and missing configuration arguments.
|
|
31
31
|
5. Invokes the feature extraction process if conditions are met.
|
|
32
32
|
|
|
33
|
-
..
|
|
33
|
+
.. note::
|
|
34
34
|
|
|
35
35
|
`Tutorial <https://github.com/sgoldenlab/simba/blob/master/docs/extractFeatures.md>`_.
|
|
36
36
|
|
simba/utils/data.py
CHANGED
|
@@ -5,6 +5,7 @@ import configparser
|
|
|
5
5
|
import gc
|
|
6
6
|
import io
|
|
7
7
|
import os
|
|
8
|
+
import platform
|
|
8
9
|
import subprocess
|
|
9
10
|
from copy import deepcopy
|
|
10
11
|
from datetime import datetime
|
|
@@ -38,15 +39,18 @@ from simba.utils.checks import (check_file_exist_and_readable, check_float,
|
|
|
38
39
|
check_if_valid_rgb_tuple, check_instance,
|
|
39
40
|
check_int, check_str, check_that_column_exist,
|
|
40
41
|
check_that_hhmmss_start_is_before_end,
|
|
41
|
-
check_valid_array,
|
|
42
|
-
check_valid_dataframe,
|
|
43
|
-
|
|
42
|
+
check_valid_array, check_valid_boolean,
|
|
43
|
+
check_valid_cpu_pool, check_valid_dataframe,
|
|
44
|
+
check_valid_lst)
|
|
45
|
+
from simba.utils.enums import (OS, ConfigKey, Defaults, Dtypes, Formats, Keys,
|
|
46
|
+
Options)
|
|
44
47
|
from simba.utils.errors import (BodypartColumnNotFoundError, CountError,
|
|
45
48
|
InvalidFileTypeError, InvalidInputError,
|
|
46
49
|
NoFilesFoundError, NoROIDataError,
|
|
47
50
|
SimBAModuleNotFoundError)
|
|
48
51
|
from simba.utils.printing import stdout_success, stdout_warning
|
|
49
|
-
from simba.utils.read_write import (
|
|
52
|
+
from simba.utils.read_write import (find_core_cnt, find_video_of_file,
|
|
53
|
+
get_current_time, get_fn_ext,
|
|
50
54
|
get_video_meta_data, read_config_entry,
|
|
51
55
|
read_config_file, read_df,
|
|
52
56
|
read_project_path_and_file_type,
|
|
@@ -1781,8 +1785,8 @@ def fft_lowpass_filter(data: np.ndarray, cut_off: float = 0.1) -> np.ndarray:
|
|
|
1781
1785
|
|
|
1782
1786
|
:example:
|
|
1783
1787
|
>>> from simba.utils.read_write import read_df
|
|
1784
|
-
>>> IN_PATH = r"C
|
|
1785
|
-
>>> OUT_PATH = r"C
|
|
1788
|
+
>>> IN_PATH = r"C:/troubleshooting/RAT_NOR/project_folder/csv/outlier_corrected_movement_location/2022-06-20_NOB_DOT_4.csv"
|
|
1789
|
+
>>> OUT_PATH = r"C:/troubleshooting/RAT_NOR/project_folder/csv/outlier_corrected_movement_location/2022-06-20_NOB_DOT_4_filtered.csv"
|
|
1786
1790
|
>>> df = read_df(file_path=IN_PATH)
|
|
1787
1791
|
>>> data = df.values
|
|
1788
1792
|
>>> x = fft_lowpass_filter(data=data, cut_off=0.1)
|
|
@@ -1813,33 +1817,105 @@ def fft_lowpass_filter(data: np.ndarray, cut_off: float = 0.1) -> np.ndarray:
|
|
|
1813
1817
|
return results.astype(data.dtype)
|
|
1814
1818
|
|
|
1815
1819
|
|
|
1816
|
-
def terminate_cpu_pool(pool:
|
|
1817
|
-
force: bool = False
|
|
1820
|
+
def terminate_cpu_pool(pool: multiprocessing.pool.Pool,
|
|
1821
|
+
force: bool = False,
|
|
1822
|
+
verbose: bool = True,
|
|
1823
|
+
source: Optional[str] = None) -> None:
|
|
1818
1824
|
"""
|
|
1819
|
-
Safely terminates a multiprocessing.Pool instance.
|
|
1825
|
+
Safely terminates a multiprocessing.Pool instance with optional graceful shutdown.
|
|
1820
1826
|
|
|
1821
|
-
|
|
1822
|
-
|
|
1823
|
-
|
|
1827
|
+
.. note::
|
|
1828
|
+
If pool is None or invalid, function returns without action. Exceptions during termination are silently caught.
|
|
1829
|
+
|
|
1830
|
+
:param multiprocessing.pool.Pool pool: The multiprocessing pool to terminate. If None, function returns without action.
|
|
1831
|
+
:param bool force: If True, skips graceful shutdown (close/join) and immediately terminates. Default: False.
|
|
1832
|
+
:param bool verbose: If True, prints termination message with timestamp. Default: True.
|
|
1833
|
+
:param Optional[str] source: Optional identifier string for logging purposes (e.g., 'VideoProcessor'). Default: None.
|
|
1824
1834
|
|
|
1825
1835
|
:example:
|
|
1826
1836
|
>>> import multiprocessing
|
|
1827
1837
|
>>> pool = multiprocessing.Pool(4)
|
|
1828
|
-
>>> terminate_cpu_pool(pool)
|
|
1838
|
+
>>> terminate_cpu_pool(pool=pool, force=False, verbose=True, source='FeatureExtractor')
|
|
1829
1839
|
"""
|
|
1830
1840
|
if pool is None:
|
|
1831
1841
|
return
|
|
1832
|
-
check_valid_cpu_pool(value=pool, source=terminate_cpu_pool.__name__, raise_error=
|
|
1842
|
+
if not check_valid_cpu_pool(value=pool, source=terminate_cpu_pool.__name__, raise_error=False):
|
|
1843
|
+
return
|
|
1833
1844
|
try:
|
|
1845
|
+
core_cnt = pool._processes if hasattr(pool, '_processes') else None
|
|
1834
1846
|
if not force:
|
|
1835
1847
|
pool.close()
|
|
1836
1848
|
pool.join()
|
|
1837
1849
|
pool.terminate()
|
|
1850
|
+
if verbose: print(f'[{get_current_time()}] {"" if source is None else f"{core_cnt} core"} SimBA CPU pool {"" if source is None else source} terminated.')
|
|
1838
1851
|
except (ValueError, AssertionError, AttributeError):
|
|
1839
1852
|
pass
|
|
1840
1853
|
gc.collect()
|
|
1841
1854
|
|
|
1842
1855
|
|
|
1856
|
+
|
|
1857
|
+
def get_cpu_pool(core_cnt: int = -1,
|
|
1858
|
+
maxtasksperchild: int = Defaults.MAXIMUM_MAX_TASK_PER_CHILD.value,
|
|
1859
|
+
context: Literal['fork', 'spawn', 'forkserver'] = None,
|
|
1860
|
+
verbose: bool = True,
|
|
1861
|
+
source: Optional[str] = None) -> multiprocessing.Pool:
|
|
1862
|
+
"""
|
|
1863
|
+
Creates and returns a multiprocessing.Pool instance with platform-appropriate defaults and validation.
|
|
1864
|
+
|
|
1865
|
+
:param int core_cnt: Number of worker processes. -1 uses all available cores. Default: -1.
|
|
1866
|
+
:param int maxtasksperchild: Maximum number of tasks a worker process can complete before being replaced. Default: From Defaults.MAXIMUM_MAX_TASK_PER_CHILD.
|
|
1867
|
+
:param Optional[Literal['fork', 'spawn', 'forkserver']] context: Multiprocessing start method. None uses platform default. Default: None.
|
|
1868
|
+
:param bool verbose: If True, prints pool creation message with timestamp. Default: True.
|
|
1869
|
+
:param Optional[str] source: Optional identifier string for logging purposes (e.g., 'VideoProcessor'). Default: None.
|
|
1870
|
+
:return: Configured multiprocessing.Pool instance.
|
|
1871
|
+
:rtype: multiprocessing.Pool
|
|
1872
|
+
|
|
1873
|
+
:example:
|
|
1874
|
+
>>> pool = get_cpu_pool(core_cnt=4, source='FeatureExtractor')
|
|
1875
|
+
>>> pool = get_cpu_pool(core_cnt=-1, context='spawn', verbose=True)
|
|
1876
|
+
>>> pool = get_cpu_pool(core_cnt=8, maxtasksperchild=100, source='VideoProcessor')
|
|
1877
|
+
"""
|
|
1878
|
+
|
|
1879
|
+
check_int(name=f'{get_cpu_pool.__name__} core_cnt', min_value=-1, unaccepted_vals=[0], value=core_cnt, raise_error=True)
|
|
1880
|
+
check_int(name=f'{get_cpu_pool.__name__} maxtasksperchild', min_value=1, value=maxtasksperchild, raise_error=True)
|
|
1881
|
+
check_valid_boolean(value=verbose, source=f'{get_cpu_pool.__name__} verbose', raise_error=True)
|
|
1882
|
+
if source is not None: check_str(name=f'{get_cpu_pool.__name__} source', value=source, raise_error=True, allow_blank=True)
|
|
1883
|
+
current_process = multiprocessing.current_process()
|
|
1884
|
+
if current_process.name != 'MainProcess': core_cnt = 1
|
|
1885
|
+
core_cnt = find_core_cnt()[0] if core_cnt == -1 or core_cnt > find_core_cnt()[0] else core_cnt
|
|
1886
|
+
if verbose: print(f'[{get_current_time()}] {core_cnt} core SimBA CPU pool {"" if source is None else source} started.')
|
|
1887
|
+
if context is not None:
|
|
1888
|
+
check_str(name=f'{get_cpu_pool.__name__} context', value=context, options=('fork', 'spawn', 'forkserver'), raise_error=True)
|
|
1889
|
+
else:
|
|
1890
|
+
existing_method = multiprocessing.get_start_method(allow_none=True)
|
|
1891
|
+
if existing_method is not None:
|
|
1892
|
+
context = existing_method
|
|
1893
|
+
else:
|
|
1894
|
+
system = platform.system()
|
|
1895
|
+
if system == OS.WINDOWS.value: context = OS.SPAWN.value
|
|
1896
|
+
elif system == OS.MAC.value: context = OS.SPAWN.value
|
|
1897
|
+
else: context = OS.FORK.value
|
|
1898
|
+
|
|
1899
|
+
if context is not None:
|
|
1900
|
+
try:
|
|
1901
|
+
ctx = multiprocessing.get_context(context)
|
|
1902
|
+
except ValueError:
|
|
1903
|
+
system = platform.system()
|
|
1904
|
+
if system == OS.WINDOWS.value: fallback_context = OS.SPAWN.value
|
|
1905
|
+
elif system == OS.MAC.value: fallback_context = OS.SPAWN.value
|
|
1906
|
+
else: fallback_context = OS.FORK.value
|
|
1907
|
+
try:
|
|
1908
|
+
ctx = multiprocessing.get_context(fallback_context)
|
|
1909
|
+
except ValueError:
|
|
1910
|
+
pool = multiprocessing.Pool(processes=core_cnt, maxtasksperchild=maxtasksperchild)
|
|
1911
|
+
return pool
|
|
1912
|
+
pool = ctx.Pool(processes=core_cnt, maxtasksperchild=maxtasksperchild)
|
|
1913
|
+
else:
|
|
1914
|
+
pool = multiprocessing.Pool(processes=core_cnt, maxtasksperchild=maxtasksperchild)
|
|
1915
|
+
return pool
|
|
1916
|
+
|
|
1917
|
+
|
|
1918
|
+
#get_cpu_pool()
|
|
1843
1919
|
# run_user_defined_feature_extraction_class(config_path='/Users/simon/Desktop/envs/troubleshooting/circular_features_zebrafish/project_folder/project_config.ini', file_path='/Users/simon/Desktop/fish_feature_extractor_2023_version_5.py')
|
|
1844
1920
|
|
|
1845
1921
|
|
simba/utils/enums.py
CHANGED
|
@@ -127,6 +127,7 @@ class OS(Enum):
|
|
|
127
127
|
LINUX = "Linux"
|
|
128
128
|
MAC = "Darwin"
|
|
129
129
|
SPAWN = 'spawn'
|
|
130
|
+
FORK = 'fork'
|
|
130
131
|
PYTHON_VER = str(f"{sys.version_info.major}.{sys.version_info.minor}")
|
|
131
132
|
try:
|
|
132
133
|
SIMBA_VERSION = pkg_resources.get_distribution("simba-uw-tf-dev").version
|