boris-behav-obs 9.6.2__tar.gz → 9.6.4__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 (130) hide show
  1. {boris_behav_obs-9.6.2 → boris_behav_obs-9.6.4}/PKG-INFO +22 -16
  2. {boris_behav_obs-9.6.2 → boris_behav_obs-9.6.4}/README.TXT +20 -22
  3. {boris_behav_obs-9.6.2 → boris_behav_obs-9.6.4}/README.md +12 -6
  4. boris_behav_obs-9.6.4/boris/1.py +45 -0
  5. boris_behav_obs-9.6.4/boris/analysis_plugins/irr_cohen_kappa.py +97 -0
  6. boris_behav_obs-9.6.4/boris/analysis_plugins/irr_cohen_kappa_with_modifiers.py +101 -0
  7. {boris_behav_obs-9.6.2 → boris_behav_obs-9.6.4}/boris/analysis_plugins/irr_weighted_cohen_kappa.py +36 -10
  8. {boris_behav_obs-9.6.2 → boris_behav_obs-9.6.4}/boris/analysis_plugins/irr_weighted_cohen_kappa_with_modifiers.py +36 -10
  9. {boris_behav_obs-9.6.2 → boris_behav_obs-9.6.4}/boris/analysis_plugins/time_budget.py +0 -4
  10. {boris_behav_obs-9.6.2 → boris_behav_obs-9.6.4}/boris/behav_coding_map_creator.py +0 -1
  11. {boris_behav_obs-9.6.2 → boris_behav_obs-9.6.4}/boris/coding_pad.py +0 -2
  12. {boris_behav_obs-9.6.2 → boris_behav_obs-9.6.4}/boris/config_file.py +0 -2
  13. {boris_behav_obs-9.6.2 → boris_behav_obs-9.6.4}/boris/core.py +9 -24
  14. {boris_behav_obs-9.6.2 → boris_behav_obs-9.6.4}/boris/db_functions.py +4 -4
  15. {boris_behav_obs-9.6.2 → boris_behav_obs-9.6.4}/boris/edit_event.py +0 -9
  16. {boris_behav_obs-9.6.2 → boris_behav_obs-9.6.4}/boris/export_events.py +68 -76
  17. {boris_behav_obs-9.6.2 → boris_behav_obs-9.6.4}/boris/gui_utilities.py +0 -1
  18. {boris_behav_obs-9.6.2 → boris_behav_obs-9.6.4}/boris/modifier_coding_map_creator.py +0 -2
  19. {boris_behav_obs-9.6.2 → boris_behav_obs-9.6.4}/boris/observation_operations.py +2 -4
  20. {boris_behav_obs-9.6.2 → boris_behav_obs-9.6.4}/boris/param_panel.py +0 -4
  21. {boris_behav_obs-9.6.2 → boris_behav_obs-9.6.4}/boris/plot_spectrogram_rt.py +2 -1
  22. {boris_behav_obs-9.6.2 → boris_behav_obs-9.6.4}/boris/plot_waveform_rt.py +2 -1
  23. {boris_behav_obs-9.6.2 → boris_behav_obs-9.6.4}/boris/plugins.py +41 -3
  24. {boris_behav_obs-9.6.2 → boris_behav_obs-9.6.4}/boris/preferences.py +23 -7
  25. {boris_behav_obs-9.6.2 → boris_behav_obs-9.6.4}/boris/time_budget_functions.py +0 -9
  26. {boris_behav_obs-9.6.2 → boris_behav_obs-9.6.4}/boris/version.py +2 -2
  27. {boris_behav_obs-9.6.2 → boris_behav_obs-9.6.4}/boris/video_equalizer.py +0 -2
  28. {boris_behav_obs-9.6.2 → boris_behav_obs-9.6.4}/boris/view_df.py +0 -2
  29. {boris_behav_obs-9.6.2 → boris_behav_obs-9.6.4}/boris/write_event.py +0 -9
  30. {boris_behav_obs-9.6.2 → boris_behav_obs-9.6.4}/boris_behav_obs.egg-info/PKG-INFO +22 -16
  31. {boris_behav_obs-9.6.2 → boris_behav_obs-9.6.4}/boris_behav_obs.egg-info/SOURCES.txt +1 -0
  32. boris_behav_obs-9.6.4/boris_behav_obs.egg-info/requires.txt +18 -0
  33. {boris_behav_obs-9.6.2 → boris_behav_obs-9.6.4}/pyproject.toml +10 -10
  34. boris_behav_obs-9.6.2/boris/analysis_plugins/irr_cohen_kappa.py +0 -72
  35. boris_behav_obs-9.6.2/boris/analysis_plugins/irr_cohen_kappa_with_modifiers.py +0 -77
  36. boris_behav_obs-9.6.2/boris_behav_obs.egg-info/requires.txt +0 -18
  37. {boris_behav_obs-9.6.2 → boris_behav_obs-9.6.4}/LICENSE.TXT +0 -0
  38. {boris_behav_obs-9.6.2 → boris_behav_obs-9.6.4}/MANIFEST.in +0 -0
  39. {boris_behav_obs-9.6.2 → boris_behav_obs-9.6.4}/boris/__init__.py +0 -0
  40. {boris_behav_obs-9.6.2 → boris_behav_obs-9.6.4}/boris/__main__.py +0 -0
  41. {boris_behav_obs-9.6.2 → boris_behav_obs-9.6.4}/boris/about.py +0 -0
  42. {boris_behav_obs-9.6.2 → boris_behav_obs-9.6.4}/boris/add_modifier.py +0 -0
  43. {boris_behav_obs-9.6.2 → boris_behav_obs-9.6.4}/boris/add_modifier_ui.py +0 -0
  44. {boris_behav_obs-9.6.2 → boris_behav_obs-9.6.4}/boris/advanced_event_filtering.py +0 -0
  45. {boris_behav_obs-9.6.2 → boris_behav_obs-9.6.4}/boris/analysis_plugins/__init__.py +0 -0
  46. {boris_behav_obs-9.6.2 → boris_behav_obs-9.6.4}/boris/analysis_plugins/_latency.py +0 -0
  47. {boris_behav_obs-9.6.2 → boris_behav_obs-9.6.4}/boris/analysis_plugins/list_of_dataframe_columns.py +0 -0
  48. {boris_behav_obs-9.6.2 → boris_behav_obs-9.6.4}/boris/analysis_plugins/number_of_occurences.py +0 -0
  49. {boris_behav_obs-9.6.2 → boris_behav_obs-9.6.4}/boris/analysis_plugins/number_of_occurences_by_independent_variable.py +0 -0
  50. {boris_behav_obs-9.6.2 → boris_behav_obs-9.6.4}/boris/behavior_binary_table.py +0 -0
  51. {boris_behav_obs-9.6.2 → boris_behav_obs-9.6.4}/boris/behaviors_coding_map.py +0 -0
  52. {boris_behav_obs-9.6.2 → boris_behav_obs-9.6.4}/boris/boris_cli.py +0 -0
  53. {boris_behav_obs-9.6.2 → boris_behav_obs-9.6.4}/boris/cmd_arguments.py +0 -0
  54. {boris_behav_obs-9.6.2 → boris_behav_obs-9.6.4}/boris/config.py +0 -0
  55. {boris_behav_obs-9.6.2 → boris_behav_obs-9.6.4}/boris/connections.py +0 -0
  56. {boris_behav_obs-9.6.2 → boris_behav_obs-9.6.4}/boris/converters.py +0 -0
  57. {boris_behav_obs-9.6.2 → boris_behav_obs-9.6.4}/boris/converters_ui.py +0 -0
  58. {boris_behav_obs-9.6.2 → boris_behav_obs-9.6.4}/boris/cooccurence.py +0 -0
  59. {boris_behav_obs-9.6.2 → boris_behav_obs-9.6.4}/boris/core_qrc.py +0 -0
  60. {boris_behav_obs-9.6.2 → boris_behav_obs-9.6.4}/boris/core_ui.py +0 -0
  61. {boris_behav_obs-9.6.2 → boris_behav_obs-9.6.4}/boris/dev.py +0 -0
  62. {boris_behav_obs-9.6.2 → boris_behav_obs-9.6.4}/boris/dialog.py +0 -0
  63. {boris_behav_obs-9.6.2 → boris_behav_obs-9.6.4}/boris/duration_widget.py +0 -0
  64. {boris_behav_obs-9.6.2 → boris_behav_obs-9.6.4}/boris/edit_event_ui.py +0 -0
  65. {boris_behav_obs-9.6.2 → boris_behav_obs-9.6.4}/boris/event_operations.py +0 -0
  66. {boris_behav_obs-9.6.2 → boris_behav_obs-9.6.4}/boris/events_cursor.py +0 -0
  67. {boris_behav_obs-9.6.2 → boris_behav_obs-9.6.4}/boris/events_snapshots.py +0 -0
  68. {boris_behav_obs-9.6.2 → boris_behav_obs-9.6.4}/boris/exclusion_matrix.py +0 -0
  69. {boris_behav_obs-9.6.2 → boris_behav_obs-9.6.4}/boris/export_observation.py +0 -0
  70. {boris_behav_obs-9.6.2 → boris_behav_obs-9.6.4}/boris/external_processes.py +0 -0
  71. {boris_behav_obs-9.6.2 → boris_behav_obs-9.6.4}/boris/geometric_measurement.py +0 -0
  72. {boris_behav_obs-9.6.2 → boris_behav_obs-9.6.4}/boris/image_overlay.py +0 -0
  73. {boris_behav_obs-9.6.2 → boris_behav_obs-9.6.4}/boris/import_observations.py +0 -0
  74. {boris_behav_obs-9.6.2 → boris_behav_obs-9.6.4}/boris/irr.py +0 -0
  75. {boris_behav_obs-9.6.2 → boris_behav_obs-9.6.4}/boris/latency.py +0 -0
  76. {boris_behav_obs-9.6.2 → boris_behav_obs-9.6.4}/boris/measurement_widget.py +0 -0
  77. {boris_behav_obs-9.6.2 → boris_behav_obs-9.6.4}/boris/media_file.py +0 -0
  78. {boris_behav_obs-9.6.2 → boris_behav_obs-9.6.4}/boris/menu_options.py +0 -0
  79. {boris_behav_obs-9.6.2 → boris_behav_obs-9.6.4}/boris/modifiers_coding_map.py +0 -0
  80. {boris_behav_obs-9.6.2 → boris_behav_obs-9.6.4}/boris/mpv-1.0.3.py +0 -0
  81. {boris_behav_obs-9.6.2 → boris_behav_obs-9.6.4}/boris/mpv.py +0 -0
  82. {boris_behav_obs-9.6.2 → boris_behav_obs-9.6.4}/boris/mpv2.py +0 -0
  83. {boris_behav_obs-9.6.2 → boris_behav_obs-9.6.4}/boris/observation.py +0 -0
  84. {boris_behav_obs-9.6.2 → boris_behav_obs-9.6.4}/boris/observation_ui.py +0 -0
  85. {boris_behav_obs-9.6.2 → boris_behav_obs-9.6.4}/boris/observations_list.py +0 -0
  86. {boris_behav_obs-9.6.2 → boris_behav_obs-9.6.4}/boris/otx_parser.py +0 -0
  87. {boris_behav_obs-9.6.2 → boris_behav_obs-9.6.4}/boris/param_panel_ui.py +0 -0
  88. {boris_behav_obs-9.6.2 → boris_behav_obs-9.6.4}/boris/player_dock_widget.py +0 -0
  89. {boris_behav_obs-9.6.2 → boris_behav_obs-9.6.4}/boris/plot_data_module.py +0 -0
  90. {boris_behav_obs-9.6.2 → boris_behav_obs-9.6.4}/boris/plot_events.py +0 -0
  91. {boris_behav_obs-9.6.2 → boris_behav_obs-9.6.4}/boris/plot_events_rt.py +0 -0
  92. {boris_behav_obs-9.6.2 → boris_behav_obs-9.6.4}/boris/portion/__init__.py +0 -0
  93. {boris_behav_obs-9.6.2 → boris_behav_obs-9.6.4}/boris/portion/const.py +0 -0
  94. {boris_behav_obs-9.6.2 → boris_behav_obs-9.6.4}/boris/portion/dict.py +0 -0
  95. {boris_behav_obs-9.6.2 → boris_behav_obs-9.6.4}/boris/portion/func.py +0 -0
  96. {boris_behav_obs-9.6.2 → boris_behav_obs-9.6.4}/boris/portion/interval.py +0 -0
  97. {boris_behav_obs-9.6.2 → boris_behav_obs-9.6.4}/boris/portion/io.py +0 -0
  98. {boris_behav_obs-9.6.2 → boris_behav_obs-9.6.4}/boris/preferences_ui.py +0 -0
  99. {boris_behav_obs-9.6.2 → boris_behav_obs-9.6.4}/boris/project.py +0 -0
  100. {boris_behav_obs-9.6.2 → boris_behav_obs-9.6.4}/boris/project_functions.py +0 -0
  101. {boris_behav_obs-9.6.2 → boris_behav_obs-9.6.4}/boris/project_import_export.py +0 -0
  102. {boris_behav_obs-9.6.2 → boris_behav_obs-9.6.4}/boris/project_ui.py +0 -0
  103. {boris_behav_obs-9.6.2 → boris_behav_obs-9.6.4}/boris/qrc_boris.py +0 -0
  104. {boris_behav_obs-9.6.2 → boris_behav_obs-9.6.4}/boris/qrc_boris5.py +0 -0
  105. {boris_behav_obs-9.6.2 → boris_behav_obs-9.6.4}/boris/select_modifiers.py +0 -0
  106. {boris_behav_obs-9.6.2 → boris_behav_obs-9.6.4}/boris/select_observations.py +0 -0
  107. {boris_behav_obs-9.6.2 → boris_behav_obs-9.6.4}/boris/select_subj_behav.py +0 -0
  108. {boris_behav_obs-9.6.2 → boris_behav_obs-9.6.4}/boris/state_events.py +0 -0
  109. {boris_behav_obs-9.6.2 → boris_behav_obs-9.6.4}/boris/subjects_pad.py +0 -0
  110. {boris_behav_obs-9.6.2 → boris_behav_obs-9.6.4}/boris/synthetic_time_budget.py +0 -0
  111. {boris_behav_obs-9.6.2 → boris_behav_obs-9.6.4}/boris/time_budget_widget.py +0 -0
  112. {boris_behav_obs-9.6.2 → boris_behav_obs-9.6.4}/boris/transitions.py +0 -0
  113. {boris_behav_obs-9.6.2 → boris_behav_obs-9.6.4}/boris/utilities.py +0 -0
  114. {boris_behav_obs-9.6.2 → boris_behav_obs-9.6.4}/boris/video_equalizer_ui.py +0 -0
  115. {boris_behav_obs-9.6.2 → boris_behav_obs-9.6.4}/boris/video_operations.py +0 -0
  116. {boris_behav_obs-9.6.2 → boris_behav_obs-9.6.4}/boris/view_df_ui.py +0 -0
  117. {boris_behav_obs-9.6.2 → boris_behav_obs-9.6.4}/boris_behav_obs.egg-info/dependency_links.txt +0 -0
  118. {boris_behav_obs-9.6.2 → boris_behav_obs-9.6.4}/boris_behav_obs.egg-info/entry_points.txt +0 -0
  119. {boris_behav_obs-9.6.2 → boris_behav_obs-9.6.4}/boris_behav_obs.egg-info/top_level.txt +0 -0
  120. {boris_behav_obs-9.6.2 → boris_behav_obs-9.6.4}/setup.cfg +0 -0
  121. {boris_behav_obs-9.6.2 → boris_behav_obs-9.6.4}/tests/test_db_functions.py +0 -0
  122. {boris_behav_obs-9.6.2 → boris_behav_obs-9.6.4}/tests/test_export_observation.py +0 -0
  123. {boris_behav_obs-9.6.2 → boris_behav_obs-9.6.4}/tests/test_irr.py +0 -0
  124. {boris_behav_obs-9.6.2 → boris_behav_obs-9.6.4}/tests/test_observation_gui.py +0 -0
  125. {boris_behav_obs-9.6.2 → boris_behav_obs-9.6.4}/tests/test_otx_parser.py +0 -0
  126. {boris_behav_obs-9.6.2 → boris_behav_obs-9.6.4}/tests/test_preferences_gui.py +0 -0
  127. {boris_behav_obs-9.6.2 → boris_behav_obs-9.6.4}/tests/test_project_functions.py +0 -0
  128. {boris_behav_obs-9.6.2 → boris_behav_obs-9.6.4}/tests/test_time_budget.py +0 -0
  129. {boris_behav_obs-9.6.2 → boris_behav_obs-9.6.4}/tests/test_utilities.py +0 -0
  130. {boris_behav_obs-9.6.2 → boris_behav_obs-9.6.4}/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.6.2
