boris-behav-obs 9.3.3__py2.py3-none-any.whl → 9.3.5__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/dialog.py CHANGED
@@ -20,9 +20,8 @@ This file is part of BORIS.
20
20
 
21
21
  """
22
22
 
23
- from decimal import Decimal as dec
24
- from typing import Union
25
23
  import datetime as dt
24
+ from decimal import Decimal as dec
26
25
  import logging
27
26
  import math
28
27
  import pathlib as pl
@@ -30,6 +29,7 @@ import platform
30
29
  import subprocess
31
30
  import sys
32
31
  import traceback
32
+ from typing import Union
33
33
 
34
34
  from PySide6.QtCore import Qt, Signal, qVersion, QRect, QTime, QDateTime, QSize
35
35
  from PySide6.QtWidgets import (
@@ -184,7 +184,7 @@ class Info_widget(QWidget):
184
184
 
185
185
  class get_time_widget(QWidget):
186
186
  """
187
- widget for selecting a time in various formats: secondes, HH:MM:SS:ZZZ or YYYY-mm-DD HH:MM:SS:ZZZ
187
+ widget for selecting a time in various formats: seconds, HH:MM:SS:ZZZ or YYYY-mm-DD HH:MM:SS:ZZZ
188
188
  """
189
189
 
190
190
  def __init__(self, time_value=dec(0), parent=None):
@@ -383,7 +383,7 @@ class get_time_widget(QWidget):
383
383
  dec: time in seconds (None if no format selected)
384
384
  """
385
385
 
386
- time_sec = None
386
+ time_sec = dec("NaN")
387
387
 
388
388
  if self.rb_seconds.isChecked():
389
389
  try:
@@ -396,7 +396,7 @@ class get_time_widget(QWidget):
396
396
  QMessageBox.Ok | QMessageBox.Default,
397
397
  QMessageBox.NoButton,
398
398
  )
399
- return None
399
+ return dec("NaN")
400
400
 
401
401
  if self.rb_time.isChecked():
402
402
  time_sec = self.sb_hour.value() * 3600
@@ -408,7 +408,7 @@ class get_time_widget(QWidget):
408
408
  if self.pb_sign.text() == "-":
409
409
  time_sec = -time_sec
410
410
 
411
- return dec(time_sec) if time_sec is not None else None
411
+ return dec(time_sec).quantize(dec("0.001")) # if time_sec is not None else None
412
412
 
413
413
  def set_time(self, new_time: dec) -> None:
