boris-behav-obs 9.4__tar.gz → 9.5__tar.gz

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.
Files changed (122) hide show
  1. {boris_behav_obs-9.4/boris_behav_obs.egg-info → boris_behav_obs-9.5}/PKG-INFO +4 -1
  2. {boris_behav_obs-9.4 → boris_behav_obs-9.5}/boris/analysis_plugins/_latency.py +1 -1
  3. {boris_behav_obs-9.4 → boris_behav_obs-9.5}/boris/config.py +10 -0
  4. {boris_behav_obs-9.4 → boris_behav_obs-9.5}/boris/connections.py +2 -1
  5. {boris_behav_obs-9.4 → boris_behav_obs-9.5}/boris/core.py +45 -54
  6. {boris_behav_obs-9.4 → boris_behav_obs-9.5}/boris/core_ui.py +6 -2
  7. {boris_behav_obs-9.4 → boris_behav_obs-9.5}/boris/external_processes.py +98 -73
  8. {boris_behav_obs-9.4 → boris_behav_obs-9.5}/boris/import_observations.py +28 -19
  9. {boris_behav_obs-9.4 → boris_behav_obs-9.5}/boris/observation.py +8 -4
  10. {boris_behav_obs-9.4 → boris_behav_obs-9.5}/boris/observation_operations.py +17 -1
  11. {boris_behav_obs-9.4 → boris_behav_obs-9.5}/boris/player_dock_widget.py +0 -24
  12. {boris_behav_obs-9.4 → boris_behav_obs-9.5}/boris/plot_events.py +1 -1
  13. {boris_behav_obs-9.4 → boris_behav_obs-9.5}/boris/plot_events_rt.py +1 -1
  14. {boris_behav_obs-9.4 → boris_behav_obs-9.5}/boris/plot_spectrogram_rt.py +62 -13
  15. {boris_behav_obs-9.4 → boris_behav_obs-9.5}/boris/plot_waveform_rt.py +1 -1
  16. {boris_behav_obs-9.4 → boris_behav_obs-9.5}/boris/plugins.py +136 -25
  17. {boris_behav_obs-9.4 → boris_behav_obs-9.5}/boris/preferences.py +182 -108
  18. {boris_behav_obs-9.4 → boris_behav_obs-9.5}/boris/preferences_ui.py +216 -32
  19. {boris_behav_obs-9.4 → boris_behav_obs-9.5}/boris/project_functions.py +1 -3
  20. {boris_behav_obs-9.4 → boris_behav_obs-9.5}/boris/utilities.py +21 -14
  21. {boris_behav_obs-9.4 → boris_behav_obs-9.5}/boris/version.py +2 -2
  22. {boris_behav_obs-9.4 → boris_behav_obs-9.5}/boris/write_event.py +11 -2
  23. {boris_behav_obs-9.4 → boris_behav_obs-9.5/boris_behav_obs.egg-info}/PKG-INFO +4 -1
  24. {boris_behav_obs-9.4 → boris_behav_obs-9.5}/boris_behav_obs.egg-info/SOURCES.txt +0 -1
  25. {boris_behav_obs-9.4 → boris_behav_obs-9.5}/boris_behav_obs.egg-info/requires.txt +4 -0
  26. {boris_behav_obs-9.4 → boris_behav_obs-9.5}/pyproject.toml +4 -2
  27. boris_behav_obs-9.4/boris/1.py +0 -45
  28. {boris_behav_obs-9.4 → boris_behav_obs-9.5}/LICENSE.TXT +0 -0
  29. {boris_behav_obs-9.4 → boris_behav_obs-9.5}/MANIFEST.in +0 -0
  30. {boris_behav_obs-9.4 → boris_behav_obs-9.5}/README.TXT +0 -0
  31. {boris_behav_obs-9.4 → boris_behav_obs-9.5}/README.md +0 -0
  32. {boris_behav_obs-9.4 → boris_behav_obs-9.5}/boris/__init__.py +0 -0
  33. {boris_behav_obs-9.4 → boris_behav_obs-9.5}/boris/__main__.py +0 -0
  34. {boris_behav_obs-9.4 → boris_behav_obs-9.5}/boris/about.py +0 -0
  35. {boris_behav_obs-9.4 → boris_behav_obs-9.5}/boris/add_modifier.py +0 -0
  36. {boris_behav_obs-9.4 → boris_behav_obs-9.5}/boris/add_modifier_ui.py +0 -0
  37. {boris_behav_obs-9.4 → boris_behav_obs-9.5}/boris/advanced_event_filtering.py +0 -0
  38. {boris_behav_obs-9.4 → boris_behav_obs-9.5}/boris/analysis_plugins/__init__.py +0 -0
  39. {boris_behav_obs-9.4 → boris_behav_obs-9.5}/boris/analysis_plugins/number_of_occurences.py +0 -0
  40. {boris_behav_obs-9.4 → boris_behav_obs-9.5}/boris/analysis_plugins/number_of_occurences_by_independent_variable.py +0 -0
  41. {boris_behav_obs-9.4 → boris_behav_obs-9.5}/boris/analysis_plugins/time_budget.py +0 -0
  42. {boris_behav_obs-9.4 → boris_behav_obs-9.5}/boris/behav_coding_map_creator.py +0 -0
  43. {boris_behav_obs-9.4 → boris_behav_obs-9.5}/boris/behavior_binary_table.py +0 -0
  44. {boris_behav_obs-9.4 → boris_behav_obs-9.5}/boris/behaviors_coding_map.py +0 -0
  45. {boris_behav_obs-9.4 → boris_behav_obs-9.5}/boris/boris_cli.py +0 -0
  46. {boris_behav_obs-9.4 → boris_behav_obs-9.5}/boris/cmd_arguments.py +0 -0
  47. {boris_behav_obs-9.4 → boris_behav_obs-9.5}/boris/coding_pad.py +0 -0
  48. {boris_behav_obs-9.4 → boris_behav_obs-9.5}/boris/config_file.py +0 -0
  49. {boris_behav_obs-9.4 → boris_behav_obs-9.5}/boris/converters.py +0 -0
  50. {boris_behav_obs-9.4 → boris_behav_obs-9.5}/boris/converters_ui.py +0 -0
  51. {boris_behav_obs-9.4 → boris_behav_obs-9.5}/boris/cooccurence.py +0 -0
  52. {boris_behav_obs-9.4 → boris_behav_obs-9.5}/boris/core_qrc.py +0 -0
  53. {boris_behav_obs-9.4 → boris_behav_obs-9.5}/boris/db_functions.py +0 -0
  54. {boris_behav_obs-9.4 → boris_behav_obs-9.5}/boris/dev.py +0 -0
  55. {boris_behav_obs-9.4 → boris_behav_obs-9.5}/boris/dialog.py +0 -0
  56. {boris_behav_obs-9.4 → boris_behav_obs-9.5}/boris/duration_widget.py +0 -0
  57. {boris_behav_obs-9.4 → boris_behav_obs-9.5}/boris/edit_event.py +0 -0
  58. {boris_behav_obs-9.4 → boris_behav_obs-9.5}/boris/edit_event_ui.py +0 -0
  59. {boris_behav_obs-9.4 → boris_behav_obs-9.5}/boris/event_operations.py +0 -0
  60. {boris_behav_obs-9.4 → boris_behav_obs-9.5}/boris/events_cursor.py +0 -0
  61. {boris_behav_obs-9.4 → boris_behav_obs-9.5}/boris/events_snapshots.py +0 -0
  62. {boris_behav_obs-9.4 → boris_behav_obs-9.5}/boris/exclusion_matrix.py +0 -0
  63. {boris_behav_obs-9.4 → boris_behav_obs-9.5}/boris/export_events.py +0 -0
  64. {boris_behav_obs-9.4 → boris_behav_obs-9.5}/boris/export_observation.py +0 -0
  65. {boris_behav_obs-9.4 → boris_behav_obs-9.5}/boris/geometric_measurement.py +0 -0
  66. {boris_behav_obs-9.4 → boris_behav_obs-9.5}/boris/gui_utilities.py +0 -0
  67. {boris_behav_obs-9.4 → boris_behav_obs-9.5}/boris/image_overlay.py +0 -0
  68. {boris_behav_obs-9.4 → boris_behav_obs-9.5}/boris/irr.py +0 -0
  69. {boris_behav_obs-9.4 → boris_behav_obs-9.5}/boris/latency.py +0 -0
  70. {boris_behav_obs-9.4 → boris_behav_obs-9.5}/boris/measurement_widget.py +0 -0
  71. {boris_behav_obs-9.4 → boris_behav_obs-9.5}/boris/media_file.py +0 -0
  72. {boris_behav_obs-9.4 → boris_behav_obs-9.5}/boris/menu_options.py +0 -0
  73. {boris_behav_obs-9.4 → boris_behav_obs-9.5}/boris/modifier_coding_map_creator.py +0 -0
  74. {boris_behav_obs-9.4 → boris_behav_obs-9.5}/boris/modifiers_coding_map.py +0 -0
  75. {boris_behav_obs-9.4 → boris_behav_obs-9.5}/boris/mpv-1.0.3.py +0 -0
  76. {boris_behav_obs-9.4 → boris_behav_obs-9.5}/boris/mpv.py +0 -0
  77. {boris_behav_obs-9.4 → boris_behav_obs-9.5}/boris/mpv2.py +0 -0
  78. {boris_behav_obs-9.4 → boris_behav_obs-9.5}/boris/observation_ui.py +0 -0
  79. {boris_behav_obs-9.4 → boris_behav_obs-9.5}/boris/observations_list.py +0 -0
  80. {boris_behav_obs-9.4 → boris_behav_obs-9.5}/boris/otx_parser.py +0 -0
  81. {boris_behav_obs-9.4 → boris_behav_obs-9.5}/boris/param_panel.py +0 -0
  82. {boris_behav_obs-9.4 → boris_behav_obs-9.5}/boris/param_panel_ui.py +0 -0
  83. {boris_behav_obs-9.4 → boris_behav_obs-9.5}/boris/plot_data_module.py +0 -0
  84. {boris_behav_obs-9.4 → boris_behav_obs-9.5}/boris/portion/__init__.py +0 -0
  85. {boris_behav_obs-9.4 → boris_behav_obs-9.5}/boris/portion/const.py +0 -0
  86. {boris_behav_obs-9.4 → boris_behav_obs-9.5}/boris/portion/dict.py +0 -0
  87. {boris_behav_obs-9.4 → boris_behav_obs-9.5}/boris/portion/func.py +0 -0
  88. {boris_behav_obs-9.4 → boris_behav_obs-9.5}/boris/portion/interval.py +0 -0
  89. {boris_behav_obs-9.4 → boris_behav_obs-9.5}/boris/portion/io.py +0 -0
  90. {boris_behav_obs-9.4 → boris_behav_obs-9.5}/boris/project.py +0 -0
  91. {boris_behav_obs-9.4 → boris_behav_obs-9.5}/boris/project_import_export.py +0 -0
  92. {boris_behav_obs-9.4 → boris_behav_obs-9.5}/boris/project_ui.py +0 -0
  93. {boris_behav_obs-9.4 → boris_behav_obs-9.5}/boris/qrc_boris.py +0 -0
  94. {boris_behav_obs-9.4 → boris_behav_obs-9.5}/boris/qrc_boris5.py +0 -0
  95. {boris_behav_obs-9.4 → boris_behav_obs-9.5}/boris/select_modifiers.py +0 -0
  96. {boris_behav_obs-9.4 → boris_behav_obs-9.5}/boris/select_observations.py +0 -0
  97. {boris_behav_obs-9.4 → boris_behav_obs-9.5}/boris/select_subj_behav.py +0 -0
  98. {boris_behav_obs-9.4 → boris_behav_obs-9.5}/boris/state_events.py +0 -0
  99. {boris_behav_obs-9.4 → boris_behav_obs-9.5}/boris/subjects_pad.py +0 -0
  100. {boris_behav_obs-9.4 → boris_behav_obs-9.5}/boris/synthetic_time_budget.py +0 -0
  101. {boris_behav_obs-9.4 → boris_behav_obs-9.5}/boris/time_budget_functions.py +0 -0
  102. {boris_behav_obs-9.4 → boris_behav_obs-9.5}/boris/time_budget_widget.py +0 -0
  103. {boris_behav_obs-9.4 → boris_behav_obs-9.5}/boris/transitions.py +0 -0
  104. {boris_behav_obs-9.4 → boris_behav_obs-9.5}/boris/video_equalizer.py +0 -0
  105. {boris_behav_obs-9.4 → boris_behav_obs-9.5}/boris/video_equalizer_ui.py +0 -0
  106. {boris_behav_obs-9.4 → boris_behav_obs-9.5}/boris/video_operations.py +0 -0
  107. {boris_behav_obs-9.4 → boris_behav_obs-9.5}/boris/view_df.py +0 -0
  108. {boris_behav_obs-9.4 → boris_behav_obs-9.5}/boris/view_df_ui.py +0 -0
  109. {boris_behav_obs-9.4 → boris_behav_obs-9.5}/boris_behav_obs.egg-info/dependency_links.txt +0 -0
  110. {boris_behav_obs-9.4 → boris_behav_obs-9.5}/boris_behav_obs.egg-info/entry_points.txt +0 -0
  111. {boris_behav_obs-9.4 → boris_behav_obs-9.5}/boris_behav_obs.egg-info/top_level.txt +0 -0
  112. {boris_behav_obs-9.4 → boris_behav_obs-9.5}/setup.cfg +0 -0
  113. {boris_behav_obs-9.4 → boris_behav_obs-9.5}/tests/test_db_functions.py +0 -0
  114. {boris_behav_obs-9.4 → boris_behav_obs-9.5}/tests/test_export_observation.py +0 -0
  115. {boris_behav_obs-9.4 → boris_behav_obs-9.5}/tests/test_irr.py +0 -0
  116. {boris_behav_obs-9.4 → boris_behav_obs-9.5}/tests/test_observation_gui.py +0 -0
  117. {boris_behav_obs-9.4 → boris_behav_obs-9.5}/tests/test_otx_parser.py +0 -0
  118. {boris_behav_obs-9.4 → boris_behav_obs-9.5}/tests/test_preferences_gui.py +0 -0
  119. {boris_behav_obs-9.4 → boris_behav_obs-9.5}/tests/test_project_functions.py +0 -0
  120. {boris_behav_obs-9.4 → boris_behav_obs-9.5}/tests/test_time_budget.py +0 -0
  121. {boris_behav_obs-9.4 → boris_behav_obs-9.5}/tests/test_utilities.py +0 -0
  122. {boris_behav_obs-9.4 → boris_behav_obs-9.5}/tests/test_utilities2.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: boris-behav-obs
