boris-behav-obs 9.0.8__tar.gz → 9.1__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.
- {boris_behav_obs-9.0.8 → boris_behav_obs-9.1}/PKG-INFO +1 -1
- {boris_behav_obs-9.0.8 → boris_behav_obs-9.1}/boris/advanced_event_filtering.py +9 -4
- {boris_behav_obs-9.0.8 → boris_behav_obs-9.1}/boris/analysis_plugins/number_of_occurences.py +1 -2
- {boris_behav_obs-9.0.8 → boris_behav_obs-9.1}/boris/analysis_plugins/time_budget.py +1 -3
- {boris_behav_obs-9.0.8 → boris_behav_obs-9.1}/boris/behavior_binary_table.py +12 -0
- {boris_behav_obs-9.0.8 → boris_behav_obs-9.1}/boris/config.py +5 -0
- {boris_behav_obs-9.0.8 → boris_behav_obs-9.1}/boris/config_file.py +8 -8
- {boris_behav_obs-9.0.8 → boris_behav_obs-9.1}/boris/cooccurence.py +9 -1
- {boris_behav_obs-9.0.8 → boris_behav_obs-9.1}/boris/core.py +178 -62
- {boris_behav_obs-9.0.8 → boris_behav_obs-9.1}/boris/event_operations.py +0 -3
- {boris_behav_obs-9.0.8 → boris_behav_obs-9.1}/boris/events_snapshots.py +5 -5
- {boris_behav_obs-9.0.8 → boris_behav_obs-9.1}/boris/export_events.py +29 -13
- {boris_behav_obs-9.0.8 → boris_behav_obs-9.1}/boris/export_observation.py +17 -2
- {boris_behav_obs-9.0.8 → boris_behav_obs-9.1}/boris/observation_operations.py +37 -1
- {boris_behav_obs-9.0.8 → boris_behav_obs-9.1}/boris/param_panel.py +12 -0
- {boris_behav_obs-9.0.8 → boris_behav_obs-9.1}/boris/param_panel_ui.py +6 -0
- {boris_behav_obs-9.0.8 → boris_behav_obs-9.1}/boris/plot_events.py +13 -6
- {boris_behav_obs-9.0.8 → boris_behav_obs-9.1}/boris/project_functions.py +22 -12
- {boris_behav_obs-9.0.8 → boris_behav_obs-9.1}/boris/project_import_export.py +9 -9
- {boris_behav_obs-9.0.8 → boris_behav_obs-9.1}/boris/select_observations.py +1 -3
- {boris_behav_obs-9.0.8 → boris_behav_obs-9.1}/boris/select_subj_behav.py +12 -1
- {boris_behav_obs-9.0.8 → boris_behav_obs-9.1}/boris/synthetic_time_budget.py +8 -0
- {boris_behav_obs-9.0.8 → boris_behav_obs-9.1}/boris/time_budget_functions.py +20 -15
- {boris_behav_obs-9.0.8 → boris_behav_obs-9.1}/boris/time_budget_widget.py +18 -7
- {boris_behav_obs-9.0.8 → boris_behav_obs-9.1}/boris/utilities.py +3 -3
- {boris_behav_obs-9.0.8 → boris_behav_obs-9.1}/boris/version.py +2 -2
- {boris_behav_obs-9.0.8 → boris_behav_obs-9.1}/boris/write_event.py +2 -1
- {boris_behav_obs-9.0.8 → boris_behav_obs-9.1}/boris_behav_obs.egg-info/PKG-INFO +1 -1
- {boris_behav_obs-9.0.8 → boris_behav_obs-9.1}/pyproject.toml +2 -2
- {boris_behav_obs-9.0.8 → boris_behav_obs-9.1}/LICENSE.TXT +0 -0
- {boris_behav_obs-9.0.8 → boris_behav_obs-9.1}/MANIFEST.in +0 -0
- {boris_behav_obs-9.0.8 → boris_behav_obs-9.1}/README.TXT +0 -0
- {boris_behav_obs-9.0.8 → boris_behav_obs-9.1}/README.md +0 -0
- {boris_behav_obs-9.0.8 → boris_behav_obs-9.1}/boris/__init__.py +0 -0
- {boris_behav_obs-9.0.8 → boris_behav_obs-9.1}/boris/__main__.py +0 -0
- {boris_behav_obs-9.0.8 → boris_behav_obs-9.1}/boris/about.py +0 -0
- {boris_behav_obs-9.0.8 → boris_behav_obs-9.1}/boris/add_modifier.py +0 -0
- {boris_behav_obs-9.0.8 → boris_behav_obs-9.1}/boris/add_modifier_ui.py +0 -0
- {boris_behav_obs-9.0.8 → boris_behav_obs-9.1}/boris/analysis_plugins/__init__.py +0 -0
- {boris_behav_obs-9.0.8 → boris_behav_obs-9.1}/boris/analysis_plugins/number_of_occurences_by_independent_variable.py +0 -0
- {boris_behav_obs-9.0.8 → boris_behav_obs-9.1}/boris/behav_coding_map_creator.py +0 -0
- {boris_behav_obs-9.0.8 → boris_behav_obs-9.1}/boris/behaviors_coding_map.py +0 -0
- {boris_behav_obs-9.0.8 → boris_behav_obs-9.1}/boris/boris_cli.py +0 -0
- {boris_behav_obs-9.0.8 → boris_behav_obs-9.1}/boris/cmd_arguments.py +0 -0
- {boris_behav_obs-9.0.8 → boris_behav_obs-9.1}/boris/coding_pad.py +0 -0
- {boris_behav_obs-9.0.8 → boris_behav_obs-9.1}/boris/connections.py +0 -0
- {boris_behav_obs-9.0.8 → boris_behav_obs-9.1}/boris/converters.py +0 -0
- {boris_behav_obs-9.0.8 → boris_behav_obs-9.1}/boris/converters_ui.py +0 -0
- {boris_behav_obs-9.0.8 → boris_behav_obs-9.1}/boris/core_qrc.py +0 -0
- {boris_behav_obs-9.0.8 → boris_behav_obs-9.1}/boris/core_ui.py +0 -0
- {boris_behav_obs-9.0.8 → boris_behav_obs-9.1}/boris/db_functions.py +0 -0
- {boris_behav_obs-9.0.8 → boris_behav_obs-9.1}/boris/dev.py +0 -0
- {boris_behav_obs-9.0.8 → boris_behav_obs-9.1}/boris/dialog.py +0 -0
- {boris_behav_obs-9.0.8 → boris_behav_obs-9.1}/boris/duration_widget.py +0 -0
- {boris_behav_obs-9.0.8 → boris_behav_obs-9.1}/boris/edit_event.py +0 -0
- {boris_behav_obs-9.0.8 → boris_behav_obs-9.1}/boris/edit_event_ui.py +0 -0
- {boris_behav_obs-9.0.8 → boris_behav_obs-9.1}/boris/events_cursor.py +0 -0
- {boris_behav_obs-9.0.8 → boris_behav_obs-9.1}/boris/exclusion_matrix.py +0 -0
- {boris_behav_obs-9.0.8 → boris_behav_obs-9.1}/boris/external_processes.py +0 -0
- {boris_behav_obs-9.0.8 → boris_behav_obs-9.1}/boris/geometric_measurement.py +0 -0
- {boris_behav_obs-9.0.8 → boris_behav_obs-9.1}/boris/gui_utilities.py +0 -0
- {boris_behav_obs-9.0.8 → boris_behav_obs-9.1}/boris/image_overlay.py +0 -0
- {boris_behav_obs-9.0.8 → boris_behav_obs-9.1}/boris/import_observations.py +0 -0
- {boris_behav_obs-9.0.8 → boris_behav_obs-9.1}/boris/irr.py +0 -0
- {boris_behav_obs-9.0.8 → boris_behav_obs-9.1}/boris/latency.py +0 -0
- {boris_behav_obs-9.0.8 → boris_behav_obs-9.1}/boris/map_creator.py +0 -0
- {boris_behav_obs-9.0.8 → boris_behav_obs-9.1}/boris/measurement_widget.py +0 -0
- {boris_behav_obs-9.0.8 → boris_behav_obs-9.1}/boris/media_file.py +0 -0
- {boris_behav_obs-9.0.8 → boris_behav_obs-9.1}/boris/menu_options.py +0 -0
- {boris_behav_obs-9.0.8 → boris_behav_obs-9.1}/boris/modifiers_coding_map.py +0 -0
- {boris_behav_obs-9.0.8 → boris_behav_obs-9.1}/boris/mpv-1.0.3.py +0 -0
- {boris_behav_obs-9.0.8 → boris_behav_obs-9.1}/boris/mpv.py +0 -0
- {boris_behav_obs-9.0.8 → boris_behav_obs-9.1}/boris/mpv2.py +0 -0
- {boris_behav_obs-9.0.8 → boris_behav_obs-9.1}/boris/observation.py +0 -0
- {boris_behav_obs-9.0.8 → boris_behav_obs-9.1}/boris/observation_ui.py +0 -0
- {boris_behav_obs-9.0.8 → boris_behav_obs-9.1}/boris/observations_list.py +0 -0
- {boris_behav_obs-9.0.8 → boris_behav_obs-9.1}/boris/otx_parser.py +0 -0
- {boris_behav_obs-9.0.8 → boris_behav_obs-9.1}/boris/player_dock_widget.py +0 -0
- {boris_behav_obs-9.0.8 → boris_behav_obs-9.1}/boris/plot_data_module.py +0 -0
- {boris_behav_obs-9.0.8 → boris_behav_obs-9.1}/boris/plot_events_rt.py +0 -0
- {boris_behav_obs-9.0.8 → boris_behav_obs-9.1}/boris/plot_spectrogram_rt.py +0 -0
- {boris_behav_obs-9.0.8 → boris_behav_obs-9.1}/boris/plot_waveform_rt.py +0 -0
- {boris_behav_obs-9.0.8 → boris_behav_obs-9.1}/boris/plugins.py +0 -0
- {boris_behav_obs-9.0.8 → boris_behav_obs-9.1}/boris/portion/__init__.py +0 -0
- {boris_behav_obs-9.0.8 → boris_behav_obs-9.1}/boris/portion/const.py +0 -0
- {boris_behav_obs-9.0.8 → boris_behav_obs-9.1}/boris/portion/dict.py +0 -0
- {boris_behav_obs-9.0.8 → boris_behav_obs-9.1}/boris/portion/func.py +0 -0
- {boris_behav_obs-9.0.8 → boris_behav_obs-9.1}/boris/portion/interval.py +0 -0
- {boris_behav_obs-9.0.8 → boris_behav_obs-9.1}/boris/portion/io.py +0 -0
- {boris_behav_obs-9.0.8 → boris_behav_obs-9.1}/boris/preferences.py +0 -0
- {boris_behav_obs-9.0.8 → boris_behav_obs-9.1}/boris/preferences_ui.py +0 -0
- {boris_behav_obs-9.0.8 → boris_behav_obs-9.1}/boris/project.py +0 -0
- {boris_behav_obs-9.0.8 → boris_behav_obs-9.1}/boris/project_ui.py +0 -0
- {boris_behav_obs-9.0.8 → boris_behav_obs-9.1}/boris/qrc_boris.py +0 -0
- {boris_behav_obs-9.0.8 → boris_behav_obs-9.1}/boris/qrc_boris5.py +0 -0
- {boris_behav_obs-9.0.8 → boris_behav_obs-9.1}/boris/select_modifiers.py +0 -0
- {boris_behav_obs-9.0.8 → boris_behav_obs-9.1}/boris/state_events.py +0 -0
- {boris_behav_obs-9.0.8 → boris_behav_obs-9.1}/boris/subjects_pad.py +0 -0
- {boris_behav_obs-9.0.8 → boris_behav_obs-9.1}/boris/transitions.py +0 -0
- {boris_behav_obs-9.0.8 → boris_behav_obs-9.1}/boris/video_equalizer.py +0 -0
- {boris_behav_obs-9.0.8 → boris_behav_obs-9.1}/boris/video_equalizer_ui.py +0 -0
- {boris_behav_obs-9.0.8 → boris_behav_obs-9.1}/boris/video_operations.py +0 -0
- {boris_behav_obs-9.0.8 → boris_behav_obs-9.1}/boris/view_df.py +0 -0
- {boris_behav_obs-9.0.8 → boris_behav_obs-9.1}/boris/view_df_ui.py +0 -0
- {boris_behav_obs-9.0.8 → boris_behav_obs-9.1}/boris_behav_obs.egg-info/SOURCES.txt +0 -0
- {boris_behav_obs-9.0.8 → boris_behav_obs-9.1}/boris_behav_obs.egg-info/dependency_links.txt +0 -0
- {boris_behav_obs-9.0.8 → boris_behav_obs-9.1}/boris_behav_obs.egg-info/entry_points.txt +0 -0
- {boris_behav_obs-9.0.8 → boris_behav_obs-9.1}/boris_behav_obs.egg-info/requires.txt +0 -0
- {boris_behav_obs-9.0.8 → boris_behav_obs-9.1}/boris_behav_obs.egg-info/top_level.txt +0 -0
- {boris_behav_obs-9.0.8 → boris_behav_obs-9.1}/setup.cfg +0 -0
- {boris_behav_obs-9.0.8 → boris_behav_obs-9.1}/tests/test_db_functions.py +0 -0
- {boris_behav_obs-9.0.8 → boris_behav_obs-9.1}/tests/test_export_observation.py +0 -0
- {boris_behav_obs-9.0.8 → boris_behav_obs-9.1}/tests/test_irr.py +0 -0
- {boris_behav_obs-9.0.8 → boris_behav_obs-9.1}/tests/test_observation_gui.py +0 -0
- {boris_behav_obs-9.0.8 → boris_behav_obs-9.1}/tests/test_otx_parser.py +0 -0
- {boris_behav_obs-9.0.8 → boris_behav_obs-9.1}/tests/test_preferences_gui.py +0 -0
- {boris_behav_obs-9.0.8 → boris_behav_obs-9.1}/tests/test_project_functions.py +0 -0
- {boris_behav_obs-9.0.8 → boris_behav_obs-9.1}/tests/test_time_budget.py +0 -0
- {boris_behav_obs-9.0.8 → boris_behav_obs-9.1}/tests/test_utilities.py +0 -0
|
@@ -235,7 +235,7 @@ class Advanced_event_filtering_dialog(QDialog):
|
|
|
235
235
|
self.tw.clear()
|
|
236
236
|
|
|
237
237
|
if flag_error or self.rb_details.isChecked():
|
|
238
|
-
self.lb_results.setText(f"Results ({len(self.out)} event{'s'*(len(self.out) > 1)})")
|
|
238
|
+
self.lb_results.setText(f"Results ({len(self.out)} event{'s' * (len(self.out) > 1)})")
|
|
239
239
|
|
|
240
240
|
self.tw.setRowCount(len(self.out))
|
|
241
241
|
self.tw.setColumnCount(len(self.details_header)) # obs_id, comment, start, stop, duration
|
|
@@ -261,7 +261,7 @@ class Advanced_event_filtering_dialog(QDialog):
|
|
|
261
261
|
]
|
|
262
262
|
)
|
|
263
263
|
|
|
264
|
-
self.lb_results.setText(f"Results ({len(summary)} observation{'s'*(len(summary) > 1)})")
|
|
264
|
+
self.lb_results.setText(f"Results ({len(summary)} observation{'s' * (len(summary) > 1)})")
|
|
265
265
|
self.tw.setRowCount(len(summary))
|
|
266
266
|
self.tw.setColumnCount(len(self.summary_header)) # obs_id, mean, stdev
|
|
267
267
|
self.tw.setHorizontalHeaderLabels(self.summary_header)
|
|
@@ -352,17 +352,22 @@ def event_filtering(self):
|
|
|
352
352
|
|
|
353
353
|
max_media_duration_all_obs, _ = observation_operations.media_duration(self.pj[cfg.OBSERVATIONS], selected_observations)
|
|
354
354
|
|
|
355
|
+
start_interval, end_interval = observation_operations.time_intervals_range(self.pj[cfg.OBSERVATIONS], selected_observations)
|
|
356
|
+
|
|
355
357
|
parameters = select_subj_behav.choose_obs_subj_behav_category(
|
|
356
358
|
self,
|
|
357
359
|
selected_observations,
|
|
358
360
|
start_coding=start_coding,
|
|
359
361
|
end_coding=end_coding,
|
|
362
|
+
start_interval=start_interval,
|
|
363
|
+
end_interval=end_interval,
|
|
360
364
|
maxTime=max_media_duration_all_obs,
|
|
361
365
|
show_include_modifiers=False,
|
|
362
366
|
show_exclude_non_coded_behaviors=False,
|
|
363
367
|
by_category=False,
|
|
364
368
|
n_observations=len(selected_observations),
|
|
365
369
|
)
|
|
370
|
+
|
|
366
371
|
if parameters == {}:
|
|
367
372
|
return
|
|
368
373
|
|
|
@@ -380,7 +385,7 @@ def event_filtering(self):
|
|
|
380
385
|
cursor.execute("SELECT MIN(start), MAX(stop) FROM aggregated_events")
|
|
381
386
|
min_time, max_time = cursor.fetchone()
|
|
382
387
|
|
|
383
|
-
if parameters[cfg.TIME_INTERVAL]
|
|
388
|
+
if parameters[cfg.TIME_INTERVAL] in (cfg.TIME_ARBITRARY_INTERVAL, cfg.TIME_OBS_INTERVAL):
|
|
384
389
|
min_time = float(parameters[cfg.START_TIME])
|
|
385
390
|
max_time = float(parameters[cfg.END_TIME])
|
|
386
391
|
|
|
@@ -443,6 +448,6 @@ def event_filtering(self):
|
|
|
443
448
|
|
|
444
449
|
w = Advanced_event_filtering_dialog(events)
|
|
445
450
|
w.lb_time_interval.setText(
|
|
446
|
-
("Time interval:
|
|
451
|
+
(f"Time interval: {util.smart_time_format(min_time, self.timeFormat)} - {util.smart_time_format(max_time, self.timeFormat)}")
|
|
447
452
|
)
|
|
448
453
|
w.exec_()
|
{boris_behav_obs-9.0.8 → boris_behav_obs-9.1}/boris/analysis_plugins/number_of_occurences.py
RENAMED
|
@@ -17,10 +17,9 @@ def run(df: pd.DataFrame):
|
|
|
17
17
|
Calculate the number of occurrences of behaviors by subject.
|
|
18
18
|
"""
|
|
19
19
|
|
|
20
|
-
string_results: str = ""
|
|
21
20
|
df_results: pd.DataFrame = df.groupby(["Subject", "Behavior"])["Behavior"].count().reset_index(name="number of occurences")
|
|
22
21
|
|
|
23
|
-
return df_results
|
|
22
|
+
return df_results
|
|
24
23
|
|
|
25
24
|
|
|
26
25
|
def main(df: pd.DataFrame, observations_list: list = [], parameters: dict = {}) -> pd.DataFrame:
|
|
@@ -26,8 +26,6 @@ def run(df: pd.DataFrame):
|
|
|
26
26
|
- % of total subject observation duration
|
|
27
27
|
"""
|
|
28
28
|
|
|
29
|
-
string_results: str = "test\ntest1"
|
|
30
|
-
|
|
31
29
|
group_by = ["Subject", "Behavior"]
|
|
32
30
|
|
|
33
31
|
dfs = [
|
|
@@ -60,7 +58,7 @@ def run(df: pd.DataFrame):
|
|
|
60
58
|
for df in dfs[1:]:
|
|
61
59
|
merged_df = pd.merge(merged_df, df, on=group_by)
|
|
62
60
|
|
|
63
|
-
return merged_df
|
|
61
|
+
return merged_df
|
|
64
62
|
|
|
65
63
|
|
|
66
64
|
def main(df: pd.DataFrame, observations_list: list = [], parameters: dict = {}) -> pd.DataFrame:
|
|
@@ -79,6 +79,14 @@ def create_behavior_binary_table(pj: dict, selected_observations: list, paramete
|
|
|
79
79
|
max_obs_length, _ = observation_operations.observation_length(pj, [obs_id])
|
|
80
80
|
end_time = dec(max_obs_length)
|
|
81
81
|
|
|
82
|
+
if parameters_obs["time"] == cfg.TIME_OBS_INTERVAL:
|
|
83
|
+
obs_interval = pj[cfg.OBSERVATIONS][obs_id][cfg.OBSERVATION_TIME_INTERVAL]
|
|
84
|
+
offset = pj[cfg.OBSERVATIONS][obs_id][cfg.TIME_OFFSET]
|
|
85
|
+
start_time = dec(obs_interval[0]) + offset
|
|
86
|
+
# Use max observation length for end time if no interval is defined (=0)
|
|
87
|
+
max_obs_length, _ = observation_operations.observation_length(pj, [obs_id])
|
|
88
|
+
end_time = dec(obs_interval[1]) + offset if obs_interval[1] != 0 else dec(max_obs_length)
|
|
89
|
+
|
|
82
90
|
if obs_id not in results_df:
|
|
83
91
|
results_df[obs_id] = {}
|
|
84
92
|
|
|
@@ -201,11 +209,15 @@ def behavior_binary_table(self):
|
|
|
201
209
|
|
|
202
210
|
start_coding, end_coding, _ = observation_operations.coding_time(self.pj[cfg.OBSERVATIONS], selected_observations)
|
|
203
211
|
|
|
212
|
+
start_interval, end_interval = observation_operations.time_intervals_range(self.pj[cfg.OBSERVATIONS], selected_observations)
|
|
213
|
+
|
|
204
214
|
parameters = select_subj_behav.choose_obs_subj_behav_category(
|
|
205
215
|
self,
|
|
206
216
|
selected_observations,
|
|
207
217
|
start_coding=start_coding,
|
|
208
218
|
end_coding=end_coding,
|
|
219
|
+
start_interval=start_interval,
|
|
220
|
+
end_interval=end_interval,
|
|
209
221
|
maxTime=max_media_duration_all_obs,
|
|
210
222
|
show_include_modifiers=True,
|
|
211
223
|
show_exclude_non_coded_behaviors=True,
|
|
@@ -256,9 +256,13 @@ HAS_AUDIO_IDX = 6
|
|
|
256
256
|
STATE_EVENT = "State event"
|
|
257
257
|
STATE_EVENT_WITH_CODING_MAP = "State event with coding map"
|
|
258
258
|
|
|
259
|
+
STATE_EVENT_TYPES = [STATE_EVENT, STATE_EVENT_WITH_CODING_MAP]
|
|
260
|
+
|
|
259
261
|
POINT_EVENT = "Point event"
|
|
260
262
|
POINT_EVENT_WITH_CODING_MAP = "Point event with coding map"
|
|
261
263
|
|
|
264
|
+
POINT_EVENT_TYPES = [POINT_EVENT, POINT_EVENT_WITH_CODING_MAP]
|
|
265
|
+
|
|
262
266
|
BEHAVIOR_TYPES = [
|
|
263
267
|
POINT_EVENT,
|
|
264
268
|
STATE_EVENT,
|
|
@@ -395,6 +399,7 @@ TIMESTAMP_idx = 3
|
|
|
395
399
|
|
|
396
400
|
TIME_FULL_OBS = "full obs"
|
|
397
401
|
TIME_EVENTS = "limit to events"
|
|
402
|
+
TIME_OBS_INTERVAL = "interval of observation"
|
|
398
403
|
TIME_ARBITRARY_INTERVAL = "time interval"
|
|
399
404
|
|
|
400
405
|
AVAILABLE_INDEP_VAR_TYPES = [NUMERIC, TEXT, SET_OF_VALUES, TIMESTAMP]
|
|
@@ -36,19 +36,19 @@ def read(self):
|
|
|
36
36
|
read config file
|
|
37
37
|
"""
|
|
38
38
|
|
|
39
|
-
|
|
39
|
+
ini_fil_p_pe_p_path = pl.Path.home() / pl.Path(".boris")
|
|
40
40
|
|
|
41
|
-
logging.debug(f"read config file: {
|
|
41
|
+
logging.debug(f"read config file: {ini_fil_p_pe_p_path}")
|
|
42
42
|
|
|
43
|
-
if
|
|
44
|
-
settings = QSettings(str(
|
|
43
|
+
if ini_fil_p_pe_p_path.is_file():
|
|
44
|
+
settings = QSettings(str(ini_fil_p_pe_p_path), QSettings.IniFormat)
|
|
45
45
|
|
|
46
46
|
try:
|
|
47
47
|
self.config_param = settings.value("config")
|
|
48
48
|
except Exception:
|
|
49
|
-
self.config_param =
|
|
49
|
+
self.config_param = {}
|
|
50
50
|
|
|
51
|
-
if self.config_param
|
|
51
|
+
if self.config_param == {}:
|
|
52
52
|
self.config_param = cfg.INIT_PARAM
|
|
53
53
|
|
|
54
54
|
# for back compatibility
|
|
@@ -245,7 +245,7 @@ def read(self):
|
|
|
245
245
|
if (
|
|
246
246
|
dialog.MessageDialog(
|
|
247
247
|
cfg.programName,
|
|
248
|
-
("The colors list contain colors that are very light.\
|
|
248
|
+
("The colors list contain colors that are very light.\nDo you want to reload the default colors list?"),
|
|
249
249
|
[cfg.NO, cfg.YES],
|
|
250
250
|
)
|
|
251
251
|
== cfg.YES
|
|
@@ -262,7 +262,7 @@ def read(self):
|
|
|
262
262
|
if (
|
|
263
263
|
dialog.MessageDialog(
|
|
264
264
|
cfg.programName,
|
|
265
|
-
("The colors list contain colors that are very light.\
|
|
265
|
+
("The colors list contain colors that are very light.\nDo you want to reload the default colors list?"),
|
|
266
266
|
[cfg.NO, cfg.YES],
|
|
267
267
|
)
|
|
268
268
|
== cfg.YES
|
|
@@ -82,6 +82,8 @@ def get_cooccurence(self):
|
|
|
82
82
|
if not_ok or not selected_observations:
|
|
83
83
|
return
|
|
84
84
|
|
|
85
|
+
max_media_duration_all_obs, _ = observation_operations.media_duration(self.pj[cfg.OBSERVATIONS], selected_observations)
|
|
86
|
+
|
|
85
87
|
start_coding, end_coding, _ = observation_operations.coding_time(self.pj[cfg.OBSERVATIONS], selected_observations)
|
|
86
88
|
# exit with message if events do not have timestamp
|
|
87
89
|
if start_coding.is_nan():
|
|
@@ -94,12 +96,18 @@ def get_cooccurence(self):
|
|
|
94
96
|
)
|
|
95
97
|
return
|
|
96
98
|
|
|
99
|
+
start_interval, end_interval = observation_operations.time_intervals_range(self.pj[cfg.OBSERVATIONS], selected_observations)
|
|
100
|
+
|
|
97
101
|
while True:
|
|
98
102
|
flag_ok: bool = True
|
|
99
103
|
parameters = select_subj_behav.choose_obs_subj_behav_category(
|
|
100
104
|
self,
|
|
101
105
|
selected_observations,
|
|
102
|
-
|
|
106
|
+
start_coding=start_coding,
|
|
107
|
+
end_coding=end_coding,
|
|
108
|
+
start_interval=start_interval,
|
|
109
|
+
end_interval=end_interval,
|
|
110
|
+
maxTime=max_media_duration_all_obs,
|
|
103
111
|
n_observations=len(selected_observations),
|
|
104
112
|
show_include_modifiers=False,
|
|
105
113
|
show_exclude_non_coded_behaviors=True,
|
|
@@ -52,7 +52,7 @@ from decimal import Decimal as dec
|
|
|
52
52
|
from decimal import ROUND_DOWN
|
|
53
53
|
import gzip
|
|
54
54
|
from collections import deque
|
|
55
|
-
|
|
55
|
+
import pandas as pd
|
|
56
56
|
import matplotlib
|
|
57
57
|
import zipfile
|
|
58
58
|
import shutil
|
|
@@ -60,7 +60,18 @@ import shutil
|
|
|
60
60
|
matplotlib.use("QtAgg")
|
|
61
61
|
|
|
62
62
|
import PySide6
|
|
63
|
-
from PySide6.QtCore import
|
|
63
|
+
from PySide6.QtCore import (
|
|
64
|
+
Qt,
|
|
65
|
+
QPoint,
|
|
66
|
+
Signal,
|
|
67
|
+
QEvent,
|
|
68
|
+
QDateTime,
|
|
69
|
+
QUrl,
|
|
70
|
+
QAbstractTableModel,
|
|
71
|
+
qVersion,
|
|
72
|
+
QElapsedTimer,
|
|
73
|
+
QSettings,
|
|
74
|
+
)
|
|
64
75
|
from PySide6.QtGui import QIcon, QPixmap, QFont, QKeyEvent, QDesktopServices, QColor, QPainter, QPolygon, QAction
|
|
65
76
|
from PySide6.QtMultimedia import QSoundEffect
|
|
66
77
|
from PySide6.QtWidgets import (
|
|
@@ -229,6 +240,19 @@ class TableModel(QAbstractTableModel):
|
|
|
229
240
|
return self._data[row][event_idx]
|
|
230
241
|
|
|
231
242
|
|
|
243
|
+
"""
|
|
244
|
+
class ButtonEventFilter(QObject):
|
|
245
|
+
def eventFilter(self, obj, event):
|
|
246
|
+
print("event filter")
|
|
247
|
+
if isinstance(obj, QPushButton) and event.type() == QEvent.KeyPress:
|
|
248
|
+
print("keypress")
|
|
249
|
+
if event.key() in (Qt.Key_Enter, Qt.Key_Return, Qt.Key_Space):
|
|
250
|
+
print("enter sapce")
|
|
251
|
+
return False # Block the event
|
|
252
|
+
return super().eventFilter(obj, event)
|
|
253
|
+
"""
|
|
254
|
+
|
|
255
|
+
|
|
232
256
|
class MainWindow(QMainWindow, Ui_MainWindow):
|
|
233
257
|
"""
|
|
234
258
|
Main BORIS window
|
|
@@ -369,6 +393,11 @@ class MainWindow(QMainWindow, Ui_MainWindow):
|
|
|
369
393
|
super(MainWindow, self).__init__(parent)
|
|
370
394
|
self.setupUi(self)
|
|
371
395
|
|
|
396
|
+
# disable trigger with RETURN or SPACE keys
|
|
397
|
+
"""filter_obj = ButtonEventFilter()
|
|
398
|
+
self.pb_live_obs.installEventFilter(filter_obj)"""
|
|
399
|
+
self.pb_live_obs.setFocusPolicy(Qt.NoFocus)
|
|
400
|
+
|
|
372
401
|
self.ffmpeg_bin = ffmpeg_bin
|
|
373
402
|
# set icons
|
|
374
403
|
self.setWindowIcon(QIcon(":/small_logo"))
|
|
@@ -771,7 +800,7 @@ class MainWindow(QMainWindow, Ui_MainWindow):
|
|
|
771
800
|
title="Select the behaviors to show in the ethogram table",
|
|
772
801
|
text="Behaviors to show in ethogram list",
|
|
773
802
|
table=cfg.ETHOGRAM,
|
|
774
|
-
behavior_type=
|
|
803
|
+
behavior_type=cfg.STATE_EVENT_TYPES,
|
|
775
804
|
) -> Tuple[bool, list]:
|
|
776
805
|
"""
|
|
777
806
|
allow user to:
|
|
@@ -793,7 +822,7 @@ class MainWindow(QMainWindow, Ui_MainWindow):
|
|
|
793
822
|
if not self.pj[cfg.ETHOGRAM]:
|
|
794
823
|
return True, []
|
|
795
824
|
|
|
796
|
-
behavior_type = [x.upper() for x in behavior_type]
|
|
825
|
+
# behavior_type = [x.upper() for x in behavior_type]
|
|
797
826
|
|
|
798
827
|
paramPanelWindow = param_panel.Param_panel()
|
|
799
828
|
paramPanelWindow.setWindowTitle(title)
|
|
@@ -1382,9 +1411,9 @@ class MainWindow(QMainWindow, Ui_MainWindow):
|
|
|
1382
1411
|
ask user for updating
|
|
1383
1412
|
"""
|
|
1384
1413
|
|
|
1385
|
-
|
|
1414
|
+
version_URL = "https://www.boris.unito.it/static/ver4.dat"
|
|
1386
1415
|
try:
|
|
1387
|
-
last_version = urllib.request.urlopen(
|
|
1416
|
+
last_version = urllib.request.urlopen(version_URL).read().strip().decode("utf-8")
|
|
1388
1417
|
except Exception:
|
|
1389
1418
|
QMessageBox.warning(self, cfg.programName, "Can not check for updates...")
|
|
1390
1419
|
return
|
|
@@ -2264,8 +2293,6 @@ class MainWindow(QMainWindow, Ui_MainWindow):
|
|
|
2264
2293
|
"""
|
|
2265
2294
|
populate table view with events
|
|
2266
2295
|
"""
|
|
2267
|
-
logging.debug("populate tv_events")
|
|
2268
|
-
|
|
2269
2296
|
model = self.tv_events.model()
|
|
2270
2297
|
if model is not None:
|
|
2271
2298
|
self.tv_events.setModel(None)
|
|
@@ -2275,7 +2302,7 @@ class MainWindow(QMainWindow, Ui_MainWindow):
|
|
|
2275
2302
|
mem_behav: dict = {}
|
|
2276
2303
|
state_events_list = util.state_behavior_codes(self.pj[cfg.ETHOGRAM])
|
|
2277
2304
|
|
|
2278
|
-
state
|
|
2305
|
+
state = [""] * len(self.pj[cfg.OBSERVATIONS][obs_id][cfg.EVENTS])
|
|
2279
2306
|
|
|
2280
2307
|
for idx, row in enumerate(self.pj[cfg.OBSERVATIONS][obs_id][cfg.EVENTS]):
|
|
2281
2308
|
code = row[cfg.PJ_OBS_FIELDS[self.playerType][cfg.BEHAVIOR_CODE]]
|
|
@@ -2341,16 +2368,17 @@ class MainWindow(QMainWindow, Ui_MainWindow):
|
|
|
2341
2368
|
|
|
2342
2369
|
logging.debug(f"begin load events from obs in tableView: {obs_id}")
|
|
2343
2370
|
|
|
2344
|
-
#
|
|
2345
|
-
|
|
2371
|
+
# t1 = time.time()
|
|
2346
2372
|
self.populate_tv_events(
|
|
2347
2373
|
obs_id,
|
|
2348
|
-
[s.capitalize() for s in cfg.TW_EVENTS_FIELDS[self.playerType]],
|
|
2374
|
+
[s.capitalize() for s in cfg.TW_EVENTS_FIELDS[self.playerType]],
|
|
2349
2375
|
self.timeFormat,
|
|
2350
2376
|
self.filtered_behaviors,
|
|
2351
2377
|
self.filtered_subjects,
|
|
2352
2378
|
)
|
|
2353
2379
|
|
|
2380
|
+
# print("load table view:", time.time() - t1)
|
|
2381
|
+
|
|
2354
2382
|
return
|
|
2355
2383
|
|
|
2356
2384
|
"""
|
|
@@ -2692,11 +2720,15 @@ class MainWindow(QMainWindow, Ui_MainWindow):
|
|
|
2692
2720
|
return
|
|
2693
2721
|
start_coding, end_coding, _ = observation_operations.coding_time(self.pj[cfg.OBSERVATIONS], selected_observations)
|
|
2694
2722
|
|
|
2723
|
+
start_interval, end_interval = observation_operations.time_intervals_range(self.pj[cfg.OBSERVATIONS], selected_observations)
|
|
2724
|
+
|
|
2695
2725
|
parameters = select_subj_behav.choose_obs_subj_behav_category(
|
|
2696
2726
|
self,
|
|
2697
2727
|
selected_observations,
|
|
2698
2728
|
start_coding=start_coding,
|
|
2699
2729
|
end_coding=end_coding,
|
|
2730
|
+
start_interval=start_interval,
|
|
2731
|
+
end_interval=end_interval,
|
|
2700
2732
|
maxTime=max_obs_length,
|
|
2701
2733
|
show_exclude_non_coded_behaviors=True,
|
|
2702
2734
|
by_category=False,
|
|
@@ -2791,11 +2823,15 @@ class MainWindow(QMainWindow, Ui_MainWindow):
|
|
|
2791
2823
|
|
|
2792
2824
|
start_coding, end_coding, _ = observation_operations.coding_time(self.pj[cfg.OBSERVATIONS], selected_observations)
|
|
2793
2825
|
|
|
2826
|
+
start_interval, end_interval = observation_operations.time_intervals_range(self.pj[cfg.OBSERVATIONS], selected_observations)
|
|
2827
|
+
|
|
2794
2828
|
parameters = select_subj_behav.choose_obs_subj_behav_category(
|
|
2795
2829
|
self,
|
|
2796
2830
|
selected_observations,
|
|
2797
2831
|
start_coding=start_coding,
|
|
2798
2832
|
end_coding=end_coding,
|
|
2833
|
+
start_interval=start_interval,
|
|
2834
|
+
end_interval=end_interval,
|
|
2799
2835
|
maxTime=max_obs_length if len(selected_observations) > 1 else selectedObsTotalMediaLength,
|
|
2800
2836
|
show_include_modifiers=False,
|
|
2801
2837
|
show_exclude_non_coded_behaviors=True,
|
|
@@ -3488,9 +3524,16 @@ class MainWindow(QMainWindow, Ui_MainWindow):
|
|
|
3488
3524
|
check project integrity
|
|
3489
3525
|
to be used after opening or saving the current project
|
|
3490
3526
|
"""
|
|
3527
|
+
|
|
3528
|
+
logging.debug("check project integrity open save")
|
|
3529
|
+
|
|
3491
3530
|
if self.automaticBackup:
|
|
3492
3531
|
return
|
|
3493
3532
|
|
|
3533
|
+
logging.debug(
|
|
3534
|
+
f"{self.config_param[cfg.CHECK_PROJECT_INTEGRITY] if cfg.CHECK_PROJECT_INTEGRITY in self.config_param else "Check project integrity config NOT FOUND"=}"
|
|
3535
|
+
)
|
|
3536
|
+
|
|
3494
3537
|
if self.config_param.get(cfg.CHECK_PROJECT_INTEGRITY, True):
|
|
3495
3538
|
msg = project_functions.check_project_integrity(
|
|
3496
3539
|
self.pj,
|
|
@@ -3712,6 +3755,8 @@ class MainWindow(QMainWindow, Ui_MainWindow):
|
|
|
3712
3755
|
|
|
3713
3756
|
start_coding, end_coding, _ = observation_operations.coding_time(self.pj[cfg.OBSERVATIONS], selected_observations)
|
|
3714
3757
|
|
|
3758
|
+
start_interval, end_interval = observation_operations.time_intervals_range(self.pj[cfg.OBSERVATIONS], selected_observations)
|
|
3759
|
+
|
|
3715
3760
|
if start_coding.is_nan():
|
|
3716
3761
|
QMessageBox.critical(
|
|
3717
3762
|
None,
|
|
@@ -3727,6 +3772,8 @@ class MainWindow(QMainWindow, Ui_MainWindow):
|
|
|
3727
3772
|
selected_observations,
|
|
3728
3773
|
start_coding=start_coding,
|
|
3729
3774
|
end_coding=end_coding,
|
|
3775
|
+
start_interval=start_interval,
|
|
3776
|
+
end_interval=end_interval,
|
|
3730
3777
|
maxTime=max_media_duration_all_obs,
|
|
3731
3778
|
show_include_modifiers=False,
|
|
3732
3779
|
show_exclude_non_coded_behaviors=False,
|
|
@@ -3932,6 +3979,11 @@ class MainWindow(QMainWindow, Ui_MainWindow):
|
|
|
3932
3979
|
ethogram_idx = [x for x in self.pj[cfg.ETHOGRAM] if self.pj[cfg.ETHOGRAM][x][cfg.BEHAVIOR_CODE] == code][0]
|
|
3933
3980
|
|
|
3934
3981
|
event = self.full_event(ethogram_idx)
|
|
3982
|
+
# MEDIA / LIVE
|
|
3983
|
+
"""
|
|
3984
|
+
if self.pj[cfg.OBSERVATIONS][self.observationId][cfg.TYPE] in (cfg.MEDIA, cfg.LIVE):
|
|
3985
|
+
time_ = self.getLaps()
|
|
3986
|
+
"""
|
|
3935
3987
|
|
|
3936
3988
|
# IMAGES
|
|
3937
3989
|
if self.pj[cfg.OBSERVATIONS][self.observationId][cfg.TYPE] == cfg.IMAGES:
|
|
@@ -3944,6 +3996,11 @@ class MainWindow(QMainWindow, Ui_MainWindow):
|
|
|
3944
3996
|
|
|
3945
3997
|
time_, cumulative_time = self.get_obs_time()
|
|
3946
3998
|
|
|
3999
|
+
"""
|
|
4000
|
+
print(time_)
|
|
4001
|
+
print(cumulative_time)
|
|
4002
|
+
"""
|
|
4003
|
+
|
|
3947
4004
|
if self.pj[cfg.OBSERVATIONS][self.observationId].get(cfg.MEDIA_CREATION_DATE_AS_OFFSET, False):
|
|
3948
4005
|
write_event.write_event(self, event, time_)
|
|
3949
4006
|
else:
|
|
@@ -4863,6 +4920,7 @@ class MainWindow(QMainWindow, Ui_MainWindow):
|
|
|
4863
4920
|
|
|
4864
4921
|
def keyPressEvent(self, event) -> None:
|
|
4865
4922
|
"""
|
|
4923
|
+
http://qt-project.org/doc/qt-5.0/qtcore/qt.html#Key-enum
|
|
4866
4924
|
https://github.com/pyqt/python-qt5/blob/master/PySide6/qml/builtins.qmltypes
|
|
4867
4925
|
|
|
4868
4926
|
ESC: 16777216
|
|
@@ -4922,6 +4980,19 @@ class MainWindow(QMainWindow, Ui_MainWindow):
|
|
|
4922
4980
|
|
|
4923
4981
|
flagPlayerPlaying = self.is_playing()
|
|
4924
4982
|
|
|
4983
|
+
# play / pause with space bar
|
|
4984
|
+
if self.pj[cfg.OBSERVATIONS][self.observationId][cfg.TYPE] == cfg.LIVE:
|
|
4985
|
+
if ek in (Qt.Key_Space, Qt.Key_Enter, Qt.Key_Return):
|
|
4986
|
+
if self.liveObservationStarted:
|
|
4987
|
+
if (
|
|
4988
|
+
dialog.MessageDialog(cfg.programName, "Are you sure to stop the current live observation?", [cfg.YES, cfg.NO])
|
|
4989
|
+
== cfg.YES
|
|
4990
|
+
):
|
|
4991
|
+
self.start_live_observation()
|
|
4992
|
+
else:
|
|
4993
|
+
self.start_live_observation()
|
|
4994
|
+
return
|
|
4995
|
+
|
|
4925
4996
|
if self.pj[cfg.OBSERVATIONS][self.observationId][cfg.TYPE] == cfg.MEDIA:
|
|
4926
4997
|
# speed down
|
|
4927
4998
|
if ek == Qt.Key_End:
|
|
@@ -5172,6 +5243,8 @@ class MainWindow(QMainWindow, Ui_MainWindow):
|
|
|
5172
5243
|
else:
|
|
5173
5244
|
write_event.write_event(self, event, memLaps)
|
|
5174
5245
|
|
|
5246
|
+
# write_event.write_event(self, event, memLaps)
|
|
5247
|
+
|
|
5175
5248
|
elif subject_idx is not None:
|
|
5176
5249
|
self.update_subject(self.pj[cfg.SUBJECTS][subject_idx][cfg.SUBJECT_NAME])
|
|
5177
5250
|
|
|
@@ -5525,7 +5598,7 @@ class MainWindow(QMainWindow, Ui_MainWindow):
|
|
|
5525
5598
|
def actionQuit_activated(self):
|
|
5526
5599
|
self.close()
|
|
5527
5600
|
|
|
5528
|
-
def play_video(self):
|
|
5601
|
+
def play_video(self) -> bool | None:
|
|
5529
5602
|
"""
|
|
5530
5603
|
play video
|
|
5531
5604
|
check if first player ended
|
|
@@ -5534,32 +5607,34 @@ class MainWindow(QMainWindow, Ui_MainWindow):
|
|
|
5534
5607
|
if self.geometric_measurements_mode:
|
|
5535
5608
|
return
|
|
5536
5609
|
|
|
5537
|
-
if self.playerType
|
|
5538
|
-
|
|
5539
|
-
for i, dw in enumerate(self.dw_player):
|
|
5540
|
-
if (
|
|
5541
|
-
str(i + 1) in self.pj[cfg.OBSERVATIONS][self.observationId][cfg.FILE]
|
|
5542
|
-
and self.pj[cfg.OBSERVATIONS][self.observationId][cfg.FILE][str(i + 1)]
|
|
5543
|
-
):
|
|
5544
|
-
dw.player.pause = False
|
|
5610
|
+
if self.playerType != cfg.MEDIA:
|
|
5611
|
+
return
|
|
5545
5612
|
|
|
5546
|
-
|
|
5613
|
+
# check if player 1 is ended
|
|
5614
|
+
for i, dw in enumerate(self.dw_player):
|
|
5615
|
+
if (
|
|
5616
|
+
str(i + 1) in self.pj[cfg.OBSERVATIONS][self.observationId][cfg.FILE]
|
|
5617
|
+
and self.pj[cfg.OBSERVATIONS][self.observationId][cfg.FILE][str(i + 1)]
|
|
5618
|
+
):
|
|
5619
|
+
dw.player.pause = False
|
|
5547
5620
|
|
|
5548
|
-
|
|
5549
|
-
# or self.pj[cfg.OBSERVATIONS][self.observationId].get(VISUALIZE_SPECTROGRAM, False):
|
|
5621
|
+
self.lb_player_status.clear()
|
|
5550
5622
|
|
|
5551
|
-
|
|
5623
|
+
# if self.pj[cfg.OBSERVATIONS][self.observationId].get(cfg.VISUALIZE_WAVEFORM, False) \
|
|
5624
|
+
# or self.pj[cfg.OBSERVATIONS][self.observationId].get(VISUALIZE_SPECTROGRAM, False):
|
|
5552
5625
|
|
|
5553
|
-
|
|
5626
|
+
self.statusbar.showMessage("", 0)
|
|
5554
5627
|
|
|
5555
|
-
|
|
5556
|
-
for data_timer in self.ext_data_timer_list:
|
|
5557
|
-
data_timer.start()
|
|
5628
|
+
self.plot_timer.start()
|
|
5558
5629
|
|
|
5559
|
-
|
|
5560
|
-
|
|
5630
|
+
# start all timer for plotting data
|
|
5631
|
+
for data_timer in self.ext_data_timer_list:
|
|
5632
|
+
data_timer.start()
|
|
5561
5633
|
|
|
5562
|
-
|
|
5634
|
+
self.actionPlay.setIcon(QIcon(f":/pause_{self.theme_mode()}"))
|
|
5635
|
+
self.actionPlay.setText("Pause")
|
|
5636
|
+
|
|
5637
|
+
return True
|
|
5563
5638
|
|
|
5564
5639
|
def pause_video(self, msg: str = "Player paused"):
|
|
5565
5640
|
"""
|
|
@@ -5597,12 +5672,16 @@ class MainWindow(QMainWindow, Ui_MainWindow):
|
|
|
5597
5672
|
"""
|
|
5598
5673
|
button 'play' activated
|
|
5599
5674
|
"""
|
|
5675
|
+
if not self.observationId:
|
|
5676
|
+
return
|
|
5600
5677
|
|
|
5601
|
-
if self.
|
|
5602
|
-
|
|
5603
|
-
|
|
5604
|
-
|
|
5605
|
-
|
|
5678
|
+
if self.pj[cfg.OBSERVATIONS][self.observationId][cfg.TYPE] != cfg.MEDIA:
|
|
5679
|
+
return
|
|
5680
|
+
|
|
5681
|
+
if not self.is_playing():
|
|
5682
|
+
self.play_video()
|
|
5683
|
+
else:
|
|
5684
|
+
self.pause_video()
|
|
5606
5685
|
|
|
5607
5686
|
def jumpBackward_activated(self):
|
|
5608
5687
|
"""
|
|
@@ -5707,11 +5786,15 @@ class MainWindow(QMainWindow, Ui_MainWindow):
|
|
|
5707
5786
|
|
|
5708
5787
|
start_coding, end_coding, _ = observation_operations.coding_time(self.pj[cfg.OBSERVATIONS], selected_observations)
|
|
5709
5788
|
|
|
5789
|
+
start_interval, end_interval = observation_operations.time_intervals_range(self.pj[cfg.OBSERVATIONS], selected_observations)
|
|
5790
|
+
|
|
5710
5791
|
parameters: dict = select_subj_behav.choose_obs_subj_behav_category(
|
|
5711
5792
|
self,
|
|
5712
5793
|
selected_observations,
|
|
5713
5794
|
start_coding=start_coding,
|
|
5714
5795
|
end_coding=end_coding,
|
|
5796
|
+
start_interval=start_interval,
|
|
5797
|
+
end_interval=end_interval,
|
|
5715
5798
|
maxTime=max_media_duration_all_obs,
|
|
5716
5799
|
by_category=False,
|
|
5717
5800
|
n_observations=len(selected_observations),
|
|
@@ -5781,19 +5864,39 @@ class MainWindow(QMainWindow, Ui_MainWindow):
|
|
|
5781
5864
|
logging.debug(f"{df.info()}")
|
|
5782
5865
|
logging.debug(f"{df.head()}")
|
|
5783
5866
|
|
|
5784
|
-
df_results, str_results = plugin_module.main(df, observations_list=selected_observations, parameters=parameters)
|
|
5785
|
-
|
|
5786
|
-
|
|
5787
|
-
|
|
5788
|
-
)
|
|
5789
|
-
|
|
5790
|
-
|
|
5791
|
-
|
|
5792
|
-
|
|
5793
|
-
|
|
5794
|
-
|
|
5795
|
-
|
|
5796
|
-
|
|
5867
|
+
# df_results, str_results = plugin_module.main(df, observations_list=selected_observations, parameters=parameters)
|
|
5868
|
+
|
|
5869
|
+
plugin_results = plugin_module.main(df, observations_list=selected_observations, parameters=parameters)
|
|
5870
|
+
# test if tuple: if not transform to tuple
|
|
5871
|
+
if not isinstance(plugin_results, tuple):
|
|
5872
|
+
plugin_results = tuple([plugin_results])
|
|
5873
|
+
|
|
5874
|
+
self.plugin_visu: list = []
|
|
5875
|
+
for result in plugin_results:
|
|
5876
|
+
if isinstance(result, str):
|
|
5877
|
+
self.plugin_visu.append(dialog.Results_dialog())
|
|
5878
|
+
self.plugin_visu[-1].setWindowTitle(self.sender().text())
|
|
5879
|
+
self.plugin_visu[-1].ptText.clear()
|
|
5880
|
+
self.plugin_visu[-1].ptText.appendPlainText(result)
|
|
5881
|
+
self.plugin_visu[-1].show()
|
|
5882
|
+
elif isinstance(result, pd.DataFrame):
|
|
5883
|
+
self.plugin_visu.append(
|
|
5884
|
+
view_df.View_df(self.sender().text(), f"{plugin_module.__version__} ({plugin_module.__version_date__})", result)
|
|
5885
|
+
)
|
|
5886
|
+
self.plugin_visu[-1].show()
|
|
5887
|
+
else:
|
|
5888
|
+
# result is not str nor dataframe
|
|
5889
|
+
QMessageBox.critical(
|
|
5890
|
+
None,
|
|
5891
|
+
cfg.programName,
|
|
5892
|
+
(
|
|
5893
|
+
f"Plugin returns an unknown object type: {type(result)}\n\n"
|
|
5894
|
+
"Plugins must return str and/or Pandas Dataframes.\n"
|
|
5895
|
+
"Check the plugin code."
|
|
5896
|
+
),
|
|
5897
|
+
QMessageBox.Ok | QMessageBox.Default,
|
|
5898
|
+
QMessageBox.NoButton,
|
|
5899
|
+
)
|
|
5797
5900
|
|
|
5798
5901
|
|
|
5799
5902
|
def main():
|
|
@@ -5864,18 +5967,31 @@ def main():
|
|
|
5864
5967
|
window.load_project(project_path, project_changed, pj)
|
|
5865
5968
|
|
|
5866
5969
|
# check project integrity
|
|
5867
|
-
|
|
5868
|
-
|
|
5869
|
-
|
|
5870
|
-
|
|
5871
|
-
|
|
5872
|
-
|
|
5873
|
-
|
|
5874
|
-
|
|
5875
|
-
|
|
5876
|
-
|
|
5877
|
-
|
|
5878
|
-
|
|
5970
|
+
# read config
|
|
5971
|
+
config_param: dict = {}
|
|
5972
|
+
ini_file_path = pl.Path.home() / pl.Path(".boris")
|
|
5973
|
+
if ini_file_path.is_file():
|
|
5974
|
+
settings = QSettings(str(ini_file_path), QSettings.IniFormat)
|
|
5975
|
+
try:
|
|
5976
|
+
config_param = settings.value("config")
|
|
5977
|
+
except Exception:
|
|
5978
|
+
config_param = {}
|
|
5979
|
+
if config_param == {}:
|
|
5980
|
+
config_param = cfg.INIT_PARAM
|
|
5981
|
+
|
|
5982
|
+
if config_param.get(cfg.CHECK_PROJECT_INTEGRITY, True):
|
|
5983
|
+
msg = project_functions.check_project_integrity(
|
|
5984
|
+
pj,
|
|
5985
|
+
"S",
|
|
5986
|
+
project_path,
|
|
5987
|
+
media_file_available=True,
|
|
5988
|
+
)
|
|
5989
|
+
if msg:
|
|
5990
|
+
results = dialog.Results_dialog()
|
|
5991
|
+
results.setWindowTitle("Project integrity results")
|
|
5992
|
+
results.ptText.clear()
|
|
5993
|
+
results.ptText.appendHtml(f"Some issues were found in the project<br><br>{msg}")
|
|
5994
|
+
results.show()
|
|
5879
5995
|
|
|
5880
5996
|
window.show()
|
|
5881
5997
|
window.raise_()
|