414
414
  """
@@ -440,6 +440,11 @@ class get_time_widget(QWidget):
440
440
 
441
441
 
442
442
  class Ask_time(QDialog):
443
+ """
444
+ Qdialog class for asking time to user
445
+ User can select a time format between seconds, HHMMSS.zzz or YYY-mm-DD HH:MM:SS.zzz
446
+ """
447
+
443
448
  def __init__(self, time_value=0):
444
449
  super().__init__()
445
450
  self.setWindowTitle("")
@@ -453,10 +458,10 @@ class Ask_time(QDialog):
453
458
 
454
459
  hbox.addWidget(self.time_widget)
455
460
 
456
- self.pbOK = QPushButton("OK", clicked=self.pb_ok_clicked)
461
+ self.pbOK = QPushButton(cfg.OK, clicked=self.pb_ok_clicked)
457
462
  self.pbOK.setDefault(True)
458
463
 
459
- self.pbCancel = QPushButton("Cancel")
464
+ self.pbCancel = QPushButton(cfg.CANCEL)
460
465
  self.pbCancel.clicked.connect(self.reject)
461
466
 
462
467
  self.hbox2 = QHBoxLayout(self)
@@ -484,7 +489,7 @@ class Ask_time(QDialog):
484
489
  )
485
490
  return
486
491
  # test time value
487
- if self.time_widget.get_time() is None:
492
+ if self.time_widget.get_time().is_nan():
488
493
  return
489
494
 
490
495
  self.accept()
@@ -975,6 +980,70 @@ class Results_dialog(QDialog):
975
980
  self.done(cfg.SAVE_DATASET)
976
981
 
977
982
 
983
+ class Results_dialog_exit_code(QDialog):
984
+ """
985
+ widget for visualizing text output
986
+ """
987
+
988
+ def __init__(self):
989
+ super().__init__()
990
+
991
+ self.dataset = False
992
+
993
+ self.setWindowTitle("")
994
+
995
+ hbox = QVBoxLayout()
996
+
997
+ self.lb = QLabel("")
998
+ hbox.addWidget(self.lb)
999
+
1000
+ self.ptText = QPlainTextEdit()
1001
+ self.ptText.setReadOnly(True)
1002
+ hbox.addWidget(self.ptText)
1003
+
1004
+ hbox2 = QHBoxLayout()
1005
+ hbox2.addItem(QSpacerItem(241, 20, QSizePolicy.Expanding, QSizePolicy.Minimum))
1006
+
1007
+ self.pbSave = QPushButton("Save results", clicked=self.save_results)
1008
+ hbox2.addWidget(self.pbSave)
1009
+
1010
+ self.pb1 = QPushButton("1", clicked=lambda: self.done_(1))
1011
+ hbox2.addWidget(self.pb1)
1012
+
1013
+ self.pb2 = QPushButton("2", clicked=lambda: self.done_(2))
1014
+ hbox2.addWidget(self.pb2)
1015
+
1016
+ self.pb3 = QPushButton("3", clicked=lambda: self.done_(3))
1017
+ hbox2.addWidget(self.pb3)
1018
+
1019
+ hbox.addLayout(hbox2)
1020
+ self.setLayout(hbox)
1021
+
1022
+ self.resize(800, 640)
1023
+
1024
+ def done_(self, status):
1025
+ self.done(status)
1026
+
1027
+ def save_results(self):
1028
+ """
1029
+ save content of self.ptText
1030
+ """
1031
+
1032
+ if not self.dataset:
1033
+ file_name, _ = QFileDialog().getSaveFileName(self, "Save results", "", "Text files (*.txt *.tsv);;All files (*)")
1034
+
1035
+ if not file_name:
1036
+ return
1037
+ try:
1038
+ with open(file_name, "w") as f:
1039
+ f.write(self.ptText.toPlainText())
1040
+ except Exception:
1041
+ QMessageBox.critical(self, cfg.programName, f"The file {file_name} can not be saved")
1042
+
1043
+ else:
1044
+ self.done(cfg.SAVE_DATASET)
1045
+
1046
+
978
1047
  class View_data(QDialog):
979
1048
  """
980
1049
  widget for visualizing rows of data file