3
+ Version: 9.6.4
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
@@ -18,16 +18,16 @@ Classifier: Topic :: Scientific/Engineering
18
18
  Requires-Python: >=3.12
19
19
  Description-Content-Type: text/markdown
20
20
  License-File: LICENSE.TXT
21
- Requires-Dist: exifread>=3.0.0
22
- Requires-Dist: numpy>=1.26.4
23
- Requires-Dist: matplotlib>=3.3.3
24
- Requires-Dist: pandas>=2.2.2
25
- Requires-Dist: tablib[cli,html,ods,pandas,xls,xlsx]>=3
26
- Requires-Dist: pyreadr
21
+ Requires-Dist: exifread==3.5.1
22
+ Requires-Dist: numpy==2.3.2
23
+ Requires-Dist: matplotlib==3.10.5
24
+ Requires-Dist: pandas==2.3.2
25
+ Requires-Dist: tablib[cli,html,ods,pandas,xls,xlsx]==3.8.0
26
+ Requires-Dist: pyreadr==0.5.3
27
27
  Requires-Dist: pyside6==6.9
28
- Requires-Dist: hachoir>=3.3.0
29
- Requires-Dist: scipy>=1.15.3
30
- Requires-Dist: scikit-learn>=1.7.1
28
+ Requires-Dist: hachoir==3.3.0
29
+ Requires-Dist: scipy==1.16.1
30
+ Requires-Dist: scikit-learn==1.7.1
31
31
  Provides-Extra: dev
