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/transitions.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
|
|
|
@@ -24,9 +24,9 @@ import logging
|
|
|
24
24
|
import os
|
|
25
25
|
import subprocess
|
|
26
26
|
import tempfile
|
|
27
|
-
from
|
|
27
|
+
from pathlib import Path
|
|
28
28
|
|
|
29
|
-
from
|
|
29
|
+
from PySide6.QtWidgets import QFileDialog, QMessageBox
|
|
30
30
|
|
|
31
31
|
from . import config as cfg
|
|
32
32
|
from . import dialog, export_observation, select_subj_behav
|
|
@@ -135,17 +135,15 @@ def create_transitions_gv_from_matrix(matrix, cutoff_all=0, cutoff_behavior=0, e
|
|
|
135
135
|
else:
|
|
136
136
|
transitions[row.split("\t")[0]][behaviours[idx]] = int(r)
|
|
137
137
|
|
|
138
|
-
transitions_total_number = sum([sum(transitions[x].values()) for x in transitions])
|
|
138
|
+
"""transitions_total_number = sum([sum(transitions[x].values()) for x in transitions])"""
|
|
139
139
|
|
|
140
140
|
out = "digraph G { \n"
|
|
141
141
|
|
|
142
142
|
for behaviour1 in behaviours:
|
|
143
143
|
for behaviour2 in behaviours:
|
|
144
|
-
|
|
145
144
|
if behaviour1 not in transitions or behaviour2 not in transitions:
|
|
146
145
|
return True, "Error: the file does not seem a transition matrix"
|
|
147
146
|
if transitions[behaviour1][behaviour2]:
|
|
148
|
-
|
|
149
147
|
if edge_label == "percent_node":
|
|
150
148
|
if transitions[behaviour1][behaviour2] > cutoff_all:
|
|
151
149
|
out += '"{behaviour1}" -> "{behaviour2}" [label="{label:0.3f}"];\n'.format(
|
|
@@ -173,6 +171,8 @@ def transitions_matrix(self, mode):
|
|
|
173
171
|
* number
|
|
174
172
|
* frequencies_after_behaviors
|
|
175
173
|
"""
|
|
174
|
+
logging.debug("flag transitions_matrix function")
|
|
175
|
+
|
|
176
176
|
# ask user observations to analyze
|
|
177
177
|
_, selected_observations = select_observations.select_observations2(
|
|
178
178
|
self, cfg.MULTIPLE, windows_title="Select observations for transitions matrix"
|
|
@@ -184,8 +184,8 @@ def transitions_matrix(self, mode):
|
|
|
184
184
|
parameters = select_subj_behav.choose_obs_subj_behav_category(
|
|
185
185
|
self,
|
|
186
186
|
selected_observations,
|
|
187
|
-
|
|
188
|
-
|
|
187
|
+
show_include_modifiers=True,
|
|
188
|
+
show_exclude_non_coded_behaviors=False,
|
|
189
189
|
n_observations=len(selected_observations),
|
|
190
190
|
)
|
|
191
191
|
|
|
@@ -197,21 +197,20 @@ def transitions_matrix(self, mode):
|
|
|
197
197
|
|
|
198
198
|
flagMulti = False
|
|
199
199
|
if len(parameters[cfg.SELECTED_SUBJECTS]) == 1:
|
|
200
|
-
|
|
201
|
-
fn = QFileDialog().getSaveFileName(
|
|
200
|
+
file_name, _ = QFileDialog().getSaveFileName(
|
|
202
201
|
None,
|
|
203
202
|
"Create matrix of transitions " + mode,
|
|
204
203
|
"",
|
|
205
204
|
"Transitions matrix files (*.txt *.tsv);;All files (*)",
|
|
206
205
|
)
|
|
207
|
-
|
|
208
|
-
|
|
206
|
+
if not file_name:
|
|
207
|
+
return
|
|
209
208
|
else:
|
|
210
|
-
exportDir = QFileDialog
|
|
209
|
+
exportDir = QFileDialog.getExistingDirectory(
|
|
211
210
|
self,
|
|
212
211
|
"Choose a directory to save the transitions matrices",
|
|
213
|
-
|
|
214
|
-
options=QFileDialog
|
|
212
|
+
str(Path.home()),
|
|
213
|
+
options=QFileDialog.ShowDirsOnly,
|
|
215
214
|
)
|
|
216
215
|
if not exportDir:
|
|
217
216
|
return
|
|
@@ -219,15 +218,12 @@ def transitions_matrix(self, mode):
|
|
|
219
218
|
|
|
220
219
|
flag_overwrite_all = False
|
|
221
220
|
for subject in parameters[cfg.SELECTED_SUBJECTS]:
|
|
222
|
-
|
|
223
221
|
logging.debug(f"subjects: {subject}")
|
|
224
222
|
|
|
225
223
|
strings_list = []
|
|
226
224
|
for obs_id in selected_observations:
|
|
227
225
|
strings_list.append(
|
|
228
|
-
export_observation.events_to_behavioral_sequences(
|
|
229
|
-
self.pj, obs_id, subject, parameters, self.behav_seq_separator
|
|
230
|
-
)
|
|
226
|
+
export_observation.events_to_behavioral_sequences(self.pj, obs_id, subject, parameters, self.behav_seq_separator)
|
|
231
227
|
)
|
|
232
228
|
|
|
233
229
|
sequences, observed_behaviors = behavioral_strings_analysis(strings_list, self.behav_seq_separator)
|
|
@@ -244,7 +240,6 @@ def transitions_matrix(self, mode):
|
|
|
244
240
|
|
|
245
241
|
if flagMulti:
|
|
246
242
|
try:
|
|
247
|
-
|
|
248
243
|
nf = f"{exportDir}{os.sep}{subject}_transitions_{mode}_matrix.tsv"
|
|
249
244
|
|
|
250
245
|
if os.path.isfile(nf) and not flag_overwrite_all:
|
|
@@ -264,11 +259,11 @@ def transitions_matrix(self, mode):
|
|
|
264
259
|
QMessageBox.critical(self, cfg.programName, f"The file {nf} can not be saved")
|
|
265
260
|
else:
|
|
266
261
|
try:
|
|
267
|
-
with open(
|
|
262
|
+
with open(file_name, "w") as outfile:
|
|
268
263
|
outfile.write(observed_matrix)
|
|
269
264
|
|
|
270
265
|
except Exception:
|
|
271
|
-
QMessageBox.critical(self, cfg.programName, f"The file {
|
|
266
|
+
QMessageBox.critical(self, cfg.programName, f"The file {file_name} can not be saved")
|
|
272
267
|
|
|
273
268
|
|
|
274
269
|
def transitions_dot_script():
|
|
@@ -276,21 +271,18 @@ def transitions_dot_script():
|
|
|
276
271
|
create dot script (graphviz language) from transitions frequencies matrix
|
|
277
272
|
"""
|
|
278
273
|
|
|
279
|
-
|
|
274
|
+
file_names, _ = QFileDialog().getOpenFileNames(
|
|
280
275
|
None,
|
|
281
276
|
"Select one or more transitions matrix files",
|
|
282
277
|
"",
|
|
283
278
|
"Transitions matrix files (*.txt *.tsv);;All files (*)",
|
|
284
279
|
)
|
|
285
|
-
fileNames = fn[0] if type(fn) is tuple else fn
|
|
286
280
|
|
|
287
281
|
out = ""
|
|
288
282
|
|
|
289
|
-
for
|
|
290
|
-
with open(
|
|
291
|
-
result, gv = create_transitions_gv_from_matrix(
|
|
292
|
-
infile.read(), cutoff_all=0, cutoff_behavior=0, edge_label="percent_node"
|
|
293
|
-
)
|
|
283
|
+
for file_name in file_names:
|
|
284
|
+
with open(file_name, "r") as infile:
|
|
285
|
+
result, gv = create_transitions_gv_from_matrix(infile.read(), cutoff_all=0, cutoff_behavior=0, edge_label="percent_node")
|
|
294
286
|
if result:
|
|
295
287
|
QMessageBox.critical(
|
|
296
288
|
None,
|
|
@@ -299,16 +291,24 @@ def transitions_dot_script():
|
|
|
299
291
|
)
|
|
300
292
|
return
|
|
301
293
|
|
|
302
|
-
|
|
303
|
-
|
|
294
|
+
try:
|
|
295
|
+
with open(file_name + ".gv", "w") as file_out:
|
|
296
|
+
file_out.write(gv)
|
|
297
|
+
except Exception:
|
|
298
|
+
QMessageBox.critical(
|
|
299
|
+
None,
|
|
300
|
+
cfg.programName,
|
|
301
|
+
("Error saving the file"),
|
|
302
|
+
)
|
|
303
|
+
return
|
|
304
304
|
|
|
305
|
-
out += f"<b>{
|
|
305
|
+
out += f"<b>{file_name}.gv</b> created<br>"
|
|
306
306
|
|
|
307
307
|
if out:
|
|
308
308
|
QMessageBox.information(
|
|
309
309
|
None,
|
|
310
310
|
cfg.programName,
|
|
311
|
-
(f"{out}<br><br>The DOT scripts can be used with Graphviz or WebGraphviz
|
|
311
|
+
(f"{out}<br><br>The DOT scripts can be used with the Graphviz package or WebGraphviz to generate diagram"),
|
|
312
312
|
)
|
|
313
313
|
|
|
314
314
|
|
|
@@ -332,20 +332,17 @@ def transitions_flow_diagram():
|
|
|
332
332
|
)
|
|
333
333
|
return
|
|
334
334
|
|
|
335
|
-
|
|
335
|
+
file_names, _ = QFileDialog().getOpenFileNames(
|
|
336
336
|
None,
|
|
337
337
|
"Select one or more transitions matrix files",
|
|
338
338
|
"",
|
|
339
339
|
"Transitions matrix files (*.txt *.tsv);;All files (*)",
|
|
340
340
|
)
|
|
341
|
-
fileNames = fn[0] if type(fn) is tuple else fn
|
|
342
341
|
|
|
343
342
|
out = ""
|
|
344
|
-
for
|
|
345
|
-
with open(
|
|
346
|
-
result, gv = create_transitions_gv_from_matrix(
|
|
347
|
-
infile.read(), cutoff_all=0, cutoff_behavior=0, edge_label="percent_node"
|
|
348
|
-
)
|
|
343
|
+
for file_name in file_names:
|
|
344
|
+
with open(file_name, "r") as infile:
|
|
345
|
+
result, gv = create_transitions_gv_from_matrix(infile.read(), cutoff_all=0, cutoff_behavior=0, edge_label="percent_node")
|
|
349
346
|
if result:
|
|
350
347
|
QMessageBox.critical(
|
|
351
348
|
None,
|
|
@@ -354,18 +351,15 @@ def transitions_flow_diagram():
|
|
|
354
351
|
)
|
|
355
352
|
return
|
|
356
353
|
|
|
357
|
-
with open(tempfile.gettempdir() + os.sep + os.path.basename(
|
|
354
|
+
with open(tempfile.gettempdir() + os.sep + os.path.basename(file_name) + ".tmp.gv", "w") as f:
|
|
358
355
|
f.write(gv)
|
|
359
356
|
result = subprocess.getoutput(
|
|
360
|
-
(
|
|
361
|
-
f'dot -Tpng -o "{fileName}.png" '
|
|
362
|
-
f'"{tempfile.gettempdir() + os.sep + os.path.basename(fileName)}.tmp.gv"'
|
|
363
|
-
)
|
|
357
|
+
(f'dot -Tpng -o "{file_name}.png" "{tempfile.gettempdir() + os.sep + os.path.basename(file_name)}.tmp.gv"')
|
|
364
358
|
)
|
|
365
359
|
if not result:
|
|
366
|
-
out += f"<b>{
|
|
360
|
+
out += f"<b>{file_name}.png</b> created<br>"
|
|
367
361
|
else:
|
|
368
|
-
out += f"Problem with <b>{
|
|
362
|
+
out += f"Problem with <b>{file_name}</b><br>"
|
|
369
363
|
|
|
370
364
|
if out:
|
|
371
365
|
QMessageBox.information(None, cfg.programName, out)
|