boris-behav-obs 8.16.5__py3-none-any.whl → 9.7.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- boris/__init__.py +1 -1
- boris/__main__.py +1 -1
- boris/about.py +24 -36
- boris/add_modifier.py +88 -80
- boris/add_modifier_ui.py +235 -131
- boris/advanced_event_filtering.py +23 -29
- boris/analysis_plugins/__init__.py +0 -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 +228 -229
- 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 +16 -34
- boris/config.py +102 -50
- boris/config_file.py +55 -64
- boris/connections.py +105 -58
- boris/converters.py +13 -37
- boris/converters_ui.py +187 -110
- boris/cooccurence.py +250 -0
- boris/core.py +2108 -1275
- 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 +304 -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 +493 -210
- boris/observation_operations.py +1010 -391
- 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 +18 -53
- boris/plot_events.py +56 -153
- boris/plot_events_rt.py +16 -30
- boris/plot_spectrogram_rt.py +80 -56
- boris/plot_waveform_rt.py +23 -48
- boris/plugins.py +431 -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 +298 -123
- boris/preferences_ui.py +664 -225
- boris/project.py +293 -270
- boris/project_functions.py +610 -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 +6 -8
- 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 +562 -222
- boris/version.py +3 -3
- boris/video_equalizer.py +16 -14
- boris/video_equalizer_ui.py +199 -130
- boris/video_operations.py +78 -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.1.dist-info/METADATA +140 -0
- boris_behav_obs-9.7.1.dist-info/RECORD +109 -0
- {boris_behav_obs-8.16.5.dist-info → boris_behav_obs-9.7.1.dist-info}/WHEEL +1 -1
- boris_behav_obs-9.7.1.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.1.dist-info/licenses}/LICENSE.TXT +0 -0
- {boris_behav_obs-8.16.5.dist-info → boris_behav_obs-9.7.1.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"
|
|
@@ -118,17 +135,29 @@ CHAR_FORBIDDEN_IN_MODIFIERS = "(|),`~"
|
|
|
118
135
|
ADAPT_FAST_JUMP = "adapt_fast_jump"
|
|
119
136
|
ADAPT_FAST_JUMP_DEFAULT = False
|
|
120
137
|
|
|
138
|
+
TIME = "time"
|
|
139
|
+
BEHAVIOR_CODE = "code"
|
|
140
|
+
SUBJECT = "subject"
|
|
141
|
+
MODIFIER = "modifier"
|
|
142
|
+
COMMENT = "comment"
|
|
143
|
+
BEHAVIOR_KEY = "key"
|
|
144
|
+
SUBJECT_KEY = "key"
|
|
145
|
+
BEHAVIOR_CATEGORY = "category"
|
|
146
|
+
|
|
121
147
|
|
|
122
|
-
subjectsFields = [
|
|
148
|
+
subjectsFields = [SUBJECT_KEY, SUBJECT_NAME, DESCRIPTION]
|
|
123
149
|
|
|
124
150
|
UNPAIRED = "UNPAIRED"
|
|
125
151
|
DISPLAY_SUBTITLES = "display_subtitles"
|
|
152
|
+
CHECK_PROJECT_INTEGRITY = "check_project_integrity"
|
|
126
153
|
|
|
127
154
|
|
|
128
155
|
YES = "Yes"
|
|
129
156
|
NO = "No"
|
|
130
157
|
CANCEL = "Cancel"
|
|
158
|
+
IGNORE = "Ignore"
|
|
131
159
|
APPEND = "Append"
|
|
160
|
+
CLOSE = "Close"
|
|
132
161
|
REPLACE = "Replace"
|
|
133
162
|
REMOVE = "Remove"
|
|
134
163
|
SAVE = "Save"
|
|
@@ -173,13 +202,6 @@ DATA_PLOT_FIELDS = {
|
|
|
173
202
|
}
|
|
174
203
|
DATA_PLOT_STYLES = ["b-", "r-", "g-", "bo", "ro", "go"]
|
|
175
204
|
|
|
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
205
|
|
|
184
206
|
FILE_PATH = "file_path"
|
|
185
207
|
|
|
@@ -188,27 +210,19 @@ IMAGE_PATH = "image path"
|
|
|
188
210
|
FRAME_INDEX = "frame index"
|
|
189
211
|
|
|
190
212
|
ZOOM_LEVEL = "zoom level"
|
|
213
|
+
PAN_X = "pan-x"
|
|
214
|
+
PAN_Y = "pan-y"
|
|
191
215
|
ROTATION_ANGLE = "rotation angle"
|
|
192
216
|
DISPLAY_MEDIA_SUBTITLES = "display subtitles"
|
|
193
217
|
OVERLAY = "video overlay"
|
|
194
218
|
|
|
195
219
|
|
|
196
220
|
USE_EXIF_DATE = "use_exif_date"
|
|
221
|
+
SUBSTRACT_FIRST_EXIF_DATE = "substract_first_exif_date"
|
|
197
222
|
TIME_LAPSE = "time_lapse_delay"
|
|
198
223
|
|
|
199
224
|
|
|
200
225
|
# 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
226
|
|
|
213
227
|
ETHOGRAM_TABLE_COLUMNS: dict = {
|
|
214
228
|
0: "key",
|
|
@@ -233,18 +247,6 @@ behavioursFields: dict = {
|
|
|
233
247
|
"excluded": 7,
|
|
234
248
|
"coding map": 8,
|
|
235
249
|
}
|
|
236
|
-
"""
|
|
237
|
-
ETHOGRAM_FIELDS = [
|
|
238
|
-
"type",
|
|
239
|
-
"key",
|
|
240
|
-
"code",
|
|
241
|
-
"description",
|
|
242
|
-
"category",
|
|
243
|
-
"modifiers",
|
|
244
|
-
"excluded",
|
|
245
|
-
"coding map",
|
|
246
|
-
]
|
|
247
|
-
"""
|
|
248
250
|
ETHOGRAM_EDITABLE_FIELDS: tuple = ("key", "code", "description")
|
|
249
251
|
|
|
250
252
|
PROJECT_BEHAVIORS_KEY_FIELD_IDX = 1
|
|
@@ -254,13 +256,20 @@ MEDIA_FILE_PATH_IDX = 2
|
|
|
254
256
|
HAS_AUDIO_IDX = 6
|
|
255
257
|
|
|
256
258
|
STATE_EVENT = "State event"
|
|
259
|
+
STATE_EVENT_WITH_CODING_MAP = "State event with coding map"
|
|
260
|
+
|
|
261
|
+
STATE_EVENT_TYPES = [STATE_EVENT, STATE_EVENT_WITH_CODING_MAP]
|
|
262
|
+
|
|
257
263
|
POINT_EVENT = "Point event"
|
|
264
|
+
POINT_EVENT_WITH_CODING_MAP = "Point event with coding map"
|
|
265
|
+
|
|
266
|
+
POINT_EVENT_TYPES = [POINT_EVENT, POINT_EVENT_WITH_CODING_MAP]
|
|
258
267
|
|
|
259
268
|
BEHAVIOR_TYPES = [
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
269
|
+
POINT_EVENT,
|
|
270
|
+
STATE_EVENT,
|
|
271
|
+
POINT_EVENT_WITH_CODING_MAP,
|
|
272
|
+
STATE_EVENT_WITH_CODING_MAP,
|
|
264
273
|
]
|
|
265
274
|
|
|
266
275
|
DEFAULT_BEHAVIOR_TYPE = "Point event"
|
|
@@ -272,7 +281,7 @@ MEDIA_TW_EVENTS_FIELDS_DEFAULT = ("time", FRAME_INDEX, "subject", "code", "type"
|
|
|
272
281
|
MEDIA_TW_EVENTS_FIELDS = ("time", FRAME_INDEX, "subject", "code", "type", "modifier", "comment")
|
|
273
282
|
# MEDIA_TW_EVENTS_FIELDS = ("time", "subject", "code", "type", "modifier", "comment")
|
|
274
283
|
LIVE_TW_EVENTS_FIELDS = ("time", "subject", "code", "type", "modifier", "comment")
|
|
275
|
-
IMAGES_TW_EVENTS_FIELDS = ("time", "subject", "code", "type", "modifier", "comment", IMAGE_INDEX,
|
|
284
|
+
IMAGES_TW_EVENTS_FIELDS = ("time", "subject", "code", "type", "modifier", "comment", IMAGE_INDEX, IMAGE_PATH)
|
|
276
285
|
|
|
277
286
|
TW_EVENTS_FIELDS = {
|
|
278
287
|
MEDIA: MEDIA_TW_EVENTS_FIELDS,
|
|
@@ -294,7 +303,7 @@ for observation_type in TW_EVENTS_FIELDS:
|
|
|
294
303
|
# fields for project events list
|
|
295
304
|
MEDIA_PJ_EVENTS_FIELDS = (TIME, "subject", "code", "modifier", "comment", FRAME_INDEX)
|
|
296
305
|
LIVE_PJ_EVENTS_FIELDS = (TIME, "subject", "code", "modifier", "comment")
|
|
297
|
-
IMAGES_PJ_EVENTS_FIELDS = (TIME, "subject", "code", "modifier", "comment",
|
|
306
|
+
IMAGES_PJ_EVENTS_FIELDS = (TIME, "subject", "code", "modifier", "comment", IMAGE_INDEX, IMAGE_PATH)
|
|
298
307
|
|
|
299
308
|
PJ_EVENTS_FIELDS = {
|
|
300
309
|
MEDIA: MEDIA_PJ_EVENTS_FIELDS,
|
|
@@ -305,9 +314,6 @@ PJ_EVENTS_FIELDS = {
|
|
|
305
314
|
VIEWER_IMAGES: IMAGES_PJ_EVENTS_FIELDS,
|
|
306
315
|
}
|
|
307
316
|
|
|
308
|
-
# fields for independent variable definition
|
|
309
|
-
tw_indVarFields = ["label", "description", "type", "default value", "possible values"]
|
|
310
|
-
|
|
311
317
|
|
|
312
318
|
PJ_OBS_FIELDS = {}
|
|
313
319
|
for observation_type in PJ_EVENTS_FIELDS:
|
|
@@ -315,12 +321,17 @@ for observation_type in PJ_EVENTS_FIELDS:
|
|
|
315
321
|
for idx, field in enumerate(PJ_EVENTS_FIELDS[observation_type]):
|
|
316
322
|
PJ_OBS_FIELDS[observation_type][field] = idx
|
|
317
323
|
|
|
324
|
+
|
|
325
|
+
# fields for independent variable definition
|
|
326
|
+
tw_indVarFields = ["label", "description", "type", "default value", "possible values"]
|
|
327
|
+
|
|
328
|
+
|
|
318
329
|
EVENT_TIME_FIELD_IDX = 0
|
|
319
330
|
EVENT_SUBJECT_FIELD_IDX = 1
|
|
320
331
|
EVENT_BEHAVIOR_FIELD_IDX = 2
|
|
321
332
|
EVENT_MODIFIER_FIELD_IDX = 3
|
|
322
333
|
EVENT_COMMENT_FIELD_IDX = 4
|
|
323
|
-
EVENT_STATUS_FIELD_IDX =
|
|
334
|
+
EVENT_STATUS_FIELD_IDX = -1
|
|
324
335
|
# EVENT_IMAGEIDX_FIELD_IDX = 6
|
|
325
336
|
# EVENT_IMAGEPATH_FIELD_IDX = 7
|
|
326
337
|
|
|
@@ -345,6 +356,14 @@ START_FROM_CURRENT_EPOCH_TIME = "start_from_current_epoch_time"
|
|
|
345
356
|
|
|
346
357
|
SCAN_SAMPLING_TIME = "scan_sampling_time"
|
|
347
358
|
|
|
359
|
+
POINT_OBJECT = "Point"
|
|
360
|
+
SEGMENT_OBJECT = "Segment"
|
|
361
|
+
ANGLE_OBJECT = "Angle"
|
|
362
|
+
ORIENTED_ANGLE_OBJECT = "Oriented angle"
|
|
363
|
+
POLYGON_OBJECT = "Polygon"
|
|
364
|
+
POLYLINE_OBJECT = "Polyline"
|
|
365
|
+
|
|
366
|
+
|
|
348
367
|
NEW = "new"
|
|
349
368
|
LIST = "list"
|
|
350
369
|
EDIT = "edit"
|
|
@@ -364,6 +383,7 @@ SELECTED_BEHAVIORS = "selected behaviors"
|
|
|
364
383
|
SELECTED_SUBJECTS = "selected subjects"
|
|
365
384
|
INCLUDE_MODIFIERS = "include modifiers"
|
|
366
385
|
EXCLUDE_BEHAVIORS = "exclude behaviors"
|
|
386
|
+
EXCLUDE_NON_CODED_MODIFIERS = "exclude_non_coded_modifiers"
|
|
367
387
|
EXCLUDED_BEHAVIORS = "excluded behaviors"
|
|
368
388
|
TIME_INTERVAL = "time"
|
|
369
389
|
START_TIME = "start time"
|
|
@@ -381,6 +401,7 @@ TIMESTAMP_idx = 3
|
|
|
381
401
|
|
|
382
402
|
TIME_FULL_OBS = "full obs"
|
|
383
403
|
TIME_EVENTS = "limit to events"
|
|
404
|
+
TIME_OBS_INTERVAL = "interval of observation"
|
|
384
405
|
TIME_ARBITRARY_INTERVAL = "time interval"
|
|
385
406
|
|
|
386
407
|
AVAILABLE_INDEP_VAR_TYPES = [NUMERIC, TEXT, SET_OF_VALUES, TIMESTAMP]
|
|
@@ -390,16 +411,27 @@ OBSERVATIONS = "observations"
|
|
|
390
411
|
|
|
391
412
|
CLOSE_BEHAVIORS_BETWEEN_VIDEOS = "close_behaviors_between_videos"
|
|
392
413
|
|
|
393
|
-
|
|
394
|
-
MPV_HWDEC_DEFAULT_VALUE = "auto"
|
|
414
|
+
# MPV hardware decode
|
|
395
415
|
MPV_HWDEC = "mpv_hwdec"
|
|
416
|
+
MPV_HWDEC_NO = "no"
|
|
417
|
+
MPV_HWDEC_AUTO = "auto"
|
|
418
|
+
MPV_HWDEC_AUTOSAFE = "auto-safe"
|
|
419
|
+
MPV_HWDEC_OPTIONS = (MPV_HWDEC_AUTO, MPV_HWDEC_AUTOSAFE, MPV_HWDEC_NO)
|
|
420
|
+
MPV_HWDEC_DEFAULT_VALUE = MPV_HWDEC_AUTO
|
|
396
421
|
|
|
422
|
+
ANALYSIS_PLUGINS = "analysis_plugins"
|
|
423
|
+
EXCLUDED_PLUGINS = "excluded_plugins"
|
|
424
|
+
PERSONAL_PLUGINS_DIR = "personal_plugins_dir"
|
|
397
425
|
|
|
398
426
|
PROJECT_FILE_INDENTATION = "project file indentation"
|
|
399
427
|
PROJECT_FILE_INDENTATION_COMBO_OPTIONS = ("None", "Newline", "Tab", "2 spaces", "4 spaces")
|
|
400
428
|
PROJECT_FILE_INDENTATION_OPTIONS = (None, 0, "\t", 2, 4)
|
|
401
429
|
PROJECT_FILE_INDENTATION_DEFAULT_VALUE = None
|
|
402
430
|
|
|
431
|
+
TOOLBAR_ICON_SIZE = "toolbar icon size"
|
|
432
|
+
DEFAULT_TOOLBAR_ICON_SIZE_VALUE = 24
|
|
433
|
+
|
|
434
|
+
|
|
403
435
|
VIDEO_VIEWER = 0
|
|
404
436
|
PICTURE_VIEWER = 1
|
|
405
437
|
|
|
@@ -416,6 +448,7 @@ LENGTH = "length"
|
|
|
416
448
|
FPS = "fps"
|
|
417
449
|
HAS_AUDIO = "hasAudio"
|
|
418
450
|
HAS_VIDEO = "hasVideo"
|
|
451
|
+
MEDIA_CREATION_TIME = "media_creation_time"
|
|
419
452
|
|
|
420
453
|
STATE = "STATE"
|
|
421
454
|
POINT = "POINT"
|
|
@@ -423,12 +456,15 @@ POINT = "POINT"
|
|
|
423
456
|
START = "START"
|
|
424
457
|
STOP = "STOP"
|
|
425
458
|
|
|
426
|
-
PLAYER1
|
|
459
|
+
PLAYER1 = "1"
|
|
460
|
+
PLAYER2 = "2"
|
|
427
461
|
ALL_PLAYERS = [str(x + 1) for x in range(N_PLAYER)]
|
|
428
462
|
|
|
429
463
|
VISUALIZE_SPECTROGRAM = "visualize_spectrogram"
|
|
430
464
|
VISUALIZE_WAVEFORM = "visualize_waveform"
|
|
465
|
+
MEDIA_CREATION_DATE_AS_OFFSET = "media_creation_date_as_offset"
|
|
431
466
|
|
|
467
|
+
MEDIA_SCAN_SAMPLING_DURATION = "media_scan_sampling_duration"
|
|
432
468
|
IMAGE_DISPLAY_DURATION = "image_display_duration"
|
|
433
469
|
|
|
434
470
|
# plot type
|
|
@@ -436,6 +472,9 @@ WAVEFORM_PLOT = "waveform"
|
|
|
436
472
|
SPECTROGRAM_PLOT = "spectrogram"
|
|
437
473
|
EVENTS_PLOT = "plot_events"
|
|
438
474
|
|
|
475
|
+
PLAYING = "playing"
|
|
476
|
+
PAUSED = "paused"
|
|
477
|
+
STOPPED = "stopped"
|
|
439
478
|
|
|
440
479
|
POINT_EVENT_ST_DURATION = 0.5
|
|
441
480
|
|
|
@@ -446,6 +485,8 @@ SLIDER_MAXIMUM = 1000
|
|
|
446
485
|
|
|
447
486
|
FRAME_DEFAULT_CACHE_SIZE = 1
|
|
448
487
|
|
|
488
|
+
EXCLUDED = "excluded"
|
|
489
|
+
|
|
449
490
|
# modifiers
|
|
450
491
|
MODIFIERS = "modifiers"
|
|
451
492
|
SINGLE_SELECTION = 0
|
|
@@ -489,6 +530,16 @@ NO_COLOR_CODING_PAD = "#777777"
|
|
|
489
530
|
SPECTROGRAM_COLOR_MAPS = ["viridis", "inferno", "plasma", "magma", "gray", "YlOrRd"]
|
|
490
531
|
SPECTROGRAM_DEFAULT_COLOR_MAP = "viridis"
|
|
491
532
|
SPECTROGRAM_DEFAULT_TIME_INTERVAL = 10
|
|
533
|
+
SPECTROGRAM_WINDOW_TYPE = "SPECTROGRAM_WINDOW_TYPE"
|
|
534
|
+
SPECTROGRAM_DEFAULT_WINDOW_TYPE = "hanning"
|
|
535
|
+
SPECTROGRAM_NFFT = "SPECTROGRAM_NFFT"
|
|
536
|
+
SPECTROGRAM_DEFAULT_NFFT = "1024"
|
|
537
|
+
SPECTROGRAM_NOVERLAP = "SPECTROGRAM_NOVERLAP"
|
|
538
|
+
SPECTROGRAM_DEFAULT_NOVERLAP = 900
|
|
539
|
+
SPECTROGRAM_VMIN = "SPECTROGRAM_VMIN"
|
|
540
|
+
SPECTROGRAM_DEFAULT_VMIN = -100
|
|
541
|
+
SPECTROGRAM_VMAX = "SPECTROGRAM_VMAX"
|
|
542
|
+
SPECTROGRAM_DEFAULT_VMAX = -20
|
|
492
543
|
|
|
493
544
|
# see matplotlib.colors.cnames.keys()
|
|
494
545
|
# https://xkcd.com/color/rgb/
|
|
@@ -663,6 +714,7 @@ EMPTY_PROJECT = {
|
|
|
663
714
|
ETHOGRAM: {},
|
|
664
715
|
OBSERVATIONS: {},
|
|
665
716
|
BEHAVIORAL_CATEGORIES: [],
|
|
717
|
+
BEHAVIORAL_CATEGORIES_CONF: {},
|
|
666
718
|
INDEPENDENT_VARIABLES: {},
|
|
667
719
|
CODING_MAP: {},
|
|
668
720
|
BEHAVIORS_CODING_MAP: [],
|
|
@@ -683,10 +735,10 @@ INIT_PARAM = {
|
|
|
683
735
|
SDIS_EXT = "sds"
|
|
684
736
|
TBS_EXT = "tbs"
|
|
685
737
|
TSV_EXT = "tsv"
|
|
686
|
-
CSV_EXT = "
|
|
738
|
+
CSV_EXT = "csv"
|
|
687
739
|
RDS_EXT = "rds"
|
|
688
740
|
PANDAS_DF_EXT = "pkl"
|
|
689
|
-
|
|
741
|
+
HTML_EXT = "html"
|
|
690
742
|
SQL_EXT = "sql"
|
|
691
743
|
ODS_EXT = "ods"
|
|
692
744
|
XLS_EXT = "xls"
|
|
@@ -716,7 +768,7 @@ FILE_NAME_SUFFIX = {
|
|
|
716
768
|
XLSX: XLSX_EXT,
|
|
717
769
|
XLSX_WB: XLSX_EXT,
|
|
718
770
|
XLS: XLS_EXT,
|
|
719
|
-
HTML:
|
|
771
|
+
HTML: HTML_EXT,
|
|
720
772
|
PANDAS_DF: PANDAS_DF_EXT,
|
|
721
773
|
RDS: RDS_EXT,
|
|
722
774
|
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:
|
|
@@ -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:
|