boris/edit_event.py CHANGED
@@ -21,7 +21,7 @@ This file is part of BORIS.
21
21
  """
22
22
 
23
23
  from decimal import Decimal as dec
24
- import math
24
+ import logging
25
25
 
26
26
  from PySide6.QtWidgets import (
27
27
  QDialog,
@@ -44,11 +44,12 @@ class DlgEditEvent(QDialog, Ui_Form):
44
44
  def __init__(
45
45
  self,
46
46
  observation_type: str,
47
- time_value: dec = dec(0),
47
+ time_value: dec = dec("NaN"),
48
48
  image_idx=None,
49
49
  current_time=0,
50
50
  time_format: str = cfg.S,
51
51
  show_set_current_time: bool = False,
52
+ exif_date_time: dec | None = None,
52
53
  parent=None,
53
54
  ):
54
55
  super().__init__(parent)
@@ -59,42 +60,49 @@ class DlgEditEvent(QDialog, Ui_Form):
59
60
 
60
61
  self.pb_set_to_current_time.setVisible(show_set_current_time)
61
62
  self.current_time = current_time
63
+ self.exif_date_time = exif_date_time
64
+
65
+ # hide frame index for all observations
66
+ # frame index is determined in base of time
67
+ for w in (
68
+ self.lb_frame_idx,
69
+ self.sb_frame_idx,
70
+ self.cb_set_frame_idx_na,
71
+ ):
72
+ w.setVisible(False)
62
73
 
63
74
  # hide image index
64
75
  if observation_type in (cfg.LIVE, cfg.MEDIA):
65
- for w in (self.lb_image_idx, self.sb_image_idx, self.cb_set_time_na, self.pb_set_to_current_image_index):
66
- w.setVisible(False)
67
- # hide frame index because frame index is automatically extracted
68
- for w in (self.lb_frame_idx, self.sb_frame_idx, self.cb_set_frame_idx_na):
76
+ # hide image index
77
+ for w in (
78
+ self.cb_set_time_na,
79
+ self.gb_image_index,
80
+ ):
69
81
  w.setVisible(False)
70
82
 
71
- if (observation_type in (cfg.LIVE, cfg.MEDIA)) or (observation_type == cfg.IMAGES and not math.isnan(self.time_value)):
72
- self.time_widget = dialog.get_time_widget(self.time_value)
83
+ # widget for time
84
+ self.time_widget = dialog.get_time_widget(self.time_value)
73
85
 
74
- if time_format == cfg.S:
75
- self.time_widget.rb_seconds.setChecked(True)
76
- if time_format == cfg.HHMMSS:
77
- self.time_widget.rb_time.setChecked(True)
78
- if self.time_value > cfg.DATE_CUTOFF:
79
- self.time_widget.rb_datetime.setChecked(True)
86
+ if time_format == cfg.S:
87
+ self.time_widget.rb_seconds.setChecked(True)
88
+ if time_format == cfg.HHMMSS:
89
+ self.time_widget.rb_time.setChecked(True)
90
+ if not self.time_value.is_nan() and int(self.time_value) > cfg.DATE_CUTOFF:
91
+ self.time_widget.rb_datetime.setChecked(True)
80
92
 
81
- self.horizontalLayout_2.insertWidget(0, self.time_widget)
93
+ self.horizontalLayout_3.insertWidget(0, self.time_widget)
82
94
 
83
95
  if observation_type == cfg.IMAGES:
84
- self.time_widget = dialog.get_time_widget(self.time_value)
85
96
  # hide frame index widgets
86
- for w in (self.lb_frame_idx, self.sb_frame_idx, self.cb_set_frame_idx_na, self.pb_set_to_current_time):
87
- w.setVisible(False)
97
+ self.pb_set_to_current_time.setVisible(self.exif_date_time is not None)
88
98
  self.sb_image_idx.setValue(self.image_idx)
89
99
 
90
- # self.pb_set_to_current_time.setText("Set to current image index")
91
-
92
100
  self.pb_set_to_current_time.clicked.connect(self.set_to_current_time)
93
101
  self.pb_set_to_current_image_index.clicked.connect(self.set_to_current_image_index)
94
102
 
95
103
  self.cb_set_time_na.stateChanged.connect(self.time_na)
96
104
 
97
- self.cb_set_frame_idx_na.stateChanged.connect(self.frame_idx_na)
105
+ # self.cb_set_frame_idx_na.stateChanged.connect(self.frame_idx_na)
98
106
  self.pbOK.clicked.connect(self.close_widget)
99
107
  self.pbCancel.clicked.connect(self.reject)
100
108
 
@@ -119,22 +127,34 @@ class DlgEditEvent(QDialog, Ui_Form):
119
127
  """
120
128
  set time to current media time
121
129
  """
130
+
131
+ print(f"{self.current_time=}")
132
+
122
133
  if self.observation_type in (cfg.LIVE, cfg.MEDIA):
123
134
  self.time_widget.set_time(dec(float(self.current_time)))
124
135
 
125
- def frame_idx_na(self):
126
- """
127
- set/unset frame index NA
128
- """
129
- self.lb_frame_idx.setEnabled(not self.cb_set_frame_idx_na.isChecked())
130
- self.sb_frame_idx.setEnabled(not self.cb_set_frame_idx_na.isChecked())
136
+ if self.observation_type == cfg.IMAGES:
137
+ if self.exif_date_time is not None:
138
+ self.time_widget.set_time(dec(self.exif_date_time))
139
+
140
+ # def frame_idx_na(self):
141
+ # """
142
+ # set/unset frame index NA
143
+ # """
144
+ # self.lb_frame_idx.setEnabled(not self.cb_set_frame_idx_na.isChecked())
145
+ # self.sb_frame_idx.setEnabled(not self.cb_set_frame_idx_na.isChecked())
131
146
 