3
- Version: 9.4
3
+ Version: 9.5
4
4
  Summary: BORIS - Behavioral Observation Research Interactive Software
5
5
  Author-email: Olivier Friard <olivier.friard@unito.it>
6
6
  License-Expression: GPL-3.0-only
@@ -26,10 +26,13 @@ Requires-Dist: tablib[cli,html,ods,pandas,xls,xlsx]>=3
26
26
  Requires-Dist: pyreadr
27
27
  Requires-Dist: pyside6==6.9
28
28
  Requires-Dist: hachoir>=3.3.0
29
+ Requires-Dist: scipy>=1.15.3
29
30
  Provides-Extra: dev
30
31
  Requires-Dist: ruff; extra == "dev"
31
32
  Requires-Dist: pytest; extra == "dev"
32
33
  Requires-Dist: pytest-cov; extra == "dev"
34
+ Provides-Extra: r
35
+ Requires-Dist: rpy2>=3.6.1; extra == "r"
33
36
  Dynamic: license-file
34
37
 
35
38
  BORIS (Behavioral Observation Research Interactive Software)
@@ -8,7 +8,7 @@ import pandas as pd
8
8
 
9
9
  __version__ = "0.0.1"
10
10
  __version_date__ = "2025-04-10"
11
- __plugin_name__ = "Behavior latency"
11
+ __plugin_name__ = "Behavior latencyxxx"
12
12
  __author__ = "Olivier Friard - University of Torino - Italy"
