boris-behav-obs 8.16.5__py3-none-any.whl → 9.7.12__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.
- boris/__init__.py +1 -1
- boris/__main__.py +1 -1
- boris/about.py +28 -40
- boris/add_modifier.py +88 -80
- boris/add_modifier_ui.py +266 -144
- boris/advanced_event_filtering.py +23 -29
- boris/analysis_plugins/__init__.py +0 -0
- boris/analysis_plugins/_export_to_feral.py +225 -0
- boris/analysis_plugins/_latency.py +59 -0
- boris/analysis_plugins/irr_cohen_kappa.py +109 -0
- boris/analysis_plugins/irr_cohen_kappa_with_modifiers.py +112 -0
- boris/analysis_plugins/irr_weighted_cohen_kappa.py +157 -0
- boris/analysis_plugins/irr_weighted_cohen_kappa_with_modifiers.py +162 -0
- boris/analysis_plugins/list_of_dataframe_columns.py +22 -0
- boris/analysis_plugins/number_of_occurences.py +22 -0
- boris/analysis_plugins/number_of_occurences_by_independent_variable.py +54 -0
- boris/analysis_plugins/time_budget.py +61 -0
- boris/behav_coding_map_creator.py +235 -236
- boris/behavior_binary_table.py +33 -50
- boris/behaviors_coding_map.py +17 -18
- boris/boris_cli.py +6 -25
- boris/cmd_arguments.py +12 -1
- boris/coding_pad.py +19 -36
- boris/config.py +109 -50
- boris/config_file.py +58 -67
- boris/connections.py +105 -58
- boris/converters.py +13 -37
- boris/converters_ui.py +187 -110
- boris/cooccurence.py +250 -0
- boris/core.py +2174 -1303
- boris/core_qrc.py +15892 -10829
- boris/core_ui.py +941 -806
- boris/db_functions.py +17 -42
- boris/dev.py +27 -7
- boris/dialog.py +461 -242
- boris/duration_widget.py +9 -14
- boris/edit_event.py +61 -31
- boris/edit_event_ui.py +208 -97
- boris/event_operations.py +405 -281
- boris/events_cursor.py +25 -17
- boris/events_snapshots.py +36 -82
- boris/exclusion_matrix.py +4 -9
- boris/export_events.py +180 -203
- boris/export_observation.py +60 -73
- boris/external_processes.py +123 -98
- boris/geometric_measurement.py +427 -218
- boris/gui_utilities.py +91 -14
- boris/image_overlay.py +4 -4
- boris/import_observations.py +190 -98
- boris/ipc_mpv.py +325 -0
- boris/irr.py +20 -57
- boris/latency.py +31 -24
- boris/measurement_widget.py +14 -18
- boris/media_file.py +17 -19
- boris/menu_options.py +16 -6
- boris/modifier_coding_map_creator.py +1013 -0
- boris/modifiers_coding_map.py +7 -9
- boris/mpv2.py +128 -35
- boris/observation.py +501 -211
- boris/observation_operations.py +1037 -393
- boris/observation_ui.py +573 -363
- boris/observations_list.py +51 -58
- boris/otx_parser.py +74 -68
- boris/param_panel.py +45 -59
- boris/param_panel_ui.py +254 -138
- boris/player_dock_widget.py +91 -56
- boris/plot_data_module.py +20 -53
- boris/plot_events.py +56 -153
- boris/plot_events_rt.py +16 -30
- boris/plot_spectrogram_rt.py +83 -56
- boris/plot_waveform_rt.py +27 -49
- boris/plugins.py +468 -0
- boris/portion/__init__.py +18 -8
- boris/portion/const.py +35 -18
- boris/portion/dict.py +5 -5
- boris/portion/func.py +2 -2
- boris/portion/interval.py +21 -41
- boris/portion/io.py +41 -32
- boris/preferences.py +307 -123
- boris/preferences_ui.py +686 -227
- boris/project.py +294 -271
- boris/project_functions.py +626 -537
- boris/project_import_export.py +204 -213
- boris/project_ui.py +673 -441
- boris/qrc_boris.py +6 -3
- boris/qrc_boris5.py +6 -3
- boris/select_modifiers.py +62 -90
- boris/select_observations.py +19 -197
- boris/select_subj_behav.py +67 -39
- boris/state_events.py +51 -33
- boris/subjects_pad.py +7 -9
- boris/synthetic_time_budget.py +42 -26
- boris/time_budget_functions.py +169 -169
- boris/time_budget_widget.py +77 -89
- boris/transitions.py +41 -41
- boris/utilities.py +594 -226
- boris/version.py +3 -3
- boris/video_equalizer.py +16 -14
- boris/video_equalizer_ui.py +199 -130
- boris/video_operations.py +86 -28
- boris/view_df.py +104 -0
- boris/view_df_ui.py +75 -0
- boris/write_event.py +240 -136
- boris_behav_obs-9.7.12.dist-info/METADATA +139 -0
- boris_behav_obs-9.7.12.dist-info/RECORD +110 -0
- {boris_behav_obs-8.16.5.dist-info → boris_behav_obs-9.7.12.dist-info}/WHEEL +1 -1
- boris_behav_obs-9.7.12.dist-info/entry_points.txt +2 -0
- boris/README.TXT +0 -22
- boris/add_modifier.ui +0 -323
- boris/converters.ui +0 -289
- boris/core.qrc +0 -37
- boris/core.ui +0 -1571
- boris/edit_event.ui +0 -233
- boris/icons/logo_eye.ico +0 -0
- boris/map_creator.py +0 -982
- boris/observation.ui +0 -814
- boris/param_panel.ui +0 -379
- boris/preferences.ui +0 -537
- boris/project.ui +0 -1074
- boris/vlc_local.py +0 -90
- boris_behav_obs-8.16.5.dist-info/LICENSE.TXT +0 -674
- boris_behav_obs-8.16.5.dist-info/METADATA +0 -134
- boris_behav_obs-8.16.5.dist-info/RECORD +0 -107
- boris_behav_obs-8.16.5.dist-info/entry_points.txt +0 -2
- {boris → boris_behav_obs-9.7.12.dist-info/licenses}/LICENSE.TXT +0 -0
- {boris_behav_obs-8.16.5.dist-info → boris_behav_obs-9.7.12.dist-info}/top_level.txt +0 -0
boris/config.py
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"""
|
|
2
2
|
BORIS
|
|
3
3
|
Behavioral Observation Research Interactive Software
|
|
4
|
-
Copyright 2012-
|
|
4
|
+
Copyright 2012-2025 Olivier Friard
|
|
5
5
|
|
|
6
6
|
This file is part of BORIS.
|
|
7
7
|
|
|
@@ -22,8 +22,23 @@ This file is part of BORIS.
|
|
|
22
22
|
|
|
23
23
|
programName: str = "BORIS"
|
|
24
24
|
|
|
25
|
+
# socket for MPV IPC mode
|
|
26
|
+
MPV_SOCKET = "/tmp/mpvsocket"
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
ETHOGRAM_REPOSITORY_URL = "https://www.boris.unito.it/static/ethograms"
|
|
30
|
+
|
|
25
31
|
project_format_version: str = "7.0"
|
|
26
32
|
|
|
33
|
+
SECONDS_PER_DAY: int = 86_400
|
|
34
|
+
|
|
35
|
+
# cutoff value for displaying HH:MM:SS.zzz or YYYY-mm-DD HH:MM:SS:ZZZ
|
|
36
|
+
HOUR_CUTOFF: int = 7 * 24
|
|
37
|
+
DATE_CUTOFF: int = HOUR_CUTOFF * 60 * 60 # 1 week
|
|
38
|
+
|
|
39
|
+
# cutoff for displaying time in HH:MM:SS.zzz format
|
|
40
|
+
SMART_TIME_CUTOFF_DEFAULT: int = 300
|
|
41
|
+
|
|
27
42
|
# minimal project version for handling observations from images
|
|
28
43
|
IMAGES_OBS_PROJECT_MIN_VERSION: tuple = (8, 6)
|
|
29
44
|
|
|
@@ -37,11 +52,12 @@ MAX_UNDO_QUEUE: int = 25
|
|
|
37
52
|
|
|
38
53
|
NA: str = "NA"
|
|
39
54
|
|
|
40
|
-
REALTIME_PLOT_CURSOR_COLOR = "red"
|
|
55
|
+
REALTIME_PLOT_CURSOR_COLOR: str = "red"
|
|
41
56
|
|
|
42
|
-
|
|
57
|
+
DARKER_DIFFERENCE = 5
|
|
43
58
|
|
|
44
59
|
CTRL_KEY: str = "Ctrl"
|
|
60
|
+
ALT_KEY: str = "Alt"
|
|
45
61
|
|
|
46
62
|
SPECTRO_TIMER: int = 500
|
|
47
63
|
|
|
@@ -72,6 +88,7 @@ EVENTS = "events"
|
|
|
72
88
|
TIME_OFFSET = "time offset"
|
|
73
89
|
|
|
74
90
|
CODING_MAP = "coding_map"
|
|
91
|
+
CODING_MAP_sp = "coding map" # space between words (no underscore)
|
|
75
92
|
BEHAVIORS_CODING_MAP = "behaviors_coding_map"
|
|
76
93
|
SUBJECTS = "subjects_conf"
|
|
77
94
|
ETHOGRAM = "behaviors_conf"
|
|
@@ -115,20 +132,34 @@ POINT_EVENT_PLOT_COLOR = "black"
|
|
|
115
132
|
|
|
116
133
|
CHAR_FORBIDDEN_IN_MODIFIERS = "(|),`~"
|
|
117
134
|
|
|
135
|
+
FAST_FORWARD_DEFAULT_VALUE: float = 10.0
|
|
136
|
+
|
|
118
137
|
ADAPT_FAST_JUMP = "adapt_fast_jump"
|
|
119
138
|
ADAPT_FAST_JUMP_DEFAULT = False
|
|
120
139
|
|
|
140
|
+
TIME = "time"
|
|
141
|
+
BEHAVIOR_CODE = "code"
|
|
142
|
+
SUBJECT = "subject"
|
|
143
|
+
MODIFIER = "modifier"
|
|
144
|
+
COMMENT = "comment"
|
|
145
|
+
BEHAVIOR_KEY = "key"
|
|
146
|
+
SUBJECT_KEY = "key"
|
|
147
|
+
BEHAVIOR_CATEGORY = "category"
|
|
148
|
+
|
|
121
149
|
|
|
122
|
-
subjectsFields = [
|
|
150
|
+
subjectsFields = [SUBJECT_KEY, SUBJECT_NAME, DESCRIPTION]
|
|
123
151
|
|
|
124
152
|
UNPAIRED = "UNPAIRED"
|
|
125
153
|
DISPLAY_SUBTITLES = "display_subtitles"
|
|
154
|
+
CHECK_PROJECT_INTEGRITY = "check_project_integrity"
|
|
126
155
|
|
|
127
156
|
|
|
128
157
|
YES = "Yes"
|
|
129
158
|
NO = "No"
|
|
130
159
|
CANCEL = "Cancel"
|
|
160
|
+
IGNORE = "Ignore"
|
|
131
161
|
APPEND = "Append"
|
|
162
|
+
CLOSE = "Close"
|
|
132
163
|
REPLACE = "Replace"
|
|
133
164
|
REMOVE = "Remove"
|
|
134
165
|
SAVE = "Save"
|
|
@@ -173,13 +204,6 @@ DATA_PLOT_FIELDS = {
|
|
|
173
204
|
}
|
|
174
205
|
DATA_PLOT_STYLES = ["b-", "r-", "g-", "bo", "ro", "go"]
|
|
175
206
|
|
|
176
|
-
TIME = "time"
|
|
177
|
-
BEHAVIOR_CODE = "code"
|
|
178
|
-
SUBJECT = "subject"
|
|
179
|
-
MODIFIER = "modifier"
|
|
180
|
-
COMMENT = "comment"
|
|
181
|
-
BEHAVIOR_KEY = "key"
|
|
182
|
-
BEHAVIOR_CATEGORY = "category"
|
|
183
207
|
|
|
184
208
|
FILE_PATH = "file_path"
|
|
185
209
|
|
|
@@ -188,27 +212,19 @@ IMAGE_PATH = "image path"
|
|
|
188
212
|
FRAME_INDEX = "frame index"
|
|
189
213
|
|
|
190
214
|
ZOOM_LEVEL = "zoom level"
|
|
215
|
+
PAN_X = "pan-x"
|
|
216
|
+
PAN_Y = "pan-y"
|
|
191
217
|
ROTATION_ANGLE = "rotation angle"
|
|
192
218
|
DISPLAY_MEDIA_SUBTITLES = "display subtitles"
|
|
193
219
|
OVERLAY = "video overlay"
|
|
194
220
|
|
|
195
221
|
|
|
196
222
|
USE_EXIF_DATE = "use_exif_date"
|
|
223
|
+
SUBSTRACT_FIRST_EXIF_DATE = "substract_first_exif_date"
|
|
197
224
|
TIME_LAPSE = "time_lapse_delay"
|
|
198
225
|
|
|
199
226
|
|
|
200
227
|
# fields for event configuration
|
|
201
|
-
"""
|
|
202
|
-
fields = {
|
|
203
|
-
"type": 0,
|
|
204
|
-
"key": 1,
|
|
205
|
-
"code": 2,
|
|
206
|
-
"description": 3,
|
|
207
|
-
"modifiers": 4,
|
|
208
|
-
"excluded": 5,
|
|
209
|
-
"coding map": 6,
|
|
210
|
-
}
|
|
211
|
-
"""
|
|
212
228
|
|
|
213
229
|
ETHOGRAM_TABLE_COLUMNS: dict = {
|
|
214
230
|
0: "key",
|
|
@@ -233,18 +249,6 @@ behavioursFields: dict = {
|
|
|
233
249
|
"excluded": 7,
|
|
234
250
|
"coding map": 8,
|
|
235
251
|
}
|
|
236
|
-
"""
|
|
237
|
-
ETHOGRAM_FIELDS = [
|
|
238
|
-
"type",
|
|
239
|
-
"key",
|
|
240
|
-
"code",
|
|
241
|
-
"description",
|
|
242
|
-
"category",
|
|
243
|
-
"modifiers",
|
|
244
|
-
"excluded",
|
|
245
|
-
"coding map",
|
|
246
|
-
]
|
|
247
|
-
"""
|
|
248
252
|
ETHOGRAM_EDITABLE_FIELDS: tuple = ("key", "code", "description")
|
|
249
253
|
|
|
250
254
|
PROJECT_BEHAVIORS_KEY_FIELD_IDX = 1
|
|
@@ -254,13 +258,20 @@ MEDIA_FILE_PATH_IDX = 2
|
|
|
254
258
|
HAS_AUDIO_IDX = 6
|
|
255
259
|
|
|
256
260
|
STATE_EVENT = "State event"
|
|
261
|
+
STATE_EVENT_WITH_CODING_MAP = "State event with coding map"
|
|
262
|
+
|
|
263
|
+
STATE_EVENT_TYPES = [STATE_EVENT, STATE_EVENT_WITH_CODING_MAP]
|
|
264
|
+
|
|
257
265
|
POINT_EVENT = "Point event"
|
|
266
|
+
POINT_EVENT_WITH_CODING_MAP = "Point event with coding map"
|
|
267
|
+
|
|
268
|
+
POINT_EVENT_TYPES = [POINT_EVENT, POINT_EVENT_WITH_CODING_MAP]
|
|
258
269
|
|
|
259
270
|
BEHAVIOR_TYPES = [
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
271
|
+
POINT_EVENT,
|
|
272
|
+
STATE_EVENT,
|
|
273
|
+
POINT_EVENT_WITH_CODING_MAP,
|
|
274
|
+
STATE_EVENT_WITH_CODING_MAP,
|
|
264
275
|
]
|
|
265
276
|
|
|
266
277
|
DEFAULT_BEHAVIOR_TYPE = "Point event"
|
|
@@ -272,7 +283,7 @@ MEDIA_TW_EVENTS_FIELDS_DEFAULT = ("time", FRAME_INDEX, "subject", "code", "type"
|
|
|
272
283
|
MEDIA_TW_EVENTS_FIELDS = ("time", FRAME_INDEX, "subject", "code", "type", "modifier", "comment")
|
|
273
284
|
# MEDIA_TW_EVENTS_FIELDS = ("time", "subject", "code", "type", "modifier", "comment")
|
|
274
285
|
LIVE_TW_EVENTS_FIELDS = ("time", "subject", "code", "type", "modifier", "comment")
|
|
275
|
-
IMAGES_TW_EVENTS_FIELDS = ("time", "subject", "code", "type", "modifier", "comment", IMAGE_INDEX,
|
|
286
|
+
IMAGES_TW_EVENTS_FIELDS = ("time", "subject", "code", "type", "modifier", "comment", IMAGE_INDEX, IMAGE_PATH)
|
|
276
287
|
|
|
277
288
|
TW_EVENTS_FIELDS = {
|
|
278
289
|
MEDIA: MEDIA_TW_EVENTS_FIELDS,
|
|
@@ -294,7 +305,7 @@ for observation_type in TW_EVENTS_FIELDS:
|
|
|
294
305
|
# fields for project events list
|
|
295
306
|
MEDIA_PJ_EVENTS_FIELDS = (TIME, "subject", "code", "modifier", "comment", FRAME_INDEX)
|
|
296
307
|
LIVE_PJ_EVENTS_FIELDS = (TIME, "subject", "code", "modifier", "comment")
|
|
297
|
-
IMAGES_PJ_EVENTS_FIELDS = (TIME, "subject", "code", "modifier", "comment",
|
|
308
|
+
IMAGES_PJ_EVENTS_FIELDS = (TIME, "subject", "code", "modifier", "comment", IMAGE_INDEX, IMAGE_PATH)
|
|
298
309
|
|
|
299
310
|
PJ_EVENTS_FIELDS = {
|
|
300
311
|
MEDIA: MEDIA_PJ_EVENTS_FIELDS,
|
|
@@ -305,9 +316,6 @@ PJ_EVENTS_FIELDS = {
|
|
|
305
316
|
VIEWER_IMAGES: IMAGES_PJ_EVENTS_FIELDS,
|
|
306
317
|
}
|
|
307
318
|
|
|
308
|
-
# fields for independent variable definition
|
|
309
|
-
tw_indVarFields = ["label", "description", "type", "default value", "possible values"]
|
|
310
|
-
|
|
311
319
|
|
|
312
320
|
PJ_OBS_FIELDS = {}
|
|
313
321
|
for observation_type in PJ_EVENTS_FIELDS:
|
|
@@ -315,12 +323,17 @@ for observation_type in PJ_EVENTS_FIELDS:
|
|
|
315
323
|
for idx, field in enumerate(PJ_EVENTS_FIELDS[observation_type]):
|
|
316
324
|
PJ_OBS_FIELDS[observation_type][field] = idx
|
|
317
325
|
|
|
326
|
+
|
|
327
|
+
# fields for independent variable definition
|
|
328
|
+
tw_indVarFields = ["label", "description", "type", "default value", "possible values"]
|
|
329
|
+
|
|
330
|
+
|
|
318
331
|
EVENT_TIME_FIELD_IDX = 0
|
|
319
332
|
EVENT_SUBJECT_FIELD_IDX = 1
|
|
320
333
|
EVENT_BEHAVIOR_FIELD_IDX = 2
|
|
321
334
|
EVENT_MODIFIER_FIELD_IDX = 3
|
|
322
335
|
EVENT_COMMENT_FIELD_IDX = 4
|
|
323
|
-
EVENT_STATUS_FIELD_IDX =
|
|
336
|
+
EVENT_STATUS_FIELD_IDX = -1
|
|
324
337
|
# EVENT_IMAGEIDX_FIELD_IDX = 6
|
|
325
338
|
# EVENT_IMAGEPATH_FIELD_IDX = 7
|
|
326
339
|
|
|
@@ -345,6 +358,14 @@ START_FROM_CURRENT_EPOCH_TIME = "start_from_current_epoch_time"
|
|
|
345
358
|
|
|
346
359
|
SCAN_SAMPLING_TIME = "scan_sampling_time"
|
|
347
360
|
|
|
361
|
+
POINT_OBJECT = "Point"
|
|
362
|
+
SEGMENT_OBJECT = "Segment"
|
|
363
|
+
ANGLE_OBJECT = "Angle"
|
|
364
|
+
ORIENTED_ANGLE_OBJECT = "Oriented angle"
|
|
365
|
+
POLYGON_OBJECT = "Polygon"
|
|
366
|
+
POLYLINE_OBJECT = "Polyline"
|
|
367
|
+
|
|
368
|
+
|
|
348
369
|
NEW = "new"
|
|
349
370
|
LIST = "list"
|
|
350
371
|
EDIT = "edit"
|
|
@@ -364,6 +385,7 @@ SELECTED_BEHAVIORS = "selected behaviors"
|
|
|
364
385
|
SELECTED_SUBJECTS = "selected subjects"
|
|
365
386
|
INCLUDE_MODIFIERS = "include modifiers"
|
|
366
387
|
EXCLUDE_BEHAVIORS = "exclude behaviors"
|
|
388
|
+
EXCLUDE_NON_CODED_MODIFIERS = "exclude_non_coded_modifiers"
|
|
367
389
|
EXCLUDED_BEHAVIORS = "excluded behaviors"
|
|
368
390
|
TIME_INTERVAL = "time"
|
|
369
391
|
START_TIME = "start time"
|
|
@@ -381,6 +403,7 @@ TIMESTAMP_idx = 3
|
|
|
381
403
|
|
|
382
404
|
TIME_FULL_OBS = "full obs"
|
|
383
405
|
TIME_EVENTS = "limit to events"
|
|
406
|
+
TIME_OBS_INTERVAL = "interval of observation"
|
|
384
407
|
TIME_ARBITRARY_INTERVAL = "time interval"
|
|
385
408
|
|
|
386
409
|
AVAILABLE_INDEP_VAR_TYPES = [NUMERIC, TEXT, SET_OF_VALUES, TIMESTAMP]
|
|
@@ -390,16 +413,31 @@ OBSERVATIONS = "observations"
|
|
|
390
413
|
|
|
391
414
|
CLOSE_BEHAVIORS_BETWEEN_VIDEOS = "close_behaviors_between_videos"
|
|
392
415
|
|
|
393
|
-
|
|
394
|
-
MPV_HWDEC_DEFAULT_VALUE = "auto"
|
|
416
|
+
# MPV hardware decode
|
|
395
417
|
MPV_HWDEC = "mpv_hwdec"
|
|
418
|
+
MPV_HWDEC_NO = "no"
|
|
419
|
+
MPV_HWDEC_AUTO = "auto"
|
|
420
|
+
MPV_HWDEC_AUTOSAFE = "auto-safe"
|
|
421
|
+
MPV_HWDEC_OPTIONS = (MPV_HWDEC_AUTO, MPV_HWDEC_AUTOSAFE, MPV_HWDEC_NO)
|
|
422
|
+
MPV_HWDEC_DEFAULT_VALUE = MPV_HWDEC_AUTO
|
|
423
|
+
|
|
424
|
+
# frame step size (disabled)
|
|
425
|
+
# FRAME_STEP_SIZE: str = "frame_step_size"
|
|
426
|
+
# FRAME_STEP_SIZE_DEFAULT_VALUE: int = 1
|
|
396
427
|
|
|
428
|
+
ANALYSIS_PLUGINS = "analysis_plugins"
|
|
429
|
+
EXCLUDED_PLUGINS = "excluded_plugins"
|
|
430
|
+
PERSONAL_PLUGINS_DIR = "personal_plugins_dir"
|
|
397
431
|
|
|
398
432
|
PROJECT_FILE_INDENTATION = "project file indentation"
|
|
399
433
|
PROJECT_FILE_INDENTATION_COMBO_OPTIONS = ("None", "Newline", "Tab", "2 spaces", "4 spaces")
|
|
400
434
|
PROJECT_FILE_INDENTATION_OPTIONS = (None, 0, "\t", 2, 4)
|
|
401
435
|
PROJECT_FILE_INDENTATION_DEFAULT_VALUE = None
|
|
402
436
|
|
|
437
|
+
TOOLBAR_ICON_SIZE = "toolbar icon size"
|
|
438
|
+
DEFAULT_TOOLBAR_ICON_SIZE_VALUE = 24
|
|
439
|
+
|
|
440
|
+
|
|
403
441
|
VIDEO_VIEWER = 0
|
|
404
442
|
PICTURE_VIEWER = 1
|
|
405
443
|
|
|
@@ -416,6 +454,7 @@ LENGTH = "length"
|
|
|
416
454
|
FPS = "fps"
|
|
417
455
|
HAS_AUDIO = "hasAudio"
|
|
418
456
|
HAS_VIDEO = "hasVideo"
|
|
457
|
+
MEDIA_CREATION_TIME = "media_creation_time"
|
|
419
458
|
|
|
420
459
|
STATE = "STATE"
|
|
421
460
|
POINT = "POINT"
|
|
@@ -423,12 +462,15 @@ POINT = "POINT"
|
|
|
423
462
|
START = "START"
|
|
424
463
|
STOP = "STOP"
|
|
425
464
|
|
|
426
|
-
PLAYER1
|
|
465
|
+
PLAYER1 = "1"
|
|
466
|
+
PLAYER2 = "2"
|
|
427
467
|
ALL_PLAYERS = [str(x + 1) for x in range(N_PLAYER)]
|
|
428
468
|
|
|
429
469
|
VISUALIZE_SPECTROGRAM = "visualize_spectrogram"
|
|
430
470
|
VISUALIZE_WAVEFORM = "visualize_waveform"
|
|
471
|
+
MEDIA_CREATION_DATE_AS_OFFSET = "media_creation_date_as_offset"
|
|
431
472
|
|
|
473
|
+
MEDIA_SCAN_SAMPLING_DURATION = "media_scan_sampling_duration"
|
|
432
474
|
IMAGE_DISPLAY_DURATION = "image_display_duration"
|
|
433
475
|
|
|
434
476
|
# plot type
|
|
@@ -436,6 +478,9 @@ WAVEFORM_PLOT = "waveform"
|
|
|
436
478
|
SPECTROGRAM_PLOT = "spectrogram"
|
|
437
479
|
EVENTS_PLOT = "plot_events"
|
|
438
480
|
|
|
481
|
+
PLAYING = "playing"
|
|
482
|
+
PAUSED = "paused"
|
|
483
|
+
STOPPED = "stopped"
|
|
439
484
|
|
|
440
485
|
POINT_EVENT_ST_DURATION = 0.5
|
|
441
486
|
|
|
@@ -446,6 +491,8 @@ SLIDER_MAXIMUM = 1000
|
|
|
446
491
|
|
|
447
492
|
FRAME_DEFAULT_CACHE_SIZE = 1
|
|
448
493
|
|
|
494
|
+
EXCLUDED = "excluded"
|
|
495
|
+
|
|
449
496
|
# modifiers
|
|
450
497
|
MODIFIERS = "modifiers"
|
|
451
498
|
SINGLE_SELECTION = 0
|
|
@@ -489,6 +536,16 @@ NO_COLOR_CODING_PAD = "#777777"
|
|
|
489
536
|
SPECTROGRAM_COLOR_MAPS = ["viridis", "inferno", "plasma", "magma", "gray", "YlOrRd"]
|
|
490
537
|
SPECTROGRAM_DEFAULT_COLOR_MAP = "viridis"
|
|
491
538
|
SPECTROGRAM_DEFAULT_TIME_INTERVAL = 10
|
|
539
|
+
SPECTROGRAM_WINDOW_TYPE = "SPECTROGRAM_WINDOW_TYPE"
|
|
540
|
+
SPECTROGRAM_DEFAULT_WINDOW_TYPE = "hanning"
|
|
541
|
+
SPECTROGRAM_NFFT = "SPECTROGRAM_NFFT"
|
|
542
|
+
SPECTROGRAM_DEFAULT_NFFT = "1024"
|
|
543
|
+
SPECTROGRAM_NOVERLAP = "SPECTROGRAM_NOVERLAP"
|
|
544
|
+
SPECTROGRAM_DEFAULT_NOVERLAP = 900
|
|
545
|
+
SPECTROGRAM_VMIN = "SPECTROGRAM_VMIN"
|
|
546
|
+
SPECTROGRAM_DEFAULT_VMIN = -100
|
|
547
|
+
SPECTROGRAM_VMAX = "SPECTROGRAM_VMAX"
|
|
548
|
+
SPECTROGRAM_DEFAULT_VMAX = -20
|
|
492
549
|
|
|
493
550
|
# see matplotlib.colors.cnames.keys()
|
|
494
551
|
# https://xkcd.com/color/rgb/
|
|
@@ -663,6 +720,7 @@ EMPTY_PROJECT = {
|
|
|
663
720
|
ETHOGRAM: {},
|
|
664
721
|
OBSERVATIONS: {},
|
|
665
722
|
BEHAVIORAL_CATEGORIES: [],
|
|
723
|
+
BEHAVIORAL_CATEGORIES_CONF: {},
|
|
666
724
|
INDEPENDENT_VARIABLES: {},
|
|
667
725
|
CODING_MAP: {},
|
|
668
726
|
BEHAVIORS_CODING_MAP: [],
|
|
@@ -678,15 +736,16 @@ INIT_PARAM = {
|
|
|
678
736
|
MPV_HWDEC: MPV_HWDEC_DEFAULT_VALUE,
|
|
679
737
|
PROJECT_FILE_INDENTATION: PROJECT_FILE_INDENTATION_DEFAULT_VALUE,
|
|
680
738
|
f"{MEDIA} tw fields": MEDIA_TW_EVENTS_FIELDS_DEFAULT,
|
|
739
|
+
# FRAME_STEP_SIZE: FRAME_STEP_SIZE_DEFAULT_VALUE,
|
|
681
740
|
}
|
|
682
741
|
|
|
683
742
|
SDIS_EXT = "sds"
|
|
684
743
|
TBS_EXT = "tbs"
|
|
685
744
|
TSV_EXT = "tsv"
|
|
686
|
-
CSV_EXT = "
|
|
745
|
+
CSV_EXT = "csv"
|
|
687
746
|
RDS_EXT = "rds"
|
|
688
747
|
PANDAS_DF_EXT = "pkl"
|
|
689
|
-
|
|
748
|
+
HTML_EXT = "html"
|
|
690
749
|
SQL_EXT = "sql"
|
|
691
750
|
ODS_EXT = "ods"
|
|
692
751
|
XLS_EXT = "xls"
|
|
@@ -716,7 +775,7 @@ FILE_NAME_SUFFIX = {
|
|
|
716
775
|
XLSX: XLSX_EXT,
|
|
717
776
|
XLSX_WB: XLSX_EXT,
|
|
718
777
|
XLS: XLS_EXT,
|
|
719
|
-
HTML:
|
|
778
|
+
HTML: HTML_EXT,
|
|
720
779
|
PANDAS_DF: PANDAS_DF_EXT,
|
|
721
780
|
RDS: RDS_EXT,
|
|
722
781
|
SQL: SQL_EXT,
|
boris/config_file.py
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"""
|
|
2
2
|
BORIS
|
|
3
3
|
Behavioral Observation Research Interactive Software
|
|
4
|
-
Copyright 2012-
|
|
4
|
+
Copyright 2012-2025 Olivier Friard
|
|
5
5
|
|
|
6
6
|
This file is part of BORIS.
|
|
7
7
|
|
|
@@ -18,21 +18,17 @@ This file is part of BORIS.
|
|
|
18
18
|
You should have received a copy of the GNU General Public License
|
|
19
19
|
along with this program; if not see <http://www.gnu.org/licenses/>.
|
|
20
20
|
|
|
21
|
-
"""
|
|
22
|
-
|
|
23
|
-
"""
|
|
24
21
|
Read and write the BORIS config file
|
|
25
22
|
"""
|
|
26
23
|
|
|
27
24
|
import pathlib as pl
|
|
28
25
|
import logging
|
|
29
26
|
import time
|
|
30
|
-
import os
|
|
31
27
|
|
|
32
28
|
from . import config as cfg
|
|
33
29
|
from . import dialog
|
|
34
30
|
|
|
35
|
-
from
|
|
31
|
+
from PySide6.QtCore import QByteArray, QSettings
|
|
36
32
|
|
|
37
33
|
|
|
38
34
|
def read(self):
|
|
@@ -40,19 +36,19 @@ def read(self):
|
|
|
40
36
|
read config file
|
|
41
37
|
"""
|
|
42
38
|
|
|
43
|
-
|
|
39
|
+
ini_fil_p_pe_p_path = pl.Path.home() / pl.Path(".boris")
|
|
44
40
|
|
|
45
|
-
logging.debug(f"read config file: {
|
|
41
|
+
logging.debug(f"read config file: {ini_fil_p_pe_p_path}")
|
|
46
42
|
|
|
47
|
-
if
|
|
48
|
-
settings = QSettings(str(
|
|
43
|
+
if ini_fil_p_pe_p_path.is_file():
|
|
44
|
+
settings = QSettings(str(ini_fil_p_pe_p_path), QSettings.IniFormat)
|
|
49
45
|
|
|
50
46
|
try:
|
|
51
47
|
self.config_param = settings.value("config")
|
|
52
48
|
except Exception:
|
|
53
|
-
self.config_param =
|
|
54
|
-
|
|
55
|
-
if self.config_param
|
|
49
|
+
self.config_param = {}
|
|
50
|
+
|
|
51
|
+
if self.config_param == {}:
|
|
56
52
|
self.config_param = cfg.INIT_PARAM
|
|
57
53
|
|
|
58
54
|
# for back compatibility
|
|
@@ -76,7 +72,7 @@ def read(self):
|
|
|
76
72
|
if not isinstance(self.saved_state, QByteArray):
|
|
77
73
|
self.saved_state = None
|
|
78
74
|
|
|
79
|
-
logging.debug(f"saved state: {self.saved_state}")
|
|
75
|
+
# logging.debug(f"saved state: {self.saved_state}")
|
|
80
76
|
|
|
81
77
|
self.timeFormat = cfg.HHMMSS
|
|
82
78
|
try:
|
|
@@ -86,11 +82,11 @@ def read(self):
|
|
|
86
82
|
|
|
87
83
|
logging.debug(f"time format: {self.timeFormat}")
|
|
88
84
|
|
|
89
|
-
self.fast =
|
|
85
|
+
self.fast = cfg.FAST_FORWARD_DEFAULT_VALUE
|
|
90
86
|
try:
|
|
91
|
-
self.fast =
|
|
87
|
+
self.fast = float(settings.value("Time/fast_forward_speed"))
|
|
92
88
|
except Exception:
|
|
93
|
-
self.fast =
|
|
89
|
+
self.fast = cfg.FAST_FORWARD_DEFAULT_VALUE
|
|
94
90
|
|
|
95
91
|
logging.debug(f"Time/fast_forward_speed: {self.fast}")
|
|
96
92
|
|
|
@@ -172,25 +168,27 @@ def read(self):
|
|
|
172
168
|
|
|
173
169
|
# check for new version
|
|
174
170
|
self.checkForNewVersion = False
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
(
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
171
|
+
|
|
172
|
+
if not self.no_first_launch_dialog:
|
|
173
|
+
try:
|
|
174
|
+
if settings.value("check_for_new_version") is None:
|
|
175
|
+
self.checkForNewVersion = (
|
|
176
|
+
dialog.MessageDialog(
|
|
177
|
+
cfg.programName,
|
|
178
|
+
(
|
|
179
|
+
"Allow BORIS to automatically check for new version and news?\n"
|
|
180
|
+
"(An internet connection is required)\n"
|
|
181
|
+
"You can change this option in the Preferences (File > Preferences)"
|
|
182
|
+
),
|
|
183
|
+
[cfg.YES, cfg.NO],
|
|
184
|
+
)
|
|
185
|
+
== cfg.YES
|
|
186
186
|
)
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
self.checkForNewVersion =
|
|
191
|
-
|
|
192
|
-
self.checkForNewVersion = False
|
|
193
|
-
logging.debug(f"check_for_new_version: {self.checkForNewVersion}")
|
|
187
|
+
else:
|
|
188
|
+
self.checkForNewVersion = settings.value("check_for_new_version") == "true"
|
|
189
|
+
except Exception:
|
|
190
|
+
self.checkForNewVersion = False
|
|
191
|
+
logging.debug(f"Automatic check for new version: {self.checkForNewVersion}")
|
|
194
192
|
|
|
195
193
|
# pause before add event
|
|
196
194
|
self.pause_before_addevent = False
|
|
@@ -203,11 +201,11 @@ def read(self):
|
|
|
203
201
|
|
|
204
202
|
if self.checkForNewVersion:
|
|
205
203
|
if settings.value("last_check_for_new_version") and (
|
|
206
|
-
int(time.mktime(time.localtime())) - int(settings.value("last_check_for_new_version"))
|
|
207
|
-
> cfg.CHECK_NEW_VERSION_DELAY
|
|
204
|
+
int(time.mktime(time.localtime())) - int(settings.value("last_check_for_new_version")) > cfg.CHECK_NEW_VERSION_DELAY
|
|
208
205
|
):
|
|
209
206
|
self.actionCheckUpdate_activated(flagMsgOnlyIfNew=True)
|
|
210
|
-
|
|
207
|
+
|
|
208
|
+
logging.debug(f"last check for new version: {settings.value('last_check_for_new_version')}")
|
|
211
209
|
|
|
212
210
|
self.ffmpeg_cache_dir = ""
|
|
213
211
|
try:
|
|
@@ -245,10 +243,7 @@ def read(self):
|
|
|
245
243
|
if (
|
|
246
244
|
dialog.MessageDialog(
|
|
247
245
|
cfg.programName,
|
|
248
|
-
(
|
|
249
|
-
"The colors list contain colors that are very light.\n"
|
|
250
|
-
"Do you want to reload the default colors list?"
|
|
251
|
-
),
|
|
246
|
+
("The colors list contain colors that are very light.\nDo you want to reload the default colors list?"),
|
|
252
247
|
[cfg.NO, cfg.YES],
|
|
253
248
|
)
|
|
254
249
|
== cfg.YES
|
|
@@ -261,18 +256,11 @@ def read(self):
|
|
|
261
256
|
except Exception:
|
|
262
257
|
self.behav_category_colors = cfg.CATEGORY_COLORS_LIST
|
|
263
258
|
|
|
264
|
-
if
|
|
265
|
-
"white" in self.behav_category_colors
|
|
266
|
-
or "azure" in self.behav_category_colors
|
|
267
|
-
or "snow" in self.behav_category_colors
|
|
268
|
-
):
|
|
259
|
+
if "white" in self.behav_category_colors or "azure" in self.behav_category_colors or "snow" in self.behav_category_colors:
|
|
269
260
|
if (
|
|
270
261
|
dialog.MessageDialog(
|
|
271
262
|
cfg.programName,
|
|
272
|
-
(
|
|
273
|
-
"The colors list contain colors that are very light.\n"
|
|
274
|
-
"Do you want to reload the default colors list?"
|
|
275
|
-
),
|
|
263
|
+
("The colors list contain colors that are very light.\nDo you want to reload the default colors list?"),
|
|
276
264
|
[cfg.NO, cfg.YES],
|
|
277
265
|
)
|
|
278
266
|
== cfg.YES
|
|
@@ -282,25 +270,28 @@ def read(self):
|
|
|
282
270
|
else: # no .boris file found
|
|
283
271
|
logging.info("No config file found")
|
|
284
272
|
# ask user for checking for new version
|
|
285
|
-
self.
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
273
|
+
if not self.no_first_launch_dialog:
|
|
274
|
+
self.checkForNewVersion = (
|
|
275
|
+
dialog.MessageDialog(
|
|
276
|
+
cfg.programName,
|
|
277
|
+
(
|
|
278
|
+
"Allow BORIS to automatically check for new version?\n"
|
|
279
|
+
"(An internet connection is required)\n"
|
|
280
|
+
"You can change this option in the"
|
|
281
|
+
" Preferences (File > Preferences)"
|
|
282
|
+
),
|
|
283
|
+
[cfg.NO, cfg.YES],
|
|
284
|
+
)
|
|
285
|
+
== cfg.YES
|
|
295
286
|
)
|
|
296
|
-
|
|
297
|
-
|
|
287
|
+
else:
|
|
288
|
+
self.checkForNewVersion = False
|
|
298
289
|
|
|
299
290
|
# recent projects
|
|
300
|
-
logging.
|
|
301
|
-
|
|
302
|
-
if
|
|
303
|
-
settings = QSettings(
|
|
291
|
+
logging.debug("read recent projects")
|
|
292
|
+
recent_projects_file_path = pl.Path.home() / ".boris_recent_projects"
|
|
293
|
+
if recent_projects_file_path.is_file():
|
|
294
|
+
settings = QSettings(str(recent_projects_file_path), QSettings.IniFormat)
|
|
304
295
|
try:
|
|
305
296
|
self.recent_projects = settings.value("recent_projects").split("|||")
|
|
306
297
|
while "" in self.recent_projects:
|