132
147
  def time_na(self):
133
148
  """
134
149
  set/unset time to NA
135
150
  """
136
151
 
152
+ logging.debug("time_na function")
153
+
154
+ self.time_widget.setVisible(not self.cb_set_time_na.isChecked())
137
155
  self.time_widget.setEnabled(not self.cb_set_time_na.isChecked())
156
+
157
+ self.pb_set_to_current_time.setVisible(not self.cb_set_time_na.isChecked() and self.exif_date_time is not None)
138
158
  self.pb_set_to_current_time.setEnabled(not self.cb_set_time_na.isChecked())
139
159
 
140
160
 
boris/edit_event_ui.py CHANGED
@@ -3,7 +3,7 @@
3
3
  ################################################################################
4
4
  ## Form generated from reading UI file 'edit_event.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
  ################################################################################
@@ -15,60 +15,89 @@ from PySide6.QtGui import (QBrush, QColor, QConicalGradient, QCursor,
15
15
  QFont, QFontDatabase, QGradient, QIcon,
16
16
  QImage, QKeySequence, QLinearGradient, QPainter,
17
17
  QPalette, QPixmap, QRadialGradient, QTransform)
18
- from PySide6.QtWidgets import (QApplication, QCheckBox, QComboBox, QHBoxLayout,
19
- QLabel, QPlainTextEdit, QPushButton, QSizePolicy,
20
- QSpacerItem, QSpinBox, QVBoxLayout, QWidget)
18
+ from PySide6.QtWidgets import (QApplication, QCheckBox, QComboBox, QGroupBox,
19
+ QHBoxLayout, QLabel, QPlainTextEdit, QPushButton,
20
+ QSizePolicy, QSpacerItem, QSpinBox, QVBoxLayout,
21
+ QWidget)
21
22
 
22
23
  class Ui_Form(object):
23
24
  def setupUi(self, Form):
24
25
  if not Form.objectName():
25
26
  Form.setObjectName(u"Form")
26
- Form.resize(413, 488)
27
- self.verticalLayout = QVBoxLayout(Form)
27
+ Form.resize(600, 638)
28
+ self.verticalLayout_3 = QVBoxLayout(Form)
29
+ self.verticalLayout_3.setObjectName(u"verticalLayout_3")
30
+ self.gb_time = QGroupBox(Form)
31
+ self.gb_time.setObjectName(u"gb_time")
32
+ self.verticalLayout = QVBoxLayout(self.gb_time)
28
33
  self.verticalLayout.setObjectName(u"verticalLayout")
34
+ self.horizontalLayout_8 = QHBoxLayout()
35
+ self.horizontalLayout_8.setObjectName(u"horizontalLayout_8")
36
+ self.cb_set_time_na = QCheckBox(self.gb_time)
37
+ self.cb_set_time_na.setObjectName(u"cb_set_time_na")
38
+
39
+ self.horizontalLayout_8.addWidget(self.cb_set_time_na)
40
+
41
+ self.horizontalSpacer_7 = QSpacerItem(40, 20, QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Minimum)
42
+
43
+ self.horizontalLayout_8.addItem(self.horizontalSpacer_7)
44
+
45
+
46
+ self.verticalLayout.addLayout(self.horizontalLayout_8)
47
+
29
48
  self.horizontalLayout_3 = QHBoxLayout()
30
49
  self.horizontalLayout_3.setObjectName(u"horizontalLayout_3")
31
- self.label = QLabel(Form)
32
- self.label.setObjectName(u"label")
50
+ self.lb_time = QLabel(self.gb_time)
51
+ self.lb_time.setObjectName(u"lb_time")
33
52
 
34
- self.horizontalLayout_3.addWidget(self.label)
53
+ self.horizontalLayout_3.addWidget(self.lb_time)
35
54
 
36
55
  self.horizontalLayout_2 = QHBoxLayout()
37
56
  self.horizontalLayout_2.setObjectName(u"horizontalLayout_2")
38
- self.pb_set_to_current_time = QPushButton(Form)
57
+ self.horizontalSpacer = QSpacerItem(40, 20, QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Minimum)
58
+
59
+ self.horizontalLayout_2.addItem(self.horizontalSpacer)
60
+
61
+
62
+ self.horizontalLayout_3.addLayout(self.horizontalLayout_2)
63
+
64
+
65
+ self.verticalLayout.addLayout(self.horizontalLayout_3)
66
+
67
+ self.horizontalLayout_9 = QHBoxLayout()
68
+ self.horizontalLayout_9.setObjectName(u"horizontalLayout_9")
69
+ self.pb_set_to_current_time = QPushButton(self.gb_time)
39
70
  self.pb_set_to_current_time.setObjectName(u"pb_set_to_current_time")
40
71
 
41
- self.horizontalLayout_2.addWidget(self.pb_set_to_current_time)
72
+ self.horizontalLayout_9.addWidget(self.pb_set_to_current_time)
42
73
 
43
- self.cb_set_time_na = QCheckBox(Form)
44
- self.cb_set_time_na.setObjectName(u"cb_set_time_na")
74
+ self.horizontalSpacer_8 = QSpacerItem(40, 20, QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Minimum)
45
75
 
46
- self.horizontalLayout_2.addWidget(self.cb_set_time_na)
76
+ self.horizontalLayout_9.addItem(self.horizontalSpacer_8)
47
77
 
48
- self.horizontalSpacer = QSpacerItem(40, 20, QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Minimum)
49
78
 
50
- self.horizontalLayout_2.addItem(self.horizontalSpacer)
79
+ self.verticalLayout.addLayout(self.horizontalLayout_9)
51
80
 
81
+ self.verticalSpacer = QSpacerItem(20, 40, QSizePolicy.Policy.Minimum, QSizePolicy.Policy.Expanding)
52
82
 
53
- self.horizontalLayout_3.addLayout(self.horizontalLayout_2)
83
+ self.verticalLayout.addItem(self.verticalSpacer)
54
84
 
55
85
 
56
- self.verticalLayout.addLayout(self.horizontalLayout_3)
86
+ self.verticalLayout_3.addWidget(self.gb_time)
57
87
 
88
+ self.gb_image_index = QGroupBox(Form)
89
+ self.gb_image_index.setObjectName(u"gb_image_index")
90
+ self.verticalLayout_2 = QVBoxLayout(self.gb_image_index)
91
+ self.verticalLayout_2.setObjectName(u"verticalLayout_2")
58
92
  self.horizontalLayout_7 = QHBoxLayout()
59
93
  self.horizontalLayout_7.setObjectName(u"horizontalLayout_7")
60
- self.lb_image_idx = QLabel(Form)
61
- self.lb_image_idx.setObjectName(u"lb_image_idx")
62
-
63
- self.horizontalLayout_7.addWidget(self.lb_image_idx)
64
-
65
- self.sb_image_idx = QSpinBox(Form)
94
+ self.sb_image_idx = QSpinBox(self.gb_image_index)
66
95
  self.sb_image_idx.setObjectName(u"sb_image_idx")
67
96
  self.sb_image_idx.setMaximum(10000000)
68
97
 
69
98
  self.horizontalLayout_7.addWidget(self.sb_image_idx)
70
99
 
71
- self.pb_set_to_current_image_index = QPushButton(Form)
100
+ self.pb_set_to_current_image_index = QPushButton(self.gb_image_index)
72
101
  self.pb_set_to_current_image_index.setObjectName(u"pb_set_to_current_image_index")
73
102
 
74
103
  self.horizontalLayout_7.addWidget(self.pb_set_to_current_image_index)
@@ -78,7 +107,10 @@ class Ui_Form(object):
78
107
  self.horizontalLayout_7.addItem(self.horizontalSpacer_6)
79
108
 
80
109
 
81
- self.verticalLayout.addLayout(self.horizontalLayout_7)
110
+ self.verticalLayout_2.addLayout(self.horizontalLayout_7)
111
+
112
+
113
+ self.verticalLayout_3.addWidget(self.gb_image_index)
82
114
 
83
115
  self.horizontalLayout_4 = QHBoxLayout()
84
116
  self.horizontalLayout_4.setObjectName(u"horizontalLayout_4")
@@ -97,7 +129,7 @@ class Ui_Form(object):
97
129
  self.horizontalLayout_4.addItem(self.horizontalSpacer_2)
98
130
 
99
131
 
100
- self.verticalLayout.addLayout(self.horizontalLayout_4)
132
+ self.verticalLayout_3.addLayout(self.horizontalLayout_4)
101
133
 
102
134
  self.horizontalLayout_5 = QHBoxLayout()
103
135
  self.horizontalLayout_5.setObjectName(u"horizontalLayout_5")
@@ -116,7 +148,7 @@ class Ui_Form(object):
116
148
  self.horizontalLayout_5.addItem(self.horizontalSpacer_3)
117
149
 
118
150
 
119
- self.verticalLayout.addLayout(self.horizontalLayout_5)
151
+ self.verticalLayout_3.addLayout(self.horizontalLayout_5)
120
152
 
121
153
  self.horizontalLayout_6 = QHBoxLayout()
122
154
  self.horizontalLayout_6.setObjectName(u"horizontalLayout_6")
@@ -142,17 +174,17 @@ class Ui_Form(object):
142
174
  self.horizontalLayout_6.addItem(self.horizontalSpacer_5)
143
175
 
144
176
 
145
- self.verticalLayout.addLayout(self.horizontalLayout_6)
177
+ self.verticalLayout_3.addLayout(self.horizontalLayout_6)
146
178
 
147
179
  self.label_4 = QLabel(Form)
148
180
  self.label_4.setObjectName(u"label_4")
149
181
 
150
- self.verticalLayout.addWidget(self.label_4)
182
+ self.verticalLayout_3.addWidget(self.label_4)
151
183
 
152
184
  self.leComment = QPlainTextEdit(Form)
153
185
  self.leComment.setObjectName(u"leComment")
154
186
 
155
- self.verticalLayout.addWidget(self.leComment)
187
+ self.verticalLayout_3.addWidget(self.leComment)
156
188
 
157
189
  self.horizontalLayout = QHBoxLayout()
158
190
  self.horizontalLayout.setObjectName(u"horizontalLayout")
@@ -171,7 +203,7 @@ class Ui_Form(object):
171
203
  self.horizontalLayout.addWidget(self.pbOK)
172
204
 
173
205
 
174
- self.verticalLayout.addLayout(self.horizontalLayout)
206
+ self.verticalLayout_3.addLayout(self.horizontalLayout)
175
207
 
176
208
 
177
209
  self.retranslateUi(Form)
@@ -184,13 +216,14 @@ class Ui_Form(object):
184
216
 
185
217
  def retranslateUi(self, Form):
186
218
  Form.setWindowTitle(QCoreApplication.translate("Form", u"Edit event", None))
187
- self.label.setText(QCoreApplication.translate("Form", u"Time", None))
219
+ self.gb_time.setTitle(QCoreApplication.translate("Form", u"Time", None))
220
+ self.cb_set_time_na.setText(QCoreApplication.translate("Form", u"Set time to NA", None))
221
+ self.lb_time.setText("")
188
222
  self.pb_set_to_current_time.setText(QCoreApplication.translate("Form", u"Set to current time", None))
189
- self.cb_set_time_na.setText(QCoreApplication.translate("Form", u"Set NA", None))
190
- self.lb_image_idx.setText(QCoreApplication.translate("Form", u"Image index", None))
223
+ self.gb_image_index.setTitle(QCoreApplication.translate("Form", u"Image index", None))
191
224
  self.pb_set_to_current_image_index.setText(QCoreApplication.translate("Form", u"Set to current image index", None))
192
225
  self.lbSubject.setText(QCoreApplication.translate("Form", u"Subject", None))
193
- self.label_2.setText(QCoreApplication.translate("Form", u"Code", None))
226
+ self.label_2.setText(QCoreApplication.translate("Form", u"Behavior", None))
194
227
  self.lb_frame_idx.setText(QCoreApplication.translate("Form", u"Frame index", None))
195
228
  self.cb_set_frame_idx_na.setText(QCoreApplication.translate("Form", u"Set NA", None))
196
229
  self.label_4.setText(QCoreApplication.translate("Form", u"Comment", None))