boris-behav-obs 8.27.1__py2.py3-none-any.whl → 8.27.3__py2.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.
- boris/about.py +1 -1
- boris/observation_operations.py +7 -5
- boris/preferences_ui.py +2 -2
- boris/project.py +62 -29
- boris/project_import_export.py +22 -16
- boris/version.py +2 -2
- {boris_behav_obs-8.27.1.dist-info → boris_behav_obs-8.27.3.dist-info}/METADATA +11 -11
- {boris_behav_obs-8.27.1.dist-info → boris_behav_obs-8.27.3.dist-info}/RECORD +12 -12
- {boris_behav_obs-8.27.1.dist-info → boris_behav_obs-8.27.3.dist-info}/WHEEL +1 -1
- {boris_behav_obs-8.27.1.dist-info → boris_behav_obs-8.27.3.dist-info}/LICENSE.TXT +0 -0
- {boris_behav_obs-8.27.1.dist-info → boris_behav_obs-8.27.3.dist-info}/entry_points.txt +0 -0
- {boris_behav_obs-8.27.1.dist-info → boris_behav_obs-8.27.3.dist-info}/top_level.txt +0 -0
boris/about.py
CHANGED
boris/observation_operations.py
CHANGED
|
@@ -198,8 +198,8 @@ def load_observation(self, obs_id: str, mode: str = cfg.OBS_START) -> str:
|
|
|
198
198
|
self.observationId = obs_id
|
|
199
199
|
|
|
200
200
|
if self.pj[cfg.OBSERVATIONS][self.observationId][cfg.TYPE] == cfg.IMAGES:
|
|
201
|
-
self.image_idx
|
|
202
|
-
self.images_list
|
|
201
|
+
self.image_idx = 0
|
|
202
|
+
self.images_list = []
|
|
203
203
|
|
|
204
204
|
if mode == cfg.OBS_START:
|
|
205
205
|
self.playerType = cfg.IMAGES
|
|
@@ -1803,12 +1803,14 @@ def initialize_new_media_observation(self) -> bool:
|
|
|
1803
1803
|
|
|
1804
1804
|
self.dw_player[i].fps[mediaFile] = mediaFPS
|
|
1805
1805
|
|
|
1806
|
+
# add media file to playlist
|
|
1806
1807
|
self.dw_player[i].player.playlist_append(media_full_path)
|
|
1807
|
-
|
|
1808
|
-
#
|
|
1808
|
+
|
|
1809
|
+
# add media file name to player window title
|
|
1810
|
+
self.dw_player[i].setWindowTitle(f"Player #{i + 1} ({pl.Path(media_full_path).name})")
|
|
1809
1811
|
|
|
1810
1812
|
# media duration cumuled in seconds
|
|
1811
|
-
self.dw_player[i].cumul_media_durations_sec
|
|
1813
|
+
self.dw_player[i].cumul_media_durations_sec = [round(dec(x / 1000), 3) for x in self.dw_player[i].cumul_media_durations]
|
|
1812
1814
|
|
|
1813
1815
|
# check if BORIS is running on a Windows VM with the 'WMIC COMPUTERSYSTEM GET SERIALNUMBER' command
|
|
1814
1816
|
# because "auto" or "auto-safe" crash in Windows VM
|
boris/preferences_ui.py
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# -*- coding: utf-8 -*-
|
|
2
2
|
|
|
3
|
-
# Form implementation generated from reading ui file 'preferences.ui'
|
|
3
|
+
# Form implementation generated from reading ui file 'boris/preferences.ui'
|
|
4
4
|
#
|
|
5
5
|
# Created by: PyQt5 UI code generator 5.15.6
|
|
6
6
|
#
|
|
@@ -331,7 +331,7 @@ class Ui_prefDialog(object):
|
|
|
331
331
|
self.pb_reset_category_colors.setText(_translate("prefDialog", "Reset colors to default"))
|
|
332
332
|
self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_colors), _translate("prefDialog", "Plot colors"))
|
|
333
333
|
self.label_9.setText(_translate("prefDialog", "Toolbar icons size"))
|
|
334
|
-
self.cb_darkmode.setText(_translate("prefDialog", "Dark mode"))
|
|
334
|
+
self.cb_darkmode.setText(_translate("prefDialog", "Dark mode (should be necessary to relaunch BORIS)"))
|
|
335
335
|
self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_interface), _translate("prefDialog", "Interface"))
|
|
336
336
|
self.pb_refresh.setText(_translate("prefDialog", "Refresh"))
|
|
337
337
|
self.pbCancel.setText(_translate("prefDialog", "Cancel"))
|
boris/project.py
CHANGED
|
@@ -27,6 +27,7 @@ import re
|
|
|
27
27
|
from PyQt5.QtCore import Qt, QDateTime
|
|
28
28
|
from PyQt5.QtGui import QColor
|
|
29
29
|
from PyQt5.QtWidgets import (
|
|
30
|
+
QApplication,
|
|
30
31
|
QCheckBox,
|
|
31
32
|
QDialog,
|
|
32
33
|
QFileDialog,
|
|
@@ -59,10 +60,11 @@ class BehavioralCategories(QDialog):
|
|
|
59
60
|
Class for managing the behavioral categories
|
|
60
61
|
"""
|
|
61
62
|
|
|
62
|
-
def __init__(self, pj):
|
|
63
|
+
def __init__(self, pj, dark_mode):
|
|
63
64
|
super().__init__()
|
|
64
65
|
|
|
65
66
|
self.pj = pj
|
|
67
|
+
self.dark_mode = dark_mode
|
|
66
68
|
self.setWindowTitle("Behavioral categories")
|
|
67
69
|
|
|
68
70
|
self.renamed = None
|
|
@@ -102,7 +104,8 @@ class BehavioralCategories(QDialog):
|
|
|
102
104
|
if behav_cat[key].get(cfg.COLOR, ""):
|
|
103
105
|
item.setBackground(QColor(behav_cat[key].get(cfg.COLOR, "")))
|
|
104
106
|
else:
|
|
105
|
-
item.setBackground(QColor(230, 230, 230))
|
|
107
|
+
# item.setBackground(QColor(230, 230, 230))
|
|
108
|
+
item.setBackground(self.not_editable_column_color())
|
|
106
109
|
# item.setFlags(Qt.ItemIsEnabled)
|
|
107
110
|
self.lw.setItem(idx, 1, item)
|
|
108
111
|
else:
|
|
@@ -135,8 +138,8 @@ class BehavioralCategories(QDialog):
|
|
|
135
138
|
self.vbox.addLayout(self.hbox0)
|
|
136
139
|
|
|
137
140
|
hbox1 = QHBoxLayout()
|
|
138
|
-
self.pbOK = QPushButton(
|
|
139
|
-
self.pbCancel = QPushButton(
|
|
141
|
+
self.pbOK = QPushButton(cfg.OK, clicked=self.accept)
|
|
142
|
+
self.pbCancel = QPushButton(cfg.CANCEL, clicked=self.accept)
|
|
140
143
|
|
|
141
144
|
spacerItem = QSpacerItem(40, 20, QSizePolicy.Expanding, QSizePolicy.Minimum)
|
|
142
145
|
hbox1.addItem(spacerItem)
|
|
@@ -146,6 +149,15 @@ class BehavioralCategories(QDialog):
|
|
|
146
149
|
|
|
147
150
|
self.setLayout(self.vbox)
|
|
148
151
|
|
|
152
|
+
def not_editable_column_color(self):
|
|
153
|
+
"""
|
|
154
|
+
return a color for the not editable column
|
|
155
|
+
"""
|
|
156
|
+
if self.dark_mode:
|
|
157
|
+
return QColor(55, 65, 79)
|
|
158
|
+
else:
|
|
159
|
+
return QColor(230, 230, 230)
|
|
160
|
+
|
|
149
161
|
def lw_double_clicked(self, row: int, column: int):
|
|
150
162
|
"""
|
|
151
163
|
change color
|
|
@@ -165,7 +177,8 @@ class BehavioralCategories(QDialog):
|
|
|
165
177
|
color = col_diag.currentColor()
|
|
166
178
|
if color.name() == "#000000": # black -> delete color
|
|
167
179
|
self.lw.item(row, 1).setText("")
|
|
168
|
-
self.lw.item(row, 1).setBackground(QColor(230, 230, 230))
|
|
180
|
+
# self.lw.item(row, 1).setBackground(QColor(230, 230, 230))
|
|
181
|
+
self.lw.item(row, 1).setBackground(self.not_editable_column_color())
|
|
169
182
|
elif color.isValid():
|
|
170
183
|
self.lw.item(row, 1).setText(color.name())
|
|
171
184
|
self.lw.item(row, 1).setBackground(color)
|
|
@@ -253,9 +266,7 @@ class BehavioralCategories(QDialog):
|
|
|
253
266
|
flag_rename = (
|
|
254
267
|
dialog.MessageDialog(
|
|
255
268
|
cfg.programName,
|
|
256
|
-
("Some behavior belong to the <b>{
|
|
257
|
-
"<br>".join(behaviors_in_category), category_to_rename
|
|
258
|
-
),
|
|
269
|
+
(f"Some behavior belong to the <b>{category_to_rename}</b> to rename:<br>{'<br>'.join(behaviors_in_category)}<br>"),
|
|
259
270
|
["Rename category", cfg.CANCEL],
|
|
260
271
|
)
|
|
261
272
|
== "Rename category"
|
|
@@ -271,7 +282,7 @@ class BehavioralCategories(QDialog):
|
|
|
271
282
|
self.lw.item(self.lw.indexFromItem(selected_item).row(), 0).setText(new_category_name)
|
|
272
283
|
# check behaviors belonging to the renamed category
|
|
273
284
|
self.renamed = [category_to_rename, new_category_name]
|
|
274
|
-
self.accept()
|
|
285
|
+
# self.accept()
|
|
275
286
|
|
|
276
287
|
|
|
277
288
|
class projectDialog(QDialog, Ui_dlgProject):
|
|
@@ -415,6 +426,15 @@ class projectDialog(QDialog, Ui_dlgProject):
|
|
|
415
426
|
self.twSubjects.horizontalHeader().sortIndicatorChanged.connect(self.sort_twSubjects)
|
|
416
427
|
self.twVariables.horizontalHeader().sortIndicatorChanged.connect(self.sort_twVariables)
|
|
417
428
|
|
|
429
|
+
def not_editable_column_color(self):
|
|
430
|
+
"""
|
|
431
|
+
return a color for the not editable column
|
|
432
|
+
"""
|
|
433
|
+
if self.config_param[cfg.DARK_MODE]:
|
|
434
|
+
return QColor(55, 65, 79)
|
|
435
|
+
else:
|
|
436
|
+
return QColor(230, 230, 230)
|
|
437
|
+
|
|
418
438
|
def add_button_menu(self, data, menu_obj):
|
|
419
439
|
"""
|
|
420
440
|
add menu option from dictionary
|
|
@@ -558,7 +578,7 @@ class projectDialog(QDialog, Ui_dlgProject):
|
|
|
558
578
|
# convert modifier shortcuts
|
|
559
579
|
if self.twBehaviors.item(row, cfg.behavioursFields[cfg.MODIFIERS]).text():
|
|
560
580
|
modifiers_dict = (
|
|
561
|
-
|
|
581
|
+
json.loads(self.twBehaviors.item(row, cfg.behavioursFields[cfg.MODIFIERS]).text())
|
|
562
582
|
if self.twBehaviors.item(row, cfg.behavioursFields[cfg.MODIFIERS]).text()
|
|
563
583
|
else {}
|
|
564
584
|
)
|
|
@@ -573,7 +593,7 @@ class projectDialog(QDialog, Ui_dlgProject):
|
|
|
573
593
|
except Exception:
|
|
574
594
|
logging.warning("error during conversion of modifier short cut to lower case")
|
|
575
595
|
|
|
576
|
-
self.twBehaviors.item(row, cfg.behavioursFields[cfg.MODIFIERS]).setText(
|
|
596
|
+
self.twBehaviors.item(row, cfg.behavioursFields[cfg.MODIFIERS]).setText(json.dumps(modifiers_dict))
|
|
577
597
|
|
|
578
598
|
def convert_subjects_keys_to_lower_case(self):
|
|
579
599
|
"""
|
|
@@ -665,14 +685,23 @@ class projectDialog(QDialog, Ui_dlgProject):
|
|
|
665
685
|
self.twBehavCodingMap.removeRow(self.twBehavCodingMap.selectedIndexes()[0].row())
|
|
666
686
|
|
|
667
687
|
def leLabel_changed(self):
|
|
688
|
+
"""
|
|
689
|
+
independent variable label changed
|
|
690
|
+
"""
|
|
668
691
|
if self.selected_twvariables_row != -1:
|
|
669
692
|
self.twVariables.item(self.selected_twvariables_row, 0).setText(self.leLabel.text())
|
|
670
693
|
|
|
671
694
|
def leDescription_changed(self):
|
|
695
|
+
"""
|
|
696
|
+
independent variable description changed
|
|
697
|
+
"""
|
|
672
698
|
if self.selected_twvariables_row != -1:
|
|
673
699
|
self.twVariables.item(self.selected_twvariables_row, 1).setText(self.leDescription.text())
|
|
674
700
|
|
|
675
701
|
def lePredefined_changed(self):
|
|
702
|
+
"""
|
|
703
|
+
independent variable predefined value changed
|
|
704
|
+
"""
|
|
676
705
|
if self.selected_twvariables_row != -1:
|
|
677
706
|
self.twVariables.item(self.selected_twvariables_row, 3).setText(self.lePredefined.text())
|
|
678
707
|
if not self.lePredefined.hasFocus():
|
|
@@ -681,12 +710,15 @@ class projectDialog(QDialog, Ui_dlgProject):
|
|
|
681
710
|
QMessageBox.warning(self, f"{cfg.programName} - Independent variables error", msg)
|
|
682
711
|
|
|
683
712
|
def leSetValues_changed(self):
|
|
713
|
+
"""
|
|
714
|
+
independent variable available values changed
|
|
715
|
+
"""
|
|
684
716
|
if self.selected_twvariables_row != -1:
|
|
685
717
|
self.twVariables.item(self.selected_twvariables_row, 4).setText(self.leSetValues.text())
|
|
686
718
|
|
|
687
719
|
def dte_default_date_changed(self):
|
|
688
720
|
"""
|
|
689
|
-
default timestamp changed
|
|
721
|
+
independent variable default timestamp changed
|
|
690
722
|
"""
|
|
691
723
|
if self.selected_twvariables_row != -1:
|
|
692
724
|
self.twVariables.item(self.selected_twvariables_row, 3).setText(
|
|
@@ -698,7 +730,7 @@ class projectDialog(QDialog, Ui_dlgProject):
|
|
|
698
730
|
behavioral categories manager
|
|
699
731
|
"""
|
|
700
732
|
|
|
701
|
-
bc = BehavioralCategories(self.pj)
|
|
733
|
+
bc = BehavioralCategories(self.pj, self.config_param[cfg.DARK_MODE])
|
|
702
734
|
|
|
703
735
|
if bc.exec_():
|
|
704
736
|
self.pj[cfg.BEHAVIORAL_CATEGORIES] = []
|
|
@@ -754,17 +786,17 @@ class projectDialog(QDialog, Ui_dlgProject):
|
|
|
754
786
|
"""
|
|
755
787
|
|
|
756
788
|
# check if double click on excluded column
|
|
757
|
-
if column == cfg.behavioursFields[
|
|
789
|
+
if column == cfg.behavioursFields[cfg.EXCLUDED]:
|
|
758
790
|
self.exclusion_matrix()
|
|
759
791
|
|
|
760
792
|
# check if double click on 'coding map' column
|
|
761
|
-
if column == cfg.behavioursFields[
|
|
793
|
+
if column == cfg.behavioursFields[cfg.CODING_MAP_sp]:
|
|
762
794
|
if "with coding map" in self.twBehaviors.item(row, cfg.behavioursFields[cfg.TYPE]).text():
|
|
763
795
|
self.behavior_type_changed(row)
|
|
764
796
|
else:
|
|
765
797
|
QMessageBox.information(self, cfg.programName, "Change the behavior type on first column to select a coding map")
|
|
766
798
|
|
|
767
|
-
# check if double click on
|
|
799
|
+
# check if double click on behavior type
|
|
768
800
|
if column == cfg.behavioursFields["type"]:
|
|
769
801
|
self.behavior_type_doubleclicked(row)
|
|
770
802
|
|
|
@@ -776,11 +808,12 @@ class projectDialog(QDialog, Ui_dlgProject):
|
|
|
776
808
|
if column == cfg.behavioursFields[cfg.BEHAVIOR_CATEGORY]:
|
|
777
809
|
self.category_doubleclicked(row)
|
|
778
810
|
|
|
811
|
+
# check if double click on modifiers
|
|
779
812
|
if column == cfg.behavioursFields[cfg.MODIFIERS]:
|
|
780
813
|
# check if behavior has coding map
|
|
781
814
|
if (
|
|
782
|
-
self.twBehaviors.item(row, cfg.behavioursFields[
|
|
783
|
-
and self.twBehaviors.item(row, cfg.behavioursFields[
|
|
815
|
+
self.twBehaviors.item(row, cfg.behavioursFields[cfg.CODING_MAP_sp]) is not None
|
|
816
|
+
and self.twBehaviors.item(row, cfg.behavioursFields[cfg.CODING_MAP_sp]).text()
|
|
784
817
|
):
|
|
785
818
|
QMessageBox.warning(self, cfg.programName, "Use the coding map to set/modify the areas")
|
|
786
819
|
else:
|
|
@@ -835,7 +868,8 @@ class projectDialog(QDialog, Ui_dlgProject):
|
|
|
835
868
|
color = col_diag.currentColor()
|
|
836
869
|
if color.name() == "#000000": # black -> delete color
|
|
837
870
|
self.twBehaviors.item(row, cfg.behavioursFields[cfg.COLOR]).setText("")
|
|
838
|
-
self.twBehaviors.item(row, cfg.behavioursFields[cfg.COLOR]).setBackground(QColor(230, 230, 230))
|
|
871
|
+
# self.twBehaviors.item(row, cfg.behavioursFields[cfg.COLOR]).setBackground(QColor(230, 230, 230))
|
|
872
|
+
self.twBehaviors.item(row, cfg.behavioursFields[cfg.COLOR]).setBackground(self.not_editable_column_color())
|
|
839
873
|
elif color.isValid():
|
|
840
874
|
self.twBehaviors.item(row, cfg.behavioursFields[cfg.COLOR]).setText(color.name())
|
|
841
875
|
self.twBehaviors.item(row, cfg.behavioursFields[cfg.COLOR]).setBackground(color)
|
|
@@ -1166,7 +1200,8 @@ class projectDialog(QDialog, Ui_dlgProject):
|
|
|
1166
1200
|
if e == self.twBehaviors.item(r, cfg.behavioursFields[cfg.BEHAVIOR_CODE]).text():
|
|
1167
1201
|
item = QTableWidgetItem(",".join(new_excl[e]))
|
|
1168
1202
|
item.setFlags(Qt.ItemIsEnabled)
|
|
1169
|
-
item.setBackground(QColor(230, 230, 230))
|
|
1203
|
+
# item.setBackground(QColor(230, 230, 230))
|
|
1204
|
+
item.setBackground(self.not_editable_column_color())
|
|
1170
1205
|
self.twBehaviors.setItem(r, cfg.behavioursFields["excluded"], item)
|
|
1171
1206
|
|
|
1172
1207
|
def remove_all_behaviors(self):
|
|
@@ -1269,13 +1304,16 @@ class projectDialog(QDialog, Ui_dlgProject):
|
|
|
1269
1304
|
self.twBehaviors.setItem(self.twBehaviors.rowCount() - 1, cfg.behavioursFields[field], item)
|
|
1270
1305
|
if field in (cfg.TYPE, "category", "excluded", "coding map", "modifiers"):
|
|
1271
1306
|
item.setFlags(Qt.ItemIsEnabled)
|
|
1272
|
-
item.setBackground(QColor(230, 230, 230))
|
|
1307
|
+
# item.setBackground(QColor(230, 230, 230))
|
|
1308
|
+
item.setBackground(self.not_editable_column_color())
|
|
1273
1309
|
if field == cfg.COLOR:
|
|
1274
1310
|
item.setFlags(Qt.ItemIsEnabled)
|
|
1275
1311
|
if QColor(self.twBehaviors.item(row, cfg.behavioursFields[field]).text()).isValid():
|
|
1276
1312
|
item.setBackground(QColor(self.twBehaviors.item(row, cfg.behavioursFields[field]).text()))
|
|
1277
1313
|
else:
|
|
1278
|
-
item.setBackground(QColor(230, 230, 230))
|
|
1314
|
+
# item.setBackground(QColor(230, 230, 230))
|
|
1315
|
+
item.setBackground(self.not_editable_column_color())
|
|
1316
|
+
|
|
1279
1317
|
self.twBehaviors.scrollToBottom()
|
|
1280
1318
|
|
|
1281
1319
|
def remove_behavior(self):
|
|
@@ -1326,7 +1364,8 @@ class projectDialog(QDialog, Ui_dlgProject):
|
|
|
1326
1364
|
# no manual editing, gray back ground
|
|
1327
1365
|
if field_type in (cfg.TYPE, cfg.COLOR, "category", cfg.MODIFIERS, "modifiers", "excluded", "coding map"):
|
|
1328
1366
|
item.setFlags(Qt.ItemIsEnabled)
|
|
1329
|
-
item.setBackground(QColor(230, 230, 230))
|
|
1367
|
+
# item.setBackground(QColor(230, 230, 230))
|
|
1368
|
+
item.setBackground(self.not_editable_column_color())
|
|
1330
1369
|
self.twBehaviors.setItem(self.twBehaviors.rowCount() - 1, cfg.behavioursFields[field_type], item)
|
|
1331
1370
|
self.twBehaviors.scrollToBottom()
|
|
1332
1371
|
|
|
@@ -1697,12 +1736,6 @@ class projectDialog(QDialog, Ui_dlgProject):
|
|
|
1697
1736
|
QMessageBox.critical(self, cfg.programName, "Error removing leading/trailing spaces in modifiers")
|
|
1698
1737
|
|
|
1699
1738
|
else:
|
|
1700
|
-
"""
|
|
1701
|
-
if row["modifiers"]:
|
|
1702
|
-
row["modifiers"] = eval(row["modifiers"])
|
|
1703
|
-
else:
|
|
1704
|
-
row["modifiers"] = {}
|
|
1705
|
-
"""
|
|
1706
1739
|
row["modifiers"] = json.loads(row["modifiers"]) if row["modifiers"] else {}
|
|
1707
1740
|
else:
|
|
1708
1741
|
row[field] = ""
|
boris/project_import_export.py
CHANGED
|
@@ -133,7 +133,7 @@ def export_ethogram(self) -> None:
|
|
|
133
133
|
# modifiers
|
|
134
134
|
if self.twBehaviors.item(r, cfg.behavioursFields[cfg.MODIFIERS]).text():
|
|
135
135
|
# modifiers a string
|
|
136
|
-
modifiers_dict =
|
|
136
|
+
modifiers_dict = json.loads(self.twBehaviors.item(r, cfg.behavioursFields[cfg.MODIFIERS]).text())
|
|
137
137
|
modifiers_list = []
|
|
138
138
|
for key in modifiers_dict:
|
|
139
139
|
values = ",".join(modifiers_dict[key]["values"])
|
|
@@ -350,19 +350,22 @@ def import_ethogram_from_dict(self, project: dict):
|
|
|
350
350
|
item.setBackground(QColor(230, 230, 230))
|
|
351
351
|
|
|
352
352
|
else:
|
|
353
|
-
if field == cfg.MODIFIERS
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
353
|
+
if field == cfg.MODIFIERS:
|
|
354
|
+
if isinstance(project[cfg.ETHOGRAM][i][field], str):
|
|
355
|
+
modif_set_dict = {}
|
|
356
|
+
if project[cfg.ETHOGRAM][i][field]:
|
|
357
|
+
modif_set_list = project[cfg.ETHOGRAM][i][field].split("|")
|
|
358
|
+
for modif_set in modif_set_list:
|
|
359
|
+
modif_set_dict[str(len(modif_set_dict))] = {
|
|
360
|
+
"name": "",
|
|
361
|
+
"type": cfg.SINGLE_SELECTION,
|
|
362
|
+
"values": modif_set.split(","),
|
|
363
|
+
}
|
|
364
|
+
project[cfg.ETHOGRAM][i][field] = dict(modif_set_dict)
|
|
365
|
+
else:
|
|
366
|
+
item.setText(json.dumps(project[cfg.ETHOGRAM][i][field]))
|
|
367
|
+
else:
|
|
368
|
+
item.setText(project[cfg.ETHOGRAM][i][field])
|
|
366
369
|
|
|
367
370
|
if field not in cfg.ETHOGRAM_EDITABLE_FIELDS:
|
|
368
371
|
item.setFlags(Qt.ItemIsEnabled)
|
|
@@ -460,8 +463,11 @@ def load_dataframe_into_behaviors_tablewidget(self, df: pd.DataFrame) -> int:
|
|
|
460
463
|
|
|
461
464
|
|
|
462
465
|
def import_behaviors_from_project(self):
|
|
466
|
+
"""
|
|
467
|
+
import ethogram from a BORIS project file
|
|
468
|
+
"""
|
|
463
469
|
fn = QFileDialog().getOpenFileName(
|
|
464
|
-
self, "Import behaviors from project file", "", ("Project files (*.boris *.boris.gz);;" "All files (*)")
|
|
470
|
+
self, "Import behaviors from BORIS project file", "", ("Project files (*.boris *.boris.gz);;" "All files (*)")
|
|
465
471
|
)
|
|
466
472
|
file_name = fn[0] if type(fn) is tuple else fn
|
|
467
473
|
|
|
@@ -474,7 +480,7 @@ def import_behaviors_from_project(self):
|
|
|
474
480
|
|
|
475
481
|
def import_behaviors_from_text_file(self):
|
|
476
482
|
"""
|
|
477
|
-
Import
|
|
483
|
+
Import ethogram from text file (CSV or TSV)
|
|
478
484
|
"""
|
|
479
485
|
|
|
480
486
|
if self.twBehaviors.rowCount():
|
boris/version.py
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: boris-behav-obs
|
|
3
|
-
Version: 8.27.
|
|
3
|
+
Version: 8.27.3
|
|
4
4
|
Summary: BORIS - Behavioral Observation Research Interactive Software
|
|
5
5
|
Author-email: Olivier Friard <olivier.friard@unito.it>
|
|
6
6
|
License: GNU GENERAL PUBLIC LICENSE
|
|
@@ -696,18 +696,18 @@ Classifier: Operating System :: OS Independent
|
|
|
696
696
|
Requires-Python: >=3.8
|
|
697
697
|
Description-Content-Type: text/x-rst
|
|
698
698
|
License-File: LICENSE.TXT
|
|
699
|
-
Requires-Dist: exifread
|
|
700
|
-
Requires-Dist: numpy
|
|
701
|
-
Requires-Dist: matplotlib
|
|
702
|
-
Requires-Dist: pandas
|
|
703
|
-
Requires-Dist: tablib[cli,html,ods,pandas,xls,xlsx]
|
|
704
|
-
Requires-Dist: pyqt5
|
|
699
|
+
Requires-Dist: exifread>=3.0.0
|
|
700
|
+
Requires-Dist: numpy>=1.26.4
|
|
701
|
+
Requires-Dist: matplotlib>=3.3.3
|
|
702
|
+
Requires-Dist: pandas>=2.2.2
|
|
703
|
+
Requires-Dist: tablib[cli,html,ods,pandas,xls,xlsx]>=3
|
|
704
|
+
Requires-Dist: pyqt5>=5.15
|
|
705
705
|
Requires-Dist: pyreadr
|
|
706
706
|
Provides-Extra: dev
|
|
707
|
-
Requires-Dist: black
|
|
708
|
-
Requires-Dist: ruff
|
|
709
|
-
Requires-Dist: pytest
|
|
710
|
-
Requires-Dist: pytest-cov
|
|
707
|
+
Requires-Dist: black; extra == "dev"
|
|
708
|
+
Requires-Dist: ruff; extra == "dev"
|
|
709
|
+
Requires-Dist: pytest; extra == "dev"
|
|
710
|
+
Requires-Dist: pytest-cov; extra == "dev"
|
|
711
711
|
|
|
712
712
|
===============================================================
|
|
713
713
|
BORIS (Behavioral Observation Research Interactive Software)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
boris/__init__.py,sha256=vEqzYsbV0DwIWYPXIv3OXrBBFW71dpYRSL63Dedv4xE,773
|
|
2
2
|
boris/__main__.py,sha256=_cKab_aODdiWYjyf6mWu57D-84izlVDPAm13QxH-cCg,764
|
|
3
|
-
boris/about.py,sha256=
|
|
3
|
+
boris/about.py,sha256=S8S1EiQhfQhlacQKuRIp-yhVkWnZ1BS7X5t9EOtCoZA,5259
|
|
4
4
|
boris/add_modifier.py,sha256=dtP1xZCwO0QlUJVir0JP2ShL5WrOvH26vQfwGwu683Q,26465
|
|
5
5
|
boris/add_modifier_ui.py,sha256=ZKXDcpavvzF5X8gkTuza1WYsw3x9TB-qQjrhn1fka5c,10537
|
|
6
6
|
boris/advanced_event_filtering.py,sha256=ScKwLy5zELU8R9WOS5wVZPk4OtWG1Cn4XeMxyHzG1Rc,15180
|
|
@@ -46,7 +46,7 @@ boris/modifiers_coding_map.py,sha256=XBTubBHw6Sayw5jUNaWR_jVIw6ttaJcbhbmUSF6_lx4
|
|
|
46
46
|
boris/mpv.py,sha256=EfzIHjPbgewG4w3smEtqEUPZoVwYmMQkL4Q8ZyW-a58,76410
|
|
47
47
|
boris/mpv2.py,sha256=EXRtzQqFjOn4wMC6482Ilq3fNQ9N1GRP1VxwLzdeaBY,88077
|
|
48
48
|
boris/observation.py,sha256=pHP68WnjA1rZsefo6zNtmwaXcjwjpItZCQrefqwOCCQ,52832
|
|
49
|
-
boris/observation_operations.py,sha256=
|
|
49
|
+
boris/observation_operations.py,sha256=eW5DPoU_21EQEWUUmOvqe6flgHxgTcFkGaJjfS6yWJo,100276
|
|
50
50
|
boris/observation_ui.py,sha256=dfk7pS2DlaiEgMjouH0-_t6kPgMwovQbloHtc3ZoCmY,30278
|
|
51
51
|
boris/observations_list.py,sha256=rMuEVa3QccA89vjARcEVtSlLnr5s0sfihUlcwciV3OM,10600
|
|
52
52
|
boris/otx_parser.py,sha256=Ul5GokK46azx60P6-pk8wbSPUqUR9O4WLV42z3rE40s,16367
|
|
@@ -59,10 +59,10 @@ boris/plot_events_rt.py,sha256=UfO1NKSqBR7j-vnfG8CKuOcdg5o8QQI_0eYdcz29Ufc,8358
|
|
|
59
59
|
boris/plot_spectrogram_rt.py,sha256=yc8ifg9HCl-v_upMHkH_rmIZLhWBYkWBOhtKftvRvh0,8394
|
|
60
60
|
boris/plot_waveform_rt.py,sha256=kNk6NVjM3wT3MpAw5zE9ktH94Pkd2AJ4ppv6uM6BVBc,7502
|
|
61
61
|
boris/preferences.py,sha256=W_BHck8lxODvZ9NzIgfvhvXAwUI5A66aJVmdTRTxZMo,11494
|
|
62
|
-
boris/preferences_ui.py,sha256=
|
|
63
|
-
boris/project.py,sha256=
|
|
62
|
+
boris/preferences_ui.py,sha256=fz0jHW7Nqw2P68FLBqheaGrQsZATNz8d8J00TVMX_Ig,21981
|
|
63
|
+
boris/project.py,sha256=wMOcWsz7tA-efmHOrKe0_s5I4Vy-u1u_fUTWzxTVdp8,83465
|
|
64
64
|
boris/project_functions.py,sha256=R3DS_faDuMGKTpMnV0OhqgZp9yO1ojoA5wUIXdtHNIE,70972
|
|
65
|
-
boris/project_import_export.py,sha256=
|
|
65
|
+
boris/project_import_export.py,sha256=Vrif3p4XiGYf0zcbmV8lUKSYAQBlWu8e762rEmP0kaQ,38358
|
|
66
66
|
boris/project_ui.py,sha256=TRJlsqq4XbIl8k2f20BKr2PtKa0QNjFNr6UnMieZYqU,35915
|
|
67
67
|
boris/qrc_boris.py,sha256=4U2cD_fIBTtsTPhirOl9I3kTArOhXWYvfuO_A0M9N0I,675001
|
|
68
68
|
boris/qrc_boris5.py,sha256=6bwT8OVtIr84nVIYp2ldUL7XL6WJi9zgJow6kgRxuIQ,161601
|
|
@@ -76,7 +76,7 @@ boris/time_budget_functions.py,sha256=L-0PuPWYR33UMfqmxpcCVH-w4mLLrtZ8b8kBTmBwls
|
|
|
76
76
|
boris/time_budget_widget.py,sha256=9WV-iKYSl1f3HBrGcL-eHDjUswrFQh6-WUcffTtce1Y,42852
|
|
77
77
|
boris/transitions.py,sha256=2zucdoa2jTpWtM6nWHr8lOvjXkrQmo9j71fz_fMLALU,11998
|
|
78
78
|
boris/utilities.py,sha256=07qXAQ6aGyiSC2h6RMJ031OlXYy05-KTLJtnQtXn6FU,48724
|
|
79
|
-
boris/version.py,sha256=
|
|
79
|
+
boris/version.py,sha256=SA4oy39PhzqMXmo1rg8CQQ23Zm7hv2vxrs__W1TBhNk,788
|
|
80
80
|
boris/video_equalizer.py,sha256=QpVgmdqX_E4HnMa2f_Qo_fKJTl9nBoTQd_ykv9RWlIQ,5862
|
|
81
81
|
boris/video_equalizer_ui.py,sha256=A2_Sz9AAVnJygTRUeK_YXxf-WWQpxSSlFw0MjkxiwSg,9762
|
|
82
82
|
boris/video_operations.py,sha256=96jR-3snNn9VeEURRD6rCwvOL2sSHXoqlP_gYFwgO8A,9379
|
|
@@ -105,9 +105,9 @@ boris/qdarkstyle/utils/__init__.py,sha256=Nlma8-zbHoJc5n2NVT7OvwxPG5765JnsmMeGzr
|
|
|
105
105
|
boris/qdarkstyle/utils/__main__.py,sha256=J1biUyDzfutKU1n9NdH9WnD0gFHaF-OJA4Q-n6Q2ehs,3309
|
|
106
106
|
boris/qdarkstyle/utils/images.py,sha256=af-BJllzWgVoVz6QMvhFcKqvF3mo44AThaBjuAuHtNE,14444
|
|
107
107
|
boris/qdarkstyle/utils/scss.py,sha256=n7WNo6pPRft8-dU7_gfjB_jA-JZAy50-S792RwR7Ri0,9366
|
|
108
|
-
boris_behav_obs-8.27.
|
|
109
|
-
boris_behav_obs-8.27.
|
|
110
|
-
boris_behav_obs-8.27.
|
|
111
|
-
boris_behav_obs-8.27.
|
|
112
|
-
boris_behav_obs-8.27.
|
|
113
|
-
boris_behav_obs-8.27.
|
|
108
|
+
boris_behav_obs-8.27.3.dist-info/LICENSE.TXT,sha256=WJ7YI-moTFb-uVrFjnzzhGJrnL9P2iqQe8NuED3hutI,35141
|
|
109
|
+
boris_behav_obs-8.27.3.dist-info/METADATA,sha256=cW0c3nD4XfG3rDY9t3mP290LsT0QvcP-JEHueoEekGE,45533
|
|
110
|
+
boris_behav_obs-8.27.3.dist-info/WHEEL,sha256=M4n4zmFKzQZk4mLCcycNIzIXO7YPKE_b5Cw4PnhHEg8,109
|
|
111
|
+
boris_behav_obs-8.27.3.dist-info/entry_points.txt,sha256=fuO7JxKFLOm6xp6m3JHRA1UO_QW1dYU-F0IooA1NqQs,37
|
|
112
|
+
boris_behav_obs-8.27.3.dist-info/top_level.txt,sha256=fJSgm62S7WesiwTorGbOO4nNN0yzgZ3klgfGi3Px4qI,6
|
|
113
|
+
boris_behav_obs-8.27.3.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|