13
13
 
14
14
 
@@ -531,6 +531,16 @@ NO_COLOR_CODING_PAD = "#777777"
531
531
  SPECTROGRAM_COLOR_MAPS = ["viridis", "inferno", "plasma", "magma", "gray", "YlOrRd"]
532
532
  SPECTROGRAM_DEFAULT_COLOR_MAP = "viridis"
533
533
  SPECTROGRAM_DEFAULT_TIME_INTERVAL = 10
534
+ SPECTROGRAM_WINDOW_TYPE = "SPECTROGRAM_WINDOW_TYPE"
535
+ SPECTROGRAM_DEFAULT_WINDOW_TYPE = "hanning"
536
+ SPECTROGRAM_NFFT = "SPECTROGRAM_NFFT"
537
+ SPECTROGRAM_DEFAULT_NFFT = "1024"
538
+ SPECTROGRAM_NOVERLAP = "SPECTROGRAM_NOVERLAP"
539
+ SPECTROGRAM_DEFAULT_NOVERLAP = 900
540
+ SPECTROGRAM_VMIN = "SPECTROGRAM_VMIN"
541
+ SPECTROGRAM_DEFAULT_VMIN = -100
542
+ SPECTROGRAM_VMAX = "SPECTROGRAM_VMAX"
543
+ SPECTROGRAM_DEFAULT_VMAX = -20
534
544
 