32
32
  Requires-Dist: ruff; extra == "dev"
33
33
  Requires-Dist: pytest; extra == "dev"
@@ -49,7 +49,10 @@ You can not longer run BORIS natively on MacOS (since v.8). Some alternatives to
49
49
 
50
50
  It provides also some analysis tools like time budget and some plotting functions.
51
51
 
52
- The BORIS paper has more than [![BORIS citations counter](http://penelope.unito.it/friard/boris_scopus_citations.png) citations](https://www.boris.unito.it/citations) in peer-reviewed scientific publications.
52
+ <!-- The BO-RIS paper has more than [![BORIS citations counter](https://penelope.unito.it/friard/boris_scopus_citations.png) citations](https://www.boris.unito.it/citations) in peer-reviewed scientific publications. -->
53
+
54
+
55
+ The BORIS paper has more than 2332 citations in peer-reviewed scientific publications.
53
56
 
54
57
 
55
58
 
@@ -59,13 +62,17 @@ See the official [BORIS web site](https://www.boris.unito.it).
59
62
  [![Python web site](https://img.shields.io/badge/Made%20with-Python-1f425f.svg)](https://www.python.org)
60
63
  ![Python versions](https://img.shields.io/pypi/pyversions/boris-behav-obs)
61
64
  ![BORIS license](https://img.shields.io/pypi/l/boris-behav-obs)
65
+ [![PyPI version](https://img.shields.io/pypi/v/boris-behav-obs.svg)](https://pypi.org/project/boris-behav-obs/)
66
+
62
67
  [![Number of downloads](https://static.pepy.tech/personalized-badge/boris-behav-obs?period=total&units=international_system&left_color=black&right_color=orange&left_text=Downloads)](https://pepy.tech/project/boris-behav-obs)
63
68
  ![commit-activity](https://img.shields.io/github/commit-activity/m/olivierfriard/BORIS)
64
- [![PyPI version](https://img.shields.io/pypi/v/boris-behav-obs.svg)](https://pypi.org/project/boris-behav-obs/)
65
- ![BORIS scopus citations badge](http://penelope.unito.it/friard/boris_scopus_citations.svg)
69
+ ![GitHub last commit](https://img.shields.io/github/last-commit/olivierfriard/BORIS)
66
70
 
71
+ ![BORIS scopus citations badge](https://penelope.unito.it/friard/boris_scopus_citations.svg)
67
72
 
68
73
 
74
+ ![GitHub Repo stars](https://img.shields.io/github/stars/olivierfriard/BORIS?style=flat&label=Stars)
75
+ [![Please Star](https://img.shields.io/badge/⭐-Star%20this%20repo-blue?style=flat-square)](https://github.com/olivierfriard/BORIS/stargazers)
69
76
 
70
77
  # Documentation
71
78
 
@@ -82,8 +89,7 @@ Some [video tutorials](https://www.boris.unito.it/video_tutorials/) are availabl
82
89
  # Bug reports and feature requests
83
90
 
84
91
 
85
- To search for bugs, report them or request a feature, please use the github tracker:
86
- https://github.com/olivierfriard/BORIS/issues
92
+ To search for bugs, report them or request a feature, please use the [GitHub issues tracker](https://github.com/olivierfriard/BORIS/issues)
87
93
 
88
94
 
89
95
 
@@ -129,7 +135,7 @@ GNU General Public License for more details.
129
135
 
130
136
  Distributed with a [GPL v.3 license](LICENSE.TXT).
131
137
 
132
- Copyright (C) 2012-2024 Olivier Friard
138
+ Copyright (C) 2012-2025 Olivier Friard
133
139
 
134
140
 
135
141
 
@@ -1,22 +1,20 @@
1
- BORIS
2
- Behavioral Observation Research Interactive Software
3
-
4
- Copyright 2012-2023 Olivier Friard
5
-
6
- BORIS is free software; you can redistribute it and/or modify
7
- it under the terms of the GNU General Public License as published by
8
- the Free Software Foundation; either version 3 of the License, or
9
- any later version.
10
-
11
- BORIS is distributed in the hope that it will be useful,
12
- but WITHOUT ANY WARRANTY; without even the implied warranty of
13
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
- GNU General Public License for more details.
15
-
16
- You should have received a copy of the GNU General Public License
17
- along with this program; if not, write to the Free Software
18
- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19
- MA 02110-1301, USA.
20
-
21
-
22
-
1
+ BORIS
2
+ Behavioral Observation Research Interactive Software
3
+
4
+ Copyright 2012-2025 Olivier Friard
5
+
6
+ BORIS is free software; you can redistribute it and/or modify
7
+ it under the terms of the GNU General Public License as published by
8
+ the Free Software Foundation; either version 3 of the License, or
9
+ any later version.
10
+
11
+ BORIS is distributed in the hope that it will be useful,
12
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
+ GNU General Public License for more details.
15
+
16
+ You should have received a copy of the GNU General Public License
17
+ along with this program; if not, write to the Free Software
18
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19
+ MA 02110-1301, USA.
20
+
@@ -11,7 +11,10 @@ You can not longer run BORIS natively on MacOS (since v.8). Some alternatives to
11
11
 
12
12
  It provides also some analysis tools like time budget and some plotting functions.
13
13
 
14
- The BORIS paper has more than [![BORIS citations counter](http://penelope.unito.it/friard/boris_scopus_citations.png) citations](https://www.boris.unito.it/citations) in peer-reviewed scientific publications.
14
+ <!-- The BO-RIS paper has more than [![BORIS citations counter](https://penelope.unito.it/friard/boris_scopus_citations.png) citations](https://www.boris.unito.it/citations) in peer-reviewed scientific publications. -->
15
+
16
+
17
+ The BORIS paper has more than 2332 citations in peer-reviewed scientific publications.
15
18
 
16
19
 
17
20
 
@@ -21,13 +24,17 @@ See the official [BORIS web site](https://www.boris.unito.it).
21
24
  [![Python web site](https://img.shields.io/badge/Made%20with-Python-1f425f.svg)](https://www.python.org)
22
25
  ![Python versions](https://img.shields.io/pypi/pyversions/boris-behav-obs)
23
26
  ![BORIS license](https://img.shields.io/pypi/l/boris-behav-obs)
27
+ [![PyPI version](https://img.shields.io/pypi/v/boris-behav-obs.svg)](https://pypi.org/project/boris-behav-obs/)
28
+
24
29
  [![Number of downloads](https://static.pepy.tech/personalized-badge/boris-behav-obs?period=total&units=international_system&left_color=black&right_color=orange&left_text=Downloads)](https://pepy.tech/project/boris-behav-obs)
25
30
  ![commit-activity](https://img.shields.io/github/commit-activity/m/olivierfriard/BORIS)
26
- [![PyPI version](https://img.shields.io/pypi/v/boris-behav-obs.svg)](https://pypi.org/project/boris-behav-obs/)
27
- ![BORIS scopus citations badge](http://penelope.unito.it/friard/boris_scopus_citations.svg)
31
+ ![GitHub last commit](https://img.shields.io/github/last-commit/olivierfriard/BORIS)
28
32
 
33
+ ![BORIS scopus citations badge](https://penelope.unito.it/friard/boris_scopus_citations.svg)
29
34
 
30
35
 
36
+ ![GitHub Repo stars](https://img.shields.io/github/stars/olivierfriard/BORIS?style=flat&label=Stars)
37
+ [![Please Star](https://img.shields.io/badge/⭐-Star%20this%20repo-blue?style=flat-square)](https://github.com/olivierfriard/BORIS/stargazers)
31
38
 
32
39
  # Documentation
33
40
 
@@ -44,8 +51,7 @@ Some [video tutorials](https://www.boris.unito.it/video_tutorials/) are availabl
44
51
  # Bug reports and feature requests
45
52
 
46
53
 
47
- To search for bugs, report them or request a feature, please use the github tracker:
48
- https://github.com/olivierfriard/BORIS/issues
54
+ To search for bugs, report them or request a feature, please use the [GitHub issues tracker](https://github.com/olivierfriard/BORIS/issues)
49
55
 
50
56
 
51
57
 
@@ -91,7 +97,7 @@ GNU General Public License for more details.
91
97
 
92
98
  Distributed with a [GPL v.3 license](LICENSE.TXT).
93
99
 
94
- Copyright (C) 2012-2024 Olivier Friard
100
+ Copyright (C) 2012-2025 Olivier Friard
95
101
 
96
102
 
97
103
 
@@ -0,0 +1,45 @@
1
+ import time
2
+ from PIL import Image, ImageDraw, ImageFont
3
+ import mpv
4
+
5
+ player = mpv.MPV()
6
+
7
+ player.loop = True
8
+ player.play('/home/olivier/gdrive_sync/src/python/generate_video_test/video1.mp4')
9
+ player.wait_until_playing()
10
+
11
+ font = ImageFont.truetype('DejaVuSans.ttf', 40)
12
+
13
+ overlay = player.create_image_overlay()
14
+
15
+ img = Image.new('RGBA', (400, 150), (255, 255, 255, 0))
16
+ d = ImageDraw.Draw(img)
17
+ d.text((10, 10), 'Hello World', font=font, fill=(0, 255, 255, 128))
18
+ #d.text((10, 60), f't={ts:.3f}', font=font, fill=(255, 0, 255, 255))
19
+
20
+ pos = 100
21
+
22
+ overlay.update(img, pos=(2*pos, pos))
23
+
24
+
25
+ while not player.core_idle:
26
+ pass
27
+
28
+
29
+ '''
30
+ for pos in range(0, 500, 5):
31
+ ts = player.time_pos
32
+ if ts is None:
33
+ break
34
+
35
+ img = Image.new('RGBA', (400, 150), (255, 255, 255, 0))
36
+ d = ImageDraw.Draw(img)
37
+ d.text((10, 10), 'Hello World', font=font, fill=(0, 255, 255, 128))
38
+ d.text((10, 60), f't={ts:.3f}', font=font, fill=(255, 0, 255, 255))
39
+
40
+ overlay.update(img, pos=(2*pos, pos))
41
+ time.sleep(0.05)
42
+
43
+
44
+ overlay.remove()
45
+ '''
@@ -0,0 +1,97 @@
1
+ """
2
+ BORIS plugin
3
+
4
+ Inter Rater Reliability (IRR) Unweighted Cohen's Kappa
5
+ """
6
+
7
+ import pandas as pd
8
+ from sklearn.metrics import cohen_kappa_score
9
+ from typing import Dict, Tuple
10
+
11
+ __version__ = "0.0.2"
12
+ __version_date__ = "2025-08-29"
13
+ __plugin_name__ = "Inter Rater Reliability - Unweighted Cohen's Kappa"
14
+ __author__ = "Olivier Friard - University of Torino - Italy"
15
+ __description__ = """
16
+ This plugin calculates Cohen's Kappa to measure inter-rater reliability between two observers who code categorical behaviors over time intervals.
17
+ Unlike the weighted version, this approach does not take into account the duration of the intervals.
18
+ Each segment of time is treated equally, regardless of how long it lasts.
19
+ This plugin does not take into account the modifiers.
20
+
21
+ How it works:
22
+
23
+ Time segmentation
24
+ The program identifies all the time boundaries (start and end points) used by both observers.
25
+ These boundaries are merged into a common timeline, which is then divided into a set of non-overlapping elementary intervals.
26
+
27
+ Assigning codes
28
+ For each elementary interval, the program determines which behavior was coded by each observer.
29
+
30
+ Comparison of codes
31
+ The program builds two parallel lists of behavior codes, one for each observer.
32
+ Each elementary interval is counted as one unit of observation, no matter how long the interval actually lasts.
33
+
34
+ Cohen's Kappa calculation
35
+ Using these two lists, the program computes Cohen's Kappa using the cohen_kappa_score function of the sklearn package.
36
+ (see https://scikit-learn.org/stable/modules/generated/sklearn.metrics.cohen_kappa_score.html for details)
37
+ This coefficient measures how much the observers agree on their coding, adjusted for the amount of agreement that would be expected by chance.
38
+
39
+ """
40
+
41
+
42
+ def run(df: pd.DataFrame) -> pd.DataFrame:
43
+ """
44
+ Calculate the Inter Rater Reliability - Unweighted Cohen's Kappa
45
+ """
46
+
47
+ # Attribute all active codes for each interval
48
+ def get_code(t_start, obs):
49
+ active_codes = [seg[2] for seg in obs if seg[0] <= t_start < seg[1]]
50
+ if not active_codes:
51
+ return ""
52
+ # Sort to ensure deterministic representation (e.g., "A+B" instead of "B+A")
53
+ return "+".join(sorted(active_codes))
54
+
55
+ # Get unique values
56
+ unique_obs_list = df["Observation id"].unique().tolist()
57
+
58
+ # Convert to tuples grouped by observation
59
+ grouped = {
60
+ obs: [
61
+ (row[0], row[1], row[2] + "|" + row[3]) # concatenate subject and behavior with |
62
+ for row in group[["Start (s)", "Stop (s)", "Subject", "Behavior"]].itertuples(index=False, name=None)
63
+ ]
64
+ for obs, group in df.groupby("Observation id")
65
+ }
66
+
67
+ ck_results: Dict[Tuple[str, str], str] = {}
68
+ for idx1, obs_id1 in enumerate(unique_obs_list):
69
+ obs1 = grouped[obs_id1]
70
+
71
+ # Perfect agreement with itself
72
+ ck_results[(obs_id1, obs_id1)] = "1.000"
73
+
74
+ for obs_id2 in unique_obs_list[idx1 + 1 :]:
75
+ obs2 = grouped[obs_id2]
76
+
77
+ # get all the break points
78
+ time_points = sorted(set([t for seg in obs1 for t in seg[:2]] + [t for seg in obs2 for t in seg[:2]]))
79
+
80
+ # elementary intervals
81
+ elementary_intervals = [(time_points[i], time_points[i + 1]) for i in range(len(time_points) - 1)]
82
+
83
+ obs1_codes = [get_code(t[0], obs1) for t in elementary_intervals]
84
+
85
+ obs2_codes = [get_code(t[0], obs2) for t in elementary_intervals]
86
+
87
+ # Cohen's Kappa
88
+ kappa = cohen_kappa_score(obs1_codes, obs2_codes)
89
+ print(f"{obs_id1} - {obs_id2}: Cohen's Kappa : {kappa:.3f}")
90
+
91
+ ck_results[(obs_id1, obs_id2)] = f"{kappa:.3f}"
92
+ ck_results[(obs_id2, obs_id1)] = f"{kappa:.3f}"
93
+
94
+ # DataFrame conversion
95
+ df_results = pd.Series(ck_results).unstack()
96
+
97
+ return df_results
@@ -0,0 +1,101 @@
1
+ """
2
+ BORIS plugin
3
+
4
+ Inter Rater Reliability (IRR) Unweighted Cohen's Kappa with modifiers
5
+ """
6
+
7
+ import pandas as pd
8
+ from sklearn.metrics import cohen_kappa_score
9
+
10
+ __version__ = "0.0.2"
11
+ __version_date__ = "2025-08-29"
12
+ __plugin_name__ = "Inter Rater Reliability - Unweighted Cohen's Kappa with modifiers"
13
+ __author__ = "Olivier Friard - University of Torino - Italy"
14
+ __description__ = """
15
+ This plugin calculates Cohen's Kappa to measure inter-rater reliability between two observers who code categorical behaviors over time intervals.
16
+ Unlike the weighted version, this approach does not take into account the duration of the intervals.
17
+ Each segment of time is treated equally, regardless of how long it lasts.
18
+ This plugin takes into account the modifiers.
19
+
20
+
21
+ How it works:
22
+
23
+ Time segmentation
24
+ The program identifies all the time boundaries (start and end points) used by both observers.
25
+ These boundaries are merged into a common timeline, which is then divided into a set of non-overlapping elementary intervals.
26
+
27
+ Assigning codes
28
+ For each elementary interval, the program determines which behavior was coded by each observer.
29
+
30
+ Comparison of codes
31
+ The program builds two parallel lists of behavior codes, one for each observer.
32
+ Each elementary interval is counted as one unit of observation, no matter how long the interval actually lasts.
33
+
34
+ Cohen's Kappa calculation
35
+ Using these two lists, the program computes Cohen's Kappa using the cohen_kappa_score function of the sklearn package.
36
+ (see https://scikit-learn.org/stable/modules/generated/sklearn.metrics.cohen_kappa_score.html for details)
37
+ This coefficient measures how much the observers agree on their coding, adjusted for the amount of agreement that would be expected by chance.
38
+
39
+ """
40
+
41
+
42
+ def run(df: pd.DataFrame):
43
+ """
44
+ Calculate the Inter Rater Reliability - Unweighted Cohen's Kappa with modifiers
45
+ """
46
+
47
+ # Attribute all active codes for each interval
48
+ def get_code(t_start, obs):
49
+ active_codes = [seg[2] for seg in obs if seg[0] <= t_start < seg[1]]
50
+ if not active_codes:
51
+ return ""
52
+ # Sort to ensure deterministic representation (e.g., "A+B" instead of "B+A")
53
+ return "+".join(sorted(active_codes))
54
+
55
+ # Get unique values
56
+ unique_obs_list = df["Observation id"].unique().tolist()
57
+
58
+ # Convert to tuples grouped by observation
59
+ grouped: dict = {}
60
+ modifiers: list = []
61
+ for col in df.columns:
62
+ if isinstance(col, tuple):
63
+ modifiers.append(col)
64
+
65
+ for obs, group in df.groupby("Observation id"):
66
+ o: list = []
67
+ for row in group[["Start (s)", "Stop (s)", "Subject", "Behavior"] + modifiers].itertuples(index=False, name=None):
68
+ modif_list = [row[i] for idx, i in enumerate(range(4, 4 + len(modifiers))) if modifiers[idx][0] == row[3]]
69
+ o.append((row[0], row[1], row[2] + "|" + row[3] + "|" + ",".join(modif_list)))
70
+ grouped[obs] = o
71
+
72
+ ck_results: dict = {}
73
+ for idx1, obs_id1 in enumerate(unique_obs_list):
74
+ obs1 = grouped[obs_id1]
75
+
76
+ ck_results[(obs_id1, obs_id1)] = "1.000"
77
+
78
+ for obs_id2 in unique_obs_list[idx1 + 1 :]:
79
+ obs2 = grouped[obs_id2]
80
+
81
+ # get all the break points
82
+ time_points = sorted(set([t for seg in obs1 for t in seg[:2]] + [t for seg in obs2 for t in seg[:2]]))
83
+
84
+ # elementary intervals
85
+ elementary_intervals = [(time_points[i], time_points[i + 1]) for i in range(len(time_points) - 1)]
86
+
87
+ obs1_codes = [get_code(t[0], obs1) for t in elementary_intervals]
88
+
89
+ obs2_codes = [get_code(t[0], obs2) for t in elementary_intervals]
90
+
91
+ # Cohen's Kappa
92
+ kappa = cohen_kappa_score(obs1_codes, obs2_codes)
93
+ print(f"{obs_id1} - {obs_id2}: Cohen's Kappa : {kappa:.3f}")
94
+
95
+ ck_results[(obs_id1, obs_id2)] = f"{kappa:.3f}"
96
+ ck_results[(obs_id2, obs_id1)] = f"{kappa:.3f}"
97
+
98
+ # DataFrame conversion
99
+ df_results = pd.Series(ck_results).unstack()
100
+
101
+ return df_results
@@ -1,21 +1,47 @@
1
1
  """
2
2
  BORIS plugin
3
3
 
4
- Inter Rater Reliability (IRR) Weighted Cohen Kappa
4
+ Inter Rater Reliability (IRR) Weighted Cohen's Kappa
5
5
  """
6
6
 
7
7
  import pandas as pd
8
8
  from typing import List, Tuple, Dict, Optional
9
9
 
10
- __version__ = "0.0.1"
11
- __version_date__ = "2025-08-25"
12
- __plugin_name__ = "Inter Rater Reliability - Weighted Cohen Kappa"
10
+ __version__ = "0.0.2"
11
+ __version_date__ = "2025-08-29"
12
+ __plugin_name__ = "Inter Rater Reliability - Weighted Cohen's Kappa"
13
13
  __author__ = "Olivier Friard - University of Torino - Italy"
14
+ __description__ = """
15
+ This plugin calculates Cohen's Kappa to measure inter-rater reliability between two observers who code categorical behaviors over time intervals.
16
+ Unlike the unweighted version, this approach takes into account the duration of each coded interval, giving more weight to longer intervals in the agreement calculation.
17
+ This plugin does not take into account the modifiers.
18
+
19
+ How it works:
20
+
21
+ Time segmentation
22
+ The program collects all the time boundaries from both observers and merges them into a unified set of time points.
23
+ These define a set of non-overlapping elementary intervals covering the entire observed period.
24
+
25
+ Assigning codes
26
+ For each elementary interval, the program identifies the behavior category assigned by each observer.
27
+
28
+ Weighted contingency table
29
+ Instead of treating each interval equally, the program assigns a weight equal to the duration of the interval.
30
+ These durations are accumulated in a contingency table that records how much time was spent in each combination of categories across the two observers.
31
+
32
+ Agreement calculation
33
+
34
+ Observed agreement (po): The proportion of total time where both observers assigned the same category.
35
+
36
+ Expected agreement (pe): The proportion of agreement expected by chance, based on the time-weighted marginal distributions of each observer's coding.
37
+
38
+ Cohen's Kappa (κ): Computed from the weighted observed and expected agreements.
39
+ """
14
40
 
15
41
 
16
42
  def run(df: pd.DataFrame):
17
43
  """
18
- Calculate the Inter Rater Reliability - Weighted Cohen Kappa
44
+ Calculate the Inter Rater Reliability - Weighted Cohen's Kappa
19
45
  """
20
46
 
21
47
  def cohen_kappa_weighted_by_time(
@@ -41,12 +67,12 @@ def run(df: pd.DataFrame):
41
67
  # 2. Build elementary intervals (non-overlapping time bins)
42
68
  elementary_intervals = [(time_points[i], time_points[i + 1]) for i in range(len(time_points) - 1)]
43
69
 
44
- # 3. Helper: get the active code for an observer at a given time
70
+ # 3. # Attribute all active codes for each interval
45
71
  def get_code(t: float, obs: List[Tuple[float, float, str]]) -> Optional[str]:
46
- for seg in obs:
47
- if seg[0] <= t < seg[1]:
48
- return seg[2]
49
- return None # in case no segment covers this time
72
+ active_codes = [seg[2] for seg in obs if seg[0] <= t < seg[1]]
73
+ if not active_codes:
74
+ return None
75
+ return "+".join(sorted(active_codes)) # rappresentazione deterministica
50
76
 
51
77
  # 4. Build weighted contingency table (durations instead of counts)
52
78
  contingency: Dict[Tuple[Optional[str], Optional[str]], float] = {}
@@ -1,21 +1,47 @@
1
1
  """
2
2
  BORIS plugin
3
3
 
4
- Inter Rater Reliability (IRR) Weighted Cohen Kappa with modifiers
4
+ Inter Rater Reliability (IRR) Weighted Cohen's Kappa with modifiers
5
5
  """
6
6
 
7
7
  import pandas as pd
8
8
  from typing import List, Tuple, Dict, Optional
9
9
 
10
- __version__ = "0.0.1"
11
- __version_date__ = "2025-08-25"
12
- __plugin_name__ = "Inter Rater Reliability - Weighted Cohen Kappa with modifiers"
10
+ __version__ = "0.0.2"
11
+ __version_date__ = "2025-08-29"
12
+ __plugin_name__ = "Inter Rater Reliability - Weighted Cohen's Kappa with modifiers"
13
13
  __author__ = "Olivier Friard - University of Torino - Italy"
14
+ __description__ = """
15
+ This plugin calculates Cohen's Kappa to measure inter-rater reliability between two observers who code categorical behaviors over time intervals.
16
+ Unlike the unweighted version, this approach takes into account the duration of each coded interval, giving more weight to longer intervals in the agreement calculation.
17
+ This plugin takes into account the modifiers.
18
+
19
+ How it works:
20
+
21
+ Time segmentation
22
+ The program collects all the time boundaries from both observers and merges them into a unified set of time points.
23
+ These define a set of non-overlapping elementary intervals covering the entire observed period.
24
+
25
+ Assigning codes
26
+ For each elementary interval, the program identifies the behavior category assigned by each observer.
27
+
28
+ Weighted contingency table
29
+ Instead of treating each interval equally, the program assigns a weight equal to the duration of the interval.
30
+ These durations are accumulated in a contingency table that records how much time was spent in each combination of categories across the two observers.
31
+
32
+ Agreement calculation
33
+
34
+ Observed agreement (po): The proportion of total time where both observers assigned the same category.
35
+
36
+ Expected agreement (pe): The proportion of agreement expected by chance, based on the time-weighted marginal distributions of each observer's coding.
37
+
38
+ Cohen's Kappa (κ): Computed from the weighted observed and expected agreements.
39
+ """
14
40
 
15
41
 
16
42
  def run(df: pd.DataFrame):
17
43
  """
18
- Calculate the Inter Rater Reliability - Weighted Cohen Kappa with modifiers
44
+ Calculate the Inter Rater Reliability - Weighted Cohen's Kappa with modifiers
19
45
  """
20
46
 
21
47
  def cohen_kappa_weighted_by_time(
@@ -41,12 +67,12 @@ def run(df: pd.DataFrame):
41
67
  # 2. Build elementary intervals (non-overlapping time bins)
42
68
  elementary_intervals = [(time_points[i], time_points[i + 1]) for i in range(len(time_points) - 1)]
43
69
 
44
- # 3. Helper: get the active code for an observer at a given time
70
+ # 3. Attribute all active codes for each interval
45
71
  def get_code(t: float, obs: List[Tuple[float, float, str]]) -> Optional[str]:
46
- for seg in obs:
47
- if seg[0] <= t < seg[1]:
48
- return seg[2]
49
- return None # in case no segment covers this time
72
+ active_codes = [seg[2] for seg in obs if seg[0] <= t < seg[1]]
73
+ if not active_codes:
74
+ return None
75
+ return "+".join(sorted(active_codes)) # rappresentazione deterministica
50
76
 
51
77
  # 4. Build weighted contingency table (durations instead of counts)
52
78
  contingency: Dict[Tuple[Optional[str], Optional[str]], float] = {}
@@ -26,10 +26,6 @@ def run(df: pd.DataFrame):
26
26
  - % of total subject observation duration
27
27
  """
28
28
 
29
- print("running time budget plugin")
30
-
31
- print(df)
32
-
33
29
  group_by = ["Subject", "Behavior"]
34
30
 
35
31
  dfs = [
@@ -431,7 +431,6 @@ class BehaviorsMapCreatorWindow(QMainWindow):
431
431
  self.selectedPolygon = None
432
432
  self.selectedPolygonMemBrush = None
433
433
 
434
- print(self.polygonsList2)
435
434
  idx = 0
436
435
  for areaCode, pg in self.polygonsList2:
437
436
  if pg.contains(test):
@@ -261,8 +261,6 @@ def show_coding_pad(self):
261
261
  self.codingpad.setWindowFlags(Qt.WindowStaysOnTopHint)
262
262
  self.codingpad.sendEventSignal.connect(self.signal_from_widget)
263
263
 
264
- print(f"{self.signal_from_widget=}")
265
-
266
264
  self.codingpad.clickSignal.connect(self.click_signal_from_coding_pad)
267
265
  self.codingpad.close_signal.connect(self.close_signal_from_coding_pad)
268
266
  self.codingpad.show()
@@ -169,8 +169,6 @@ def read(self):
169
169
  # check for new version
170
170
  self.checkForNewVersion = False
171
171
 
172
- # print(f"{self.no_first_launch_dialog=}")
173
-
174
172
  if not self.no_first_launch_dialog:
175
173
  try:
176
174
  if settings.value("check_for_new_version") is None: