boris-behav-obs 8.9.16__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.

Files changed (129) hide show
  1. boris/__init__.py +1 -1
  2. boris/__main__.py +1 -1
  3. boris/about.py +36 -39
  4. boris/add_modifier.py +122 -109
  5. boris/add_modifier_ui.py +239 -135
  6. boris/advanced_event_filtering.py +81 -45
  7. boris/analysis_plugins/__init__.py +0 -0
  8. boris/analysis_plugins/_latency.py +59 -0
  9. boris/analysis_plugins/irr_cohen_kappa.py +109 -0
  10. boris/analysis_plugins/irr_cohen_kappa_with_modifiers.py +112 -0
  11. boris/analysis_plugins/irr_weighted_cohen_kappa.py +157 -0
  12. boris/analysis_plugins/irr_weighted_cohen_kappa_with_modifiers.py +162 -0
  13. boris/analysis_plugins/list_of_dataframe_columns.py +22 -0
  14. boris/analysis_plugins/number_of_occurences.py +22 -0
  15. boris/analysis_plugins/number_of_occurences_by_independent_variable.py +54 -0
  16. boris/analysis_plugins/time_budget.py +61 -0
  17. boris/behav_coding_map_creator.py +228 -229
  18. boris/behavior_binary_table.py +33 -50
  19. boris/behaviors_coding_map.py +17 -18
  20. boris/boris_cli.py +6 -25
  21. boris/cmd_arguments.py +12 -1
  22. boris/coding_pad.py +42 -49
  23. boris/config.py +161 -77
  24. boris/config_file.py +63 -83
  25. boris/connections.py +112 -57
  26. boris/converters.py +13 -37
  27. boris/converters_ui.py +187 -110
  28. boris/cooccurence.py +250 -0
  29. boris/core.py +2511 -1824
  30. boris/core_qrc.py +15895 -10185
  31. boris/core_ui.py +946 -792
  32. boris/db_functions.py +21 -41
  33. boris/dev.py +134 -0
  34. boris/dialog.py +505 -244
  35. boris/duration_widget.py +15 -20
  36. boris/edit_event.py +84 -28
  37. boris/edit_event_ui.py +214 -78
  38. boris/event_operations.py +517 -415
  39. boris/events_cursor.py +25 -17
  40. boris/events_snapshots.py +36 -82
  41. boris/exclusion_matrix.py +4 -9
  42. boris/export_events.py +213 -583
  43. boris/export_observation.py +98 -611
  44. boris/external_processes.py +156 -97
  45. boris/geometric_measurement.py +652 -287
  46. boris/gui_utilities.py +91 -14
  47. boris/image_overlay.py +9 -9
  48. boris/import_observations.py +190 -98
  49. boris/ipc_mpv.py +325 -0
  50. boris/irr.py +26 -63
  51. boris/latency.py +34 -25
  52. boris/measurement_widget.py +14 -18
  53. boris/media_file.py +52 -84
  54. boris/menu_options.py +17 -6
  55. boris/modifier_coding_map_creator.py +1013 -0
  56. boris/modifiers_coding_map.py +7 -9
  57. boris/mpv.py +1 -0
  58. boris/mpv2.py +732 -705
  59. boris/observation.py +655 -310
  60. boris/observation_operations.py +1036 -404
  61. boris/observation_ui.py +584 -356
  62. boris/observations_list.py +71 -53
  63. boris/otx_parser.py +74 -80
  64. boris/param_panel.py +31 -16
  65. boris/param_panel_ui.py +254 -138
  66. boris/player_dock_widget.py +90 -60
  67. boris/plot_data_module.py +43 -46
  68. boris/plot_events.py +127 -90
  69. boris/plot_events_rt.py +17 -31
  70. boris/plot_spectrogram_rt.py +95 -30
  71. boris/plot_waveform_rt.py +32 -21
  72. boris/plugins.py +431 -0
  73. boris/portion/__init__.py +18 -8
  74. boris/portion/const.py +35 -18
  75. boris/portion/dict.py +5 -5
  76. boris/portion/func.py +2 -2
  77. boris/portion/interval.py +21 -41
  78. boris/portion/io.py +41 -32
  79. boris/preferences.py +306 -83
  80. boris/preferences_ui.py +685 -228
  81. boris/project.py +448 -293
  82. boris/project_functions.py +689 -254
  83. boris/project_import_export.py +213 -222
  84. boris/project_ui.py +674 -438
  85. boris/qrc_boris.py +6 -3
  86. boris/qrc_boris5.py +6 -3
  87. boris/select_modifiers.py +74 -48
  88. boris/select_observations.py +20 -199
  89. boris/select_subj_behav.py +67 -39
  90. boris/state_events.py +53 -37
  91. boris/subjects_pad.py +6 -9
  92. boris/synthetic_time_budget.py +45 -28
  93. boris/time_budget_functions.py +171 -171
  94. boris/time_budget_widget.py +84 -114
  95. boris/transitions.py +41 -47
  96. boris/utilities.py +766 -266
  97. boris/version.py +3 -3
  98. boris/video_equalizer.py +16 -14
  99. boris/video_equalizer_ui.py +199 -130
  100. boris/video_operations.py +125 -28
  101. boris/view_df.py +104 -0
  102. boris/view_df_ui.py +75 -0
  103. boris/write_event.py +538 -0
  104. boris_behav_obs-9.7.6.dist-info/METADATA +139 -0
  105. boris_behav_obs-9.7.6.dist-info/RECORD +109 -0
  106. {boris_behav_obs-8.9.16.dist-info → boris_behav_obs-9.7.6.dist-info}/WHEEL +1 -1
  107. boris_behav_obs-9.7.6.dist-info/entry_points.txt +2 -0
  108. boris/README.TXT +0 -22
  109. boris/add_modifier.ui +0 -323
  110. boris/boris_ui.py +0 -886
  111. boris/converters.ui +0 -289
  112. boris/core.qrc +0 -35
  113. boris/core.ui +0 -1543
  114. boris/edit_event.ui +0 -175
  115. boris/icons/logo_eye.ico +0 -0
  116. boris/map_creator.py +0 -850
  117. boris/observation.ui +0 -773
  118. boris/param_panel.ui +0 -379
  119. boris/preferences.ui +0 -537
  120. boris/project.ui +0 -1069
  121. boris/project_server.py +0 -236
  122. boris/vlc.py +0 -10343
  123. boris/vlc_local.py +0 -90
  124. boris_behav_obs-8.9.16.dist-info/LICENSE.TXT +0 -674
  125. boris_behav_obs-8.9.16.dist-info/METADATA +0 -129
  126. boris_behav_obs-8.9.16.dist-info/RECORD +0 -108
  127. boris_behav_obs-8.9.16.dist-info/entry_points.txt +0 -2
  128. {boris → boris_behav_obs-9.7.6.dist-info/licenses}/LICENSE.TXT +0 -0
  129. {boris_behav_obs-8.9.16.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-2023 Olivier Friard
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 decimal import Decimal as dec
27
+ from pathlib import Path
28
28
 
29
- from PyQt5.QtWidgets import QFileDialog, QMessageBox
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
- flagShowIncludeModifiers=True,
188
- flagShowExcludeBehaviorsWoEvents=False,
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
- fileName = fn[0] if type(fn) is tuple else fn # PyQt4/5
208
-
206
+ if not file_name:
207
+ return
209
208
  else:
210
- exportDir = QFileDialog(self).getExistingDirectory(
209
+ exportDir = QFileDialog.getExistingDirectory(
211
210
  self,
212
211
  "Choose a directory to save the transitions matrices",
213
- os.path.expanduser("~"),
214
- options=QFileDialog(self).ShowDirsOnly,
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(fileName, "w") as outfile:
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 {fileName} can not be saved")
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
- fn = QFileDialog().getOpenFileNames(
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 fileName in fileNames:
290
- with open(fileName, "r") as infile:
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
- with open(fileName + ".gv", "w") as f:
303
- f.write(gv)
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>{fileName}.gv</b> created<br>"
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 " "to generate diagram"),
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
- fn = QFileDialog().getOpenFileNames(
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 fileName in fileNames:
345
- with open(fileName, "r") as infile:
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(fileName) + ".tmp.gv", "w") as f:
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>{fileName}.png</b> created<br>"
360
+ out += f"<b>{file_name}.png</b> created<br>"
367
361
  else:
368
- out += f"Problem with <b>{fileName}</b><br>"
362
+ out += f"Problem with <b>{file_name}</b><br>"
369
363
 
370
364
  if out:
371
365
  QMessageBox.information(None, cfg.programName, out)