535
545
  # see matplotlib.colors.cnames.keys()
536
546
  # https://xkcd.com/color/rgb/
@@ -193,10 +193,11 @@ def connections(self):
193
193
  self.actionAdd_image_overlay_on_video.triggered.connect(lambda: image_overlay.add_image_overlay(self))
194
194
  self.actionRemove_image_overlay.triggered.connect(lambda: image_overlay.remove_image_overlay(self))
195
195
 
196
+ self.actionMedia_file_information_2.triggered.connect(lambda: media_file.get_info(self))
196
197
  self.actionRecode_resize_video.triggered.connect(lambda: external_processes.ffmpeg_process(self, "reencode_resize"))
197
198
  self.actionRotate_video.triggered.connect(lambda: external_processes.ffmpeg_process(self, "rotate"))
198
199
  self.actionMerge_media_files.triggered.connect(lambda: external_processes.ffmpeg_process(self, "merge"))
199
- self.actionMedia_file_information_2.triggered.connect(lambda: media_file.get_info(self))
200
+ self.actionCreate_video_spectrogram.triggered.connect(lambda: external_processes.ffmpeg_process(self, "video_spectrogram"))
200
201
 
201
202
  self.actionCreate_transitions_flow_diagram.triggered.connect(transitions.transitions_dot_script)
202
203
  self.actionCreate_transitions_flow_diagram_2.triggered.connect(transitions.transitions_flow_diagram)
@@ -23,11 +23,11 @@ This file is part of BORIS.
23
23
 
24
24
  import os
25
25
  import sys
26
- import pathlib as pl
26
+ from pathlib import Path
27
27
 
28
28
  # os.environ["PATH"] = os.path.dirname(__file__) + os.sep + "misc" + os.pathsep + os.environ["PATH"]
29
29
 
30
- os.environ["PATH"] = str(pl.Path(__file__).parent / "misc") + os.pathsep + os.environ["PATH"]
30
+ os.environ["PATH"] = str(Path(__file__).parent / "misc") + os.pathsep + os.environ["PATH"]
31
31
  sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), ".")))
32
32
 
33
33
  import datetime
@@ -1023,8 +1023,7 @@ class MainWindow(QMainWindow, Ui_MainWindow):
1023
1023
  tmp_dir = self.ffmpeg_cache_dir if self.ffmpeg_cache_dir and os.path.isdir(self.ffmpeg_cache_dir) else tempfile.gettempdir()
1024
1024
 
1025
1025
  wav_file_path = (
1026
- pl.Path(tmp_dir)
1027
- / pl.Path(self.dw_player[0].player.playlist[self.dw_player[0].player.playlist_pos]["filename"] + ".wav").name
1026
+ Path(tmp_dir) / Path(self.dw_player[0].player.playlist[self.dw_player[0].player.playlist_pos]["filename"] + ".wav").name
1028
1027
  )
1029
1028
 
1030
1029
  self.spectro = plot_spectrogram_rt.Plot_spectrogram_RT()
@@ -1035,6 +1034,8 @@ class MainWindow(QMainWindow, Ui_MainWindow):
1035
1034
  self.spectro.interval = self.spectrogram_time_interval
1036
1035
  self.spectro.cursor_color = cfg.REALTIME_PLOT_CURSOR_COLOR
1037
1036
 
1037
+ self.spectro.config_param = self.config_param
1038
+
1038
1039
  # color palette
1039
1040
  try:
1040
1041
  self.spectro.spectro_color_map = matplotlib.pyplot.get_cmap(self.spectrogram_color_map)
@@ -1113,8 +1114,7 @@ class MainWindow(QMainWindow, Ui_MainWindow):
1113
1114
  tmp_dir = self.ffmpeg_cache_dir if self.ffmpeg_cache_dir and os.path.isdir(self.ffmpeg_cache_dir) else tempfile.gettempdir()
1114
1115
 
1115
1116
  wav_file_path = (
1116
- pl.Path(tmp_dir)
1117
- / pl.Path(self.dw_player[0].player.playlist[self.dw_player[0].player.playlist_pos]["filename"] + ".wav").name
1117
+ Path(tmp_dir) / Path(self.dw_player[0].player.playlist[self.dw_player[0].player.playlist_pos]["filename"] + ".wav").name
1118
1118
  )
1119
1119
 
1120
1120
  self.waveform = plot_waveform_rt.Plot_waveform_RT()
