typos and pylance
This commit is contained in:
@@ -16,6 +16,7 @@ from typing import Optional, Tuple
|
|||||||
# External library imports
|
# External library imports
|
||||||
from src.shared.shareddata import APP_NAME, PLATFORM_NAME
|
from src.shared.shareddata import APP_NAME, PLATFORM_NAME
|
||||||
|
|
||||||
|
|
||||||
ELEVATION_FLAG = "--register_file_association_elevated"
|
ELEVATION_FLAG = "--register_file_association_elevated"
|
||||||
|
|
||||||
|
|
||||||
@@ -25,7 +26,6 @@ def register_file_association(ext: Optional[str] = None,
|
|||||||
bundle_id: Optional[str] = None,
|
bundle_id: Optional[str] = None,
|
||||||
force_admin: bool = False,
|
force_admin: bool = False,
|
||||||
) -> Tuple[bool, str]:
|
) -> Tuple[bool, str]:
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Registers a custom file extension across Windows, Linux, and macOS.
|
Registers a custom file extension across Windows, Linux, and macOS.
|
||||||
Handles non-admin Windows users by falling back to local user registry.
|
Handles non-admin Windows users by falling back to local user registry.
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ from copy import deepcopy
|
|||||||
import multiprocessing as mp
|
import multiprocessing as mp
|
||||||
from itertools import compress
|
from itertools import compress
|
||||||
from queue import Empty, Queue
|
from queue import Empty, Queue
|
||||||
from typing import Any, Optional, Sequence, cast, Literal, Union
|
from typing import Any, Optional, Sequence, cast, Literal, Union, List
|
||||||
|
|
||||||
# External library imports
|
# External library imports
|
||||||
import matplotlib.pyplot as plt
|
import matplotlib.pyplot as plt
|
||||||
@@ -6274,10 +6274,21 @@ def _single_subject_epoch_coherence(
|
|||||||
# ============================================================================
|
# ============================================================================
|
||||||
|
|
||||||
def run_group_functional_connectivity_betas(
|
def run_group_functional_connectivity_betas(
|
||||||
haemo_dict, selected_paths, event_name, n_lines, vmin,
|
haemo_dict: dict[str, BaseRaw],
|
||||||
*, drift_model="cosine", drift_order=1, hrf_model="glover",
|
selected_paths: List[str],
|
||||||
apply_gsr=True, alpha=0.05, min_participants=3, resample_freq=4.0,
|
event_name: Optional[str],
|
||||||
|
n_lines: int,
|
||||||
|
vmin: float,
|
||||||
|
*,
|
||||||
|
drift_model: str = "cosine",
|
||||||
|
drift_order: int = 1,
|
||||||
|
hrf_model: str = "glover",
|
||||||
|
apply_gsr: bool = True,
|
||||||
|
alpha: float = 0.05,
|
||||||
|
min_participants: int = 3,
|
||||||
|
resample_freq: float = 4.0,
|
||||||
) -> None:
|
) -> None:
|
||||||
|
|
||||||
subject_results = []
|
subject_results = []
|
||||||
for path in selected_paths:
|
for path in selected_paths:
|
||||||
raw = haemo_dict.get(path)
|
raw = haemo_dict.get(path)
|
||||||
@@ -6311,7 +6322,7 @@ def run_group_functional_connectivity_betas(
|
|||||||
|
|
||||||
|
|
||||||
def run_group_functional_connectivity_epochs(
|
def run_group_functional_connectivity_epochs(
|
||||||
epochs_dict: dict[str | Path, Epochs],
|
epochs_dict: dict[str, Epochs],
|
||||||
selected_paths: list[str],
|
selected_paths: list[str],
|
||||||
event_name: str | None,
|
event_name: str | None,
|
||||||
n_lines: int,
|
n_lines: int,
|
||||||
|
|||||||
+2
-4
@@ -14,15 +14,14 @@ import time
|
|||||||
import shlex
|
import shlex
|
||||||
import psutil
|
import psutil
|
||||||
import shutil
|
import shutil
|
||||||
import platform
|
|
||||||
import subprocess
|
import subprocess
|
||||||
from typing import Union
|
from typing import Union
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
|
||||||
|
# External library imports
|
||||||
|
from src.shared.shareddata import APP_NAME, PLATFORM_NAME
|
||||||
|
|
||||||
PLATFORM_NAME = platform.system().lower()
|
|
||||||
APP_NAME = "flares"
|
|
||||||
|
|
||||||
if PLATFORM_NAME == 'darwin':
|
if PLATFORM_NAME == 'darwin':
|
||||||
_log_path = os.path.join(os.path.dirname(sys.executable), f"../../../{APP_NAME}_updater.log")
|
_log_path = os.path.join(os.path.dirname(sys.executable), f"../../../{APP_NAME}_updater.log")
|
||||||
@@ -189,7 +188,6 @@ def main():
|
|||||||
update_folder = sys.argv[1]
|
update_folder = sys.argv[1]
|
||||||
main_exe = sys.argv[2]
|
main_exe = sys.argv[2]
|
||||||
|
|
||||||
# Interesting naming convention
|
|
||||||
main_exe_path = Path(main_exe).resolve()
|
main_exe_path = Path(main_exe).resolve()
|
||||||
app_dir = main_exe_path.parent
|
app_dir = main_exe_path.parent
|
||||||
bundle_dir = main_exe_path.parents[2]
|
bundle_dir = main_exe_path.parents[2]
|
||||||
|
|||||||
+3
-3
@@ -21,9 +21,9 @@ from PySide6.QtWidgets import QMessageBox, QVBoxLayout, QFileDialog, QLabel, QDi
|
|||||||
from PySide6.QtCore import QThread, Signal, Qt, QTimer
|
from PySide6.QtCore import QThread, Signal, Qt, QTimer
|
||||||
from PySide6.QtGui import QAction
|
from PySide6.QtGui import QAction
|
||||||
|
|
||||||
from mne.io import read_raw_snirf
|
from mne.io import read_raw_snirf # type: ignore
|
||||||
from mne.preprocessing.nirs import source_detector_distances
|
from mne.preprocessing.nirs import source_detector_distances # type: ignore
|
||||||
from mne_nirs.channels import get_short_channels # type: ignore
|
from mne_nirs.channels import get_short_channels # type: ignore
|
||||||
|
|
||||||
from src.shared.flaresbasewidget import ProgressBubble
|
from src.shared.flaresbasewidget import ProgressBubble
|
||||||
from src.shared.shareddata import APP_NAME, CURRENT_VERSION, PLATFORM_NAME, DATA_SCHEMA
|
from src.shared.shareddata import APP_NAME, CURRENT_VERSION, PLATFORM_NAME, DATA_SCHEMA
|
||||||
|
|||||||
+4
-4
@@ -1,7 +1,7 @@
|
|||||||
src\analysis\participantfoldchannels.py 157
|
src\analysis\participantfoldchannels.py 158
|
||||||
src\shared\flaresbasewidget.py 1001+
|
src\shared\flaresbasewidget.py 1001+
|
||||||
src\window\updateevents.py 151
|
src\window\updateevents.py 83
|
||||||
flares.py 1001+
|
flares.py 1001+
|
||||||
main_unit_tests.py 153
|
main_unit_tests.py 153
|
||||||
main.py 709
|
main.py 705
|
||||||
project_manager.py 407
|
project_manager.py 405
|
||||||
@@ -9,7 +9,6 @@ License: GPL-3.0
|
|||||||
|
|
||||||
# Built-in imports
|
# Built-in imports
|
||||||
import os
|
import os
|
||||||
from pathlib import Path
|
|
||||||
from typing import Any
|
from typing import Any
|
||||||
|
|
||||||
# External library imports
|
# External library imports
|
||||||
@@ -27,7 +26,7 @@ from src.shared.shareddata import APP_NAME
|
|||||||
class ExportToCSVWidget(CSVUIMixin, FlaresBaseWidget):
|
class ExportToCSVWidget(CSVUIMixin, FlaresBaseWidget):
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
haemo_dict: dict[str | Path, BaseRaw],
|
haemo_dict: dict[str, BaseRaw],
|
||||||
cha_dict: dict[str, DataFrame],
|
cha_dict: dict[str, DataFrame],
|
||||||
df_ind_dict: dict[str, DataFrame],
|
df_ind_dict: dict[str, DataFrame],
|
||||||
design_matrix_dict: dict[str, DataFrame],
|
design_matrix_dict: dict[str, DataFrame],
|
||||||
|
|||||||
@@ -7,8 +7,7 @@ Author: Tyler de Zeeuw
|
|||||||
License: GPL-3.0
|
License: GPL-3.0
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# Built-in Imports
|
# Built-in imports
|
||||||
from pathlib import Path
|
|
||||||
from typing import Any, cast
|
from typing import Any, cast
|
||||||
|
|
||||||
# External library imports
|
# External library imports
|
||||||
@@ -69,7 +68,7 @@ DESCRIPTION = """\n1. Group Contrast 2D/3D (plot_2d_3d_contrasts_between_groups)
|
|||||||
class InterGroupBrainImageWidget(InterGroupUIMixin, FlaresBaseWidget):
|
class InterGroupBrainImageWidget(InterGroupUIMixin, FlaresBaseWidget):
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
haemo_dict: dict[str | Path, BaseRaw],
|
haemo_dict: dict[str, BaseRaw],
|
||||||
df_ind_dict: dict[str, DataFrame],
|
df_ind_dict: dict[str, DataFrame],
|
||||||
design_matrix_dict: dict[str, DataFrame],
|
design_matrix_dict: dict[str, DataFrame],
|
||||||
contrast_results_dict: dict[str, dict[str, Any]],
|
contrast_results_dict: dict[str, dict[str, Any]],
|
||||||
|
|||||||
@@ -8,7 +8,6 @@ License: GPL-3.0
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
# Built-in imports
|
# Built-in imports
|
||||||
from pathlib import Path
|
|
||||||
from typing import Any, cast
|
from typing import Any, cast
|
||||||
|
|
||||||
# External library imports
|
# External library imports
|
||||||
@@ -147,7 +146,7 @@ class InterGroupStatsWidget(InterGroupUIMixin, FlaresBaseWidget):
|
|||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
haemo_dict: dict[str | Path, BaseRaw],
|
haemo_dict: dict[str, BaseRaw],
|
||||||
cha_dict: dict[str, DataFrame],
|
cha_dict: dict[str, DataFrame],
|
||||||
df_ind_dict: dict[str, DataFrame],
|
df_ind_dict: dict[str, DataFrame],
|
||||||
design_matrix_dict: dict[str, DataFrame],
|
design_matrix_dict: dict[str, DataFrame],
|
||||||
|
|||||||
@@ -7,8 +7,7 @@ Author: Tyler de Zeeuw
|
|||||||
License: GPL-3.0
|
License: GPL-3.0
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# Built-in Imports
|
# Built-in imports
|
||||||
from pathlib import Path
|
|
||||||
from typing import Any, cast
|
from typing import Any, cast
|
||||||
|
|
||||||
# External library imports
|
# External library imports
|
||||||
@@ -79,7 +78,7 @@ DESCRIPTION = """0. FIR Model Results (plot_fir_model_results)
|
|||||||
class IntraGroupBrainImageWidget(IntraGroupUIMixin, FlaresBaseWidget):
|
class IntraGroupBrainImageWidget(IntraGroupUIMixin, FlaresBaseWidget):
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
haemo_dict: dict[str | Path, BaseRaw],
|
haemo_dict: dict[str, BaseRaw],
|
||||||
cha_dict: dict[str, DataFrame],
|
cha_dict: dict[str, DataFrame],
|
||||||
df_ind_dict: dict[str, DataFrame],
|
df_ind_dict: dict[str, DataFrame],
|
||||||
design_matrix_dict: dict[str, DataFrame],
|
design_matrix_dict: dict[str, DataFrame],
|
||||||
|
|||||||
@@ -8,7 +8,6 @@ License: GPL-3.0
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
# Built-in imports
|
# Built-in imports
|
||||||
from pathlib import Path
|
|
||||||
from typing import Any, cast
|
from typing import Any, cast
|
||||||
|
|
||||||
# External library imports
|
# External library imports
|
||||||
@@ -61,7 +60,7 @@ DESCRIPTION = """0. Beta-Series Correlation (run_group_functional_connectivity_b
|
|||||||
class IntraGroupFunctionalConnectivityWidget(IntraGroupUIMixin, FlaresBaseWidget):
|
class IntraGroupFunctionalConnectivityWidget(IntraGroupUIMixin, FlaresBaseWidget):
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
haemo_dict: dict[str | Path, BaseRaw],
|
haemo_dict: dict[str, BaseRaw],
|
||||||
epochs_dict: dict[str, Epochs],
|
epochs_dict: dict[str, Epochs],
|
||||||
group_dict: dict[str, str],
|
group_dict: dict[str, str],
|
||||||
) -> None:
|
) -> None:
|
||||||
@@ -99,7 +98,11 @@ class IntraGroupFunctionalConnectivityWidget(IntraGroupUIMixin, FlaresBaseWidget
|
|||||||
min_participants = params.get("min_participants", 3)
|
min_participants = params.get("min_participants", 3)
|
||||||
|
|
||||||
run_group_functional_connectivity_betas(
|
run_group_functional_connectivity_betas(
|
||||||
self.haemo_dict, selected_file_paths, selected_event, n_lines, vmin,
|
self.haemo_dict,
|
||||||
|
selected_file_paths,
|
||||||
|
selected_event,
|
||||||
|
n_lines,
|
||||||
|
vmin,
|
||||||
drift_model=drift_model,
|
drift_model=drift_model,
|
||||||
drift_order=drift_order,
|
drift_order=drift_order,
|
||||||
hrf_model=hrf_model,
|
hrf_model=hrf_model,
|
||||||
|
|||||||
@@ -8,7 +8,6 @@ License: GPL-3.0
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
# Built-in imports
|
# Built-in imports
|
||||||
from pathlib import Path
|
|
||||||
from typing import Any, cast
|
from typing import Any, cast
|
||||||
|
|
||||||
# External library imports
|
# External library imports
|
||||||
@@ -159,7 +158,7 @@ DESCRIPTION = """0. ROI vs. Zero (run_roi_second_level_analysis)
|
|||||||
class IntraGroupStatsWidget(IntraGroupUIMixin, FlaresBaseWidget):
|
class IntraGroupStatsWidget(IntraGroupUIMixin, FlaresBaseWidget):
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
haemo_dict: dict[str | Path, BaseRaw],
|
haemo_dict: dict[str, BaseRaw],
|
||||||
cha_dict: dict[str, DataFrame],
|
cha_dict: dict[str, DataFrame],
|
||||||
df_ind_dict: dict[str, DataFrame],
|
df_ind_dict: dict[str, DataFrame],
|
||||||
design_matrix_dict: dict[str, DataFrame],
|
design_matrix_dict: dict[str, DataFrame],
|
||||||
@@ -240,6 +239,10 @@ class IntraGroupStatsWidget(IntraGroupUIMixin, FlaresBaseWidget):
|
|||||||
if correction_method == "None":
|
if correction_method == "None":
|
||||||
correction_method = None
|
correction_method = None
|
||||||
|
|
||||||
|
if not selected_event:
|
||||||
|
print("Warning: No event condition selected for ROI analysis.")
|
||||||
|
continue
|
||||||
|
|
||||||
if df_group.empty:
|
if df_group.empty:
|
||||||
print("No ROI data (df_ind) found for selected participants.")
|
print("No ROI data (df_ind) found for selected participants.")
|
||||||
continue
|
continue
|
||||||
@@ -265,7 +268,6 @@ class IntraGroupStatsWidget(IntraGroupUIMixin, FlaresBaseWidget):
|
|||||||
else:
|
else:
|
||||||
all_cha_filtered = all_cha
|
all_cha_filtered = all_cha
|
||||||
|
|
||||||
|
|
||||||
run_roi_second_level_analysis(
|
run_roi_second_level_analysis(
|
||||||
df_roi_all=df_filtered,
|
df_roi_all=df_filtered,
|
||||||
condition=selected_event,
|
condition=selected_event,
|
||||||
@@ -303,7 +305,6 @@ class IntraGroupStatsWidget(IntraGroupUIMixin, FlaresBaseWidget):
|
|||||||
print("Both ROI A and ROI B must be specified.")
|
print("Both ROI A and ROI B must be specified.")
|
||||||
continue
|
continue
|
||||||
|
|
||||||
print(min_subjects)
|
|
||||||
run_roi_paired_contrast_analysis(
|
run_roi_paired_contrast_analysis(
|
||||||
df_roi_all=df_group,
|
df_roi_all=df_group,
|
||||||
roi_pairs=(roi_a, roi_b),
|
roi_pairs=(roi_a, roi_b),
|
||||||
|
|||||||
@@ -8,7 +8,6 @@ License: GPL-3.0
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
# Built-in imports
|
# Built-in imports
|
||||||
from pathlib import Path
|
|
||||||
from typing import Any, cast
|
from typing import Any, cast
|
||||||
|
|
||||||
# External library imports
|
# External library imports
|
||||||
@@ -69,7 +68,7 @@ PARAMETERIZED_INDEXES: dict[int, list[dict[str, Any]]] = {
|
|||||||
class ParticipantBrainViewerWidget(ParticipantUIMixin, FlaresBaseWidget):
|
class ParticipantBrainViewerWidget(ParticipantUIMixin, FlaresBaseWidget):
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
haemo_dict: dict[str | Path, BaseRaw],
|
haemo_dict: dict[str, BaseRaw],
|
||||||
cha_dict: dict[str, DataFrame],
|
cha_dict: dict[str, DataFrame],
|
||||||
) -> None:
|
) -> None:
|
||||||
|
|
||||||
|
|||||||
@@ -748,7 +748,7 @@ class ProcessOrchestrator(QObject):
|
|||||||
|
|
||||||
def __init__(self,
|
def __init__(self,
|
||||||
selected_files,
|
selected_files,
|
||||||
haemo_dict: dict[str | Path, BaseRaw],
|
haemo_dict: dict[str, BaseRaw],
|
||||||
worker_func
|
worker_func
|
||||||
):
|
):
|
||||||
|
|
||||||
|
|||||||
@@ -7,8 +7,7 @@ Author: Tyler de Zeeuw
|
|||||||
License: GPL-3.0
|
License: GPL-3.0
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# Built-in Imports
|
# Built-in imports
|
||||||
from pathlib import Path
|
|
||||||
from typing import Any, cast
|
from typing import Any, cast
|
||||||
|
|
||||||
# External library imports
|
# External library imports
|
||||||
@@ -81,7 +80,7 @@ DESCRIPTION = """0. Spectral Coherence (functional_connectivity_spectral_epochs)
|
|||||||
class ParticipantFunctionalConnectivityWidget(ParticipantUIMixin, FlaresBaseWidget):
|
class ParticipantFunctionalConnectivityWidget(ParticipantUIMixin, FlaresBaseWidget):
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
haemo_dict: dict[str | Path, BaseRaw],
|
haemo_dict: dict[str, BaseRaw],
|
||||||
epochs_dict: dict[str, Epochs],
|
epochs_dict: dict[str, Epochs],
|
||||||
) -> None:
|
) -> None:
|
||||||
|
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ Author: Tyler de Zeeuw
|
|||||||
License: GPL-3.0
|
License: GPL-3.0
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# Built-in Imports
|
# Built-in imports
|
||||||
import os.path as op
|
import os.path as op
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
@@ -26,7 +26,7 @@ from src.shared.shareddata import APP_NAME
|
|||||||
class ParticipantImageViewerWidget(FlaresBaseWidget):
|
class ParticipantImageViewerWidget(FlaresBaseWidget):
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
haemo_dict: dict[str, BaseRaw],
|
haemo_dict: dict[str, BaseRaw],
|
||||||
fig_bytes_dict: dict[str, dict[str, bytes]]
|
fig_bytes_dict: dict[str, dict[str, bytes]]
|
||||||
) -> None:
|
) -> None:
|
||||||
|
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ from pathlib import Path
|
|||||||
from typing import Any, Callable
|
from typing import Any, Callable
|
||||||
|
|
||||||
# External library imports
|
# External library imports
|
||||||
from PySide6.QtWidgets import QWidget, QVBoxLayout, QTextEdit, QLineEdit
|
from PySide6.QtWidgets import QWidget, QVBoxLayout, QTextEdit, QLineEdit, QMainWindow
|
||||||
from PySide6.QtCore import QProcess, Qt, QThread, Signal
|
from PySide6.QtCore import QProcess, Qt, QThread, Signal
|
||||||
|
|
||||||
from file_ext_registration import register_file_association, is_windows_admin
|
from file_ext_registration import register_file_association, is_windows_admin
|
||||||
@@ -124,7 +124,7 @@ class TerminalWindow(QWidget):
|
|||||||
|
|
||||||
def cmd_update(self, *args: Any) -> str:
|
def cmd_update(self, *args: Any) -> str:
|
||||||
main_win = self.parent()
|
main_win = self.parent()
|
||||||
if not isinstance(main_win, QWidget):
|
if not isinstance(main_win, QMainWindow):
|
||||||
return "[Error] Main window context not found."
|
return "[Error] Main window context not found."
|
||||||
|
|
||||||
self.updater = UpdateManager(
|
self.updater = UpdateManager(
|
||||||
|
|||||||
+63
-68
@@ -10,12 +10,9 @@ License: GPL-3.0
|
|||||||
import os
|
import os
|
||||||
import json
|
import json
|
||||||
from enum import Enum, auto
|
from enum import Enum, auto
|
||||||
from datetime import datetime
|
from typing import Any, List, Optional, cast
|
||||||
from typing import Optional
|
|
||||||
|
|
||||||
# External library imports
|
# External library imports
|
||||||
import numpy as np
|
|
||||||
|
|
||||||
from PySide6.QtWidgets import QWidget, QVBoxLayout, QLabel, QLineEdit, QPushButton, QComboBox, QHBoxLayout, QMessageBox, QFileDialog
|
from PySide6.QtWidgets import QWidget, QVBoxLayout, QLabel, QLineEdit, QPushButton, QComboBox, QHBoxLayout, QMessageBox, QFileDialog
|
||||||
from PySide6.QtCore import Qt
|
from PySide6.QtCore import Qt
|
||||||
|
|
||||||
@@ -255,15 +252,13 @@ class UpdateEventsWindow(QWidget):
|
|||||||
except (json.JSONDecodeError, FileNotFoundError, KeyError) as e:
|
except (json.JSONDecodeError, FileNotFoundError, KeyError) as e:
|
||||||
QMessageBox.warning(self, "Error", f"Failed to parse BORIS file:\n{e}")
|
QMessageBox.warning(self, "Error", f"Failed to parse BORIS file:\n{e}")
|
||||||
|
|
||||||
def extract_boris_observation_keys(self, data):
|
def extract_boris_observation_keys(self, data: dict[str, Any]) -> List[str]:
|
||||||
if "observations" not in data:
|
if "observations" not in data:
|
||||||
raise KeyError("Missing 'observations' key in BORIS file.")
|
raise KeyError("Missing 'observations' key in BORIS file.")
|
||||||
|
|
||||||
observations = data["observations"]
|
observations = cast(dict[str, Any], data["observations"])
|
||||||
if not isinstance(observations, dict):
|
|
||||||
raise TypeError("'observations' must be a dictionary.")
|
|
||||||
|
|
||||||
return list(observations.keys())
|
return list(observations.keys())
|
||||||
|
|
||||||
|
|
||||||
def on_observation_selected(self):
|
def on_observation_selected(self):
|
||||||
selected_obs = self.combo_suffix.currentText()
|
selected_obs = self.combo_suffix.currentText()
|
||||||
@@ -454,7 +449,7 @@ class UpdateEventsWindow(QWidget):
|
|||||||
save_path += ".json"
|
save_path += ".json"
|
||||||
|
|
||||||
# Build JSON dict
|
# Build JSON dict
|
||||||
json_data = {
|
json_data: dict[str, Any] = {
|
||||||
"observation": selected_obs,
|
"observation": selected_obs,
|
||||||
"snirf_anchor": {"label": snirf_label, "time": snirf_anchor_time},
|
"snirf_anchor": {"label": snirf_label, "time": snirf_anchor_time},
|
||||||
"boris_anchor": {"label": boris_label, "time": boris_anchor_time},
|
"boris_anchor": {"label": boris_label, "time": boris_anchor_time},
|
||||||
@@ -471,73 +466,73 @@ class UpdateEventsWindow(QWidget):
|
|||||||
QMessageBox.critical(self, "Error", f"Failed to write JSON:\n{e}")
|
QMessageBox.critical(self, "Error", f"Failed to write JSON:\n{e}")
|
||||||
|
|
||||||
|
|
||||||
def update_optode_positions(self, file_a, file_b, save_path):
|
# def update_optode_positions(self, file_a, file_b, save_path):
|
||||||
|
|
||||||
fiducials = {}
|
# fiducials = {}
|
||||||
ch_positions = {}
|
# ch_positions = {}
|
||||||
|
|
||||||
# Read the lines from the optode file
|
# # Read the lines from the optode file
|
||||||
with open(file_b, 'r') as f:
|
# with open(file_b, 'r') as f:
|
||||||
for line in f:
|
# for line in f:
|
||||||
if line.strip():
|
# if line.strip():
|
||||||
# Split by the semicolon and convert to meters
|
# # Split by the semicolon and convert to meters
|
||||||
ch_name, coords_str = line.split(":")
|
# ch_name, coords_str = line.split(":")
|
||||||
coords = np.array(list(map(float, coords_str.strip().split()))) * 0.001
|
# coords = np.array(list(map(float, coords_str.strip().split()))) * 0.001
|
||||||
|
|
||||||
# The key we have is a fiducial
|
# # The key we have is a fiducial
|
||||||
if ch_name.lower() in ['lpa', 'nz', 'rpa']:
|
# if ch_name.lower() in ['lpa', 'nz', 'rpa']:
|
||||||
fiducials[ch_name.lower()] = coords
|
# fiducials[ch_name.lower()] = coords
|
||||||
|
|
||||||
# The key we have is a source or detector
|
# # The key we have is a source or detector
|
||||||
else:
|
# else:
|
||||||
ch_positions[ch_name.upper()] = coords
|
# ch_positions[ch_name.upper()] = coords
|
||||||
|
|
||||||
# Create montage with updated coords in head space
|
# # Create montage with updated coords in head space
|
||||||
initial_montage = make_dig_montage(ch_pos=ch_positions, nasion=fiducials.get('nz'), lpa=fiducials.get('lpa'), rpa=fiducials.get('rpa'), coord_frame='head') # type: ignore
|
# initial_montage = make_dig_montage(ch_pos=ch_positions, nasion=fiducials.get('nz'), lpa=fiducials.get('lpa'), rpa=fiducials.get('rpa'), coord_frame='head') # type: ignore
|
||||||
|
|
||||||
# Read the SNIRF file, set the montage, and write it back
|
# # Read the SNIRF file, set the montage, and write it back
|
||||||
# TODO: Bad! read_raw_snirf doesnt release memory properly! Should be spawned in a seperate process and killed once completed
|
# # TODO: Bad! read_raw_snirf doesnt release memory properly! Should be spawned in a seperate process and killed once completed
|
||||||
raw = read_raw_snirf(file_a, preload=True)
|
# raw = read_raw_snirf(file_a, preload=True)
|
||||||
raw.set_montage(initial_montage)
|
# raw.set_montage(initial_montage)
|
||||||
write_raw_snirf(raw, save_path)
|
# write_raw_snirf(raw, save_path)
|
||||||
|
|
||||||
|
|
||||||
def _apply_events_to_snirf(self, raw, new_annotations, save_path):
|
# def _apply_events_to_snirf(self, raw, new_annotations, save_path):
|
||||||
raw.set_annotations(new_annotations)
|
# raw.set_annotations(new_annotations)
|
||||||
write_raw_snirf(raw, save_path)
|
# write_raw_snirf(raw, save_path)
|
||||||
|
|
||||||
def _write_event_mapping_json(
|
# def _write_event_mapping_json(
|
||||||
self,
|
# self,
|
||||||
file_a,
|
# file_a,
|
||||||
file_b,
|
# file_b,
|
||||||
selected_obs,
|
# selected_obs,
|
||||||
snirf_anchor,
|
# snirf_anchor,
|
||||||
boris_anchor,
|
# boris_anchor,
|
||||||
time_shift,
|
# time_shift,
|
||||||
mapped_events,
|
# mapped_events,
|
||||||
save_path
|
# save_path
|
||||||
):
|
# ):
|
||||||
|
|
||||||
payload = {
|
# payload = {
|
||||||
"source": {
|
# "source": {
|
||||||
"called_from": self.caller,
|
# "called_from": self.caller,
|
||||||
"snirf_file": os.path.basename(file_a),
|
# "snirf_file": os.path.basename(file_a),
|
||||||
"boris_file": os.path.basename(file_b),
|
# "boris_file": os.path.basename(file_b),
|
||||||
"observation": selected_obs
|
# "observation": selected_obs
|
||||||
},
|
# },
|
||||||
"alignment": {
|
# "alignment": {
|
||||||
"snirf_anchor": snirf_anchor,
|
# "snirf_anchor": snirf_anchor,
|
||||||
"boris_anchor": boris_anchor,
|
# "boris_anchor": boris_anchor,
|
||||||
"time_shift_seconds": time_shift
|
# "time_shift_seconds": time_shift
|
||||||
},
|
# },
|
||||||
"events": mapped_events,
|
# "events": mapped_events,
|
||||||
"created_at": datetime.utcnow().isoformat() + "Z"
|
# "created_at": datetime.utcnow().isoformat() + "Z"
|
||||||
}
|
# }
|
||||||
|
|
||||||
with open(save_path, "w", encoding="utf-8") as f:
|
# with open(save_path, "w", encoding="utf-8") as f:
|
||||||
json.dump(payload, f, indent=2)
|
# json.dump(payload, f, indent=2)
|
||||||
|
|
||||||
return save_path
|
# return save_path
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -747,11 +742,11 @@ class UpdateEventsBlazesWindow(QWidget):
|
|||||||
self.combo_events.setEnabled(False)
|
self.combo_events.setEnabled(False)
|
||||||
|
|
||||||
|
|
||||||
def extract_json_observation_strings(self, data):
|
def extract_json_observation_strings(self, data: dict[str, Any]) -> List[str]:
|
||||||
if "events" not in data:
|
if "events" not in data:
|
||||||
raise KeyError("Missing 'events' key in JSON file.")
|
raise KeyError("Missing 'events' key in JSON file.")
|
||||||
|
|
||||||
event_strings = []
|
event_strings: List[str] = []
|
||||||
|
|
||||||
# The new format is a flat list chronologically ordered
|
# The new format is a flat list chronologically ordered
|
||||||
for event in data["events"]:
|
for event in data["events"]:
|
||||||
@@ -772,7 +767,7 @@ class UpdateEventsBlazesWindow(QWidget):
|
|||||||
|
|
||||||
def go_action(self) -> None:
|
def go_action(self) -> None:
|
||||||
file_a = self.line_edit_file_a.text()
|
file_a = self.line_edit_file_a.text()
|
||||||
file_b = self.line_edit_file_b.text()
|
_ = self.line_edit_file_b.text()
|
||||||
suffix = APP_NAME
|
suffix = APP_NAME
|
||||||
|
|
||||||
if not hasattr(self, "json_data") or self.combo_events.count() == 0 or self.combo_snirf_events.count() == 0:
|
if not hasattr(self, "json_data") or self.combo_events.count() == 0 or self.combo_snirf_events.count() == 0:
|
||||||
|
|||||||
@@ -8,7 +8,6 @@ License: GPL-3.0
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
# Built-in imports
|
# Built-in imports
|
||||||
from pathlib import Path
|
|
||||||
from typing import Any, Callable, Type
|
from typing import Any, Callable, Type
|
||||||
|
|
||||||
# External library imports
|
# External library imports
|
||||||
@@ -36,7 +35,7 @@ from src.shared.shareddata import APP_NAME
|
|||||||
class ViewerLauncherWidget(QWidget):
|
class ViewerLauncherWidget(QWidget):
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
haemo_dict: dict[str | Path, BaseRaw],
|
haemo_dict: dict[str, BaseRaw],
|
||||||
epochs_dict: dict[str, Epochs],
|
epochs_dict: dict[str, Epochs],
|
||||||
cha_dict: dict[str, DataFrame],
|
cha_dict: dict[str, DataFrame],
|
||||||
df_ind_dict: dict[str, DataFrame],
|
df_ind_dict: dict[str, DataFrame],
|
||||||
|
|||||||
Reference in New Issue
Block a user