boris-behav-obs 8.25.4__py2.py3-none-any.whl → 8.26.1__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/add_modifier.py +48 -18
- boris/add_modifier_ui.py +9 -5
- boris/advanced_event_filtering.py +2 -2
- boris/behav_coding_map_creator.py +1 -1
- boris/behaviors_coding_map.py +1 -1
- boris/config.py +7 -23
- boris/config_file.py +0 -2
- boris/core.py +7 -6
- boris/dialog.py +2 -2
- boris/geometric_measurement.py +1 -1
- boris/measurement_widget.py +1 -1
- boris/observation.py +1 -1
- boris/otx_parser.py +1 -1
- boris/preferences.py +0 -2
- boris/project.py +29 -14
- boris/select_modifiers.py +32 -8
- boris/time_budget_widget.py +1 -1
- boris/utilities.py +14 -3
- boris/version.py +2 -2
- boris/write_event.py +178 -75
- {boris_behav_obs-8.25.4.dist-info → boris_behav_obs-8.26.1.dist-info}/METADATA +3 -3
- {boris_behav_obs-8.25.4.dist-info → boris_behav_obs-8.26.1.dist-info}/RECORD +26 -38
- boris/README.TXT +0 -22
- boris/add_modifier.ui +0 -323
- boris/converters.ui +0 -289
- boris/core.qrc +0 -67
- boris/core.ui +0 -1585
- boris/edit_event.ui +0 -240
- boris/icons/logo_eye.ico +0 -0
- boris/observation.ui +0 -848
- boris/param_panel.ui +0 -379
- boris/preferences.ui +0 -588
- boris/project.ui +0 -1074
- boris_behav_obs-8.25.4.dist-info/LICENSE.TXT +0 -674
- {boris → boris_behav_obs-8.26.1.dist-info}/LICENSE.TXT +0 -0
- {boris_behav_obs-8.25.4.dist-info → boris_behav_obs-8.26.1.dist-info}/WHEEL +0 -0
- {boris_behav_obs-8.25.4.dist-info → boris_behav_obs-8.26.1.dist-info}/entry_points.txt +0 -0
- {boris_behav_obs-8.25.4.dist-info → boris_behav_obs-8.26.1.dist-info}/top_level.txt +0 -0
boris/select_modifiers.py
CHANGED
|
@@ -43,6 +43,10 @@ from . import utilities as util
|
|
|
43
43
|
|
|
44
44
|
|
|
45
45
|
class ModifiersList(QDialog):
|
|
46
|
+
"""
|
|
47
|
+
class for selection the modifier(s)
|
|
48
|
+
"""
|
|
49
|
+
|
|
46
50
|
def __init__(self, code: str, modifiers_dict: dict, currentModifier: str):
|
|
47
51
|
super().__init__()
|
|
48
52
|
self.setWindowTitle(cfg.programName)
|
|
@@ -60,11 +64,11 @@ class ModifiersList(QDialog):
|
|
|
60
64
|
self.modifiersSetNumber = 0
|
|
61
65
|
|
|
62
66
|
for idx in util.sorted_keys(modifiers_dict):
|
|
63
|
-
if self.modifiers_dict[idx]["type"] not in
|
|
67
|
+
if self.modifiers_dict[idx]["type"] not in (
|
|
64
68
|
cfg.SINGLE_SELECTION,
|
|
65
69
|
cfg.MULTI_SELECTION,
|
|
66
70
|
cfg.NUMERIC_MODIFIER,
|
|
67
|
-
|
|
71
|
+
):
|
|
68
72
|
continue
|
|
69
73
|
|
|
70
74
|
V2layout = QVBoxLayout()
|
|
@@ -75,10 +79,13 @@ class ModifiersList(QDialog):
|
|
|
75
79
|
lb.setText(f"Modifier <b>{self.modifiers_dict[idx]['name']}</b>")
|
|
76
80
|
V2layout.addWidget(lb)
|
|
77
81
|
|
|
78
|
-
|
|
82
|
+
lb = QLabel(f"<small>{self.modifiers_dict[idx]['description']}</small>")
|
|
83
|
+
V2layout.addWidget(lb)
|
|
84
|
+
|
|
85
|
+
if self.modifiers_dict[idx]["type"] in (
|
|
79
86
|
cfg.SINGLE_SELECTION,
|
|
80
87
|
cfg.MULTI_SELECTION,
|
|
81
|
-
|
|
88
|
+
):
|
|
82
89
|
lw = QListWidget()
|
|
83
90
|
self.modifiers_dict[idx]["widget"] = lw
|
|
84
91
|
lw.setObjectName(f"lw_modifiers_({self.modifiers_dict[idx]['type']})")
|
|
@@ -114,6 +121,7 @@ class ModifiersList(QDialog):
|
|
|
114
121
|
if self.modifiers_dict[idx]["type"] in [cfg.NUMERIC_MODIFIER]:
|
|
115
122
|
le = QLineEdit()
|
|
116
123
|
self.modifiers_dict[idx]["widget"] = le
|
|
124
|
+
le.setObjectName(f"le_modifiers_({self.modifiers_dict[idx]['type']})")
|
|
117
125
|
|
|
118
126
|
if currentModifierList != [""] and currentModifierList[int(idx)] != "None":
|
|
119
127
|
le.setText(currentModifierList[int(idx)])
|
|
@@ -160,10 +168,14 @@ class ModifiersList(QDialog):
|
|
|
160
168
|
|
|
161
169
|
# accept and close dialog if enter pressed
|
|
162
170
|
if ek == Qt.Key_Enter or ek == Qt.Key_Return: # enter or enter from numeric pad
|
|
163
|
-
self.
|
|
171
|
+
if not self.pbOK_clicked():
|
|
172
|
+
return False
|
|
164
173
|
return True
|
|
165
174
|
|
|
175
|
+
modifiersSetIndex = 0
|
|
166
176
|
for widget in self.children():
|
|
177
|
+
if "_modifiers" in widget.objectName():
|
|
178
|
+
modifiersSetIndex = modifiersSetIndex + 1
|
|
167
179
|
if "lw_modifiers" in widget.objectName():
|
|
168
180
|
if self.modifiersSetNumber == 1:
|
|
169
181
|
# check if modifiers have code
|
|
@@ -172,7 +184,7 @@ class ModifiersList(QDialog):
|
|
|
172
184
|
break
|
|
173
185
|
else:
|
|
174
186
|
# modifiers have no associated code: the modifier starting with hit key will be selected
|
|
175
|
-
if ek not in
|
|
187
|
+
if ek not in (Qt.Key_Down, Qt.Key_Up):
|
|
176
188
|
if ek == Qt.Key_Space and f"({cfg.MULTI_SELECTION})" in widget.objectName(): # checking using SPACE bar
|
|
177
189
|
if widget.item(widget.currentRow()).checkState() == Qt.Checked:
|
|
178
190
|
widget.item(widget.currentRow()).setCheckState(Qt.Unchecked)
|
|
@@ -198,6 +210,7 @@ class ModifiersList(QDialog):
|
|
|
198
210
|
return
|
|
199
211
|
|
|
200
212
|
for index in range(widget.count()):
|
|
213
|
+
# check function kesy (F1, F2...)
|
|
201
214
|
if ek in cfg.function_keys:
|
|
202
215
|
if f"({cfg.function_keys[ek]})" in widget.item(index).text().upper():
|
|
203
216
|
if f"({cfg.SINGLE_SELECTION})" in widget.objectName():
|
|
@@ -206,6 +219,10 @@ class ModifiersList(QDialog):
|
|
|
206
219
|
if self.modifiersSetNumber == 1:
|
|
207
220
|
self.accept()
|
|
208
221
|
return True
|
|
222
|
+
# else move to next set of mofifiers
|
|
223
|
+
elif modifiersSetIndex != self.modifiersSetNumber:
|
|
224
|
+
widget.parent().focusNextChild()
|
|
225
|
+
return True
|
|
209
226
|
|
|
210
227
|
if f"({cfg.MULTI_SELECTION})" in widget.objectName():
|
|
211
228
|
if widget.item(index).checkState() == Qt.Checked:
|
|
@@ -220,6 +237,10 @@ class ModifiersList(QDialog):
|
|
|
220
237
|
if self.modifiersSetNumber == 1:
|
|
221
238
|
self.accept()
|
|
222
239
|
return True
|
|
240
|
+
# else move to next set of mofifiers
|
|
241
|
+
elif modifiersSetIndex != self.modifiersSetNumber:
|
|
242
|
+
widget.parent().focusNextChild()
|
|
243
|
+
return True
|
|
223
244
|
|
|
224
245
|
if f"({cfg.MULTI_SELECTION})" in widget.objectName():
|
|
225
246
|
if widget.item(index).checkState() == Qt.Checked:
|
|
@@ -271,6 +292,9 @@ class ModifiersList(QDialog):
|
|
|
271
292
|
return self.modifiers_dict
|
|
272
293
|
|
|
273
294
|
def pbOK_clicked(self):
|
|
295
|
+
"""
|
|
296
|
+
OK button is clicked
|
|
297
|
+
"""
|
|
274
298
|
for idx in util.sorted_keys(self.modifiers_dict):
|
|
275
299
|
if self.modifiers_dict[idx]["type"] == cfg.NUMERIC_MODIFIER:
|
|
276
300
|
if self.modifiers_dict[idx]["widget"].text():
|
|
@@ -280,8 +304,8 @@ class ModifiersList(QDialog):
|
|
|
280
304
|
QMessageBox.warning(
|
|
281
305
|
self,
|
|
282
306
|
cfg.programName,
|
|
283
|
-
"<b>{}</b> is not a numeric value"
|
|
307
|
+
f"<b>{self.modifiers_dict[idx]['widget'].text()}</b> is not a numeric value",
|
|
284
308
|
)
|
|
285
|
-
return
|
|
309
|
+
return False
|
|
286
310
|
|
|
287
311
|
self.accept()
|
boris/time_budget_widget.py
CHANGED
|
@@ -112,7 +112,7 @@ class timeBudgetResults(QWidget):
|
|
|
112
112
|
spacerItem = QSpacerItem(241, 20, QSizePolicy.Expanding, QSizePolicy.Minimum)
|
|
113
113
|
hbox2.addItem(spacerItem)
|
|
114
114
|
|
|
115
|
-
self.pbClose = QPushButton(
|
|
115
|
+
self.pbClose = QPushButton(cfg.CLOSE, clicked=self.close_clicked)
|
|
116
116
|
hbox2.addWidget(self.pbClose)
|
|
117
117
|
|
|
118
118
|
hbox.addLayout(hbox2)
|
boris/utilities.py
CHANGED
|
@@ -537,9 +537,9 @@ def get_current_states_modifiers_by_subject(
|
|
|
537
537
|
break
|
|
538
538
|
if x[cfg.EVENT_BEHAVIOR_FIELD_IDX] in state_behaviors_codes:
|
|
539
539
|
if (x[cfg.EVENT_BEHAVIOR_FIELD_IDX], x[cfg.EVENT_MODIFIER_FIELD_IDX]) not in current_states[x[cfg.EVENT_SUBJECT_FIELD_IDX]]:
|
|
540
|
-
current_states[x[cfg.EVENT_SUBJECT_FIELD_IDX]][
|
|
541
|
-
|
|
542
|
-
|
|
540
|
+
current_states[x[cfg.EVENT_SUBJECT_FIELD_IDX]][(x[cfg.EVENT_BEHAVIOR_FIELD_IDX], x[cfg.EVENT_MODIFIER_FIELD_IDX])] = (
|
|
541
|
+
False
|
|
542
|
+
)
|
|
543
543
|
|
|
544
544
|
current_states[x[cfg.EVENT_SUBJECT_FIELD_IDX]][
|
|
545
545
|
(x[cfg.EVENT_BEHAVIOR_FIELD_IDX], x[cfg.EVENT_MODIFIER_FIELD_IDX])
|
|
@@ -1493,6 +1493,17 @@ def all_subjects(subjects: dict) -> list:
|
|
|
1493
1493
|
return [subjects[x][cfg.SUBJECT_NAME] for x in sorted_keys(subjects)]
|
|
1494
1494
|
|
|
1495
1495
|
|
|
1496
|
+
def has_coding_map(ethogram: dict, behavior_idx: str) -> bool:
|
|
1497
|
+
"""
|
|
1498
|
+
check if behavior index has a coding map
|
|
1499
|
+
"""
|
|
1500
|
+
if not ethogram.get(behavior_idx, False):
|
|
1501
|
+
return False
|
|
1502
|
+
if not ethogram[behavior_idx].get("coding map", False):
|
|
1503
|
+
return False
|
|
1504
|
+
return False
|
|
1505
|
+
|
|
1506
|
+
|
|
1496
1507
|
def dir_images_number(dir_path_str: str) -> dict:
|
|
1497
1508
|
"""
|
|
1498
1509
|
return number of images in dir_path (see cfg.IMAGE_EXTENSIONS)
|
boris/version.py
CHANGED
boris/write_event.py
CHANGED
|
@@ -181,75 +181,6 @@ def write_event(self, event: dict, mem_time: dec) -> int:
|
|
|
181
181
|
)
|
|
182
182
|
return 1
|
|
183
183
|
|
|
184
|
-
if "from map" not in event: # modifiers only for behaviors without coding map
|
|
185
|
-
# check if event has modifiers
|
|
186
|
-
modifier_str = ""
|
|
187
|
-
|
|
188
|
-
if event[cfg.MODIFIERS]:
|
|
189
|
-
selected_modifiers, modifiers_external_data = {}, {}
|
|
190
|
-
# check if modifiers are from external data
|
|
191
|
-
for idx in event[cfg.MODIFIERS]:
|
|
192
|
-
if event[cfg.MODIFIERS][idx]["type"] == cfg.EXTERNAL_DATA_MODIFIER:
|
|
193
|
-
if "row" not in event: # no edit
|
|
194
|
-
for idx2 in self.plot_data:
|
|
195
|
-
if self.plot_data[idx2].y_label.upper() == event[cfg.MODIFIERS][idx]["name"].upper():
|
|
196
|
-
modifiers_external_data[idx] = dict(event[cfg.MODIFIERS][idx])
|
|
197
|
-
modifiers_external_data[idx]["selected"] = self.plot_data[idx2].lb_value.text()
|
|
198
|
-
else: # edit
|
|
199
|
-
original_modifiers_list = event.get("original_modifiers", "").split("|")
|
|
200
|
-
modifiers_external_data[idx] = dict(event[cfg.MODIFIERS][idx])
|
|
201
|
-
modifiers_external_data[idx]["selected"] = original_modifiers_list[int(idx)]
|
|
202
|
-
|
|
203
|
-
# check if modifiers are in single, multiple or numeric
|
|
204
|
-
if [x for x in event[cfg.MODIFIERS] if event[cfg.MODIFIERS][x]["type"] != cfg.EXTERNAL_DATA_MODIFIER]:
|
|
205
|
-
# pause media
|
|
206
|
-
if self.pj[cfg.OBSERVATIONS][self.observationId][cfg.TYPE] in [cfg.MEDIA]:
|
|
207
|
-
if self.playerType == cfg.MEDIA:
|
|
208
|
-
if self.dw_player[0].player.pause:
|
|
209
|
-
memState = "paused"
|
|
210
|
-
elif self.dw_player[0].player.time_pos is not None:
|
|
211
|
-
memState = "playing"
|
|
212
|
-
else:
|
|
213
|
-
memState = "stopped"
|
|
214
|
-
if memState == "playing":
|
|
215
|
-
self.pause_video()
|
|
216
|
-
|
|
217
|
-
# check if editing (original_modifiers key)
|
|
218
|
-
currentModifiers = event.get("original_modifiers", "")
|
|
219
|
-
|
|
220
|
-
modifiers_selector = select_modifiers.ModifiersList(event["code"], eval(str(event[cfg.MODIFIERS])), currentModifiers)
|
|
221
|
-
|
|
222
|
-
r = modifiers_selector.exec_()
|
|
223
|
-
if r:
|
|
224
|
-
selected_modifiers = modifiers_selector.get_modifiers()
|
|
225
|
-
|
|
226
|
-
# restart media
|
|
227
|
-
if self.pj[cfg.OBSERVATIONS][self.observationId][cfg.TYPE] == cfg.MEDIA:
|
|
228
|
-
if self.playerType == cfg.MEDIA:
|
|
229
|
-
if memState == "playing":
|
|
230
|
-
self.play_video()
|
|
231
|
-
if not r: # cancel button pressed
|
|
232
|
-
return
|
|
233
|
-
|
|
234
|
-
all_modifiers = {**selected_modifiers, **modifiers_external_data}
|
|
235
|
-
|
|
236
|
-
modifier_str = ""
|
|
237
|
-
for idx in util.sorted_keys(all_modifiers):
|
|
238
|
-
if modifier_str:
|
|
239
|
-
modifier_str += "|"
|
|
240
|
-
if all_modifiers[idx]["type"] in [cfg.SINGLE_SELECTION, cfg.MULTI_SELECTION]:
|
|
241
|
-
modifier_str += ",".join(all_modifiers[idx].get("selected", ""))
|
|
242
|
-
if all_modifiers[idx]["type"] in [cfg.NUMERIC_MODIFIER, cfg.EXTERNAL_DATA_MODIFIER]:
|
|
243
|
-
modifier_str += all_modifiers[idx].get("selected", "NA")
|
|
244
|
-
|
|
245
|
-
else:
|
|
246
|
-
modifier_str = event["from map"]
|
|
247
|
-
|
|
248
|
-
modifier_str = re.sub(r" \(.*\)", "", modifier_str)
|
|
249
|
-
|
|
250
|
-
# update current state
|
|
251
|
-
# TODO: verify event["subject"] / self.currentSubject
|
|
252
|
-
|
|
253
184
|
# extract State events
|
|
254
185
|
state_behaviors_codes = util.state_behavior_codes(self.pj[cfg.ETHOGRAM])
|
|
255
186
|
|
|
@@ -261,7 +192,7 @@ def write_event(self, event: dict, mem_time: dec) -> int:
|
|
|
261
192
|
if self.pj[cfg.OBSERVATIONS][self.observationId][cfg.TYPE] == cfg.IMAGES:
|
|
262
193
|
position = dec(image_idx) # decimal to pass to util.get_current_states_modifiers_by_subject
|
|
263
194
|
|
|
264
|
-
current_states = util.get_current_states_modifiers_by_subject(
|
|
195
|
+
current_states: dict = util.get_current_states_modifiers_by_subject(
|
|
265
196
|
state_behaviors_codes,
|
|
266
197
|
self.pj[cfg.OBSERVATIONS][self.observationId][cfg.EVENTS],
|
|
267
198
|
dict(self.pj[cfg.SUBJECTS], **{"": {"name": ""}}),
|
|
@@ -269,6 +200,108 @@ def write_event(self, event: dict, mem_time: dec) -> int:
|
|
|
269
200
|
include_modifiers=False,
|
|
270
201
|
)
|
|
271
202
|
|
|
203
|
+
# check if ask modifiers at stop is enabled
|
|
204
|
+
flag_ask_at_stop = False
|
|
205
|
+
if event["type"] == cfg.STATE_EVENT:
|
|
206
|
+
for idx in event[cfg.MODIFIERS]:
|
|
207
|
+
if event[cfg.MODIFIERS][idx].get("ask at stop", False):
|
|
208
|
+
flag_ask_at_stop = True
|
|
209
|
+
break
|
|
210
|
+
|
|
211
|
+
flag_ask_modifier = False
|
|
212
|
+
if flag_ask_at_stop:
|
|
213
|
+
# TODO: check if new event is a STOP one
|
|
214
|
+
|
|
215
|
+
idx_subject: str = ""
|
|
216
|
+
for idx in current_states:
|
|
217
|
+
if idx in self.pj[cfg.SUBJECTS] and self.pj[cfg.SUBJECTS][idx][cfg.SUBJECT_NAME] == self.currentSubject:
|
|
218
|
+
idx_subject = idx
|
|
219
|
+
break
|
|
220
|
+
|
|
221
|
+
if event[cfg.BEHAVIOR_CODE] in current_states[idx_subject]:
|
|
222
|
+
flag_ask_modifier = True
|
|
223
|
+
else:
|
|
224
|
+
flag_ask_modifier = True
|
|
225
|
+
|
|
226
|
+
if flag_ask_modifier:
|
|
227
|
+
if "from map" in event: # modifiers only for behaviors without coding map
|
|
228
|
+
modifier_str = event["from map"]
|
|
229
|
+
else:
|
|
230
|
+
# check if event has modifiers
|
|
231
|
+
modifier_str: str = ""
|
|
232
|
+
|
|
233
|
+
if event[cfg.MODIFIERS]:
|
|
234
|
+
selected_modifiers: dict = {}
|
|
235
|
+
modifiers_external_data: dict = {}
|
|
236
|
+
# check if modifiers are from external data
|
|
237
|
+
for idx in event[cfg.MODIFIERS]:
|
|
238
|
+
if event[cfg.MODIFIERS][idx]["type"] == cfg.EXTERNAL_DATA_MODIFIER:
|
|
239
|
+
if editing_event:
|
|
240
|
+
original_modifiers_list = event.get("original_modifiers", "").split("|")
|
|
241
|
+
modifiers_external_data[idx] = dict(event[cfg.MODIFIERS][idx])
|
|
242
|
+
modifiers_external_data[idx]["selected"] = original_modifiers_list[int(idx)]
|
|
243
|
+
|
|
244
|
+
else: # no edit
|
|
245
|
+
for idx2 in self.plot_data:
|
|
246
|
+
if self.plot_data[idx2].y_label.upper() == event[cfg.MODIFIERS][idx]["name"].upper():
|
|
247
|
+
modifiers_external_data[idx] = dict(event[cfg.MODIFIERS][idx])
|
|
248
|
+
modifiers_external_data[idx]["selected"] = self.plot_data[idx2].lb_value.text()
|
|
249
|
+
|
|
250
|
+
# check if modifiers are in single, multiple or numeric
|
|
251
|
+
if [x for x in event[cfg.MODIFIERS] if event[cfg.MODIFIERS][x]["type"] != cfg.EXTERNAL_DATA_MODIFIER]:
|
|
252
|
+
# pause media
|
|
253
|
+
if self.pj[cfg.OBSERVATIONS][self.observationId][cfg.TYPE] in (cfg.MEDIA):
|
|
254
|
+
if self.playerType == cfg.MEDIA:
|
|
255
|
+
if self.dw_player[0].player.pause:
|
|
256
|
+
memState = cfg.PAUSED
|
|
257
|
+
elif self.dw_player[0].player.time_pos is not None:
|
|
258
|
+
memState = cfg.PLAYING
|
|
259
|
+
else:
|
|
260
|
+
memState = cfg.STOPPED
|
|
261
|
+
if memState == cfg.PLAYING:
|
|
262
|
+
self.pause_video()
|
|
263
|
+
|
|
264
|
+
# check if editing (original_modifiers key)
|
|
265
|
+
currentModifiers = event.get("original_modifiers", "")
|
|
266
|
+
|
|
267
|
+
# print(f"{event=}")
|
|
268
|
+
|
|
269
|
+
modifiers_selector = select_modifiers.ModifiersList(
|
|
270
|
+
event[cfg.BEHAVIOR_CODE], eval(str(event[cfg.MODIFIERS])), currentModifiers
|
|
271
|
+
)
|
|
272
|
+
|
|
273
|
+
r = modifiers_selector.exec_()
|
|
274
|
+
if r:
|
|
275
|
+
selected_modifiers = modifiers_selector.get_modifiers()
|
|
276
|
+
|
|
277
|
+
# restart media
|
|
278
|
+
if self.pj[cfg.OBSERVATIONS][self.observationId][cfg.TYPE] == cfg.MEDIA:
|
|
279
|
+
if self.playerType == cfg.MEDIA:
|
|
280
|
+
if memState == cfg.PLAYING:
|
|
281
|
+
self.play_video()
|
|
282
|
+
if not r: # cancel button pressed
|
|
283
|
+
return
|
|
284
|
+
|
|
285
|
+
all_modifiers = {**selected_modifiers, **modifiers_external_data}
|
|
286
|
+
|
|
287
|
+
modifier_str: str = ""
|
|
288
|
+
for idx in util.sorted_keys(all_modifiers):
|
|
289
|
+
if modifier_str:
|
|
290
|
+
modifier_str += "|"
|
|
291
|
+
if all_modifiers[idx]["type"] in (cfg.SINGLE_SELECTION, cfg.MULTI_SELECTION):
|
|
292
|
+
modifier_str += ",".join(all_modifiers[idx].get("selected", ""))
|
|
293
|
+
if all_modifiers[idx]["type"] in (cfg.NUMERIC_MODIFIER, cfg.EXTERNAL_DATA_MODIFIER):
|
|
294
|
+
modifier_str += all_modifiers[idx].get("selected", "NA")
|
|
295
|
+
|
|
296
|
+
modifier_str = re.sub(r" \(.*\)", "", modifier_str)
|
|
297
|
+
else: # do not ask modifier
|
|
298
|
+
modifier_str = ""
|
|
299
|
+
|
|
300
|
+
# update current state
|
|
301
|
+
# TODO: verify event["subject"] / self.currentSubject
|
|
302
|
+
|
|
303
|
+
# print(f"{current_states=}")
|
|
304
|
+
|
|
272
305
|
# logging.debug(f"self.currentSubject {self.currentSubject}")
|
|
273
306
|
# logging.debug(f"current_states {current_states}")
|
|
274
307
|
|
|
@@ -279,7 +312,7 @@ def write_event(self, event: dict, mem_time: dec) -> int:
|
|
|
279
312
|
|
|
280
313
|
if not editing_event:
|
|
281
314
|
if self.currentSubject:
|
|
282
|
-
csj: list = []
|
|
315
|
+
csj: list = [] # list of current state for the current subject
|
|
283
316
|
for idx in current_states:
|
|
284
317
|
if idx in self.pj[cfg.SUBJECTS] and self.pj[cfg.SUBJECTS][idx][cfg.SUBJECT_NAME] == self.currentSubject:
|
|
285
318
|
csj = current_states[idx]
|
|
@@ -293,6 +326,8 @@ def write_event(self, event: dict, mem_time: dec) -> int:
|
|
|
293
326
|
|
|
294
327
|
logging.debug(f"csj {csj}")
|
|
295
328
|
|
|
329
|
+
# print(f"{csj=}")
|
|
330
|
+
|
|
296
331
|
if self.pj[cfg.OBSERVATIONS][self.observationId][cfg.TYPE] in (cfg.LIVE, cfg.MEDIA):
|
|
297
332
|
check_index = cfg.PJ_OBS_FIELDS[self.pj[cfg.OBSERVATIONS][self.observationId][cfg.TYPE]][cfg.TIME]
|
|
298
333
|
if self.pj[cfg.OBSERVATIONS][self.observationId][cfg.TYPE] == cfg.IMAGES:
|
|
@@ -308,6 +343,23 @@ def write_event(self, event: dict, mem_time: dec) -> int:
|
|
|
308
343
|
if ev[cfg.EVENT_BEHAVIOR_FIELD_IDX] == cs:
|
|
309
344
|
cm[cs] = ev[cfg.EVENT_MODIFIER_FIELD_IDX]
|
|
310
345
|
|
|
346
|
+
# print(f"{cm=}")
|
|
347
|
+
|
|
348
|
+
if flag_ask_at_stop:
|
|
349
|
+
# set modifier to START behavior
|
|
350
|
+
if event[cfg.BEHAVIOR_CODE] in csj:
|
|
351
|
+
mem_idx = -1
|
|
352
|
+
for idx, e in enumerate(self.pj[cfg.OBSERVATIONS][self.observationId][cfg.EVENTS]):
|
|
353
|
+
# print(f"{e=}")
|
|
354
|
+
if e[0] >= mem_time:
|
|
355
|
+
break
|
|
356
|
+
# same behavior, same subject and modifier(s) not set
|
|
357
|
+
if e[2] == event[cfg.BEHAVIOR_CODE] and e[1] == self.currentSubject and e[3] == "":
|
|
358
|
+
mem_idx = idx
|
|
359
|
+
if mem_idx != -1:
|
|
360
|
+
self.pj[cfg.OBSERVATIONS][self.observationId][cfg.EVENTS][mem_idx][3] = modifier_str
|
|
361
|
+
csj.remove(event[cfg.BEHAVIOR_CODE])
|
|
362
|
+
|
|
311
363
|
for cs in csj:
|
|
312
364
|
# close state if same state without modifier
|
|
313
365
|
if (
|
|
@@ -318,23 +370,74 @@ def write_event(self, event: dict, mem_time: dec) -> int:
|
|
|
318
370
|
modifier_str = cm[cs]
|
|
319
371
|
continue
|
|
320
372
|
|
|
321
|
-
if (event[
|
|
373
|
+
if (event[cfg.EXCLUDED] and cs in event[cfg.EXCLUDED].split(",")) or (
|
|
374
|
+
event[cfg.BEHAVIOR_CODE] == cs and cm[cs] != modifier_str
|
|
375
|
+
):
|
|
376
|
+
# check if behavior to stop is a 'ask modifier at stop'
|
|
377
|
+
behavior_to_stop = [
|
|
378
|
+
self.pj[cfg.ETHOGRAM][x]
|
|
379
|
+
for x in self.pj[cfg.ETHOGRAM]
|
|
380
|
+
if self.pj[cfg.ETHOGRAM][x][cfg.BEHAVIOR_CODE] == cs and self.pj[cfg.ETHOGRAM][x]["type"] == cfg.STATE_EVENT
|
|
381
|
+
]
|
|
382
|
+
if behavior_to_stop:
|
|
383
|
+
behavior_to_stop = behavior_to_stop[0]
|
|
384
|
+
|
|
385
|
+
flag_behavior_ask_at_stop = False
|
|
386
|
+
for idx in behavior_to_stop[cfg.MODIFIERS]:
|
|
387
|
+
if behavior_to_stop[cfg.MODIFIERS][idx].get("ask at stop", False):
|
|
388
|
+
flag_behavior_ask_at_stop = True
|
|
389
|
+
break
|
|
390
|
+
if flag_behavior_ask_at_stop:
|
|
391
|
+
modifiers_selector = select_modifiers.ModifiersList(
|
|
392
|
+
behavior_to_stop[cfg.BEHAVIOR_CODE],
|
|
393
|
+
eval(str(behavior_to_stop[cfg.MODIFIERS])),
|
|
394
|
+
currentModifier="",
|
|
395
|
+
)
|
|
396
|
+
|
|
397
|
+
r = modifiers_selector.exec_()
|
|
398
|
+
if r:
|
|
399
|
+
selected_modifiers = modifiers_selector.get_modifiers()
|
|
400
|
+
# print(f"{selected_modifiers=}")
|
|
401
|
+
|
|
402
|
+
behavior_to_stop_modifier_str: str = ""
|
|
403
|
+
for idx in util.sorted_keys(selected_modifiers):
|
|
404
|
+
if behavior_to_stop_modifier_str:
|
|
405
|
+
behavior_to_stop_modifier_str += "|"
|
|
406
|
+
if selected_modifiers[idx]["type"] in (cfg.SINGLE_SELECTION, cfg.MULTI_SELECTION):
|
|
407
|
+
behavior_to_stop_modifier_str += ",".join(selected_modifiers[idx].get("selected", ""))
|
|
408
|
+
if selected_modifiers[idx]["type"] in (cfg.NUMERIC_MODIFIER, cfg.EXTERNAL_DATA_MODIFIER):
|
|
409
|
+
behavior_to_stop_modifier_str += selected_modifiers[idx].get("selected", "NA")
|
|
410
|
+
|
|
411
|
+
# set the start modifier
|
|
412
|
+
mem_idx = -1
|
|
413
|
+
for idx, e in enumerate(self.pj[cfg.OBSERVATIONS][self.observationId][cfg.EVENTS]):
|
|
414
|
+
if e[0] >= mem_time - dec("0.001"):
|
|
415
|
+
break
|
|
416
|
+
# same behavior, same subject and modifier(s) not set
|
|
417
|
+
if e[2] == behavior_to_stop[cfg.BEHAVIOR_CODE] and e[1] == self.currentSubject and e[3] == "":
|
|
418
|
+
mem_idx = idx
|
|
419
|
+
if mem_idx != -1:
|
|
420
|
+
self.pj[cfg.OBSERVATIONS][self.observationId][cfg.EVENTS][mem_idx][3] = behavior_to_stop_modifier_str
|
|
421
|
+
|
|
422
|
+
else:
|
|
423
|
+
behavior_to_stop_modifier_str = cm[cs]
|
|
424
|
+
|
|
322
425
|
# add excluded state event to observations (= STOP them)
|
|
323
426
|
if self.pj[cfg.OBSERVATIONS][self.observationId][cfg.TYPE] in (cfg.LIVE):
|
|
324
427
|
bisect.insort(
|
|
325
428
|
self.pj[cfg.OBSERVATIONS][self.observationId][cfg.EVENTS],
|
|
326
|
-
[mem_time - dec("0.001"), self.currentSubject, cs,
|
|
429
|
+
[mem_time - dec("0.001"), self.currentSubject, cs, behavior_to_stop_modifier_str, ""],
|
|
327
430
|
)
|
|
328
431
|
|
|
329
432
|
if self.pj[cfg.OBSERVATIONS][self.observationId][cfg.TYPE] in (cfg.MEDIA):
|
|
330
433
|
bisect.insort(
|
|
331
434
|
self.pj[cfg.OBSERVATIONS][self.observationId][cfg.EVENTS],
|
|
332
|
-
[mem_time - dec("0.001"), self.currentSubject, cs,
|
|
435
|
+
[mem_time - dec("0.001"), self.currentSubject, cs, behavior_to_stop_modifier_str, "", cfg.NA],
|
|
333
436
|
)
|
|
334
437
|
|
|
335
438
|
if self.pj[cfg.OBSERVATIONS][self.observationId][cfg.TYPE] in (cfg.IMAGES):
|
|
336
439
|
self.pj[cfg.OBSERVATIONS][self.observationId][cfg.EVENTS].append(
|
|
337
|
-
[mem_time, self.currentSubject, cs,
|
|
440
|
+
[mem_time, self.currentSubject, cs, behavior_to_stop_modifier_str, "", image_idx, image_path]
|
|
338
441
|
)
|
|
339
442
|
|
|
340
443
|
# order by image index ASC
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: boris-behav-obs
|
|
3
|
-
Version: 8.
|
|
3
|
+
Version: 8.26.1
|
|
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
|
|
@@ -697,9 +697,9 @@ Requires-Python: >=3.8
|
|
|
697
697
|
Description-Content-Type: text/x-rst
|
|
698
698
|
License-File: LICENSE.TXT
|
|
699
699
|
Requires-Dist: exifread >=3.0.0
|
|
700
|
-
Requires-Dist: numpy >=1.
|
|
700
|
+
Requires-Dist: numpy >=1.26.4
|
|
701
701
|
Requires-Dist: matplotlib >=3.3.3
|
|
702
|
-
Requires-Dist: pandas >=
|
|
702
|
+
Requires-Dist: pandas >=2.2.2
|
|
703
703
|
Requires-Dist: tablib[cli,html,ods,pandas,xls,xlsx] >=3
|
|
704
704
|
Requires-Dist: pyqt5 >=5.15
|
|
705
705
|
Requires-Dist: pyreadr
|
|
@@ -1,36 +1,29 @@
|
|
|
1
|
-
boris/LICENSE.TXT,sha256=WJ7YI-moTFb-uVrFjnzzhGJrnL9P2iqQe8NuED3hutI,35141
|
|
2
|
-
boris/README.TXT,sha256=0506tPRqGbRsnH_JxX1HJXW3TkEuAFmUG1W1ArBTBmk,788
|
|
3
1
|
boris/__init__.py,sha256=vEqzYsbV0DwIWYPXIv3OXrBBFW71dpYRSL63Dedv4xE,773
|
|
4
2
|
boris/__main__.py,sha256=_cKab_aODdiWYjyf6mWu57D-84izlVDPAm13QxH-cCg,764
|
|
5
3
|
boris/about.py,sha256=JnsPLW8o9iYyp8I8S4Chhh3GmWNijxyyxRe9e9VFMFU,5253
|
|
6
|
-
boris/add_modifier.py,sha256=
|
|
7
|
-
boris/
|
|
8
|
-
boris/
|
|
9
|
-
boris/
|
|
10
|
-
boris/behav_coding_map_creator.py,sha256=rWU9Wm4KDxYDFJtSOC0lUWTviV1eYzlkuJdQl6x2dR0,37858
|
|
4
|
+
boris/add_modifier.py,sha256=dtP1xZCwO0QlUJVir0JP2ShL5WrOvH26vQfwGwu683Q,26465
|
|
5
|
+
boris/add_modifier_ui.py,sha256=ZKXDcpavvzF5X8gkTuza1WYsw3x9TB-qQjrhn1fka5c,10537
|
|
6
|
+
boris/advanced_event_filtering.py,sha256=ScKwLy5zELU8R9WOS5wVZPk4OtWG1Cn4XeMxyHzG1Rc,15180
|
|
7
|
+
boris/behav_coding_map_creator.py,sha256=FNU5fUjvXQhTn-fmFQpksgIUzE0ZkAxgpPCXRpSGsAM,37860
|
|
11
8
|
boris/behavior_binary_table.py,sha256=_XIJuly5xF5oSqjl8YIBMgJ_o3gtyviTJ5DJafvO-Mo,11677
|
|
12
|
-
boris/behaviors_coding_map.py,sha256=
|
|
9
|
+
boris/behaviors_coding_map.py,sha256=Q_-k8DsYtXgUBzOYUdoGl41EgLdVAvGyuir98CUDY5Q,7309
|
|
13
10
|
boris/boris_cli.py,sha256=CeUr_QKKySu9v-Gw5fkeQPjA3y_dGv7_Y4tCY41OeoA,13196
|
|
14
11
|
boris/cmd_arguments.py,sha256=dNMEvMgTRMadC1Oz5IXw4JEBJw8Tq4yCo4yuRCnNfXc,1848
|
|
15
12
|
boris/coding_pad.py,sha256=XVbg3Q7S4O6Rgxc5ZCzx4jv7eaDvbw_K2T_nQWtsvdU,10996
|
|
16
|
-
boris/config.py,sha256=
|
|
17
|
-
boris/config_file.py,sha256=
|
|
13
|
+
boris/config.py,sha256=zx5SfQESXGZjJkxXIdZKn2nGpj8nwRc-ZifcBUMNzWM,16726
|
|
14
|
+
boris/config_file.py,sha256=jTOhrX0tfxc3oHV7R85QX828xhezCsawXg6nvy5QIbE,13519
|
|
18
15
|
boris/connections.py,sha256=RIQsaooiz6pzc2jJMHw9CQSyX39TgbM5JAwifCu5eWQ,19280
|
|
19
16
|
boris/converters.py,sha256=FymqUxLEVLQwsUv6EVF7MRPowN1e87aVT2d3XjZJgAM,11771
|
|
20
|
-
boris/converters.ui,sha256=hOcg0QkCMdnLf3a9DR3O2gZBl7EbX495VGndWnQVE4E,7400
|
|
21
17
|
boris/converters_ui.py,sha256=firMWVgS3c492FF-YFv3FehOBLsbBHKaLEaVcoVctgc,8745
|
|
22
18
|
boris/cooccurence.py,sha256=scazxKCmFQjBvv7oS9h7ylB8GJdkSmwy1LJZeUv5DOY,9824
|
|
23
|
-
boris/core.py,sha256=
|
|
24
|
-
boris/core.qrc,sha256=9DibRJgfKpJ1i6xub-JQtMotLrSKhqRaF_oIkoJRqo8,2398
|
|
25
|
-
boris/core.ui,sha256=z0unUmECYdGwULy8wX8cNscOlLYcRypWuVdhwM4FJsQ,46554
|
|
19
|
+
boris/core.py,sha256=y_7xvlLojM-Jdu3FlAwzWLQoiiGtHIC2Eo6Qm2SaHhk,222161
|
|
26
20
|
boris/core_qrc.py,sha256=5YMpr7ckI4TbXaeSyCMhNJBAlrGPeLes62RedU3EbWs,865287
|
|
27
21
|
boris/core_ui.py,sha256=Z_6Ehp93fRVnPGyKRtgX2GcXRXb8QZojXipHSpJ_f3M,69854
|
|
28
22
|
boris/db_functions.py,sha256=YyI2LMSFn772aMGdkOIpfXbPuoSWEvDckZZKevwvB-4,13326
|
|
29
23
|
boris/dev.py,sha256=9pUElbjl9g17rFUJXX5aVSu55_iIKIuDxNdrB0DI_d0,3671
|
|
30
|
-
boris/dialog.py,sha256=
|
|
24
|
+
boris/dialog.py,sha256=9x9fSRUVhsxqcit_cNtnjnQMWuM6VB2c3EQ6-G3JDmo,41217
|
|
31
25
|
boris/duration_widget.py,sha256=FHnDDg6RBtORCZDG9gkpjxP9ivZ3Rb4uYWCdEkBl-a4,6930
|
|
32
26
|
boris/edit_event.py,sha256=cvZ4j2rcck8q5Rd6n5d6JGQ0wZMduVQls2UDylCuQqY,7578
|
|
33
|
-
boris/edit_event.ui,sha256=oC2AZH9rZm8f4HWvsOGxXVgAr6SUx2Wub-B44R2LDqM,5969
|
|
34
27
|
boris/edit_event_ui.py,sha256=X98eKSS0urd0eGce-q2_gkPx79GvO1XbJUEjxGCMUCI,6984
|
|
35
28
|
boris/event_operations.py,sha256=JYIZC4ObShZ-SPxNQaQZwKs8xJn4Dj0lvIiNgzc28Jo,38929
|
|
36
29
|
boris/events_cursor.py,sha256=Jfu7yV1MG7HikNmMQmOVJ7ntmEZzDZn5HHp3va8llwM,1983
|
|
@@ -39,27 +32,25 @@ boris/exclusion_matrix.py,sha256=xaEFLy2Zv5SWryMz1D0cEpywsAuZxZuBaaGYLaBGhng,527
|
|
|
39
32
|
boris/export_events.py,sha256=35tu9K9kEXlossdWjTNs74YuIs-ZQBSzw7MRnRIUK3Q,37826
|
|
40
33
|
boris/export_observation.py,sha256=TC_Mxyor5e0HZViG9xxAX_V18i61ihFnVmhioNOy_Dw,49821
|
|
41
34
|
boris/external_processes.py,sha256=069iEVOfDI-7zUYPH7WlYBEnKqTR18mjj8dReBkUACE,11965
|
|
42
|
-
boris/geometric_measurement.py,sha256=
|
|
35
|
+
boris/geometric_measurement.py,sha256=jd6HiWJNrjqRInG452a8Ke44Zj4QyNSYa9JKO8DZzOo,34609
|
|
43
36
|
boris/gui_utilities.py,sha256=IhIz53CHSRvO-qjN5XrzpgAChf_LBcUWlE3iFMBeROw,3774
|
|
44
37
|
boris/image_overlay.py,sha256=bxEHEr5p6nH_sgXRSGEWlJZJF7R07ItgHNM4_3kXTJA,2527
|
|
45
38
|
boris/import_observations.py,sha256=FrXG_oOyPYWIX1XHHWvC9eg13FHsZPzhLGjCMSQFHT8,8838
|
|
46
39
|
boris/irr.py,sha256=oFp8rJG9XxmKZ1q5fPnp79LEwFYHnu5i9Gk8CqRKiNM,22474
|
|
47
40
|
boris/latency.py,sha256=EDgH2DhR3j3lExMLemwhh7SIWFCWX9kJ4YbVXhhYv-8,9737
|
|
48
41
|
boris/map_creator.py,sha256=IJzvT2a9LoWk_Qx-Enc4jTsYh0ixpbrLNUFCLwB9idA,29437
|
|
49
|
-
boris/measurement_widget.py,sha256=
|
|
42
|
+
boris/measurement_widget.py,sha256=NI2d9qftFTtnUzy-aOtKhx3w63-mqDIJ4rz1l_8_Zos,4486
|
|
50
43
|
boris/media_file.py,sha256=ofOoGyrqEcm6HZQxnyObdmcLlKS0TrcPQNPNf8EG1BM,4766
|
|
51
44
|
boris/menu_options.py,sha256=izzYx-Rc7powf8PqhAXD3XMPYvBoVZqOYbS1jaW4sII,7094
|
|
52
45
|
boris/modifiers_coding_map.py,sha256=XBTubBHw6Sayw5jUNaWR_jVIw6ttaJcbhbmUSF6_lx4,4566
|
|
53
46
|
boris/mpv.py,sha256=EfzIHjPbgewG4w3smEtqEUPZoVwYmMQkL4Q8ZyW-a58,76410
|
|
54
47
|
boris/mpv2.py,sha256=EXRtzQqFjOn4wMC6482Ilq3fNQ9N1GRP1VxwLzdeaBY,88077
|
|
55
|
-
boris/observation.py,sha256=
|
|
56
|
-
boris/observation.ui,sha256=ZOng-yYtPJxLoUs_5Po35b5G9myTw1CTtD9Gqo_UhMI,27051
|
|
48
|
+
boris/observation.py,sha256=pHP68WnjA1rZsefo6zNtmwaXcjwjpItZCQrefqwOCCQ,52832
|
|
57
49
|
boris/observation_operations.py,sha256=tMKrL7sM-jcM4__Hpg7mPTfLkjxytXMBdKe2CKFGe5k,100217
|
|
58
50
|
boris/observation_ui.py,sha256=dfk7pS2DlaiEgMjouH0-_t6kPgMwovQbloHtc3ZoCmY,30278
|
|
59
51
|
boris/observations_list.py,sha256=rMuEVa3QccA89vjARcEVtSlLnr5s0sfihUlcwciV3OM,10600
|
|
60
|
-
boris/otx_parser.py,sha256
|
|
52
|
+
boris/otx_parser.py,sha256=Ul5GokK46azx60P6-pk8wbSPUqUR9O4WLV42z3rE40s,16367
|
|
61
53
|
boris/param_panel.py,sha256=XpFuoNtVuPx_3EieYt0JaQ2J3Bk4ZyMa4RgJha_10oE,7473
|
|
62
|
-
boris/param_panel.ui,sha256=RHcf_MvWO4qPC3pB_L4ow4l_qTX21yRfrZvePhCSLsE,11013
|
|
63
54
|
boris/param_panel_ui.py,sha256=R6Yfxd7m41_Mo5XCD9wlyAprrEKdCyBZm0jicwh_cGk,11704
|
|
64
55
|
boris/player_dock_widget.py,sha256=Pl2GB-a2XmiKiPPsun9_Q8otXXrugV1tdCEW3YMP_VE,5642
|
|
65
56
|
boris/plot_data_module.py,sha256=OazYAPHker30s1oYYKkSa0IXSj-DbB1-Qgcau0x-Il8,16582
|
|
@@ -67,33 +58,30 @@ boris/plot_events.py,sha256=HAKrdS3qf0A_PG1pGo0FRyk62femDxfxGss3w8CrlUw,23541
|
|
|
67
58
|
boris/plot_events_rt.py,sha256=UfO1NKSqBR7j-vnfG8CKuOcdg5o8QQI_0eYdcz29Ufc,8358
|
|
68
59
|
boris/plot_spectrogram_rt.py,sha256=yc8ifg9HCl-v_upMHkH_rmIZLhWBYkWBOhtKftvRvh0,8394
|
|
69
60
|
boris/plot_waveform_rt.py,sha256=kNk6NVjM3wT3MpAw5zE9ktH94Pkd2AJ4ppv6uM6BVBc,7502
|
|
70
|
-
boris/preferences.py,sha256=
|
|
71
|
-
boris/preferences.ui,sha256=xaetyovsXq9G5YEg0ZwgFamcX8Px1XDu75xt_wEeFIA,19198
|
|
61
|
+
boris/preferences.py,sha256=5KxUwP10mnsAk8CH3eSlzvd8mtsHsFJfWhzot3QOy3Y,11540
|
|
72
62
|
boris/preferences_ui.py,sha256=LQ46jW9kltJBQD85EHd5cCmlHG4c9N6v6YQLQvUisGM,21935
|
|
73
|
-
boris/project.py,sha256=
|
|
74
|
-
boris/project.ui,sha256=ZhUnCYABSAKc_kh5PLjzIFznfY7n4mGHxMXhQH8tmJM,36021
|
|
63
|
+
boris/project.py,sha256=i9XT744HoJhlV93C0QuEMD8tNmzIHL0E-iZ4PIOSadc,82219
|
|
75
64
|
boris/project_functions.py,sha256=R3DS_faDuMGKTpMnV0OhqgZp9yO1ojoA5wUIXdtHNIE,70972
|
|
76
65
|
boris/project_import_export.py,sha256=lCL4fOZuG5MaEf_wfDSHiE7-M2ZQsIbUR7KpHZjb1Uw,38097
|
|
77
66
|
boris/project_ui.py,sha256=TRJlsqq4XbIl8k2f20BKr2PtKa0QNjFNr6UnMieZYqU,35915
|
|
78
67
|
boris/qrc_boris.py,sha256=4U2cD_fIBTtsTPhirOl9I3kTArOhXWYvfuO_A0M9N0I,675001
|
|
79
68
|
boris/qrc_boris5.py,sha256=6bwT8OVtIr84nVIYp2ldUL7XL6WJi9zgJow6kgRxuIQ,161601
|
|
80
|
-
boris/select_modifiers.py,sha256=
|
|
69
|
+
boris/select_modifiers.py,sha256=TAo7xi5bhiMp9WOAwEPq9xc8i4Nsa2QrcpoCrUgPwhE,13178
|
|
81
70
|
boris/select_observations.py,sha256=snMC23nYD_qi88q95rXqV-NqbGO5BrLrC-CKlmVR3ok,14441
|
|
82
71
|
boris/select_subj_behav.py,sha256=bX-YCeysK5QowYgoxQyy-9qeZmhzWM4SwArXxSAa5ho,10342
|
|
83
72
|
boris/state_events.py,sha256=AcZmD0pIJ4AszTQe9conWlh8gJhwdBjZiGm1KOXt804,7768
|
|
84
73
|
boris/subjects_pad.py,sha256=d-vI0qBcXfonN_BvYI19ZBWgY0Ywekc2DSWLFHIjz0o,3553
|
|
85
74
|
boris/synthetic_time_budget.py,sha256=m3QJ0Ju4av7WzMUKFIvxJd5x4iNVTXc4-j9tWa3MIOE,9858
|
|
86
75
|
boris/time_budget_functions.py,sha256=L-0PuPWYR33UMfqmxpcCVH-w4mLLrtZ8b8kBTmBwlsI,50299
|
|
87
|
-
boris/time_budget_widget.py,sha256=
|
|
76
|
+
boris/time_budget_widget.py,sha256=9WV-iKYSl1f3HBrGcL-eHDjUswrFQh6-WUcffTtce1Y,42852
|
|
88
77
|
boris/transitions.py,sha256=2zucdoa2jTpWtM6nWHr8lOvjXkrQmo9j71fz_fMLALU,11998
|
|
89
|
-
boris/utilities.py,sha256=
|
|
90
|
-
boris/version.py,sha256=
|
|
78
|
+
boris/utilities.py,sha256=07qXAQ6aGyiSC2h6RMJ031OlXYy05-KTLJtnQtXn6FU,48724
|
|
79
|
+
boris/version.py,sha256=p1Eo1rAKt4WoBUXddzmCG41ZVzlVjIetATyhD0XQVaI,788
|
|
91
80
|
boris/video_equalizer.py,sha256=QpVgmdqX_E4HnMa2f_Qo_fKJTl9nBoTQd_ykv9RWlIQ,5862
|
|
92
81
|
boris/video_equalizer_ui.py,sha256=A2_Sz9AAVnJygTRUeK_YXxf-WWQpxSSlFw0MjkxiwSg,9762
|
|
93
82
|
boris/video_operations.py,sha256=96jR-3snNn9VeEURRD6rCwvOL2sSHXoqlP_gYFwgO8A,9379
|
|
94
83
|
boris/vlc_local.py,sha256=M4yQ8pGW-sY9zMJXDlWg5fzfcwLep1pFQjqwyREHlKo,3053
|
|
95
|
-
boris/write_event.py,sha256=
|
|
96
|
-
boris/icons/logo_eye.ico,sha256=pGgNoNXijGOuv6c_iaFR9OsjJ1GBqvrtzxNtfCLv_sc,45470
|
|
84
|
+
boris/write_event.py,sha256=Lsv7Jxoi4b4qVqjsxwiB2yago_TQ9BtwjjG7OejQEhI,23528
|
|
97
85
|
boris/portion/__init__.py,sha256=ZBUG4I7YWhRkeWdP-JEpxhxldJlUYQkeaJseTjdhtJE,602
|
|
98
86
|
boris/portion/const.py,sha256=hEp26BKcEg1Js4DfZsBHmDtJJts83Tl1HWQ0CNJNwEc,1588
|
|
99
87
|
boris/portion/dict.py,sha256=SyHxc7PfDw2ufNLFQycwJtzmRfL48rDp4UrM2KN7IWc,11282
|
|
@@ -117,9 +105,9 @@ boris/qdarkstyle/utils/__init__.py,sha256=Nlma8-zbHoJc5n2NVT7OvwxPG5765JnsmMeGzr
|
|
|
117
105
|
boris/qdarkstyle/utils/__main__.py,sha256=J1biUyDzfutKU1n9NdH9WnD0gFHaF-OJA4Q-n6Q2ehs,3309
|
|
118
106
|
boris/qdarkstyle/utils/images.py,sha256=af-BJllzWgVoVz6QMvhFcKqvF3mo44AThaBjuAuHtNE,14444
|
|
119
107
|
boris/qdarkstyle/utils/scss.py,sha256=n7WNo6pPRft8-dU7_gfjB_jA-JZAy50-S792RwR7Ri0,9366
|
|
120
|
-
boris_behav_obs-8.
|
|
121
|
-
boris_behav_obs-8.
|
|
122
|
-
boris_behav_obs-8.
|
|
123
|
-
boris_behav_obs-8.
|
|
124
|
-
boris_behav_obs-8.
|
|
125
|
-
boris_behav_obs-8.
|
|
108
|
+
boris_behav_obs-8.26.1.dist-info/LICENSE.TXT,sha256=WJ7YI-moTFb-uVrFjnzzhGJrnL9P2iqQe8NuED3hutI,35141
|
|
109
|
+
boris_behav_obs-8.26.1.dist-info/METADATA,sha256=38_OR718pDduPAAmZi8ixtl_iH1zyPE4T38USEQALBY,45543
|
|
110
|
+
boris_behav_obs-8.26.1.dist-info/WHEEL,sha256=DZajD4pwLWue70CAfc7YaxT1wLUciNBvN_TTcvXpltE,110
|
|
111
|
+
boris_behav_obs-8.26.1.dist-info/entry_points.txt,sha256=fuO7JxKFLOm6xp6m3JHRA1UO_QW1dYU-F0IooA1NqQs,37
|
|
112
|
+
boris_behav_obs-8.26.1.dist-info/top_level.txt,sha256=fJSgm62S7WesiwTorGbOO4nNN0yzgZ3klgfGi3Px4qI,6
|
|
113
|
+
boris_behav_obs-8.26.1.dist-info/RECORD,,
|