@@ -1224,8 +1224,7 @@ class MainWindow(QMainWindow, Ui_MainWindow):
1224
1224
 
1225
1225
  try:
1226
1226
  wav_file_path = str(
1227
- pl.Path(tmp_dir)
1228
- / pl.Path(self.dw_player[0].player.playlist[self.dw_player[0].player.playlist_pos]["filename"] + ".wav").name
1227
+ Path(tmp_dir) / Path(self.dw_player[0].player.playlist[self.dw_player[0].player.playlist_pos]["filename"] + ".wav").name
1229
1228
  )
1230
1229
  except Exception:
1231
1230
  return
@@ -1373,7 +1372,7 @@ class MainWindow(QMainWindow, Ui_MainWindow):
1373
1372
  return
1374
1373
 
1375
1374
  # check if a .git is present
1376
- if (pl.Path(__file__).parent.parent / pl.Path(".git")).is_dir():
1375
+ if (Path(__file__).parent.parent / Path(".git")).is_dir():
1377
1376
  QMessageBox.critical(self, cfg.programName, "A .git directory is present, BORIS cannot be automatically updated.")
1378
1377
  return
1379
1378
 
@@ -1403,7 +1402,7 @@ class MainWindow(QMainWindow, Ui_MainWindow):
1403
1402
 
1404
1403
  # copy from temp dir to current BORIS dir
1405
1404
  try:
1406
- shutil.copytree(f"{temp_dir.name}/BORIS-{last_version}", pl.Path(__file__).parent.parent, dirs_exist_ok=True)
1405
+ shutil.copytree(f"{temp_dir.name}/BORIS-{last_version}", Path(__file__).parent.parent, dirs_exist_ok=True)
1407
1406
  except Exception:
1408
1407
  QMessageBox.critical(self, cfg.programName, "A problem occurred during the copy the new version of BORIS.")
1409
1408
  return
@@ -1526,15 +1525,15 @@ class MainWindow(QMainWindow, Ui_MainWindow):
1526
1525
  if self.image_idx == 0:
1527
1526
  return
1528
1527
 
1529
- current_dir = pl.Path(self.images_list[self.image_idx]).parent
1528
+ current_dir = Path(self.images_list[self.image_idx]).parent
1530
1529
  for image_path in self.images_list[self.image_idx - 1 :: -1]:
1531
- if pl.Path(image_path).parent != current_dir:
1530
+ if Path(image_path).parent != current_dir:
1532
1531
  self.image_idx = self.images_list.index(image_path)
1533
1532
 
1534
1533
  # seek to first image of directory
1535
- current_dir2 = pl.Path(self.images_list[self.image_idx]).parent
1534
+ current_dir2 = Path(self.images_list[self.image_idx]).parent
1536
1535
  for image_path2 in self.images_list[self.image_idx - 1 :: -1]:
1537
- if pl.Path(image_path2).parent != current_dir2:
1536
+ if Path(image_path2).parent != current_dir2:
1538
1537
  self.image_idx = self.images_list.index(image_path2) + 1
1539
1538
  break
1540
1539
  if self.images_list.index(image_path2) == 0:
@@ -1571,9 +1570,9 @@ class MainWindow(QMainWindow, Ui_MainWindow):
1571
1570
  if self.playerType == cfg.IMAGES:
1572
1571
  if len(self.pj[cfg.OBSERVATIONS][self.observationId].get(cfg.DIRECTORIES_LIST, [])) <= 1:
1573
1572
  return
1574
- current_dir = pl.Path(self.images_list[self.image_idx]).parent
1573
+ current_dir = Path(self.images_list[self.image_idx]).parent
1575
1574
  for image_path in self.images_list[self.image_idx + 1 :]:
1576
- if pl.Path(image_path).parent != current_dir:
1575
+ if Path(image_path).parent != current_dir:
1577
1576
  self.image_idx = self.images_list.index(image_path)
1578
1577
  self.extract_frame(self.dw_player[0])
1579
1578
  break
@@ -1706,8 +1705,8 @@ class MainWindow(QMainWindow, Ui_MainWindow):
1706
1705
  msg += f"<br>Time from 1st image: <b>{seconds_from_1st_formated}</b>"
1707
1706
 
1708
1707
  # image path
1709
- msg += f"<br><br>Directory: <b>{pl.Path(self.images_list[self.image_idx]).parent}</b>"
1710
- msg += f"<br>File name: <b>{pl.Path(self.images_list[self.image_idx]).name}</b>"
1708
+ msg += f"<br><br>Directory: <b>{Path(self.images_list[self.image_idx]).parent}</b>"
1709
+ msg += f"<br>File name: <b>{Path(self.images_list[self.image_idx]).name}</b>"
1711
1710
  msg += f"<br><small>Image resolution: <b>{pixmap.size().width()}x{pixmap.size().height()}</b></small>"
1712
1711
 
1713
1712
  self.lb_current_media_time.setText(msg)
@@ -1819,16 +1818,16 @@ class MainWindow(QMainWindow, Ui_MainWindow):
1819
1818
  if self.pj[cfg.OBSERVATIONS][self.observationId][cfg.TYPE] == cfg.IMAGES:
1820
1819
  pixmap = QPixmap(self.images_list[self.image_idx])
1821
1820
  # draw measurements
1822
- RADIUS = 6
1821
+ # RADIUS = 6
1823
1822
  painter = QPainter()
1824
1823
  painter.begin(pixmap)
1825
1824
  for element in self.measurement_w.draw_mem.get(self.image_idx, []):
1826
1825
  painter = draw_element(painter, element)
1827
1826
  painter.end()
