final changes for new release

This commit is contained in:
2026-03-28 14:30:20 -07:00
parent 70c4c1e779
commit 74ce2eeb2e
3 changed files with 158 additions and 67 deletions
+54 -20
View File
@@ -17,11 +17,11 @@ import platform
import traceback
import subprocess
import concurrent.futures
from queue import Empty
from enum import Enum, auto
from pathlib import Path, PurePosixPath
from datetime import datetime
from multiprocessing import Process, current_process, freeze_support, Manager, Queue
from queue import Empty
# External library imports
import numpy as np
@@ -87,7 +87,7 @@ SECTIONS = [
{
"title": "Heart Rate",
"params": [
{"name": "HEART_RATE", "default": True, "type": bool, "help": "Should an attempt be made to calculate participants heart rates?"},
{"name": "HEART_RATE", "default": True, "type": bool, "help": "Should an attempt be made to calculate the participants heart rate?"},
{"name": "SECONDS_TO_STRIP_HR", "default": 5, "type": int, "depends_on": "HEART_RATE", "help": "Will remove this many seconds from the start and end of the file. Useful if recording before cap is firmly placed, or participant removes cap while still recording."},
{"name": "MAX_LOW_HR", "default": 40, "type": int, "depends_on": "HEART_RATE", "help": "Any heart rate windows that average below this value will be rounded up to this value."},
{"name": "MAX_HIGH_HR", "default": 200, "type": int, "depends_on": "HEART_RATE", "help": "Any heart rate windows that average above this value will be rounded down to this value."},
@@ -118,12 +118,42 @@ SECTIONS = [
{"name": "PSP_THRESHOLD", "default": 0.1, "type": float, "depends_on": "PSP", "help": "PSP threshold. A typical scale would be 0-0.5, but it is possible for values to be above this range. Higher values correspond to a better signal. If PSP is True, any channels lower than this value will be marked as bad."},
]
},
{
"title": "Cross Validation",
"params": [
{"name": "CV", "default": True, "type": bool, "help": "Identifies bad channels using the Coefficient of Variation."},
{"name": "CV_THRESHOLD", "default": 20, "type": int, "depends_on": "CV", "help": "Noise threshold (%)."},
]
},
{
"title": "Median Absolute Deviation",
"params": [
{"name": "MAD", "default": True, "type": bool, "help": "Identifies bad channels using Mean Absolute Deviation."},
{"name": "MAD_THRESHOLD", "default": 4, "type": int, "depends_on": "MAD", "help": "Amount of deviations before the channel is flagged bad."},
]
},
{
"title": "Power Spectral Density Noise",
"params": [
{"name": "PSD_NOISE", "default": True, "type": bool, "help": "Identifies bad channels based on their excessive power at high frequencies."},
{"name": "TARGET_FREQ_DIV", "default": 4, "type": int, "depends_on": "PSD_NOISE", "help": "What frequency to check for excessive power. Will take the recording frequency and divide by this number. Has to be greater than 2."},
{"name": "DB_LIMIT", "default": -60, "type": int, "depends_on": "PSD_NOISE", "help": "What db level the power level needs to be below at the target frequency."},
]
},
{
"title": "Channel Variance",
"params": [
{"name": "CHANNEL_VAR", "default": True, "type": bool, "help": "Identifies bad channels based on comparing the variance of the first 25% of the data to the last 25%."},
{"name": "CHANNEL_THRESH", "default": 0.05, "type": float, "depends_on": "CHANNEL_VAR", "help": "If the end variance is less than this % of the start variance, the channel will be marked as bad."},
]
},
{
"title": "Bad Channels Handling",
"params": [
{"name": "BAD_CHANNELS_HANDLING", "default": ["Interpolate"], "type": list, "options": ["Interpolate", "Remove", "None"], "exclusive": True, "help": "How should we deal with the bad channels that occurred? Note: Some analysis options will only work when this is set to 'Interpolate'."},
{"name": "MAX_DIST", "default": 0.03, "type": float, "depends_on": "BAD_CHANNELS_HANDLING", "depends_value": "Interpolate", "help": "The maximum distance to look for neighbours when interpolating. Used only when BAD_CHANNELS_HANDLING is set to 'Interpolate'."},
{"name": "MIN_NEIGHBORS", "default": 2, "type": int, "depends_on": "BAD_CHANNELS_HANDLING", "depends_value": "Interpolate", "help": "The minimumn amount of neighbours needed within the MAX_DIST parameter. Used only when BAD_CHANNELS_HANDLING is set to 'Interpolate'."},
{"name": "MAX_BAD_CHANNELS", "default": 12, "type": int, "depends_on": "BAD_CHANNELS_HANDLING", "depends_value": "Remove", "help": "Maximum amount of bad channels before the participant as a whole is marked as bad (exclusive). If this occurs, the participant will be prevented from processing any further. Used only when BAD_CHANNELS_HANDLING is set to 'Remove'."},
]
},
{
@@ -377,22 +407,26 @@ class UserGuideWindow(QWidget):
"Stage 6: Scalp Coupling Index\n"
"Stage 7: Signal to Noise Ratio\n"
"Stage 8: Peak Spectral Power\n"
"Stage 9: Bad Channels Handling\n"
"Stage 10: Optical Density\n"
"Stage 11: Temporal Derivative Distribution Repair Filtering\n"
"Stage 12: Wavelet Filtering\n"
"Stage 13: Haemoglobin Concentration\n"
"Stage 14: Enhance Negative Correlation\n"
"Stage 15: Filter\n"
"Stage 16: Extracting Events\n"
"Stage 17: Epoch Calculations\n"
"Stage 18: Design Matrix\n"
"Stage 19: General Linear Model\n"
"Stage 20: Generate GLM Results\n"
"Stage 21: Generate Channel Significance\n"
"Stage 22: Generate Channel, Region of Interest, and Contrast Results\n"
"Stage 23: Compute Contrast Results\n"
"Stage 24: Finishing Up\n", self)
"Stage 9: Cross Validation\n"
"Stage 10: Median Absolute Deviation\n"
"Stage 11: Power Spectral Density Noise\n"
"Stage 12: Channel Variance\n"
"Stage 13: Bad Channels Handling\n"
"Stage 14: Optical Density\n"
"Stage 15: Temporal Derivative Distribution Repair Filtering\n"
"Stage 16: Wavelet Filtering\n"
"Stage 17: Haemoglobin Concentration\n"
"Stage 18: Enhance Negative Correlation\n"
"Stage 19: Filter\n"
"Stage 20: Extracting Events\n"
"Stage 21: Epoch Calculations\n"
"Stage 22: Design Matrix\n"
"Stage 23: General Linear Model\n"
"Stage 24: Generate GLM Results\n"
"Stage 25: Generate Channel Significance\n"
"Stage 26: Generate Channel, Region of Interest, and Contrast Results\n"
"Stage 27: Compute Contrast Results\n"
"Stage 28: Finishing Up\n", self)
label3 = QLabel(f"For more information, visit the Git wiki page <a href='https://git.research.dezeeuw.ca/tyler/{APP_NAME}/wiki'>here</a>.", self)
label3.setTextFormat(Qt.TextFormat.RichText)
@@ -1620,7 +1654,7 @@ class ProgressBubble(QWidget):
self.progress_layout = QHBoxLayout()
self.rects = []
for _ in range(24):
for _ in range(28):
rect = QFrame()
rect.setFixedSize(10, 18)
rect.setStyleSheet("background-color: white; border: 1px solid gray;")
@@ -4476,7 +4510,7 @@ class GroupBrainViewerWidget(FlaresBaseWidget):
class ViewerLauncherWidget(QWidget):
def __init__(self, haemo_dict, config_dict, fig_bytes_dict, cha_dict, contrast_results_dict, df_ind, design_matrix, epochs_dict):
super().__init__()
self.setWindowTitle("Viewer Launcher")
self.setWindowTitle(f"Viewer Launcher - {APP_NAME.upper()}")
group_dict = {
file_path: config.get("GROUP", "Unknown") # default if GROUP missing