boris-behav-obs 9.1.1__tar.gz → 9.2.3__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- boris_behav_obs-9.2.3/PKG-INFO +33 -0
- {boris_behav_obs-9.1.1 → boris_behav_obs-9.2.3}/boris/advanced_event_filtering.py +5 -3
- boris_behav_obs-9.2.3/boris/analysis_plugins/number_of_occurences.py +22 -0
- boris_behav_obs-9.2.3/boris/analysis_plugins/number_of_occurences_by_independent_variable.py +34 -0
- {boris_behav_obs-9.1.1 → boris_behav_obs-9.2.3}/boris/analysis_plugins/time_budget.py +9 -47
- {boris_behav_obs-9.1.1 → boris_behav_obs-9.2.3}/boris/behavior_binary_table.py +5 -5
- {boris_behav_obs-9.1.1 → boris_behav_obs-9.2.3}/boris/connections.py +3 -1
- {boris_behav_obs-9.1.1 → boris_behav_obs-9.2.3}/boris/cooccurence.py +6 -3
- {boris_behav_obs-9.1.1 → boris_behav_obs-9.2.3}/boris/core.py +46 -122
- {boris_behav_obs-9.1.1 → boris_behav_obs-9.2.3}/boris/export_events.py +8 -6
- {boris_behav_obs-9.1.1 → boris_behav_obs-9.2.3}/boris/export_observation.py +4 -1
- {boris_behav_obs-9.1.1 → boris_behav_obs-9.2.3}/boris/gui_utilities.py +19 -11
- {boris_behav_obs-9.1.1 → boris_behav_obs-9.2.3}/boris/observation_operations.py +16 -9
- {boris_behav_obs-9.1.1 → boris_behav_obs-9.2.3}/boris/param_panel.py +6 -0
- {boris_behav_obs-9.1.1 → boris_behav_obs-9.2.3}/boris/player_dock_widget.py +19 -4
- {boris_behav_obs-9.1.1 → boris_behav_obs-9.2.3}/boris/plot_events.py +1 -1
- boris_behav_obs-9.2.3/boris/plugins.py +274 -0
- {boris_behav_obs-9.1.1 → boris_behav_obs-9.2.3}/boris/project_functions.py +29 -22
- {boris_behav_obs-9.1.1 → boris_behav_obs-9.2.3}/boris/select_subj_behav.py +4 -0
- {boris_behav_obs-9.1.1 → boris_behav_obs-9.2.3}/boris/synthetic_time_budget.py +11 -7
- {boris_behav_obs-9.1.1 → boris_behav_obs-9.2.3}/boris/time_budget_functions.py +1 -1
- {boris_behav_obs-9.1.1 → boris_behav_obs-9.2.3}/boris/time_budget_widget.py +6 -4
- {boris_behav_obs-9.1.1 → boris_behav_obs-9.2.3}/boris/utilities.py +0 -2
- {boris_behav_obs-9.1.1 → boris_behav_obs-9.2.3}/boris/version.py +2 -2
- boris_behav_obs-9.2.3/boris_behav_obs.egg-info/PKG-INFO +33 -0
- {boris_behav_obs-9.1.1 → boris_behav_obs-9.2.3}/boris_behav_obs.egg-info/SOURCES.txt +2 -1
- boris_behav_obs-9.2.3/boris_behav_obs.egg-info/entry_points.txt +2 -0
- {boris_behav_obs-9.1.1 → boris_behav_obs-9.2.3}/boris_behav_obs.egg-info/requires.txt +0 -1
- {boris_behav_obs-9.1.1 → boris_behav_obs-9.2.3}/pyproject.toml +12 -13
- {boris_behav_obs-9.1.1 → boris_behav_obs-9.2.3}/tests/test_utilities.py +7 -0
- boris_behav_obs-9.2.3/tests/test_utilities2.py +124 -0
- boris_behav_obs-9.1.1/PKG-INFO +0 -711
- boris_behav_obs-9.1.1/boris/analysis_plugins/number_of_occurences.py +0 -62
- boris_behav_obs-9.1.1/boris/analysis_plugins/number_of_occurences_by_independent_variable.py +0 -74
- boris_behav_obs-9.1.1/boris/plugins.py +0 -79
- boris_behav_obs-9.1.1/boris_behav_obs.egg-info/PKG-INFO +0 -711
- boris_behav_obs-9.1.1/boris_behav_obs.egg-info/entry_points.txt +0 -2
- {boris_behav_obs-9.1.1 → boris_behav_obs-9.2.3}/LICENSE.TXT +0 -0
- {boris_behav_obs-9.1.1 → boris_behav_obs-9.2.3}/MANIFEST.in +0 -0
- {boris_behav_obs-9.1.1 → boris_behav_obs-9.2.3}/README.TXT +0 -0
- {boris_behav_obs-9.1.1 → boris_behav_obs-9.2.3}/README.md +0 -0
- {boris_behav_obs-9.1.1 → boris_behav_obs-9.2.3}/boris/__init__.py +0 -0
- {boris_behav_obs-9.1.1 → boris_behav_obs-9.2.3}/boris/__main__.py +0 -0
- {boris_behav_obs-9.1.1 → boris_behav_obs-9.2.3}/boris/about.py +0 -0
- {boris_behav_obs-9.1.1 → boris_behav_obs-9.2.3}/boris/add_modifier.py +0 -0
- {boris_behav_obs-9.1.1 → boris_behav_obs-9.2.3}/boris/add_modifier_ui.py +0 -0
- {boris_behav_obs-9.1.1 → boris_behav_obs-9.2.3}/boris/analysis_plugins/__init__.py +0 -0
- {boris_behav_obs-9.1.1 → boris_behav_obs-9.2.3}/boris/behav_coding_map_creator.py +0 -0
- {boris_behav_obs-9.1.1 → boris_behav_obs-9.2.3}/boris/behaviors_coding_map.py +0 -0
- {boris_behav_obs-9.1.1 → boris_behav_obs-9.2.3}/boris/boris_cli.py +0 -0
- {boris_behav_obs-9.1.1 → boris_behav_obs-9.2.3}/boris/cmd_arguments.py +0 -0
- {boris_behav_obs-9.1.1 → boris_behav_obs-9.2.3}/boris/coding_pad.py +0 -0
- {boris_behav_obs-9.1.1 → boris_behav_obs-9.2.3}/boris/config.py +0 -0
- {boris_behav_obs-9.1.1 → boris_behav_obs-9.2.3}/boris/config_file.py +0 -0
- {boris_behav_obs-9.1.1 → boris_behav_obs-9.2.3}/boris/converters.py +0 -0
- {boris_behav_obs-9.1.1 → boris_behav_obs-9.2.3}/boris/converters_ui.py +0 -0
- {boris_behav_obs-9.1.1 → boris_behav_obs-9.2.3}/boris/core_qrc.py +0 -0
- {boris_behav_obs-9.1.1 → boris_behav_obs-9.2.3}/boris/core_ui.py +0 -0
- {boris_behav_obs-9.1.1 → boris_behav_obs-9.2.3}/boris/db_functions.py +0 -0
- {boris_behav_obs-9.1.1 → boris_behav_obs-9.2.3}/boris/dev.py +0 -0
- {boris_behav_obs-9.1.1 → boris_behav_obs-9.2.3}/boris/dialog.py +0 -0
- {boris_behav_obs-9.1.1 → boris_behav_obs-9.2.3}/boris/duration_widget.py +0 -0
- {boris_behav_obs-9.1.1 → boris_behav_obs-9.2.3}/boris/edit_event.py +0 -0
- {boris_behav_obs-9.1.1 → boris_behav_obs-9.2.3}/boris/edit_event_ui.py +0 -0
- {boris_behav_obs-9.1.1 → boris_behav_obs-9.2.3}/boris/event_operations.py +0 -0
- {boris_behav_obs-9.1.1 → boris_behav_obs-9.2.3}/boris/events_cursor.py +0 -0
- {boris_behav_obs-9.1.1 → boris_behav_obs-9.2.3}/boris/events_snapshots.py +0 -0
- {boris_behav_obs-9.1.1 → boris_behav_obs-9.2.3}/boris/exclusion_matrix.py +0 -0
- {boris_behav_obs-9.1.1 → boris_behav_obs-9.2.3}/boris/external_processes.py +0 -0
- {boris_behav_obs-9.1.1 → boris_behav_obs-9.2.3}/boris/geometric_measurement.py +0 -0
- {boris_behav_obs-9.1.1 → boris_behav_obs-9.2.3}/boris/image_overlay.py +0 -0
- {boris_behav_obs-9.1.1 → boris_behav_obs-9.2.3}/boris/import_observations.py +0 -0
- {boris_behav_obs-9.1.1 → boris_behav_obs-9.2.3}/boris/irr.py +0 -0
- {boris_behav_obs-9.1.1 → boris_behav_obs-9.2.3}/boris/latency.py +0 -0
- {boris_behav_obs-9.1.1 → boris_behav_obs-9.2.3}/boris/map_creator.py +0 -0
- {boris_behav_obs-9.1.1 → boris_behav_obs-9.2.3}/boris/measurement_widget.py +0 -0
- {boris_behav_obs-9.1.1 → boris_behav_obs-9.2.3}/boris/media_file.py +0 -0
- {boris_behav_obs-9.1.1 → boris_behav_obs-9.2.3}/boris/menu_options.py +0 -0
- {boris_behav_obs-9.1.1 → boris_behav_obs-9.2.3}/boris/modifiers_coding_map.py +0 -0
- {boris_behav_obs-9.1.1 → boris_behav_obs-9.2.3}/boris/mpv-1.0.3.py +0 -0
- {boris_behav_obs-9.1.1 → boris_behav_obs-9.2.3}/boris/mpv.py +0 -0
- {boris_behav_obs-9.1.1 → boris_behav_obs-9.2.3}/boris/mpv2.py +0 -0
- {boris_behav_obs-9.1.1 → boris_behav_obs-9.2.3}/boris/observation.py +0 -0
- {boris_behav_obs-9.1.1 → boris_behav_obs-9.2.3}/boris/observation_ui.py +0 -0
- {boris_behav_obs-9.1.1 → boris_behav_obs-9.2.3}/boris/observations_list.py +0 -0
- {boris_behav_obs-9.1.1 → boris_behav_obs-9.2.3}/boris/otx_parser.py +0 -0
- {boris_behav_obs-9.1.1 → boris_behav_obs-9.2.3}/boris/param_panel_ui.py +0 -0
- {boris_behav_obs-9.1.1 → boris_behav_obs-9.2.3}/boris/plot_data_module.py +0 -0
- {boris_behav_obs-9.1.1 → boris_behav_obs-9.2.3}/boris/plot_events_rt.py +0 -0
- {boris_behav_obs-9.1.1 → boris_behav_obs-9.2.3}/boris/plot_spectrogram_rt.py +0 -0
- {boris_behav_obs-9.1.1 → boris_behav_obs-9.2.3}/boris/plot_waveform_rt.py +0 -0
- {boris_behav_obs-9.1.1 → boris_behav_obs-9.2.3}/boris/portion/__init__.py +0 -0
- {boris_behav_obs-9.1.1 → boris_behav_obs-9.2.3}/boris/portion/const.py +0 -0
- {boris_behav_obs-9.1.1 → boris_behav_obs-9.2.3}/boris/portion/dict.py +0 -0
- {boris_behav_obs-9.1.1 → boris_behav_obs-9.2.3}/boris/portion/func.py +0 -0
- {boris_behav_obs-9.1.1 → boris_behav_obs-9.2.3}/boris/portion/interval.py +0 -0
- {boris_behav_obs-9.1.1 → boris_behav_obs-9.2.3}/boris/portion/io.py +0 -0
- {boris_behav_obs-9.1.1 → boris_behav_obs-9.2.3}/boris/preferences.py +0 -0
- {boris_behav_obs-9.1.1 → boris_behav_obs-9.2.3}/boris/preferences_ui.py +0 -0
- {boris_behav_obs-9.1.1 → boris_behav_obs-9.2.3}/boris/project.py +0 -0
- {boris_behav_obs-9.1.1 → boris_behav_obs-9.2.3}/boris/project_import_export.py +0 -0
- {boris_behav_obs-9.1.1 → boris_behav_obs-9.2.3}/boris/project_ui.py +0 -0
- {boris_behav_obs-9.1.1 → boris_behav_obs-9.2.3}/boris/qrc_boris.py +0 -0
- {boris_behav_obs-9.1.1 → boris_behav_obs-9.2.3}/boris/qrc_boris5.py +0 -0
- {boris_behav_obs-9.1.1 → boris_behav_obs-9.2.3}/boris/select_modifiers.py +0 -0
- {boris_behav_obs-9.1.1 → boris_behav_obs-9.2.3}/boris/select_observations.py +0 -0
- {boris_behav_obs-9.1.1 → boris_behav_obs-9.2.3}/boris/state_events.py +0 -0
- {boris_behav_obs-9.1.1 → boris_behav_obs-9.2.3}/boris/subjects_pad.py +0 -0
- {boris_behav_obs-9.1.1 → boris_behav_obs-9.2.3}/boris/transitions.py +0 -0
- {boris_behav_obs-9.1.1 → boris_behav_obs-9.2.3}/boris/video_equalizer.py +0 -0
- {boris_behav_obs-9.1.1 → boris_behav_obs-9.2.3}/boris/video_equalizer_ui.py +0 -0
- {boris_behav_obs-9.1.1 → boris_behav_obs-9.2.3}/boris/video_operations.py +0 -0
- {boris_behav_obs-9.1.1 → boris_behav_obs-9.2.3}/boris/view_df.py +0 -0
- {boris_behav_obs-9.1.1 → boris_behav_obs-9.2.3}/boris/view_df_ui.py +0 -0
- {boris_behav_obs-9.1.1 → boris_behav_obs-9.2.3}/boris/write_event.py +0 -0
- {boris_behav_obs-9.1.1 → boris_behav_obs-9.2.3}/boris_behav_obs.egg-info/dependency_links.txt +0 -0
- {boris_behav_obs-9.1.1 → boris_behav_obs-9.2.3}/boris_behav_obs.egg-info/top_level.txt +0 -0
- {boris_behav_obs-9.1.1 → boris_behav_obs-9.2.3}/setup.cfg +0 -0
- {boris_behav_obs-9.1.1 → boris_behav_obs-9.2.3}/tests/test_db_functions.py +0 -0
- {boris_behav_obs-9.1.1 → boris_behav_obs-9.2.3}/tests/test_export_observation.py +0 -0
- {boris_behav_obs-9.1.1 → boris_behav_obs-9.2.3}/tests/test_irr.py +0 -0
- {boris_behav_obs-9.1.1 → boris_behav_obs-9.2.3}/tests/test_observation_gui.py +0 -0
- {boris_behav_obs-9.1.1 → boris_behav_obs-9.2.3}/tests/test_otx_parser.py +0 -0
- {boris_behav_obs-9.1.1 → boris_behav_obs-9.2.3}/tests/test_preferences_gui.py +0 -0
- {boris_behav_obs-9.1.1 → boris_behav_obs-9.2.3}/tests/test_project_functions.py +0 -0
- {boris_behav_obs-9.1.1 → boris_behav_obs-9.2.3}/tests/test_time_budget.py +0 -0
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: boris-behav-obs
|
|
3
|
+
Version: 9.2.3
|
|
4
|
+
Summary: BORIS - Behavioral Observation Research Interactive Software
|
|
5
|
+
Author-email: Olivier Friard <olivier.friard@unito.it>
|
|
6
|
+
License-Expression: GPL-3.0-only
|
|
7
|
+
Project-URL: Homepage, http://www.boris.unito.it
|
|
8
|
+
Project-URL: Documentation, https://boris.readthedocs.io/en/latest/
|
|
9
|
+
Project-URL: Change_log, https://github.com/olivierfriard/BORIS/wiki/BORIS-change-log-v.8
|
|
10
|
+
Project-URL: Source_code, https://github.com/olivierfriard/BORIS
|
|
11
|
+
Project-URL: Issues, https://github.com/olivierfriard/BORIS/issues
|
|
12
|
+
Classifier: Topic :: Scientific/Engineering
|
|
13
|
+
Classifier: Intended Audience :: Science/Research
|
|
14
|
+
Classifier: Intended Audience :: Education
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
16
|
+
Classifier: Operating System :: OS Independent
|
|
17
|
+
Classifier: Topic :: Scientific/Engineering
|
|
18
|
+
Requires-Python: >=3.12
|
|
19
|
+
Description-Content-Type: text/x-rst
|
|
20
|
+
License-File: LICENSE.TXT
|
|
21
|
+
Requires-Dist: exifread>=3.0.0
|
|
22
|
+
Requires-Dist: numpy>=1.26.4
|
|
23
|
+
Requires-Dist: matplotlib>=3.3.3
|
|
24
|
+
Requires-Dist: pandas>=2.2.2
|
|
25
|
+
Requires-Dist: tablib[cli,html,ods,pandas,xls,xlsx]>=3
|
|
26
|
+
Requires-Dist: pyreadr
|
|
27
|
+
Requires-Dist: pyside6==6.8.0.2
|
|
28
|
+
Requires-Dist: hachoir>=3.3.0
|
|
29
|
+
Provides-Extra: dev
|
|
30
|
+
Requires-Dist: ruff; extra == "dev"
|
|
31
|
+
Requires-Dist: pytest; extra == "dev"
|
|
32
|
+
Requires-Dist: pytest-cov; extra == "dev"
|
|
33
|
+
Dynamic: license-file
|
|
@@ -359,8 +359,10 @@ def event_filtering(self):
|
|
|
359
359
|
selected_observations,
|
|
360
360
|
start_coding=start_coding,
|
|
361
361
|
end_coding=end_coding,
|
|
362
|
-
start_interval=start_interval,
|
|
363
|
-
end_interval=end_interval,
|
|
362
|
+
# start_interval=start_interval,
|
|
363
|
+
# end_interval=end_interval,
|
|
364
|
+
start_interval=None,
|
|
365
|
+
end_interval=None,
|
|
364
366
|
maxTime=max_media_duration_all_obs,
|
|
365
367
|
show_include_modifiers=False,
|
|
366
368
|
show_exclude_non_coded_behaviors=False,
|
|
@@ -368,7 +370,7 @@ def event_filtering(self):
|
|
|
368
370
|
n_observations=len(selected_observations),
|
|
369
371
|
)
|
|
370
372
|
|
|
371
|
-
if parameters
|
|
373
|
+
if not parameters:
|
|
372
374
|
return
|
|
373
375
|
|
|
374
376
|
if not parameters[cfg.SELECTED_SUBJECTS] or not parameters[cfg.SELECTED_BEHAVIORS]:
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"""
|
|
2
|
+
BORIS plugin
|
|
3
|
+
|
|
4
|
+
number of occurences of behaviors
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
import pandas as pd
|
|
8
|
+
|
|
9
|
+
__version__ = "0.3.0"
|
|
10
|
+
__version_date__ = "2025-03-17"
|
|
11
|
+
__plugin_name__ = "Number of occurences of behaviors"
|
|
12
|
+
__author__ = "Olivier Friard - University of Torino - Italy"
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def run(df: pd.DataFrame):
|
|
16
|
+
"""
|
|
17
|
+
Calculate the number of occurrences of behaviors by subject.
|
|
18
|
+
"""
|
|
19
|
+
|
|
20
|
+
df_results: pd.DataFrame = df.groupby(["Subject", "Behavior"])["Behavior"].count().reset_index(name="number of occurences")
|
|
21
|
+
|
|
22
|
+
return df_results
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
"""
|
|
2
|
+
BORIS plugin
|
|
3
|
+
|
|
4
|
+
number of occurences of behaviors by independent_variable
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
import pandas as pd
|
|
8
|
+
|
|
9
|
+
__version__ = "0.3.0"
|
|
10
|
+
__version_date__ = "2025-03-17"
|
|
11
|
+
__plugin_name__ = "Number of occurences of behaviors by subject by independent_variable"
|
|
12
|
+
__author__ = "Olivier Friard - University of Torino - Italy"
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def run(df: pd.DataFrame):
|
|
16
|
+
"""
|
|
17
|
+
Calculate the number of occurrences of behaviors by subject and by independent_variable.
|
|
18
|
+
|
|
19
|
+
This plugin returns a Pandas dataframe
|
|
20
|
+
"""
|
|
21
|
+
|
|
22
|
+
df_results: df.DataFrame = (
|
|
23
|
+
df.groupby(
|
|
24
|
+
[
|
|
25
|
+
"independent variable 'Weather'",
|
|
26
|
+
"Subject",
|
|
27
|
+
"Behavior",
|
|
28
|
+
]
|
|
29
|
+
)["Behavior"]
|
|
30
|
+
.count()
|
|
31
|
+
.reset_index(name="number of occurences")
|
|
32
|
+
)
|
|
33
|
+
|
|
34
|
+
return df_results
|
|
@@ -7,8 +7,8 @@ Time budget
|
|
|
7
7
|
import pandas as pd
|
|
8
8
|
import numpy as np
|
|
9
9
|
|
|
10
|
-
__version__ = "0.
|
|
11
|
-
__version_date__ = "2025-
|
|
10
|
+
__version__ = "0.3.0"
|
|
11
|
+
__version_date__ = "2025-03-17"
|
|
12
12
|
__plugin_name__ = "Time budget"
|
|
13
13
|
__author__ = "Olivier Friard - University of Torino - Italy"
|
|
14
14
|
|
|
@@ -18,7 +18,7 @@ def run(df: pd.DataFrame):
|
|
|
18
18
|
Calculate the following values:
|
|
19
19
|
|
|
20
20
|
- Total number of occurences of behavior
|
|
21
|
-
- Total duration of behavior (in seconds)
|
|
21
|
+
- Total duration of behavior (in seconds) (pandas.DataFrame.sum() ignore NaN values when computing the sum. Use min_count=1)
|
|
22
22
|
- Duration mean of behavior (in seconds)
|
|
23
23
|
- Standard deviation of behavior duration (in seconds)
|
|
24
24
|
- Inter-event intervals mean (in seconds)
|
|
@@ -26,11 +26,15 @@ def run(df: pd.DataFrame):
|
|
|
26
26
|
- % of total subject observation duration
|
|
27
27
|
"""
|
|
28
28
|
|
|
29
|
+
print("running time budget plugin")
|
|
30
|
+
|
|
31
|
+
print(df)
|
|
32
|
+
|
|
29
33
|
group_by = ["Subject", "Behavior"]
|
|
30
34
|
|
|
31
35
|
dfs = [
|
|
32
36
|
df.groupby(group_by)["Behavior"].count().reset_index(name="number of occurences"),
|
|
33
|
-
df.groupby(group_by)["Duration (s)"].sum().reset_index(name="total duration"),
|
|
37
|
+
df.groupby(group_by)["Duration (s)"].sum(min_count=1).reset_index(name="total duration"),
|
|
34
38
|
df.groupby(group_by)["Duration (s)"].mean().astype(float).round(3).reset_index(name="duration mean"),
|
|
35
39
|
df.groupby(group_by)["Duration (s)"].std().astype(float).round(3).reset_index(name="duration std dev"),
|
|
36
40
|
]
|
|
@@ -48,7 +52,7 @@ def run(df: pd.DataFrame):
|
|
|
48
52
|
interval = (df.groupby(["Subject"])["Stop (s)"].max() - df.groupby(["Subject"])["Start (s)"].min()).replace(0, np.nan)
|
|
49
53
|
|
|
50
54
|
dfs.append(
|
|
51
|
-
(100 * df.groupby(group_by)["Duration (s)"].sum() / interval)
|
|
55
|
+
(100 * df.groupby(group_by)["Duration (s)"].sum(min_count=1) / interval)
|
|
52
56
|
.astype(float)
|
|
53
57
|
.round(3)
|
|
54
58
|
.reset_index(name="% of total subject observation duration")
|
|
@@ -59,45 +63,3 @@ def run(df: pd.DataFrame):
|
|
|
59
63
|
merged_df = pd.merge(merged_df, df, on=group_by)
|
|
60
64
|
|
|
61
65
|
return merged_df
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
def main(df: pd.DataFrame, observations_list: list = [], parameters: dict = {}) -> pd.DataFrame:
|
|
65
|
-
"""
|
|
66
|
-
filter by selected observations.
|
|
67
|
-
filter by selected subjects.
|
|
68
|
-
filter by selected behaviors.
|
|
69
|
-
filter by time interval.
|
|
70
|
-
"""
|
|
71
|
-
|
|
72
|
-
# filter selected observations
|
|
73
|
-
if observations_list:
|
|
74
|
-
df = df[df["Observation id"].isin(observations_list)]
|
|
75
|
-
|
|
76
|
-
if parameters:
|
|
77
|
-
# filter selected subjects
|
|
78
|
-
df = df[df["Subject"].isin(parameters["selected subjects"])]
|
|
79
|
-
|
|
80
|
-
# filter selected behaviors
|
|
81
|
-
df = df[df["Behavior"].isin(parameters["selected behaviors"])]
|
|
82
|
-
|
|
83
|
-
# filter selected time interval
|
|
84
|
-
if parameters["start time"] is not None and parameters["end time"] is not None:
|
|
85
|
-
MIN_TIME = parameters["start time"]
|
|
86
|
-
MAX_TIME = parameters["end time"]
|
|
87
|
-
|
|
88
|
-
df_interval = df[
|
|
89
|
-
(
|
|
90
|
-
((df["Start (s)"] >= MIN_TIME) & (df["Start (s)"] <= MAX_TIME))
|
|
91
|
-
| ((df["Stop (s)"] >= MIN_TIME) & (df["Stop (s)"] <= MAX_TIME))
|
|
92
|
-
)
|
|
93
|
-
| ((df["Start (s)"] < MIN_TIME) & (df["Stop (s)"] > MAX_TIME))
|
|
94
|
-
]
|
|
95
|
-
|
|
96
|
-
df_interval.loc[df["Start (s)"] < MIN_TIME, "Start (s)"] = MIN_TIME
|
|
97
|
-
df_interval.loc[df["Stop (s)"] > MAX_TIME, "Stop (s)"] = MAX_TIME
|
|
98
|
-
|
|
99
|
-
df_interval.loc[:, "Duration (s)"] = df_interval["Stop (s)"] - df_interval["Start (s)"]
|
|
100
|
-
|
|
101
|
-
df = df_interval
|
|
102
|
-
|
|
103
|
-
return run(df)
|
|
@@ -80,12 +80,12 @@ def create_behavior_binary_table(pj: dict, selected_observations: list, paramete
|
|
|
80
80
|
end_time = dec(max_obs_length)
|
|
81
81
|
|
|
82
82
|
if parameters_obs["time"] == cfg.TIME_OBS_INTERVAL:
|
|
83
|
-
obs_interval = pj[cfg.OBSERVATIONS][obs_id]
|
|
83
|
+
obs_interval = pj[cfg.OBSERVATIONS][obs_id].get(cfg.OBSERVATION_TIME_INTERVAL, [0, 0])
|
|
84
84
|
offset = pj[cfg.OBSERVATIONS][obs_id][cfg.TIME_OFFSET]
|
|
85
85
|
start_time = dec(obs_interval[0]) + offset
|
|
86
86
|
# Use max observation length for end time if no interval is defined (=0)
|
|
87
87
|
max_obs_length, _ = observation_operations.observation_length(pj, [obs_id])
|
|
88
|
-
end_time = dec(obs_interval[1]) + offset if obs_interval[1]
|
|
88
|
+
end_time = dec(obs_interval[1]) + offset if obs_interval[1] not in (0, None) else dec(max_obs_length)
|
|
89
89
|
|
|
90
90
|
if obs_id not in results_df:
|
|
91
91
|
results_df[obs_id] = {}
|
|
@@ -166,8 +166,8 @@ def behavior_binary_table(self):
|
|
|
166
166
|
None,
|
|
167
167
|
cfg.programName,
|
|
168
168
|
(
|
|
169
|
-
"Depending
|
|
170
|
-
"the execution of this function may
|
|
169
|
+
"Depending on the length of yours observations "
|
|
170
|
+
"the execution of this function may take a long time.<br>"
|
|
171
171
|
"The program interface may freeze, be patient. <br>"
|
|
172
172
|
),
|
|
173
173
|
)
|
|
@@ -224,7 +224,7 @@ def behavior_binary_table(self):
|
|
|
224
224
|
by_category=False,
|
|
225
225
|
n_observations=len(selected_observations),
|
|
226
226
|
)
|
|
227
|
-
if parameters
|
|
227
|
+
if not parameters:
|
|
228
228
|
return
|
|
229
229
|
if not parameters[cfg.SELECTED_SUBJECTS] or not parameters[cfg.SELECTED_BEHAVIORS]:
|
|
230
230
|
QMessageBox.warning(None, cfg.programName, "Select subject(s) and behavior(s) to analyze")
|
|
@@ -271,7 +271,9 @@ def connections(self):
|
|
|
271
271
|
self.actionViewBehavior.triggered.connect(self.view_behavior)
|
|
272
272
|
self.twEthogram.addAction(self.actionViewBehavior)
|
|
273
273
|
|
|
274
|
-
self.actionFilterBehaviors.triggered.connect(
|
|
274
|
+
self.actionFilterBehaviors.triggered.connect(
|
|
275
|
+
lambda: self.filter_behaviors(table=cfg.ETHOGRAM, behavior_type=cfg.STATE_EVENT_TYPES + cfg.POINT_EVENT_TYPES)
|
|
276
|
+
)
|
|
275
277
|
self.twEthogram.addAction(self.actionFilterBehaviors)
|
|
276
278
|
|
|
277
279
|
self.actionShowAllBehaviors.triggered.connect(self.show_all_behaviors)
|
|
@@ -98,6 +98,7 @@ def get_cooccurence(self):
|
|
|
98
98
|
|
|
99
99
|
start_interval, end_interval = observation_operations.time_intervals_range(self.pj[cfg.OBSERVATIONS], selected_observations)
|
|
100
100
|
|
|
101
|
+
# loop on choose subjects /behaviors until parameters are OK
|
|
101
102
|
while True:
|
|
102
103
|
flag_ok: bool = True
|
|
103
104
|
parameters = select_subj_behav.choose_obs_subj_behav_category(
|
|
@@ -105,15 +106,17 @@ def get_cooccurence(self):
|
|
|
105
106
|
selected_observations,
|
|
106
107
|
start_coding=start_coding,
|
|
107
108
|
end_coding=end_coding,
|
|
108
|
-
start_interval=start_interval,
|
|
109
|
-
end_interval=end_interval,
|
|
109
|
+
# start_interval=start_interval,
|
|
110
|
+
# end_interval=end_interval,
|
|
111
|
+
start_interval=None,
|
|
112
|
+
end_interval=None,
|
|
110
113
|
maxTime=max_media_duration_all_obs,
|
|
111
114
|
n_observations=len(selected_observations),
|
|
112
115
|
show_include_modifiers=False,
|
|
113
116
|
show_exclude_non_coded_behaviors=True,
|
|
114
117
|
)
|
|
115
118
|
|
|
116
|
-
if parameters
|
|
119
|
+
if not parameters: # cancel button pressed
|
|
117
120
|
return
|
|
118
121
|
|
|
119
122
|
if not parameters[cfg.SELECTED_SUBJECTS]:
|
|
@@ -34,7 +34,6 @@ import json
|
|
|
34
34
|
import logging
|
|
35
35
|
import pathlib as pl
|
|
36
36
|
import platform
|
|
37
|
-
import importlib
|
|
38
37
|
import re
|
|
39
38
|
import PIL.Image
|
|
40
39
|
import PIL.ImageEnhance
|
|
@@ -52,7 +51,6 @@ from decimal import Decimal as dec
|
|
|
52
51
|
from decimal import ROUND_DOWN
|
|
53
52
|
import gzip
|
|
54
53
|
from collections import deque
|
|
55
|
-
import pandas as pd
|
|
56
54
|
import matplotlib
|
|
57
55
|
import zipfile
|
|
58
56
|
import shutil
|
|
@@ -129,7 +127,6 @@ from . import config_file
|
|
|
129
127
|
from . import select_subj_behav
|
|
130
128
|
from . import observation_operations
|
|
131
129
|
from . import write_event
|
|
132
|
-
from . import view_df
|
|
133
130
|
|
|
134
131
|
|
|
135
132
|
# matplotlib.pyplot.switch_backend("Qt5Agg")
|
|
@@ -797,10 +794,10 @@ class MainWindow(QMainWindow, Ui_MainWindow):
|
|
|
797
794
|
|
|
798
795
|
def filter_behaviors(
|
|
799
796
|
self,
|
|
800
|
-
title="Select the behaviors to show in the ethogram table",
|
|
801
|
-
text="Behaviors to show in ethogram list",
|
|
802
|
-
table=cfg.ETHOGRAM,
|
|
803
|
-
behavior_type=cfg.STATE_EVENT_TYPES,
|
|
797
|
+
title: str = "Select the behaviors to show in the ethogram table",
|
|
798
|
+
text: str = "Behaviors to show in ethogram list",
|
|
799
|
+
table: str = cfg.ETHOGRAM,
|
|
800
|
+
behavior_type: list = cfg.STATE_EVENT_TYPES,
|
|
804
801
|
) -> Tuple[bool, list]:
|
|
805
802
|
"""
|
|
806
803
|
allow user to:
|
|
@@ -812,6 +809,7 @@ class MainWindow(QMainWindow, Ui_MainWindow):
|
|
|
812
809
|
title (str): title of dialog box
|
|
813
810
|
text (str): text of dialog box
|
|
814
811
|
table (str): table where behaviors will be filtered
|
|
812
|
+
behavior_type
|
|
815
813
|
|
|
816
814
|
Returns:
|
|
817
815
|
(None if table = ETHOGRAM)
|
|
@@ -861,21 +859,22 @@ class MainWindow(QMainWindow, Ui_MainWindow):
|
|
|
861
859
|
categories = ["###no category###"]
|
|
862
860
|
|
|
863
861
|
for category in categories:
|
|
864
|
-
if category
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
862
|
+
if category == "###no category###":
|
|
863
|
+
continue
|
|
864
|
+
if category == "":
|
|
865
|
+
paramPanelWindow.item = QListWidgetItem("No category")
|
|
866
|
+
paramPanelWindow.item.setData(34, "No category")
|
|
867
|
+
else:
|
|
868
|
+
paramPanelWindow.item = QListWidgetItem(category)
|
|
869
|
+
paramPanelWindow.item.setData(34, category)
|
|
871
870
|
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
871
|
+
font = QFont()
|
|
872
|
+
font.setBold(True)
|
|
873
|
+
paramPanelWindow.item.setFont(font)
|
|
874
|
+
paramPanelWindow.item.setData(33, "category")
|
|
875
|
+
paramPanelWindow.item.setData(35, False)
|
|
877
876
|
|
|
878
|
-
|
|
877
|
+
paramPanelWindow.lwBehaviors.addItem(paramPanelWindow.item)
|
|
879
878
|
|
|
880
879
|
# check if behavior type must be shown
|
|
881
880
|
for behavior in [self.pj[cfg.ETHOGRAM][x][cfg.BEHAVIOR_CODE] for x in util.sorted_keys(self.pj[cfg.ETHOGRAM])]:
|
|
@@ -3634,6 +3633,17 @@ class MainWindow(QMainWindow, Ui_MainWindow):
|
|
|
3634
3633
|
else:
|
|
3635
3634
|
current_time = self.getLaps()
|
|
3636
3635
|
|
|
3636
|
+
# check if observation time interval
|
|
3637
|
+
if self.pj[cfg.OBSERVATIONS][self.observationId].get(cfg.OBSERVATION_TIME_INTERVAL, [0, 0])[1]:
|
|
3638
|
+
# check if current time outside of interval
|
|
3639
|
+
if current_time >= self.pj[cfg.OBSERVATIONS][self.observationId].get(cfg.OBSERVATION_TIME_INTERVAL, [None, None])[1]:
|
|
3640
|
+
self.beep("beep")
|
|
3641
|
+
self.liveTimer.stop()
|
|
3642
|
+
self.liveObservationStarted = False
|
|
3643
|
+
# set current time to end of observation interval
|
|
3644
|
+
current_time = dec(self.pj[cfg.OBSERVATIONS][self.observationId].get(cfg.OBSERVATION_TIME_INTERVAL, [None, None])[1])
|
|
3645
|
+
self.pb_live_obs.setText("Live observation finished")
|
|
3646
|
+
|
|
3637
3647
|
self.lb_current_media_time.setText(util.convertTime(self.timeFormat, current_time))
|
|
3638
3648
|
|
|
3639
3649
|
# extract State events
|
|
@@ -3663,14 +3673,6 @@ class MainWindow(QMainWindow, Ui_MainWindow):
|
|
|
3663
3673
|
self.liveTimer.stop()
|
|
3664
3674
|
self.pb_live_obs.setText("Live observation stopped (scan sampling)")
|
|
3665
3675
|
|
|
3666
|
-
# observation time interval
|
|
3667
|
-
if self.pj[cfg.OBSERVATIONS][self.observationId].get(cfg.OBSERVATION_TIME_INTERVAL, [0, 0])[1]:
|
|
3668
|
-
if current_time >= self.pj[cfg.OBSERVATIONS][self.observationId].get(cfg.OBSERVATION_TIME_INTERVAL, [0, 0])[1]:
|
|
3669
|
-
self.beep("beep")
|
|
3670
|
-
self.liveTimer.stop()
|
|
3671
|
-
self.liveObservationStarted = False
|
|
3672
|
-
self.pb_live_obs.setText("Live observation finished")
|
|
3673
|
-
|
|
3674
3676
|
def start_live_observation(self):
|
|
3675
3677
|
"""
|
|
3676
3678
|
activate the live observation mode
|
|
@@ -3772,8 +3774,10 @@ class MainWindow(QMainWindow, Ui_MainWindow):
|
|
|
3772
3774
|
selected_observations,
|
|
3773
3775
|
start_coding=start_coding,
|
|
3774
3776
|
end_coding=end_coding,
|
|
3775
|
-
start_interval=start_interval,
|
|
3776
|
-
end_interval=end_interval,
|
|
3777
|
+
# start_interval=start_interval,
|
|
3778
|
+
# end_interval=end_interval,
|
|
3779
|
+
start_interval=None,
|
|
3780
|
+
end_interval=None,
|
|
3777
3781
|
maxTime=max_media_duration_all_obs,
|
|
3778
3782
|
show_include_modifiers=False,
|
|
3779
3783
|
show_exclude_non_coded_behaviors=False,
|
|
@@ -5750,10 +5754,7 @@ class MainWindow(QMainWindow, Ui_MainWindow):
|
|
|
5750
5754
|
if self.playerType == cfg.MEDIA:
|
|
5751
5755
|
self.pause_video()
|
|
5752
5756
|
|
|
5753
|
-
|
|
5754
|
-
self.seek_mediaplayer(int(self.pj[cfg.OBSERVATIONS][self.observationId][cfg.OBSERVATION_TIME_INTERVAL][0]))
|
|
5755
|
-
else:
|
|
5756
|
-
self.seek_mediaplayer(0)
|
|
5757
|
+
self.seek_mediaplayer(int(self.pj[cfg.OBSERVATIONS][self.observationId].get(cfg.OBSERVATION_TIME_INTERVAL, [0, 0])[0]))
|
|
5757
5758
|
|
|
5758
5759
|
self.update_visualizations()
|
|
5759
5760
|
|
|
@@ -5762,6 +5763,9 @@ class MainWindow(QMainWindow, Ui_MainWindow):
|
|
|
5762
5763
|
self.extract_frame(self.dw_player[0])
|
|
5763
5764
|
|
|
5764
5765
|
def obs_param(self):
|
|
5766
|
+
"""
|
|
5767
|
+
allow user to select observations and then subjects and behaviors
|
|
5768
|
+
"""
|
|
5765
5769
|
_, selected_observations = select_observations.select_observations2(self, mode=cfg.MULTIPLE, windows_title="")
|
|
5766
5770
|
|
|
5767
5771
|
if not selected_observations:
|
|
@@ -5786,8 +5790,14 @@ class MainWindow(QMainWindow, Ui_MainWindow):
|
|
|
5786
5790
|
|
|
5787
5791
|
start_coding, end_coding, _ = observation_operations.coding_time(self.pj[cfg.OBSERVATIONS], selected_observations)
|
|
5788
5792
|
|
|
5793
|
+
print(f"{start_coding=}")
|
|
5794
|
+
print(f"{end_coding=}")
|
|
5795
|
+
|
|
5789
5796
|
start_interval, end_interval = observation_operations.time_intervals_range(self.pj[cfg.OBSERVATIONS], selected_observations)
|
|
5790
5797
|
|
|
5798
|
+
print(f"{start_interval=}")
|
|
5799
|
+
print(f"{end_interval=}")
|
|
5800
|
+
|
|
5791
5801
|
parameters: dict = select_subj_behav.choose_obs_subj_behav_category(
|
|
5792
5802
|
self,
|
|
5793
5803
|
selected_observations,
|
|
@@ -5803,6 +5813,8 @@ class MainWindow(QMainWindow, Ui_MainWindow):
|
|
|
5803
5813
|
if parameters == {}:
|
|
5804
5814
|
return [], {}
|
|
5805
5815
|
|
|
5816
|
+
print(f"{parameters=}")
|
|
5817
|
+
|
|
5806
5818
|
if not parameters[cfg.SELECTED_SUBJECTS] or not parameters[cfg.SELECTED_BEHAVIORS]:
|
|
5807
5819
|
QMessageBox.warning(None, cfg.programName, "Select subject(s) and behavior(s) to analyze")
|
|
5808
5820
|
return [], {}
|
|
@@ -5810,94 +5822,6 @@ class MainWindow(QMainWindow, Ui_MainWindow):
|
|
|
5810
5822
|
logging.debug(f"{parameters=}")
|
|
5811
5823
|
return selected_observations, parameters
|
|
5812
5824
|
|
|
5813
|
-
def run_plugin(self):
|
|
5814
|
-
"""
|
|
5815
|
-
run plugin
|
|
5816
|
-
"""
|
|
5817
|
-
if not self.project:
|
|
5818
|
-
QMessageBox.warning(
|
|
5819
|
-
self,
|
|
5820
|
-
cfg.programName,
|
|
5821
|
-
"No observations found. Open a project first",
|
|
5822
|
-
QMessageBox.Ok | QMessageBox.Default,
|
|
5823
|
-
QMessageBox.NoButton,
|
|
5824
|
-
)
|
|
5825
|
-
return
|
|
5826
|
-
|
|
5827
|
-
logging.debug(f"{self.config_param.get(cfg.ANALYSIS_PLUGINS, {})=}")
|
|
5828
|
-
|
|
5829
|
-
plugin_name = self.sender().text()
|
|
5830
|
-
if plugin_name not in self.config_param.get(cfg.ANALYSIS_PLUGINS, {}):
|
|
5831
|
-
QMessageBox.critical(self, cfg.programName, f"Plugin '{plugin_name}' not found")
|
|
5832
|
-
return
|
|
5833
|
-
|
|
5834
|
-
plugin_path = self.config_param.get(cfg.ANALYSIS_PLUGINS, {})[plugin_name]
|
|
5835
|
-
|
|
5836
|
-
logging.debug(f"{plugin_path=}")
|
|
5837
|
-
|
|
5838
|
-
if not pl.Path(plugin_path).is_file():
|
|
5839
|
-
QMessageBox.critical(self, cfg.programName, f"The plugin {plugin_path} was not found.")
|
|
5840
|
-
return
|
|
5841
|
-
|
|
5842
|
-
logging.debug(f"run plugin from {plugin_path}")
|
|
5843
|
-
|
|
5844
|
-
module_name = pl.Path(plugin_path).stem
|
|
5845
|
-
|
|
5846
|
-
spec = importlib.util.spec_from_file_location(module_name, plugin_path)
|
|
5847
|
-
plugin_module = importlib.util.module_from_spec(spec)
|
|
5848
|
-
|
|
5849
|
-
logging.debug(f"{plugin_module=}")
|
|
5850
|
-
|
|
5851
|
-
spec.loader.exec_module(plugin_module)
|
|
5852
|
-
|
|
5853
|
-
logging.info(
|
|
5854
|
-
f"{plugin_module.__plugin_name__} loaded v.{getattr(plugin_module, '__version__')} v. {getattr(plugin_module, '__version_date__')}"
|
|
5855
|
-
)
|
|
5856
|
-
|
|
5857
|
-
selected_observations, parameters = self.obs_param()
|
|
5858
|
-
if not selected_observations:
|
|
5859
|
-
return
|
|
5860
|
-
|
|
5861
|
-
df = project_functions.project2dataframe(self.pj, selected_observations)
|
|
5862
|
-
|
|
5863
|
-
logging.debug("dataframe info")
|
|
5864
|
-
logging.debug(f"{df.info()}")
|
|
5865
|
-
logging.debug(f"{df.head()}")
|
|
5866
|
-
|
|
5867
|
-
# df_results, str_results = plugin_module.main(df, observations_list=selected_observations, parameters=parameters)
|
|
5868
|
-
|
|
5869
|
-
plugin_results = plugin_module.main(df, observations_list=selected_observations, parameters=parameters)
|
|
5870
|
-
# test if tuple: if not transform to tuple
|
|
5871
|
-
if not isinstance(plugin_results, tuple):
|
|
5872
|
-
plugin_results = tuple([plugin_results])
|
|
5873
|
-
|
|
5874
|
-
self.plugin_visu: list = []
|
|
5875
|
-
for result in plugin_results:
|
|
5876
|
-
if isinstance(result, str):
|
|
5877
|
-
self.plugin_visu.append(dialog.Results_dialog())
|
|
5878
|
-
self.plugin_visu[-1].setWindowTitle(self.sender().text())
|
|
5879
|
-
self.plugin_visu[-1].ptText.clear()
|
|
5880
|
-
self.plugin_visu[-1].ptText.appendPlainText(result)
|
|
5881
|
-
self.plugin_visu[-1].show()
|
|
5882
|
-
elif isinstance(result, pd.DataFrame):
|
|
5883
|
-
self.plugin_visu.append(
|
|
5884
|
-
view_df.View_df(self.sender().text(), f"{plugin_module.__version__} ({plugin_module.__version_date__})", result)
|
|
5885
|
-
)
|
|
5886
|
-
self.plugin_visu[-1].show()
|
|
5887
|
-
else:
|
|
5888
|
-
# result is not str nor dataframe
|
|
5889
|
-
QMessageBox.critical(
|
|
5890
|
-
None,
|
|
5891
|
-
cfg.programName,
|
|
5892
|
-
(
|
|
5893
|
-
f"Plugin returns an unknown object type: {type(result)}\n\n"
|
|
5894
|
-
"Plugins must return str and/or Pandas Dataframes.\n"
|
|
5895
|
-
"Check the plugin code."
|
|
5896
|
-
),
|
|
5897
|
-
QMessageBox.Ok | QMessageBox.Default,
|
|
5898
|
-
QMessageBox.NoButton,
|
|
5899
|
-
)
|
|
5900
|
-
|
|
5901
5825
|
|
|
5902
5826
|
def main():
|
|
5903
5827
|
# QApplication.setAttribute(Qt.AA_EnableHighDpiScaling)
|
|
@@ -76,7 +76,7 @@ def export_events_as_behavioral_sequences(self, separated_subjects=False, timed=
|
|
|
76
76
|
else:
|
|
77
77
|
max_media_duration_all_obs = None
|
|
78
78
|
start_coding, end_coding = dec("NaN"), dec("NaN")
|
|
79
|
-
start_interval, end_interval =
|
|
79
|
+
start_interval, end_interval = None, None
|
|
80
80
|
|
|
81
81
|
parameters = select_subj_behav.choose_obs_subj_behav_category(
|
|
82
82
|
self,
|
|
@@ -169,7 +169,7 @@ def export_tabular_events(self, mode: str = "tabular") -> None:
|
|
|
169
169
|
else:
|
|
170
170
|
max_media_duration_all_obs = None
|
|
171
171
|
start_coding, end_coding = dec("NaN"), dec("NaN")
|
|
172
|
-
start_interval, end_interval =
|
|
172
|
+
start_interval, end_interval = None, None
|
|
173
173
|
|
|
174
174
|
parameters = select_subj_behav.choose_obs_subj_behav_category(
|
|
175
175
|
self,
|
|
@@ -373,7 +373,7 @@ def export_aggregated_events(self):
|
|
|
373
373
|
else:
|
|
374
374
|
max_media_duration_all_obs = None
|
|
375
375
|
start_coding, end_coding = dec("NaN"), dec("NaN")
|
|
376
|
-
start_interval, end_interval =
|
|
376
|
+
start_interval, end_interval = None, None
|
|
377
377
|
|
|
378
378
|
parameters = select_subj_behav.choose_obs_subj_behav_category(
|
|
379
379
|
self,
|
|
@@ -681,8 +681,10 @@ def export_events_as_textgrid(self) -> None:
|
|
|
681
681
|
selected_observations,
|
|
682
682
|
start_coding=start_coding,
|
|
683
683
|
end_coding=end_coding,
|
|
684
|
-
start_interval=start_interval,
|
|
685
|
-
end_interval=end_interval,
|
|
684
|
+
# start_interval=start_interval,
|
|
685
|
+
# end_interval=end_interval,
|
|
686
|
+
start_interval=None,
|
|
687
|
+
end_interval=None,
|
|
686
688
|
show_include_modifiers=False,
|
|
687
689
|
show_exclude_non_coded_behaviors=False,
|
|
688
690
|
maxTime=max_obs_length,
|
|
@@ -786,7 +788,7 @@ def export_events_as_textgrid(self) -> None:
|
|
|
786
788
|
|
|
787
789
|
if parameters["time"] == cfg.TIME_OBS_INTERVAL:
|
|
788
790
|
max_media_duration, _ = observation_operations.media_duration(self.pj[cfg.OBSERVATIONS], [obs_id])
|
|
789
|
-
obs_interval = self.pj[cfg.OBSERVATIONS][obs_id]
|
|
791
|
+
obs_interval = self.pj[cfg.OBSERVATIONS][obs_id].get(cfg.OBSERVATION_TIME_INTERVAL, [0, 0])
|
|
790
792
|
offset = float(self.pj[cfg.OBSERVATIONS][obs_id][cfg.TIME_OFFSET])
|
|
791
793
|
min_time = float(obs_interval[0]) + offset
|
|
792
794
|
# Use max media duration for max time if no interval is defined (=0)
|
|
@@ -121,7 +121,10 @@ def export_events_jwatcher(
|
|
|
121
121
|
except Exception:
|
|
122
122
|
# coded behavior not defined in ethogram
|
|
123
123
|
continue
|
|
124
|
-
if [ethogram[k][cfg.TYPE] for k in ethogram if ethogram[k][cfg.BEHAVIOR_CODE] == behav_code]
|
|
124
|
+
if [ethogram[k][cfg.TYPE] for k in ethogram if ethogram[k][cfg.BEHAVIOR_CODE] == behav_code] in [
|
|
125
|
+
[cfg.STATE_EVENT],
|
|
126
|
+
[cfg.STATE_EVENT_WITH_CODING_MAP],
|
|
127
|
+
]:
|
|
125
128
|
if behav_code in mem_number_of_state_events:
|
|
126
129
|
mem_number_of_state_events[behav_code] += 1
|
|
127
130
|
else:
|
|
@@ -31,32 +31,40 @@ def save_geometry(widget: QWidget, widget_name: str):
|
|
|
31
31
|
save window geometry in ini file
|
|
32
32
|
"""
|
|
33
33
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
34
|
+
ini_file_path = pl.Path.home() / pl.Path(".boris")
|
|
35
|
+
if ini_file_path.is_file():
|
|
36
|
+
try:
|
|
37
37
|
settings = QSettings(str(ini_file_path), QSettings.IniFormat)
|
|
38
38
|
settings.setValue(f"{widget_name} geometry", widget.saveGeometry())
|
|
39
|
-
|
|
40
|
-
|
|
39
|
+
except Exception:
|
|
40
|
+
logging.warning(f"error during saving {widget_name} geometry")
|
|
41
41
|
|
|
42
42
|
|
|
43
|
-
def restore_geometry(widget: QWidget, widget_name: str,
|
|
43
|
+
def restore_geometry(widget: QWidget, widget_name: str, default_width_height):
|
|
44
44
|
"""
|
|
45
45
|
restore window geometry in ini file
|
|
46
46
|
"""
|
|
47
|
+
def default_resize(widget, default_width_height):
|
|
48
|
+
if default_width_height != (0, 0):
|
|
49
|
+
try:
|
|
50
|
+
widget.resize(default_width_height[0], default_width_height[1])
|
|
51
|
+
except Exception:
|
|
52
|
+
logging.warning("Error during restoring default")
|
|
53
|
+
|
|
47
54
|
|
|
55
|
+
logging.debug(f'restore geometry function for {widget_name}')
|
|
48
56
|
try:
|
|
49
57
|
ini_file_path = pl.Path.home() / pl.Path(".boris")
|
|
50
58
|
if ini_file_path.is_file():
|
|
51
59
|
settings = QSettings(str(ini_file_path), QSettings.IniFormat)
|
|
60
|
+
print(settings.value(f"{widget_name} geometry"))
|
|
52
61
|
widget.restoreGeometry(settings.value(f"{widget_name} geometry"))
|
|
62
|
+
logging.debug(f'geometry restored for {widget_name} {settings.value(f"{widget_name} geometry")}')
|
|
63
|
+
else:
|
|
64
|
+
default_resize(widget, default_width_height)
|
|
53
65
|
except Exception:
|
|
54
66
|
logging.warning(f"error during restoring {widget_name} geometry")
|
|
55
|
-
|
|
56
|
-
try:
|
|
57
|
-
widget.resize(default_geometry[0], default_geometry[1])
|
|
58
|
-
except Exception:
|
|
59
|
-
logging.warning("Error during restoring default")
|
|
67
|
+
default_resize(widget, default_width_height)
|
|
60
68
|
|
|
61
69
|
|
|
62
70
|
def set_icons(self, theme_mode: str) -> None:
|