1828
1827
 
1829
- image_file_path = str(pl.Path(output_dir) / f"{pl.Path(self.images_list[self.image_idx]).stem}.jpg")
1828
+ image_file_path = str(Path(output_dir) / f"{Path(self.images_list[self.image_idx]).stem}.jpg")
1830
1829
  # check if file already exists
1831
- if pl.Path(image_file_path).is_file():
1830
+ if Path(image_file_path).is_file():
1832
1831
  if (
1833
1832
  dialog.MessageDialog(cfg.programName, f"The file {image_file_path} already exists.", (cfg.CANCEL, cfg.OVERWRITE))
1834
1833
  == cfg.CANCEL
@@ -1841,11 +1840,11 @@ class MainWindow(QMainWindow, Ui_MainWindow):
1841
1840
  for n_player, dw in enumerate(self.dw_player):
1842
1841
  pixmap = util.pil2pixmap(dw.player.screenshot_raw())
1843
1842
 
1844
- p = pl.Path(dw.player.playlist[dw.player.playlist_pos]["filename"])
1845
- image_file_path = str(pl.Path(output_dir) / f"{p.stem}_{n_player}_{dw.player.estimated_frame_number:06}.jpg")
1843
+ p = Path(dw.player.playlist[dw.player.playlist_pos]["filename"])
1844
+ image_file_path = str(Path(output_dir) / f"{p.stem}_{n_player}_{dw.player.estimated_frame_number:06}.jpg")
1846
1845
 
1847
1846
  # draw measurements
1848
- RADIUS = 6
1847
+ # RADIUS = 6
1849
1848
  painter = QPainter()
1850
1849
  painter.begin(pixmap)
1851
1850
 
@@ -1856,7 +1855,7 @@ class MainWindow(QMainWindow, Ui_MainWindow):
1856
1855
 
1857
1856
  painter.end()
1858
1857
  # check if file already exists
1859
- if pl.Path(image_file_path).is_file():
1858
+ if Path(image_file_path).is_file():
1860
1859
  if (
1861
1860
  dialog.MessageDialog(
1862
1861
  cfg.programName, f"The file {image_file_path} already exists.", (cfg.CANCEL, cfg.OVERWRITE)
@@ -1873,16 +1872,16 @@ class MainWindow(QMainWindow, Ui_MainWindow):
1873
1872
  pixmap = QPixmap(self.images_list[frame_idx])
1874
1873
 
1875
1874
  # draw measurements
1876
- RADIUS = 6
1875
+ # RADIUS = 6
1877
1876
  painter = QPainter()
1878
1877
  painter.begin(pixmap)
1879
1878
  for element in self.measurement_w.draw_mem.get(frame_idx, []):
1880
1879
  painter = draw_element(painter, element)
1881
1880
  painter.end()
1882
1881
 
1883
- image_file_path = str(pl.Path(output_dir) / f"{pl.Path(self.images_list[frame_idx]).stem}.jpg")
1882
+ image_file_path = str(Path(output_dir) / f"{Path(self.images_list[frame_idx]).stem}.jpg")
1884
1883
  # check if file already exists
1885
- if pl.Path(image_file_path).is_file():
1884
+ if Path(image_file_path).is_file():
1886
1885
  if (
1887
1886
  dialog.MessageDialog(
1888
1887
  cfg.programName, f"The file {image_file_path} already exists.", (cfg.CANCEL, cfg.OVERWRITE)
@@ -1905,10 +1904,10 @@ class MainWindow(QMainWindow, Ui_MainWindow):
1905
1904
 
1906
1905
  for frame_idx in d:
1907
1906
  for n_player in d[frame_idx]:
1908
- media_path = pl.Path(
1907
+ media_path = Path(
1909
1908
  self.dw_player[n_player - 1].player.playlist[self.dw_player[n_player - 1].player.playlist_pos]["filename"]
1910
1909
  )
1911
- file_name = pl.Path(f"{media_path.stem}_{element['player']}_{frame_idx:06}")
1910
+ file_name = Path(f"{media_path.stem}_{element['player']}_{frame_idx:06}")
1912
1911
 
1913
1912
  ffmpeg_command = [
1914
1913
  self.ffmpeg_bin,
@@ -1919,14 +1918,14 @@ class MainWindow(QMainWindow, Ui_MainWindow):
1919
1918
  rf"select=gte(n\, {frame_idx})",
1920
1919
  "-frames:v",
1921
1920
  "1",
1922
- str(pl.Path(output_dir) / file_name.with_suffix(".jpg")),
1921
+ str(Path(output_dir) / file_name.with_suffix(".jpg")),
1923
1922
  ]
1924
1923
 
1925
1924
  p = subprocess.Popen(ffmpeg_command, stdout=subprocess.PIPE, stderr=subprocess.PIPE) # do not use shell=True!
1926
1925
  out, error = p.communicate()
1927
1926
 
1928
- pixmap = QPixmap(str(pl.Path(output_dir) / file_name.with_suffix(".jpg")))
1929
- RADIUS = 6
1927
+ pixmap = QPixmap(str(Path(output_dir) / file_name.with_suffix(".jpg")))
1928
+ # RADIUS = 6
1930
1929
  painter = QPainter()
1931
1930
  painter.begin(pixmap)
1932
1931
 
@@ -1935,10 +1934,10 @@ class MainWindow(QMainWindow, Ui_MainWindow):
1935
1934
 
1936
1935
  painter.end()
1937
1936
  # check if file already exists
1938
- if (pl.Path(output_dir) / file_name.with_suffix(".jpg")).is_file():
1937
+ if (Path(output_dir) / file_name.with_suffix(".jpg")).is_file():
1939
1938
  answer = dialog.MessageDialog(
1940
1939
  cfg.programName,
1941
- f"The file {pl.Path(output_dir) / file_name.with_suffix('.jpg')} already exists.",
1940
+ f"The file {Path(output_dir) / file_name.with_suffix('.jpg')} already exists.",
1942
1941
  (cfg.CANCEL, cfg.OVERWRITE, "Abort"),
1943
1942
  )
1944
1943
  if answer == cfg.CANCEL:
@@ -1946,7 +1945,7 @@ class MainWindow(QMainWindow, Ui_MainWindow):
1946
1945
  if answer == "Abort":
1947
1946
  return
1948
1947
 
1949
- pixmap.save(str(pl.Path(output_dir) / file_name.with_suffix(".jpg")), "JPG")
1948
+ pixmap.save(str(Path(output_dir) / file_name.with_suffix(".jpg")), "JPG")
1950
1949
 
1951
1950
  def resize_dw(self, dw_id):
1952
1951
  """
@@ -2420,7 +2419,7 @@ class MainWindow(QMainWindow, Ui_MainWindow):
2420
2419
  """
2421
2420
  self.menuRecent_projects.clear()
2422
2421
  for project_file_path in self.recent_projects:
2423
- if pl.Path(project_file_path).is_file():
2422
+ if Path(project_file_path).is_file():
2424
2423
  action = QAction(self, visible=False, triggered=self.open_project_activated)
2425
2424
  action.setText(project_file_path)
2426
2425
  action.setVisible(True)
@@ -2751,7 +2750,7 @@ class MainWindow(QMainWindow, Ui_MainWindow):
2751
2750
  self.projectChanged = project_changed
2752
2751
  self.load_behaviors_in_twEthogram([self.pj[cfg.ETHOGRAM][x][cfg.BEHAVIOR_CODE] for x in self.pj[cfg.ETHOGRAM]])
2753
2752
  self.load_subjects_in_twSubjects([self.pj[cfg.SUBJECTS][x][cfg.SUBJECT_NAME] for x in self.pj[cfg.SUBJECTS]])
2754
- self.projectFileName = str(pl.Path(project_path).absolute())
2753
+ self.projectFileName = str(Path(project_path).absolute())
2755
2754
  self.project = True
2756
2755
  if str(self.projectFileName) not in self.recent_projects:
2757
2756
  self.recent_projects = [str(self.projectFileName)] + self.recent_projects
@@ -3335,7 +3334,7 @@ class MainWindow(QMainWindow, Ui_MainWindow):
3335
3334
  project_new_file_name = os.path.splitext(os.path.splitext(project_new_file_name)[0])[0]
3336
3335
  project_new_file_name += ".boris"
3337
3336
  # check if file name with extension already exists
3338
- if pl.Path(project_new_file_name).is_file():
3337
+ if Path(project_new_file_name).is_file():
3339
3338
  if (
3340
3339
  dialog.MessageDialog(
3341
3340
  cfg.programName,
@@ -3351,7 +3350,7 @@ class MainWindow(QMainWindow, Ui_MainWindow):
3351
3350
  project_new_file_name = os.path.splitext(project_new_file_name)[0]
3352
3351
  project_new_file_name += ".boris.gz"
3353
3352
  # check if file name with extension already exists
3354
- if pl.Path(project_new_file_name).is_file():
3353
+ if Path(project_new_file_name).is_file():
3355
3354
  if (
3356
3355
  dialog.MessageDialog(
3357
3356
  cfg.programName,
@@ -3431,7 +3430,7 @@ class MainWindow(QMainWindow, Ui_MainWindow):
3431
3430
  self.projectFileName = os.path.splitext(os.path.splitext(self.projectFileName)[0])[0]
3432
3431
  self.projectFileName += ".boris"
3433
3432
  # check if file name with extension already exists
3434
- if pl.Path(self.projectFileName).is_file():
3433
+ if Path(self.projectFileName).is_file():
3435
3434
  if (
3436
3435
  dialog.MessageDialog(
3437
3436
  cfg.programName,
@@ -3450,7 +3449,7 @@ class MainWindow(QMainWindow, Ui_MainWindow):
3450
3449
 
3451
3450
  self.projectFileName += ".boris.gz"
3452
3451
  # check if file name with extension already exists
3453
- if pl.Path(self.projectFileName).is_file():
3452
+ if Path(self.projectFileName).is_file():
3454
3453
  if (
3455
3454
  dialog.MessageDialog(
3456
3455
  cfg.programName,
@@ -4044,14 +4043,6 @@ class MainWindow(QMainWindow, Ui_MainWindow):
4044
4043
  """
4045
4044
  enable or disable video if any and audio if any
4046
4045
  """
4047
- # if video
4048
- # print(f"{n_player=} {enable=}")
4049
- # print(f"{self.dw_player[n_player].player.video_format=}")
4050
- # print(f"{self.dw_player[n_player].player.audio_bitrate=}")
4051
-
4052
- # self.pj[cfg.OBSERVATIONS][self.observationId][cfg.MEDIA_INFO][cfg.HAS_VIDEO][]
4053
- # if self.dw_player[n_player].player.playlist_pos is not None:
4054
- # print(self.dw_player[n_player].player.playlist[self.dw_player[n_player].player.playlist_pos]["filename"])
4055
4046
 
4056
4047
  if self.dw_player[n_player].player.video_format:
4057
4048
  self.dw_player[n_player].stack.setCurrentIndex(1 if not enable else 0)
@@ -4245,7 +4236,7 @@ class MainWindow(QMainWindow, Ui_MainWindow):
4245
4236
 
4246
4237
  # current media name
4247
4238
  if self.dw_player[0].player.playlist_pos is not None:
4248
- current_media_name = pl.Path(self.dw_player[0].player.playlist[self.dw_player[0].player.playlist_pos]["filename"]).name
4239
+ current_media_name = Path(self.dw_player[0].player.playlist[self.dw_player[0].player.playlist_pos]["filename"]).name
4249
4240
  current_playlist_index = self.dw_player[0].player.playlist_pos
4250
4241
  else:
4251
4242
  current_media_name = ""
@@ -5144,7 +5135,7 @@ class MainWindow(QMainWindow, Ui_MainWindow):
5144
5135
  ),
5145
5136
  )
5146
5137
  return
5147
- media_file_name = self.dw_player[0].player.playlist[self.dw_player[0].player.playlist_pos]["filename"]
5138
+ media_file_name = Path(self.dw_player[0].player.playlist[self.dw_player[0].player.playlist_pos]["filename"]).as_posix()
5148
5139
 
5149
5140
  time_ -= self.pj[cfg.OBSERVATIONS][self.observationId][cfg.MEDIA_INFO][cfg.MEDIA_CREATION_TIME][media_file_name]
5150
5141
 
@@ -5704,7 +5695,7 @@ def main():
5704
5695
  url = "https://github.com/boris-behav-obs/boris-behav-obs.github.io/releases/download/files/"
5705
5696
 
5706
5697
  # search where to download ffmpeg
5707
- ffmpeg_dir = pl.Path(__file__).parent / "misc"
5698
+ ffmpeg_dir = Path(__file__).parent / "misc"
5708
5699
 
5709
5700
  logging.debug(f"{ffmpeg_dir=}")
5710
5701
 
@@ -5792,7 +5783,7 @@ def main():
5792
5783
  # check project integrity
5793
5784
  # read config
5794
5785
  config_param: dict = {}
5795
- ini_file_path = pl.Path.home() / pl.Path(".boris")
5786
+ ini_file_path = Path.home() / Path(".boris")
5796
5787
  if ini_file_path.is_file():
5797
5788
  settings = QSettings(str(ini_file_path), QSettings.IniFormat)
5798
5789
  try:
@@ -3,7 +3,7 @@
3
3
  ################################################################################
4
4
  ## Form generated from reading UI file 'core.ui'
5
5
  ##
6
- ## Created by: Qt User Interface Compiler version 6.8.0
6
+ ## Created by: Qt User Interface Compiler version 6.9.0
7
7
  ##
8
8
  ## WARNING! All changes made in this file will be lost when recompiling UI file!
9
9
  ################################################################################
@@ -378,6 +378,8 @@ class Ui_MainWindow(object):
378
378
  self.actionAdd_frame_indexes.setObjectName(u"actionAdd_frame_indexes")
379
379
  self.action_load_plugins = QAction(MainWindow)
380
380
  self.action_load_plugins.setObjectName(u"action_load_plugins")
381
+ self.actionCreate_video_spectrogram = QAction(MainWindow)
382
+ self.actionCreate_video_spectrogram.setObjectName(u"actionCreate_video_spectrogram")
381
383
  self.centralwidget = QWidget(MainWindow)
382
384
  self.centralwidget.setObjectName(u"centralwidget")
383
385
  self.horizontalLayout_2 = QHBoxLayout(self.centralwidget)
@@ -484,7 +486,7 @@ class Ui_MainWindow(object):
484
486
  MainWindow.setCentralWidget(self.centralwidget)
485
487
  self.menubar = QMenuBar(MainWindow)
486
488
  self.menubar.setObjectName(u"menubar")
487
- self.menubar.setGeometry(QRect(0, 0, 1509, 22))
489
+ self.menubar.setGeometry(QRect(0, 0, 1509, 20))
488
490
  self.menuHelp = QMenu(self.menubar)
489
491
  self.menuHelp.setObjectName(u"menuHelp")
490
492
  self.menuFile = QMenu(self.menubar)
@@ -775,6 +777,7 @@ class Ui_MainWindow(object):
775
777
  self.menuMedia_file.addAction(self.actionRecode_resize_video)
776
778
  self.menuMedia_file.addAction(self.actionRotate_video)
777
779
  self.menuMedia_file.addAction(self.actionMerge_media_files)
780
+ self.menuMedia_file.addAction(self.actionCreate_video_spectrogram)
778
781
  self.toolBar.addAction(self.action_obs_list)
779
782
  self.toolBar.addAction(self.actionPlay)
780
783
  self.toolBar.addAction(self.actionReset)
@@ -1029,6 +1032,7 @@ class Ui_MainWindow(object):
1029
1032
  self.actionConfigure_tvevents_columns.setText(QCoreApplication.translate("MainWindow", u"Configure columns", None))
1030
1033
  self.actionAdd_frame_indexes.setText(QCoreApplication.translate("MainWindow", u"Add frame indexes", None))
1031
1034
  self.action_load_plugins.setText(QCoreApplication.translate("MainWindow", u"Load plugins", None))
1035
+ self.actionCreate_video_spectrogram.setText(QCoreApplication.translate("MainWindow", u"Create video spectrogram", None))
1032
1036
  self.lbLogoBoris.setText("")
1033
1037
  self.lbLogoUnito.setText("")
1034
1038
  self.lb_player_status.setText(QCoreApplication.translate("MainWindow", u"lb_player_status", None))