boris-behav-obs 9.3.2__tar.gz → 9.3.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.3.2/boris_behav_obs.egg-info → boris_behav_obs-9.3.3}/PKG-INFO +1 -1
- {boris_behav_obs-9.3.2 → boris_behav_obs-9.3.3}/boris/config.py +4 -1
- {boris_behav_obs-9.3.2 → boris_behav_obs-9.3.3}/boris/core.py +0 -5
- {boris_behav_obs-9.3.2 → boris_behav_obs-9.3.3}/boris/dialog.py +1 -1
- {boris_behav_obs-9.3.2 → boris_behav_obs-9.3.3}/boris/media_file.py +12 -10
- {boris_behav_obs-9.3.2 → boris_behav_obs-9.3.3}/boris/observation_operations.py +4 -4
- {boris_behav_obs-9.3.2 → boris_behav_obs-9.3.3}/boris/project.py +69 -21
- {boris_behav_obs-9.3.2 → boris_behav_obs-9.3.3}/boris/project_import_export.py +3 -1
- {boris_behav_obs-9.3.2 → boris_behav_obs-9.3.3}/boris/utilities.py +0 -1
- {boris_behav_obs-9.3.2 → boris_behav_obs-9.3.3}/boris/version.py +2 -2
- {boris_behav_obs-9.3.2 → boris_behav_obs-9.3.3/boris_behav_obs.egg-info}/PKG-INFO +1 -1
- {boris_behav_obs-9.3.2 → boris_behav_obs-9.3.3}/pyproject.toml +2 -2
- {boris_behav_obs-9.3.2 → boris_behav_obs-9.3.3}/tests/test_utilities.py +6 -3
- {boris_behav_obs-9.3.2 → boris_behav_obs-9.3.3}/LICENSE.TXT +0 -0
- {boris_behav_obs-9.3.2 → boris_behav_obs-9.3.3}/MANIFEST.in +0 -0
- {boris_behav_obs-9.3.2 → boris_behav_obs-9.3.3}/README.TXT +0 -0
- {boris_behav_obs-9.3.2 → boris_behav_obs-9.3.3}/README.md +0 -0
- {boris_behav_obs-9.3.2 → boris_behav_obs-9.3.3}/boris/__init__.py +0 -0
- {boris_behav_obs-9.3.2 → boris_behav_obs-9.3.3}/boris/__main__.py +0 -0
- {boris_behav_obs-9.3.2 → boris_behav_obs-9.3.3}/boris/about.py +0 -0
- {boris_behav_obs-9.3.2 → boris_behav_obs-9.3.3}/boris/add_modifier.py +0 -0
- {boris_behav_obs-9.3.2 → boris_behav_obs-9.3.3}/boris/add_modifier_ui.py +0 -0
- {boris_behav_obs-9.3.2 → boris_behav_obs-9.3.3}/boris/advanced_event_filtering.py +0 -0
- {boris_behav_obs-9.3.2 → boris_behav_obs-9.3.3}/boris/analysis_plugins/__init__.py +0 -0
- {boris_behav_obs-9.3.2 → boris_behav_obs-9.3.3}/boris/analysis_plugins/_latency.py +0 -0
- {boris_behav_obs-9.3.2 → boris_behav_obs-9.3.3}/boris/analysis_plugins/number_of_occurences.py +0 -0
- {boris_behav_obs-9.3.2 → boris_behav_obs-9.3.3}/boris/analysis_plugins/number_of_occurences_by_independent_variable.py +0 -0
- {boris_behav_obs-9.3.2 → boris_behav_obs-9.3.3}/boris/analysis_plugins/time_budget.py +0 -0
- {boris_behav_obs-9.3.2 → boris_behav_obs-9.3.3}/boris/behav_coding_map_creator.py +0 -0
- {boris_behav_obs-9.3.2 → boris_behav_obs-9.3.3}/boris/behavior_binary_table.py +0 -0
- {boris_behav_obs-9.3.2 → boris_behav_obs-9.3.3}/boris/behaviors_coding_map.py +0 -0
- {boris_behav_obs-9.3.2 → boris_behav_obs-9.3.3}/boris/boris_cli.py +0 -0
- {boris_behav_obs-9.3.2 → boris_behav_obs-9.3.3}/boris/cmd_arguments.py +0 -0
- {boris_behav_obs-9.3.2 → boris_behav_obs-9.3.3}/boris/coding_pad.py +0 -0
- {boris_behav_obs-9.3.2 → boris_behav_obs-9.3.3}/boris/config_file.py +0 -0
- {boris_behav_obs-9.3.2 → boris_behav_obs-9.3.3}/boris/connections.py +0 -0
- {boris_behav_obs-9.3.2 → boris_behav_obs-9.3.3}/boris/converters.py +0 -0
- {boris_behav_obs-9.3.2 → boris_behav_obs-9.3.3}/boris/converters_ui.py +0 -0
- {boris_behav_obs-9.3.2 → boris_behav_obs-9.3.3}/boris/cooccurence.py +0 -0
- {boris_behav_obs-9.3.2 → boris_behav_obs-9.3.3}/boris/core_qrc.py +0 -0
- {boris_behav_obs-9.3.2 → boris_behav_obs-9.3.3}/boris/core_ui.py +0 -0
- {boris_behav_obs-9.3.2 → boris_behav_obs-9.3.3}/boris/db_functions.py +0 -0
- {boris_behav_obs-9.3.2 → boris_behav_obs-9.3.3}/boris/dev.py +0 -0
- {boris_behav_obs-9.3.2 → boris_behav_obs-9.3.3}/boris/duration_widget.py +0 -0
- {boris_behav_obs-9.3.2 → boris_behav_obs-9.3.3}/boris/edit_event.py +0 -0
- {boris_behav_obs-9.3.2 → boris_behav_obs-9.3.3}/boris/edit_event_ui.py +0 -0
- {boris_behav_obs-9.3.2 → boris_behav_obs-9.3.3}/boris/event_operations.py +0 -0
- {boris_behav_obs-9.3.2 → boris_behav_obs-9.3.3}/boris/events_cursor.py +0 -0
- {boris_behav_obs-9.3.2 → boris_behav_obs-9.3.3}/boris/events_snapshots.py +0 -0
- {boris_behav_obs-9.3.2 → boris_behav_obs-9.3.3}/boris/exclusion_matrix.py +0 -0
- {boris_behav_obs-9.3.2 → boris_behav_obs-9.3.3}/boris/export_events.py +0 -0
- {boris_behav_obs-9.3.2 → boris_behav_obs-9.3.3}/boris/export_observation.py +0 -0
- {boris_behav_obs-9.3.2 → boris_behav_obs-9.3.3}/boris/external_processes.py +0 -0
- {boris_behav_obs-9.3.2 → boris_behav_obs-9.3.3}/boris/geometric_measurement.py +0 -0
- {boris_behav_obs-9.3.2 → boris_behav_obs-9.3.3}/boris/gui_utilities.py +0 -0
- {boris_behav_obs-9.3.2 → boris_behav_obs-9.3.3}/boris/image_overlay.py +0 -0
- {boris_behav_obs-9.3.2 → boris_behav_obs-9.3.3}/boris/import_observations.py +0 -0
- {boris_behav_obs-9.3.2 → boris_behav_obs-9.3.3}/boris/irr.py +0 -0
- {boris_behav_obs-9.3.2 → boris_behav_obs-9.3.3}/boris/latency.py +0 -0
- {boris_behav_obs-9.3.2 → boris_behav_obs-9.3.3}/boris/measurement_widget.py +0 -0
- {boris_behav_obs-9.3.2 → boris_behav_obs-9.3.3}/boris/menu_options.py +0 -0
- {boris_behav_obs-9.3.2 → boris_behav_obs-9.3.3}/boris/modifier_coding_map_creator.py +0 -0
- {boris_behav_obs-9.3.2 → boris_behav_obs-9.3.3}/boris/modifiers_coding_map.py +0 -0
- {boris_behav_obs-9.3.2 → boris_behav_obs-9.3.3}/boris/mpv-1.0.3.py +0 -0
- {boris_behav_obs-9.3.2 → boris_behav_obs-9.3.3}/boris/mpv.py +0 -0
- {boris_behav_obs-9.3.2 → boris_behav_obs-9.3.3}/boris/mpv2.py +0 -0
- {boris_behav_obs-9.3.2 → boris_behav_obs-9.3.3}/boris/observation.py +0 -0
- {boris_behav_obs-9.3.2 → boris_behav_obs-9.3.3}/boris/observation_ui.py +0 -0
- {boris_behav_obs-9.3.2 → boris_behav_obs-9.3.3}/boris/observations_list.py +0 -0
- {boris_behav_obs-9.3.2 → boris_behav_obs-9.3.3}/boris/otx_parser.py +0 -0
- {boris_behav_obs-9.3.2 → boris_behav_obs-9.3.3}/boris/param_panel.py +0 -0
- {boris_behav_obs-9.3.2 → boris_behav_obs-9.3.3}/boris/param_panel_ui.py +0 -0
- {boris_behav_obs-9.3.2 → boris_behav_obs-9.3.3}/boris/player_dock_widget.py +0 -0
- {boris_behav_obs-9.3.2 → boris_behav_obs-9.3.3}/boris/plot_data_module.py +0 -0
- {boris_behav_obs-9.3.2 → boris_behav_obs-9.3.3}/boris/plot_events.py +0 -0
- {boris_behav_obs-9.3.2 → boris_behav_obs-9.3.3}/boris/plot_events_rt.py +0 -0
- {boris_behav_obs-9.3.2 → boris_behav_obs-9.3.3}/boris/plot_spectrogram_rt.py +0 -0
- {boris_behav_obs-9.3.2 → boris_behav_obs-9.3.3}/boris/plot_waveform_rt.py +0 -0
- {boris_behav_obs-9.3.2 → boris_behav_obs-9.3.3}/boris/plugins.py +0 -0
- {boris_behav_obs-9.3.2 → boris_behav_obs-9.3.3}/boris/portion/__init__.py +0 -0
- {boris_behav_obs-9.3.2 → boris_behav_obs-9.3.3}/boris/portion/const.py +0 -0
- {boris_behav_obs-9.3.2 → boris_behav_obs-9.3.3}/boris/portion/dict.py +0 -0
- {boris_behav_obs-9.3.2 → boris_behav_obs-9.3.3}/boris/portion/func.py +0 -0
- {boris_behav_obs-9.3.2 → boris_behav_obs-9.3.3}/boris/portion/interval.py +0 -0
- {boris_behav_obs-9.3.2 → boris_behav_obs-9.3.3}/boris/portion/io.py +0 -0
- {boris_behav_obs-9.3.2 → boris_behav_obs-9.3.3}/boris/preferences.py +0 -0
- {boris_behav_obs-9.3.2 → boris_behav_obs-9.3.3}/boris/preferences_ui.py +0 -0
- {boris_behav_obs-9.3.2 → boris_behav_obs-9.3.3}/boris/project_functions.py +0 -0
- {boris_behav_obs-9.3.2 → boris_behav_obs-9.3.3}/boris/project_ui.py +0 -0
- {boris_behav_obs-9.3.2 → boris_behav_obs-9.3.3}/boris/qrc_boris.py +0 -0
- {boris_behav_obs-9.3.2 → boris_behav_obs-9.3.3}/boris/qrc_boris5.py +0 -0
- {boris_behav_obs-9.3.2 → boris_behav_obs-9.3.3}/boris/select_modifiers.py +0 -0
- {boris_behav_obs-9.3.2 → boris_behav_obs-9.3.3}/boris/select_observations.py +0 -0
- {boris_behav_obs-9.3.2 → boris_behav_obs-9.3.3}/boris/select_subj_behav.py +0 -0
- {boris_behav_obs-9.3.2 → boris_behav_obs-9.3.3}/boris/state_events.py +0 -0
- {boris_behav_obs-9.3.2 → boris_behav_obs-9.3.3}/boris/subjects_pad.py +0 -0
- {boris_behav_obs-9.3.2 → boris_behav_obs-9.3.3}/boris/synthetic_time_budget.py +0 -0
- {boris_behav_obs-9.3.2 → boris_behav_obs-9.3.3}/boris/time_budget_functions.py +0 -0
- {boris_behav_obs-9.3.2 → boris_behav_obs-9.3.3}/boris/time_budget_widget.py +0 -0
- {boris_behav_obs-9.3.2 → boris_behav_obs-9.3.3}/boris/transitions.py +0 -0
- {boris_behav_obs-9.3.2 → boris_behav_obs-9.3.3}/boris/video_equalizer.py +0 -0
- {boris_behav_obs-9.3.2 → boris_behav_obs-9.3.3}/boris/video_equalizer_ui.py +0 -0
- {boris_behav_obs-9.3.2 → boris_behav_obs-9.3.3}/boris/video_operations.py +0 -0
- {boris_behav_obs-9.3.2 → boris_behav_obs-9.3.3}/boris/view_df.py +0 -0
- {boris_behav_obs-9.3.2 → boris_behav_obs-9.3.3}/boris/view_df_ui.py +0 -0
- {boris_behav_obs-9.3.2 → boris_behav_obs-9.3.3}/boris/write_event.py +0 -0
- {boris_behav_obs-9.3.2 → boris_behav_obs-9.3.3}/boris_behav_obs.egg-info/SOURCES.txt +0 -0
- {boris_behav_obs-9.3.2 → boris_behav_obs-9.3.3}/boris_behav_obs.egg-info/dependency_links.txt +0 -0
- {boris_behav_obs-9.3.2 → boris_behav_obs-9.3.3}/boris_behav_obs.egg-info/entry_points.txt +0 -0
- {boris_behav_obs-9.3.2 → boris_behav_obs-9.3.3}/boris_behav_obs.egg-info/requires.txt +0 -0
- {boris_behav_obs-9.3.2 → boris_behav_obs-9.3.3}/boris_behav_obs.egg-info/top_level.txt +0 -0
- {boris_behav_obs-9.3.2 → boris_behav_obs-9.3.3}/setup.cfg +0 -0
- {boris_behav_obs-9.3.2 → boris_behav_obs-9.3.3}/tests/test_db_functions.py +0 -0
- {boris_behav_obs-9.3.2 → boris_behav_obs-9.3.3}/tests/test_export_observation.py +0 -0
- {boris_behav_obs-9.3.2 → boris_behav_obs-9.3.3}/tests/test_irr.py +0 -0
- {boris_behav_obs-9.3.2 → boris_behav_obs-9.3.3}/tests/test_observation_gui.py +0 -0
- {boris_behav_obs-9.3.2 → boris_behav_obs-9.3.3}/tests/test_otx_parser.py +0 -0
- {boris_behav_obs-9.3.2 → boris_behav_obs-9.3.3}/tests/test_preferences_gui.py +0 -0
- {boris_behav_obs-9.3.2 → boris_behav_obs-9.3.3}/tests/test_project_functions.py +0 -0
- {boris_behav_obs-9.3.2 → boris_behav_obs-9.3.3}/tests/test_time_budget.py +0 -0
- {boris_behav_obs-9.3.2 → boris_behav_obs-9.3.3}/tests/test_utilities2.py +0 -0
|
@@ -155,6 +155,7 @@ CHECK_PROJECT_INTEGRITY = "check_project_integrity"
|
|
|
155
155
|
YES = "Yes"
|
|
156
156
|
NO = "No"
|
|
157
157
|
CANCEL = "Cancel"
|
|
158
|
+
IGNORE = "Ignore"
|
|
158
159
|
APPEND = "Append"
|
|
159
160
|
CLOSE = "Close"
|
|
160
161
|
REPLACE = "Replace"
|
|
@@ -454,7 +455,8 @@ POINT = "POINT"
|
|
|
454
455
|
START = "START"
|
|
455
456
|
STOP = "STOP"
|
|
456
457
|
|
|
457
|
-
PLAYER1
|
|
458
|
+
PLAYER1 = "1"
|
|
459
|
+
PLAYER2 = "2"
|
|
458
460
|
ALL_PLAYERS = [str(x + 1) for x in range(N_PLAYER)]
|
|
459
461
|
|
|
460
462
|
VISUALIZE_SPECTROGRAM = "visualize_spectrogram"
|
|
@@ -701,6 +703,7 @@ EMPTY_PROJECT = {
|
|
|
701
703
|
ETHOGRAM: {},
|
|
702
704
|
OBSERVATIONS: {},
|
|
703
705
|
BEHAVIORAL_CATEGORIES: [],
|
|
706
|
+
BEHAVIORAL_CATEGORIES_CONF: {},
|
|
704
707
|
INDEPENDENT_VARIABLES: {},
|
|
705
708
|
CODING_MAP: {},
|
|
706
709
|
BEHAVIORS_CODING_MAP: [],
|
|
@@ -114,7 +114,6 @@ from . import cmd_arguments
|
|
|
114
114
|
|
|
115
115
|
from . import core_qrc
|
|
116
116
|
from .core_ui import Ui_MainWindow
|
|
117
|
-
import exifread
|
|
118
117
|
from . import config as cfg
|
|
119
118
|
from . import video_operations
|
|
120
119
|
|
|
@@ -4317,12 +4316,8 @@ class MainWindow(QMainWindow, Ui_MainWindow):
|
|
|
4317
4316
|
if not sys.platform.startswith(cfg.MACOS_CODE):
|
|
4318
4317
|
if self.dw_player[0].player.time_pos is not None:
|
|
4319
4318
|
for n_player in range(1, len(self.dw_player)):
|
|
4320
|
-
print(f"{n_player=}")
|
|
4321
|
-
|
|
4322
4319
|
ct = self.getLaps(n_player=n_player)
|
|
4323
4320
|
|
|
4324
|
-
print(f"{ct=}")
|
|
4325
|
-
|
|
4326
4321
|
# sync players 2..8 if time diff >= 1 s
|
|
4327
4322
|
if (
|
|
4328
4323
|
abs(ct0 - (ct + dec(self.pj[cfg.OBSERVATIONS][self.observationId][cfg.MEDIA_INFO][cfg.OFFSET][str(n_player + 1)])))
|
|
@@ -88,7 +88,7 @@ def MessageDialog(title: str, text: str, buttons: tuple) -> str:
|
|
|
88
88
|
for button in buttons:
|
|
89
89
|
message.addButton(button, QMessageBox.YesRole)
|
|
90
90
|
|
|
91
|
-
message.setWindowFlags(Qt.WindowStaysOnTopHint)
|
|
91
|
+
message.setWindowFlags(message.windowFlags() | Qt.WindowStaysOnTopHint)
|
|
92
92
|
message.exec()
|
|
93
93
|
return message.clickedButton().text()
|
|
94
94
|
|
|
@@ -20,11 +20,13 @@ This file is part of BORIS.
|
|
|
20
20
|
|
|
21
21
|
"""
|
|
22
22
|
|
|
23
|
+
from PySide6.QtWidgets import QFileDialog
|
|
24
|
+
|
|
23
25
|
from . import config as cfg
|
|
24
26
|
from . import utilities as util
|
|
25
27
|
from . import dialog
|
|
26
28
|
from . import project_functions
|
|
27
|
-
from
|
|
29
|
+
from . import utilities as util
|
|
28
30
|
|
|
29
31
|
|
|
30
32
|
def get_info(self) -> None:
|
|
@@ -38,17 +40,17 @@ def get_info(self) -> None:
|
|
|
38
40
|
if "error" in r:
|
|
39
41
|
ffmpeg_output = f"File path: {media_full_path}<br><br>{r['error']}<br><br>"
|
|
40
42
|
else:
|
|
41
|
-
ffmpeg_output = f"<br><b>{r['analysis_program']
|
|
43
|
+
ffmpeg_output = f"<br><b>{r['analysis_program']} analysis</b><br>"
|
|
42
44
|
|
|
43
45
|
ffmpeg_output += (
|
|
44
46
|
f"File path: <b>{media_full_path}</b><br><br>"
|
|
45
47
|
f"Duration: {r['duration']} seconds ({util.convertTime(self.timeFormat, r['duration'])})<br>"
|
|
48
|
+
f"FPS: {r['fps']}<br>"
|
|
49
|
+
f"Resolution: {r['resolution']} pixels<br>"
|
|
46
50
|
f"Format long name: {r.get('format_long_name', cfg.NA)}<br>"
|
|
47
51
|
f"Creation time: {r.get('creation_time', cfg.NA)}<br>"
|
|
48
|
-
f"Resolution: {r['resolution']}<br>"
|
|
49
52
|
f"Number of frames: {r['frames_number']}<br>"
|
|
50
53
|
f"Bitrate: {util.smart_size_format(r['bitrate'])} <br>"
|
|
51
|
-
f"FPS: {r['fps']}<br>"
|
|
52
54
|
f"Has video: {r['has_video']}<br>"
|
|
53
55
|
f"Has audio: {r['has_audio']}<br>"
|
|
54
56
|
f"File size: {util.smart_size_format(r.get('file size', cfg.NA))}<br>"
|
|
@@ -70,6 +72,12 @@ def get_info(self) -> None:
|
|
|
70
72
|
|
|
71
73
|
mpv_output = (
|
|
72
74
|
"<b>MPV information</b><br>"
|
|
75
|
+
f"Duration: {dw.player.duration} seconds ({util.seconds2time(dw.player.duration)})<br>"
|
|
76
|
+
# "Position: {} %<br>"
|
|
77
|
+
f"FPS: {dw.player.container_fps}<br>"
|
|
78
|
+
# "Rate: {}<br>"
|
|
79
|
+
f"Resolution: {dw.player.width}x{dw.player.height} pixels<br>"
|
|
80
|
+
# "Scale: {}<br>"
|
|
73
81
|
f"Video format: {dw.player.video_format}<br>"
|
|
74
82
|
# "State: {}<br>"
|
|
75
83
|
# "Media Resource Location: {}<br>"
|
|
@@ -77,12 +85,6 @@ def get_info(self) -> None:
|
|
|
77
85
|
# "Track: {}/{}<br>"
|
|
78
86
|
f"Number of media in media list: {dw.player.playlist_count}<br>"
|
|
79
87
|
f"Current time position: {dw.player.time_pos}<br>"
|
|
80
|
-
f"Duration: {dw.player.duration}<br>"
|
|
81
|
-
# "Position: {} %<br>"
|
|
82
|
-
f"FPS: {dw.player.container_fps}<br>"
|
|
83
|
-
# "Rate: {}<br>"
|
|
84
|
-
f"Video size: {dw.player.width}x{dw.player.height}<br>"
|
|
85
|
-
# "Scale: {}<br>"
|
|
86
88
|
f"Aspect ratio: {round(dw.player.width / dw.player.height, 3)}<br>"
|
|
87
89
|
# "is seekable? {}<br>"
|
|
88
90
|
# "has_vout? {}<br>"
|
|
@@ -2406,15 +2406,15 @@ def event2media_file_name(observation: dict, timestamp: dec) -> Optional[str]:
|
|
|
2406
2406
|
"""
|
|
2407
2407
|
|
|
2408
2408
|
cumul_media_durations: list = [dec(0)]
|
|
2409
|
-
for media_file in observation[cfg.FILE][
|
|
2409
|
+
for media_file in observation[cfg.FILE][cfg.PLAYER1]:
|
|
2410
2410
|
media_duration = dec(str(observation[cfg.MEDIA_INFO][cfg.LENGTH][media_file]))
|
|
2411
|
-
cumul_media_durations.append(cumul_media_durations[-1] + media_duration)
|
|
2411
|
+
cumul_media_durations.append(round(cumul_media_durations[-1] + media_duration, 3))
|
|
2412
2412
|
|
|
2413
2413
|
cumul_media_durations.remove(dec(0))
|
|
2414
2414
|
|
|
2415
2415
|
# test if timestamp is at end of last media
|
|
2416
2416
|
if timestamp == cumul_media_durations[-1]:
|
|
2417
|
-
player_idx = len(observation[cfg.FILE][
|
|
2417
|
+
player_idx = len(observation[cfg.FILE][cfg.PLAYER1]) - 1
|
|
2418
2418
|
else:
|
|
2419
2419
|
player_idx = -1
|
|
2420
2420
|
for idx, value in enumerate(cumul_media_durations):
|
|
@@ -2424,7 +2424,7 @@ def event2media_file_name(observation: dict, timestamp: dec) -> Optional[str]:
|
|
|
2424
2424
|
break
|
|
2425
2425
|
|
|
2426
2426
|
if player_idx != -1:
|
|
2427
|
-
video_file_name = observation[cfg.FILE][
|
|
2427
|
+
video_file_name = observation[cfg.FILE][cfg.PLAYER1][player_idx]
|
|
2428
2428
|
else:
|
|
2429
2429
|
video_file_name = None
|
|
2430
2430
|
|
|
@@ -82,12 +82,12 @@ class BehavioralCategories(QDialog):
|
|
|
82
82
|
# add categories
|
|
83
83
|
self.lw.setColumnCount(2)
|
|
84
84
|
self.lw.setHorizontalHeaderLabels(["Category name", "Color"])
|
|
85
|
-
# self.lw.verticalHeader().hide()
|
|
86
85
|
self.lw.setEditTriggers(QAbstractItemView.NoEditTriggers)
|
|
87
86
|
|
|
88
|
-
# self.lw.setSelectionBehavior(QAbstractItemView.SelectRows)
|
|
89
87
|
self.lw.setSelectionMode(QAbstractItemView.SingleSelection)
|
|
90
88
|
|
|
89
|
+
behavioral_categories: list = []
|
|
90
|
+
|
|
91
91
|
if cfg.BEHAVIORAL_CATEGORIES_CONF in pj:
|
|
92
92
|
self.lw.setRowCount(len(pj.get(cfg.BEHAVIORAL_CATEGORIES_CONF, {})))
|
|
93
93
|
behav_cat = pj.get(cfg.BEHAVIORAL_CATEGORIES_CONF, {})
|
|
@@ -95,7 +95,7 @@ class BehavioralCategories(QDialog):
|
|
|
95
95
|
# name
|
|
96
96
|
item = QTableWidgetItem()
|
|
97
97
|
item.setText(behav_cat[key]["name"])
|
|
98
|
-
|
|
98
|
+
behavioral_categories.append(behav_cat[key]["name"])
|
|
99
99
|
self.lw.setItem(idx, 0, item)
|
|
100
100
|
# color
|
|
101
101
|
item = QTableWidgetItem()
|
|
@@ -103,24 +103,21 @@ class BehavioralCategories(QDialog):
|
|
|
103
103
|
if behav_cat[key].get(cfg.COLOR, ""):
|
|
104
104
|
item.setBackground(QColor(behav_cat[key].get(cfg.COLOR, "")))
|
|
105
105
|
else:
|
|
106
|
-
# item.setBackground(QColor(230, 230, 230))
|
|
107
106
|
item.setBackground(self.not_editable_column_color())
|
|
108
|
-
# item.setFlags(Qt.ItemIsEnabled)
|
|
109
107
|
self.lw.setItem(idx, 1, item)
|
|
110
108
|
else:
|
|
111
109
|
self.lw.setRowCount(len(pj.get(cfg.BEHAVIORAL_CATEGORIES, [])))
|
|
112
110
|
for idx, category in enumerate(sorted(pj.get(cfg.BEHAVIORAL_CATEGORIES, []))):
|
|
111
|
+
# name
|
|
113
112
|
item = QTableWidgetItem()
|
|
114
113
|
item.setText(category)
|
|
115
|
-
|
|
114
|
+
behavioral_categories.append(category)
|
|
116
115
|
self.lw.setItem(idx, 0, item)
|
|
117
|
-
|
|
116
|
+
# color
|
|
118
117
|
item = QTableWidgetItem()
|
|
119
118
|
item.setText("")
|
|
120
|
-
# item.setFlags(Qt.ItemIsEnabled)
|
|
121
|
-
self.lw.setItem(idx, 1, item)
|
|
122
119
|
|
|
123
|
-
|
|
120
|
+
self.lw.setItem(idx, 1, item)
|
|
124
121
|
|
|
125
122
|
self.vbox.addWidget(self.lw)
|
|
126
123
|
|
|
@@ -148,6 +145,41 @@ class BehavioralCategories(QDialog):
|
|
|
148
145
|
|
|
149
146
|
self.setLayout(self.vbox)
|
|
150
147
|
|
|
148
|
+
# check if behavioral categories are present in events
|
|
149
|
+
behavioral_categories_in_ethogram = set(
|
|
150
|
+
sorted([pj[cfg.ETHOGRAM][idx].get(cfg.BEHAVIOR_CATEGORY, "") for idx in pj.get(cfg.ETHOGRAM, {})])
|
|
151
|
+
)
|
|
152
|
+
|
|
153
|
+
if behavioral_categories_in_ethogram.difference(set(behavioral_categories)):
|
|
154
|
+
if (
|
|
155
|
+
dialog.MessageDialog(
|
|
156
|
+
cfg.programName,
|
|
157
|
+
(
|
|
158
|
+
"They are behavioral categories that are present in ethogram but not defined.<br>"
|
|
159
|
+
f"{behavioral_categories_in_ethogram.difference(set(behavioral_categories))}<br>"
|
|
160
|
+
"<br>"
|
|
161
|
+
"Do you want to add them in the behavioral categories list?"
|
|
162
|
+
),
|
|
163
|
+
[cfg.YES, cfg.NO],
|
|
164
|
+
)
|
|
165
|
+
== cfg.YES
|
|
166
|
+
):
|
|
167
|
+
# add behavioral categories present in ethogram in behavioal categories list
|
|
168
|
+
rc = self.lw.rowCount()
|
|
169
|
+
self.lw.setRowCount(rc + len(behavioral_categories_in_ethogram.difference(set(behavioral_categories))))
|
|
170
|
+
for idx, category in enumerate(sorted(list(behavioral_categories_in_ethogram.difference(set(behavioral_categories))))):
|
|
171
|
+
print(category)
|
|
172
|
+
# name
|
|
173
|
+
item = QTableWidgetItem()
|
|
174
|
+
item.setText(category)
|
|
175
|
+
# behavioral_categories.append(category)
|
|
176
|
+
self.lw.setItem(rc + idx, 0, item)
|
|
177
|
+
# color
|
|
178
|
+
item = QTableWidgetItem()
|
|
179
|
+
item.setText("")
|
|
180
|
+
|
|
181
|
+
self.lw.setItem(rc + idx, 1, item)
|
|
182
|
+
|
|
151
183
|
def not_editable_column_color(self):
|
|
152
184
|
"""
|
|
153
185
|
return a color for the not editable column
|
|
@@ -663,7 +695,7 @@ class projectDialog(QDialog, Ui_dlgProject):
|
|
|
663
695
|
QMessageBox.warning(
|
|
664
696
|
self,
|
|
665
697
|
cfg.programName,
|
|
666
|
-
("The following behavior{} are not defined in the ethogram:<br>
|
|
698
|
+
("The following behavior{} are not defined in the ethogram:<br>{}").format(
|
|
667
699
|
"s" if len(bcm_code_not_found) > 1 else "", ",".join(bcm_code_not_found)
|
|
668
700
|
),
|
|
669
701
|
)
|
|
@@ -733,7 +765,7 @@ class projectDialog(QDialog, Ui_dlgProject):
|
|
|
733
765
|
behavioral categories manager
|
|
734
766
|
"""
|
|
735
767
|
|
|
736
|
-
bc = BehavioralCategories(self.pj)
|
|
768
|
+
bc = BehavioralCategories(self.pj)
|
|
737
769
|
|
|
738
770
|
if bc.exec_():
|
|
739
771
|
self.pj[cfg.BEHAVIORAL_CATEGORIES] = []
|
|
@@ -1377,7 +1409,7 @@ class projectDialog(QDialog, Ui_dlgProject):
|
|
|
1377
1409
|
# let user select a coding maop
|
|
1378
1410
|
file_name, _ = QFileDialog().getOpenFileName(
|
|
1379
1411
|
self,
|
|
1380
|
-
"Select a modifier coding map for
|
|
1412
|
+
f"Select a modifier coding map for {self.twBehaviors.item(row, cfg.behavioursFields['code']).text()} behavior",
|
|
1381
1413
|
"",
|
|
1382
1414
|
"BORIS map files (*.boris_map);;All files (*)",
|
|
1383
1415
|
)
|
|
@@ -1759,24 +1791,40 @@ class projectDialog(QDialog, Ui_dlgProject):
|
|
|
1759
1791
|
return {cfg.CANCEL: True}
|
|
1760
1792
|
|
|
1761
1793
|
# check if behavior belong to category that is not in categories list
|
|
1762
|
-
|
|
1794
|
+
missing_behavior_category: list = []
|
|
1763
1795
|
for idx in checked_ethogram:
|
|
1764
1796
|
if cfg.BEHAVIOR_CATEGORY in checked_ethogram[idx]:
|
|
1765
1797
|
if checked_ethogram[idx][cfg.BEHAVIOR_CATEGORY]:
|
|
1766
1798
|
if checked_ethogram[idx][cfg.BEHAVIOR_CATEGORY] not in self.pj[cfg.BEHAVIORAL_CATEGORIES]:
|
|
1767
|
-
|
|
1768
|
-
|
|
1799
|
+
missing_behavior_category.append(
|
|
1800
|
+
(checked_ethogram[idx][cfg.BEHAVIOR_CODE], checked_ethogram[idx][cfg.BEHAVIOR_CATEGORY])
|
|
1801
|
+
)
|
|
1802
|
+
if missing_behavior_category:
|
|
1769
1803
|
response = dialog.MessageDialog(
|
|
1770
1804
|
f"{cfg.programName} - Behavioral categories",
|
|
1771
1805
|
(
|
|
1772
|
-
"The behavioral
|
|
1773
|
-
f"{', '.join(set(['<b>' + x[1] + '</b>' + ' (used with <b>' + x[0] + '</b>)' for x in
|
|
1774
|
-
"are
|
|
1806
|
+
"The behavioral category/ies<br> "
|
|
1807
|
+
f"{', '.join(set(['<b>' + x[1] + '</b>' + ' (used with <b>' + x[0] + '</b>)<br>' for x in missing_behavior_category]))} "
|
|
1808
|
+
"are not defined in behavioral categories list.<br>"
|
|
1775
1809
|
),
|
|
1776
|
-
["Add behavioral category/ies",
|
|
1810
|
+
["Add behavioral category/ies", cfg.IGNORE, cfg.CANCEL],
|
|
1777
1811
|
)
|
|
1778
1812
|
if response == "Add behavioral category/ies":
|
|
1779
|
-
|
|
1813
|
+
if cfg.BEHAVIORAL_CATEGORIES_CONF not in self.pj:
|
|
1814
|
+
self.pj[cfg.BEHAVIORAL_CATEGORIES_CONF] = {}
|
|
1815
|
+
for x1 in set(x[1] for x in missing_behavior_category):
|
|
1816
|
+
self.pj[cfg.BEHAVIORAL_CATEGORIES].append(x1)
|
|
1817
|
+
|
|
1818
|
+
if self.pj[cfg.BEHAVIORAL_CATEGORIES_CONF]:
|
|
1819
|
+
index = str(max([int(k) for k in self.pj[cfg.BEHAVIORAL_CATEGORIES_CONF]]) + 1)
|
|
1820
|
+
else:
|
|
1821
|
+
index = "0"
|
|
1822
|
+
|
|
1823
|
+
self.pj[cfg.BEHAVIORAL_CATEGORIES_CONF][index] = {
|
|
1824
|
+
"name": x1,
|
|
1825
|
+
cfg.COLOR: "",
|
|
1826
|
+
}
|
|
1827
|
+
|
|
1780
1828
|
if response == cfg.CANCEL:
|
|
1781
1829
|
return {cfg.CANCEL: True}
|
|
1782
1830
|
|
|
@@ -89,9 +89,10 @@ def export_ethogram(self) -> None:
|
|
|
89
89
|
return
|
|
90
90
|
pj = dict(cfg.EMPTY_PROJECT)
|
|
91
91
|
pj[cfg.ETHOGRAM] = dict(r)
|
|
92
|
-
# behavioral categories
|
|
93
92
|
|
|
93
|
+
# behavioral categories
|
|
94
94
|
pj[cfg.BEHAVIORAL_CATEGORIES] = list(self.pj[cfg.BEHAVIORAL_CATEGORIES])
|
|
95
|
+
pj[cfg.BEHAVIORAL_CATEGORIES_CONF] = dict(self.pj.get(cfg.BEHAVIORAL_CATEGORIES_CONF, {}))
|
|
95
96
|
|
|
96
97
|
# project file indentation
|
|
97
98
|
file_indentation = self.config_param.get(cfg.PROJECT_FILE_INDENTATION, cfg.PROJECT_FILE_INDENTATION_DEFAULT_VALUE)
|
|
@@ -309,6 +310,7 @@ def import_ethogram_from_dict(self, project: dict):
|
|
|
309
310
|
"""
|
|
310
311
|
# import behavioral_categories
|
|
311
312
|
self.pj[cfg.BEHAVIORAL_CATEGORIES] = list(project.get(cfg.BEHAVIORAL_CATEGORIES, []))
|
|
313
|
+
self.pj[cfg.BEHAVIORAL_CATEGORIES_CONF] = list(project.get(cfg.BEHAVIORAL_CATEGORIES_CONF, {}))
|
|
312
314
|
|
|
313
315
|
# configuration of behaviours
|
|
314
316
|
if not (cfg.ETHOGRAM in project and project[cfg.ETHOGRAM]):
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "boris-behav-obs"
|
|
3
|
-
version = "9.3.
|
|
3
|
+
version = "9.3.3"
|
|
4
4
|
description = "BORIS - Behavioral Observation Research Interactive Software"
|
|
5
5
|
authors = [{ name="Olivier Friard", email="olivier.friard@unito.it" }]
|
|
6
6
|
readme = "README.md"
|
|
@@ -54,7 +54,7 @@ line-length = 140
|
|
|
54
54
|
exclude = ["*_ui.py", "mpv*"]
|
|
55
55
|
|
|
56
56
|
[tool.bumpver]
|
|
57
|
-
current_version = "9.3.
|
|
57
|
+
current_version = "9.3.3"
|
|
58
58
|
version_pattern = "MAJOR.MINOR.PATCH"
|
|
59
59
|
|
|
60
60
|
|
|
@@ -564,7 +564,7 @@ class Test_txt2np_array(object):
|
|
|
564
564
|
file_name="files/xxx", columns_str="4,6", substract_first_value="False", converters={}, column_converter={}
|
|
565
565
|
)
|
|
566
566
|
# print(r)
|
|
567
|
-
assert r[0]
|
|
567
|
+
assert r[0] is False
|
|
568
568
|
assert r[1] == "[Errno 2] No such file or directory: 'files/xxx'"
|
|
569
569
|
assert list(r[2].shape) == [0]
|
|
570
570
|
|
|
@@ -576,7 +576,10 @@ class Test_txt2np_array(object):
|
|
|
576
576
|
converters={},
|
|
577
577
|
column_converter={},
|
|
578
578
|
)
|
|
579
|
-
|
|
579
|
+
|
|
580
|
+
print(r)
|
|
581
|
+
|
|
582
|
+
assert r[0] is False
|
|
580
583
|
assert r[1] == "could not convert string to float: '14:38:58'"
|
|
581
584
|
assert list(r[2].shape) == [0]
|
|
582
585
|
|
|
@@ -594,7 +597,7 @@ class Test_txt2np_array(object):
|
|
|
594
597
|
},
|
|
595
598
|
column_converter={4: "HHMMSS_2_seconds"},
|
|
596
599
|
)
|
|
597
|
-
assert r[0]
|
|
600
|
+
assert r[0] is True
|
|
598
601
|
assert r[1] == ""
|
|
599
602
|
assert r[2][0, 0] == 52738.0
|
|
600
603
|
assert r[2][1, 0] == 52740.0
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{boris_behav_obs-9.3.2 → boris_behav_obs-9.3.3}/boris/analysis_plugins/number_of_occurences.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{boris_behav_obs-9.3.2 → boris_behav_obs-9.3.3}/boris_behav_obs.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|