boris-behav-obs 8.12__py3-none-any.whl → 9.7.6__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.
Potentially problematic release.
This version of boris-behav-obs might be problematic. Click here for more details.
- boris/__init__.py +1 -1
- boris/__main__.py +1 -1
- boris/about.py +28 -39
- boris/add_modifier.py +122 -109
- boris/add_modifier_ui.py +239 -135
- boris/advanced_event_filtering.py +81 -45
- 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 +42 -49
- boris/config.py +141 -65
- boris/config_file.py +58 -67
- boris/connections.py +107 -61
- boris/converters.py +13 -37
- boris/converters_ui.py +187 -110
- boris/cooccurence.py +250 -0
- boris/core.py +2373 -1786
- boris/core_qrc.py +15895 -10743
- boris/core_ui.py +943 -798
- boris/db_functions.py +17 -42
- boris/dev.py +109 -8
- boris/dialog.py +482 -236
- boris/duration_widget.py +9 -14
- boris/edit_event.py +61 -31
- boris/edit_event_ui.py +208 -97
- boris/event_operations.py +408 -293
- boris/events_cursor.py +25 -17
- boris/events_snapshots.py +36 -82
- boris/exclusion_matrix.py +4 -9
- boris/export_events.py +184 -223
- boris/export_observation.py +74 -100
- boris/external_processes.py +123 -98
- boris/geometric_measurement.py +644 -290
- 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 +17 -6
- boris/modifier_coding_map_creator.py +1013 -0
- boris/modifiers_coding_map.py +7 -9
- boris/mpv.py +1 -0
- boris/mpv2.py +732 -705
- boris/observation.py +533 -221
- boris/observation_operations.py +1025 -390
- boris/observation_ui.py +572 -362
- boris/observations_list.py +71 -53
- boris/otx_parser.py +74 -68
- boris/param_panel.py +31 -16
- boris/param_panel_ui.py +254 -138
- boris/player_dock_widget.py +90 -60
- boris/plot_data_module.py +25 -33
- boris/plot_events.py +127 -90
- boris/plot_events_rt.py +17 -31
- boris/plot_spectrogram_rt.py +95 -30
- boris/plot_waveform_rt.py +32 -21
- 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 +306 -83
- boris/preferences_ui.py +684 -227
- boris/project.py +448 -293
- boris/project_functions.py +671 -238
- boris/project_import_export.py +213 -222
- boris/project_ui.py +674 -438
- boris/qrc_boris.py +6 -3
- boris/qrc_boris5.py +6 -3
- boris/select_modifiers.py +74 -48
- boris/select_observations.py +20 -198
- boris/select_subj_behav.py +67 -39
- boris/state_events.py +52 -35
- boris/subjects_pad.py +6 -9
- boris/synthetic_time_budget.py +45 -28
- boris/time_budget_functions.py +171 -171
- boris/time_budget_widget.py +84 -114
- boris/transitions.py +41 -47
- boris/utilities.py +627 -236
- boris/version.py +3 -3
- boris/video_equalizer.py +16 -14
- boris/video_equalizer_ui.py +199 -130
- boris/video_operations.py +95 -29
- boris/view_df.py +104 -0
- boris/view_df_ui.py +75 -0
- boris/write_event.py +538 -0
- boris_behav_obs-9.7.6.dist-info/METADATA +139 -0
- boris_behav_obs-9.7.6.dist-info/RECORD +109 -0
- {boris_behav_obs-8.12.dist-info → boris_behav_obs-9.7.6.dist-info}/WHEEL +1 -1
- boris_behav_obs-9.7.6.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 -36
- boris/core.ui +0 -1556
- boris/edit_event.ui +0 -233
- boris/icons/logo_eye.ico +0 -0
- boris/map_creator.py +0 -850
- boris/observation.ui +0 -814
- boris/param_panel.ui +0 -379
- boris/preferences.ui +0 -537
- boris/project.ui +0 -1069
- boris/project_server.py +0 -236
- boris/vlc.py +0 -10343
- boris/vlc_local.py +0 -90
- boris_behav_obs-8.12.dist-info/LICENSE.TXT +0 -674
- boris_behav_obs-8.12.dist-info/METADATA +0 -128
- boris_behav_obs-8.12.dist-info/RECORD +0 -108
- boris_behav_obs-8.12.dist-info/entry_points.txt +0 -3
- {boris → boris_behav_obs-9.7.6.dist-info/licenses}/LICENSE.TXT +0 -0
- {boris_behav_obs-8.12.dist-info → boris_behav_obs-9.7.6.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,9 +52,14 @@ MAX_UNDO_QUEUE: int = 25
|
|
|
37
52
|
|
|
38
53
|
NA: str = "NA"
|
|
39
54
|
|
|
40
|
-
|
|
55
|
+
REALTIME_PLOT_CURSOR_COLOR: str = "red"
|
|
56
|
+
|
|
57
|
+
DARKER_DIFFERENCE = 5
|
|
41
58
|
|
|
42
|
-
|
|
59
|
+
CTRL_KEY: str = "Ctrl"
|
|
60
|
+
ALT_KEY: str = "Alt"
|
|
61
|
+
|
|
62
|
+
SPECTRO_TIMER: int = 500
|
|
43
63
|
|
|
44
64
|
function_keys = {
|
|
45
65
|
16777264: "F1",
|
|
@@ -68,10 +88,12 @@ EVENTS = "events"
|
|
|
68
88
|
TIME_OFFSET = "time offset"
|
|
69
89
|
|
|
70
90
|
CODING_MAP = "coding_map"
|
|
91
|
+
CODING_MAP_sp = "coding map" # space between words (no underscore)
|
|
71
92
|
BEHAVIORS_CODING_MAP = "behaviors_coding_map"
|
|
72
93
|
SUBJECTS = "subjects_conf"
|
|
73
94
|
ETHOGRAM = "behaviors_conf"
|
|
74
95
|
BEHAVIORAL_CATEGORIES = "behavioral_categories"
|
|
96
|
+
BEHAVIORAL_CATEGORIES_CONF = "behavioral_categories_config"
|
|
75
97
|
CONVERTERS = "converters"
|
|
76
98
|
|
|
77
99
|
OFFSET = "offset"
|
|
@@ -110,20 +132,34 @@ POINT_EVENT_PLOT_COLOR = "black"
|
|
|
110
132
|
|
|
111
133
|
CHAR_FORBIDDEN_IN_MODIFIERS = "(|),`~"
|
|
112
134
|
|
|
135
|
+
FAST_FORWARD_DEFAULT_VALUE: float = 10.0
|
|
136
|
+
|
|
113
137
|
ADAPT_FAST_JUMP = "adapt_fast_jump"
|
|
114
138
|
ADAPT_FAST_JUMP_DEFAULT = False
|
|
115
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
|
+
|
|
116
149
|
|
|
117
|
-
subjectsFields = [
|
|
150
|
+
subjectsFields = [SUBJECT_KEY, SUBJECT_NAME, DESCRIPTION]
|
|
118
151
|
|
|
119
152
|
UNPAIRED = "UNPAIRED"
|
|
120
153
|
DISPLAY_SUBTITLES = "display_subtitles"
|
|
154
|
+
CHECK_PROJECT_INTEGRITY = "check_project_integrity"
|
|
121
155
|
|
|
122
156
|
|
|
123
157
|
YES = "Yes"
|
|
124
158
|
NO = "No"
|
|
125
159
|
CANCEL = "Cancel"
|
|
160
|
+
IGNORE = "Ignore"
|
|
126
161
|
APPEND = "Append"
|
|
162
|
+
CLOSE = "Close"
|
|
127
163
|
REPLACE = "Replace"
|
|
128
164
|
REMOVE = "Remove"
|
|
129
165
|
SAVE = "Save"
|
|
@@ -138,6 +174,7 @@ NO_FOCAL_SUBJECT = "No focal subject"
|
|
|
138
174
|
|
|
139
175
|
TYPE = "type"
|
|
140
176
|
FILE = "file"
|
|
177
|
+
COLOR = "color"
|
|
141
178
|
DIRECTORIES_LIST = "directories_list"
|
|
142
179
|
|
|
143
180
|
SAVE_DATASET = 32
|
|
@@ -167,13 +204,6 @@ DATA_PLOT_FIELDS = {
|
|
|
167
204
|
}
|
|
168
205
|
DATA_PLOT_STYLES = ["b-", "r-", "g-", "bo", "ro", "go"]
|
|
169
206
|
|
|
170
|
-
TIME = "time"
|
|
171
|
-
BEHAVIOR_CODE = "code"
|
|
172
|
-
SUBJECT = "subject"
|
|
173
|
-
MODIFIER = "modifier"
|
|
174
|
-
COMMENT = "comment"
|
|
175
|
-
BEHAVIOR_KEY = "key"
|
|
176
|
-
BEHAVIOR_CATEGORY = "category"
|
|
177
207
|
|
|
178
208
|
FILE_PATH = "file_path"
|
|
179
209
|
|
|
@@ -182,36 +212,29 @@ IMAGE_PATH = "image path"
|
|
|
182
212
|
FRAME_INDEX = "frame index"
|
|
183
213
|
|
|
184
214
|
ZOOM_LEVEL = "zoom level"
|
|
215
|
+
PAN_X = "pan-x"
|
|
216
|
+
PAN_Y = "pan-y"
|
|
185
217
|
ROTATION_ANGLE = "rotation angle"
|
|
186
218
|
DISPLAY_MEDIA_SUBTITLES = "display subtitles"
|
|
187
219
|
OVERLAY = "video overlay"
|
|
188
220
|
|
|
189
221
|
|
|
190
222
|
USE_EXIF_DATE = "use_exif_date"
|
|
223
|
+
SUBSTRACT_FIRST_EXIF_DATE = "substract_first_exif_date"
|
|
191
224
|
TIME_LAPSE = "time_lapse_delay"
|
|
192
225
|
|
|
193
226
|
|
|
194
227
|
# fields for event configuration
|
|
195
|
-
"""
|
|
196
|
-
fields = {
|
|
197
|
-
"type": 0,
|
|
198
|
-
"key": 1,
|
|
199
|
-
"code": 2,
|
|
200
|
-
"description": 3,
|
|
201
|
-
"modifiers": 4,
|
|
202
|
-
"excluded": 5,
|
|
203
|
-
"coding map": 6,
|
|
204
|
-
}
|
|
205
|
-
"""
|
|
206
228
|
|
|
207
229
|
ETHOGRAM_TABLE_COLUMNS: dict = {
|
|
208
230
|
0: "key",
|
|
209
231
|
1: "code",
|
|
210
232
|
2: "type",
|
|
211
233
|
3: "description",
|
|
212
|
-
4: "
|
|
213
|
-
5: "
|
|
214
|
-
6: "
|
|
234
|
+
4: "color",
|
|
235
|
+
5: "category",
|
|
236
|
+
6: "modifiers",
|
|
237
|
+
7: "excluded",
|
|
215
238
|
}
|
|
216
239
|
|
|
217
240
|
# fields in ethogram table from project window
|
|
@@ -220,23 +243,12 @@ behavioursFields: dict = {
|
|
|
220
243
|
"key": 1,
|
|
221
244
|
"code": 2,
|
|
222
245
|
"description": 3,
|
|
223
|
-
"
|
|
224
|
-
"
|
|
225
|
-
"
|
|
226
|
-
"
|
|
246
|
+
"color": 4,
|
|
247
|
+
"category": 5,
|
|
248
|
+
"modifiers": 6,
|
|
249
|
+
"excluded": 7,
|
|
250
|
+
"coding map": 8,
|
|
227
251
|
}
|
|
228
|
-
"""
|
|
229
|
-
ETHOGRAM_FIELDS = [
|
|
230
|
-
"type",
|
|
231
|
-
"key",
|
|
232
|
-
"code",
|
|
233
|
-
"description",
|
|
234
|
-
"category",
|
|
235
|
-
"modifiers",
|
|
236
|
-
"excluded",
|
|
237
|
-
"coding map",
|
|
238
|
-
]
|
|
239
|
-
"""
|
|
240
252
|
ETHOGRAM_EDITABLE_FIELDS: tuple = ("key", "code", "description")
|
|
241
253
|
|
|
242
254
|
PROJECT_BEHAVIORS_KEY_FIELD_IDX = 1
|
|
@@ -246,13 +258,20 @@ MEDIA_FILE_PATH_IDX = 2
|
|
|
246
258
|
HAS_AUDIO_IDX = 6
|
|
247
259
|
|
|
248
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
|
+
|
|
249
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]
|
|
250
269
|
|
|
251
270
|
BEHAVIOR_TYPES = [
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
271
|
+
POINT_EVENT,
|
|
272
|
+
STATE_EVENT,
|
|
273
|
+
POINT_EVENT_WITH_CODING_MAP,
|
|
274
|
+
STATE_EVENT_WITH_CODING_MAP,
|
|
256
275
|
]
|
|
257
276
|
|
|
258
277
|
DEFAULT_BEHAVIOR_TYPE = "Point event"
|
|
@@ -264,7 +283,7 @@ MEDIA_TW_EVENTS_FIELDS_DEFAULT = ("time", FRAME_INDEX, "subject", "code", "type"
|
|
|
264
283
|
MEDIA_TW_EVENTS_FIELDS = ("time", FRAME_INDEX, "subject", "code", "type", "modifier", "comment")
|
|
265
284
|
# MEDIA_TW_EVENTS_FIELDS = ("time", "subject", "code", "type", "modifier", "comment")
|
|
266
285
|
LIVE_TW_EVENTS_FIELDS = ("time", "subject", "code", "type", "modifier", "comment")
|
|
267
|
-
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)
|
|
268
287
|
|
|
269
288
|
TW_EVENTS_FIELDS = {
|
|
270
289
|
MEDIA: MEDIA_TW_EVENTS_FIELDS,
|
|
@@ -286,7 +305,7 @@ for observation_type in TW_EVENTS_FIELDS:
|
|
|
286
305
|
# fields for project events list
|
|
287
306
|
MEDIA_PJ_EVENTS_FIELDS = (TIME, "subject", "code", "modifier", "comment", FRAME_INDEX)
|
|
288
307
|
LIVE_PJ_EVENTS_FIELDS = (TIME, "subject", "code", "modifier", "comment")
|
|
289
|
-
IMAGES_PJ_EVENTS_FIELDS = (TIME, "subject", "code", "modifier", "comment",
|
|
308
|
+
IMAGES_PJ_EVENTS_FIELDS = (TIME, "subject", "code", "modifier", "comment", IMAGE_INDEX, IMAGE_PATH)
|
|
290
309
|
|
|
291
310
|
PJ_EVENTS_FIELDS = {
|
|
292
311
|
MEDIA: MEDIA_PJ_EVENTS_FIELDS,
|
|
@@ -297,9 +316,6 @@ PJ_EVENTS_FIELDS = {
|
|
|
297
316
|
VIEWER_IMAGES: IMAGES_PJ_EVENTS_FIELDS,
|
|
298
317
|
}
|
|
299
318
|
|
|
300
|
-
# fields for independent variable definition
|
|
301
|
-
tw_indVarFields = ["label", "description", "type", "default value", "possible values"]
|
|
302
|
-
|
|
303
319
|
|
|
304
320
|
PJ_OBS_FIELDS = {}
|
|
305
321
|
for observation_type in PJ_EVENTS_FIELDS:
|
|
@@ -307,12 +323,17 @@ for observation_type in PJ_EVENTS_FIELDS:
|
|
|
307
323
|
for idx, field in enumerate(PJ_EVENTS_FIELDS[observation_type]):
|
|
308
324
|
PJ_OBS_FIELDS[observation_type][field] = idx
|
|
309
325
|
|
|
326
|
+
|
|
327
|
+
# fields for independent variable definition
|
|
328
|
+
tw_indVarFields = ["label", "description", "type", "default value", "possible values"]
|
|
329
|
+
|
|
330
|
+
|
|
310
331
|
EVENT_TIME_FIELD_IDX = 0
|
|
311
332
|
EVENT_SUBJECT_FIELD_IDX = 1
|
|
312
333
|
EVENT_BEHAVIOR_FIELD_IDX = 2
|
|
313
334
|
EVENT_MODIFIER_FIELD_IDX = 3
|
|
314
335
|
EVENT_COMMENT_FIELD_IDX = 4
|
|
315
|
-
EVENT_STATUS_FIELD_IDX =
|
|
336
|
+
EVENT_STATUS_FIELD_IDX = -1
|
|
316
337
|
# EVENT_IMAGEIDX_FIELD_IDX = 6
|
|
317
338
|
# EVENT_IMAGEPATH_FIELD_IDX = 7
|
|
318
339
|
|
|
@@ -337,6 +358,14 @@ START_FROM_CURRENT_EPOCH_TIME = "start_from_current_epoch_time"
|
|
|
337
358
|
|
|
338
359
|
SCAN_SAMPLING_TIME = "scan_sampling_time"
|
|
339
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
|
+
|
|
340
369
|
NEW = "new"
|
|
341
370
|
LIST = "list"
|
|
342
371
|
EDIT = "edit"
|
|
@@ -356,6 +385,7 @@ SELECTED_BEHAVIORS = "selected behaviors"
|
|
|
356
385
|
SELECTED_SUBJECTS = "selected subjects"
|
|
357
386
|
INCLUDE_MODIFIERS = "include modifiers"
|
|
358
387
|
EXCLUDE_BEHAVIORS = "exclude behaviors"
|
|
388
|
+
EXCLUDE_NON_CODED_MODIFIERS = "exclude_non_coded_modifiers"
|
|
359
389
|
EXCLUDED_BEHAVIORS = "excluded behaviors"
|
|
360
390
|
TIME_INTERVAL = "time"
|
|
361
391
|
START_TIME = "start time"
|
|
@@ -373,6 +403,7 @@ TIMESTAMP_idx = 3
|
|
|
373
403
|
|
|
374
404
|
TIME_FULL_OBS = "full obs"
|
|
375
405
|
TIME_EVENTS = "limit to events"
|
|
406
|
+
TIME_OBS_INTERVAL = "interval of observation"
|
|
376
407
|
TIME_ARBITRARY_INTERVAL = "time interval"
|
|
377
408
|
|
|
378
409
|
AVAILABLE_INDEP_VAR_TYPES = [NUMERIC, TEXT, SET_OF_VALUES, TIMESTAMP]
|
|
@@ -382,16 +413,31 @@ OBSERVATIONS = "observations"
|
|
|
382
413
|
|
|
383
414
|
CLOSE_BEHAVIORS_BETWEEN_VIDEOS = "close_behaviors_between_videos"
|
|
384
415
|
|
|
385
|
-
|
|
386
|
-
MPV_HWDEC_DEFAULT_VALUE = "auto"
|
|
416
|
+
# MPV hardware decode
|
|
387
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
|
|
388
427
|
|
|
428
|
+
ANALYSIS_PLUGINS = "analysis_plugins"
|
|
429
|
+
EXCLUDED_PLUGINS = "excluded_plugins"
|
|
430
|
+
PERSONAL_PLUGINS_DIR = "personal_plugins_dir"
|
|
389
431
|
|
|
390
432
|
PROJECT_FILE_INDENTATION = "project file indentation"
|
|
391
433
|
PROJECT_FILE_INDENTATION_COMBO_OPTIONS = ("None", "Newline", "Tab", "2 spaces", "4 spaces")
|
|
392
434
|
PROJECT_FILE_INDENTATION_OPTIONS = (None, 0, "\t", 2, 4)
|
|
393
435
|
PROJECT_FILE_INDENTATION_DEFAULT_VALUE = None
|
|
394
436
|
|
|
437
|
+
TOOLBAR_ICON_SIZE = "toolbar icon size"
|
|
438
|
+
DEFAULT_TOOLBAR_ICON_SIZE_VALUE = 24
|
|
439
|
+
|
|
440
|
+
|
|
395
441
|
VIDEO_VIEWER = 0
|
|
396
442
|
PICTURE_VIEWER = 1
|
|
397
443
|
|
|
@@ -408,6 +454,7 @@ LENGTH = "length"
|
|
|
408
454
|
FPS = "fps"
|
|
409
455
|
HAS_AUDIO = "hasAudio"
|
|
410
456
|
HAS_VIDEO = "hasVideo"
|
|
457
|
+
MEDIA_CREATION_TIME = "media_creation_time"
|
|
411
458
|
|
|
412
459
|
STATE = "STATE"
|
|
413
460
|
POINT = "POINT"
|
|
@@ -415,12 +462,15 @@ POINT = "POINT"
|
|
|
415
462
|
START = "START"
|
|
416
463
|
STOP = "STOP"
|
|
417
464
|
|
|
418
|
-
PLAYER1
|
|
465
|
+
PLAYER1 = "1"
|
|
466
|
+
PLAYER2 = "2"
|
|
419
467
|
ALL_PLAYERS = [str(x + 1) for x in range(N_PLAYER)]
|
|
420
468
|
|
|
421
469
|
VISUALIZE_SPECTROGRAM = "visualize_spectrogram"
|
|
422
470
|
VISUALIZE_WAVEFORM = "visualize_waveform"
|
|
471
|
+
MEDIA_CREATION_DATE_AS_OFFSET = "media_creation_date_as_offset"
|
|
423
472
|
|
|
473
|
+
MEDIA_SCAN_SAMPLING_DURATION = "media_scan_sampling_duration"
|
|
424
474
|
IMAGE_DISPLAY_DURATION = "image_display_duration"
|
|
425
475
|
|
|
426
476
|
# plot type
|
|
@@ -428,6 +478,9 @@ WAVEFORM_PLOT = "waveform"
|
|
|
428
478
|
SPECTROGRAM_PLOT = "spectrogram"
|
|
429
479
|
EVENTS_PLOT = "plot_events"
|
|
430
480
|
|
|
481
|
+
PLAYING = "playing"
|
|
482
|
+
PAUSED = "paused"
|
|
483
|
+
STOPPED = "stopped"
|
|
431
484
|
|
|
432
485
|
POINT_EVENT_ST_DURATION = 0.5
|
|
433
486
|
|
|
@@ -438,6 +491,8 @@ SLIDER_MAXIMUM = 1000
|
|
|
438
491
|
|
|
439
492
|
FRAME_DEFAULT_CACHE_SIZE = 1
|
|
440
493
|
|
|
494
|
+
EXCLUDED = "excluded"
|
|
495
|
+
|
|
441
496
|
# modifiers
|
|
442
497
|
MODIFIERS = "modifiers"
|
|
443
498
|
SINGLE_SELECTION = 0
|
|
@@ -481,6 +536,16 @@ NO_COLOR_CODING_PAD = "#777777"
|
|
|
481
536
|
SPECTROGRAM_COLOR_MAPS = ["viridis", "inferno", "plasma", "magma", "gray", "YlOrRd"]
|
|
482
537
|
SPECTROGRAM_DEFAULT_COLOR_MAP = "viridis"
|
|
483
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
|
|
484
549
|
|
|
485
550
|
# see matplotlib.colors.cnames.keys()
|
|
486
551
|
# https://xkcd.com/color/rgb/
|
|
@@ -655,6 +720,7 @@ EMPTY_PROJECT = {
|
|
|
655
720
|
ETHOGRAM: {},
|
|
656
721
|
OBSERVATIONS: {},
|
|
657
722
|
BEHAVIORAL_CATEGORIES: [],
|
|
723
|
+
BEHAVIORAL_CATEGORIES_CONF: {},
|
|
658
724
|
INDEPENDENT_VARIABLES: {},
|
|
659
725
|
CODING_MAP: {},
|
|
660
726
|
BEHAVIORS_CODING_MAP: [],
|
|
@@ -670,10 +736,20 @@ INIT_PARAM = {
|
|
|
670
736
|
MPV_HWDEC: MPV_HWDEC_DEFAULT_VALUE,
|
|
671
737
|
PROJECT_FILE_INDENTATION: PROJECT_FILE_INDENTATION_DEFAULT_VALUE,
|
|
672
738
|
f"{MEDIA} tw fields": MEDIA_TW_EVENTS_FIELDS_DEFAULT,
|
|
739
|
+
# FRAME_STEP_SIZE: FRAME_STEP_SIZE_DEFAULT_VALUE,
|
|
673
740
|
}
|
|
674
741
|
|
|
675
742
|
SDIS_EXT = "sds"
|
|
676
743
|
TBS_EXT = "tbs"
|
|
744
|
+
TSV_EXT = "tsv"
|
|
745
|
+
CSV_EXT = "csv"
|
|
746
|
+
RDS_EXT = "rds"
|
|
747
|
+
PANDAS_DF_EXT = "pkl"
|
|
748
|
+
HTML_EXT = "html"
|
|
749
|
+
SQL_EXT = "sql"
|
|
750
|
+
ODS_EXT = "ods"
|
|
751
|
+
XLS_EXT = "xls"
|
|
752
|
+
XLSX_EXT = "xlsx"
|
|
677
753
|
|
|
678
754
|
# Output format
|
|
679
755
|
TSV = "Tab Separated Values (*.tsv)"
|
|
@@ -692,17 +768,17 @@ TBS = "Timed Behavioral Sequences (*.tbs)"
|
|
|
692
768
|
TEXT_FILE = "Text file"
|
|
693
769
|
|
|
694
770
|
FILE_NAME_SUFFIX = {
|
|
695
|
-
TSV:
|
|
696
|
-
CSV:
|
|
697
|
-
ODS:
|
|
698
|
-
ODS_WB:
|
|
699
|
-
XLSX:
|
|
700
|
-
XLSX_WB:
|
|
701
|
-
XLS:
|
|
702
|
-
HTML:
|
|
703
|
-
PANDAS_DF:
|
|
704
|
-
RDS:
|
|
705
|
-
SQL:
|
|
771
|
+
TSV: TSV_EXT,
|
|
772
|
+
CSV: CSV_EXT,
|
|
773
|
+
ODS: ODS_EXT,
|
|
774
|
+
ODS_WB: ODS_EXT,
|
|
775
|
+
XLSX: XLSX_EXT,
|
|
776
|
+
XLSX_WB: XLSX_EXT,
|
|
777
|
+
XLS: XLS_EXT,
|
|
778
|
+
HTML: HTML_EXT,
|
|
779
|
+
PANDAS_DF: PANDAS_DF_EXT,
|
|
780
|
+
RDS: RDS_EXT,
|
|
781
|
+
SQL: SQL_EXT,
|
|
706
782
|
SDIS: SDIS_EXT,
|
|
707
783
|
TBS: TBS_EXT,
|
|
708
784
|
TEXT_FILE: "cli",
|
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:
|