mainly whitespace, but also some generic qol improvements
This commit is contained in:
1 parent
2a5e3f5606
commit
3a8ffbdf70
26 files changed
+1871
-1224
No files matched your search
+80
-78
@@ -12,6 +12,7 @@ import os
|
||||
from typing import Any
|
||||
|
||||
# External library imports
|
||||
from mne import Epochs
|
||||
from pandas import DataFrame
|
||||
|
||||
from mne.io.base import BaseRaw
|
||||
@@ -25,8 +26,9 @@ from src.shared.shareddata import APP_NAME
|
||||
|
||||
class ExportToCSVWidget(CSVUIMixin, FlaresBaseWidget):
|
||||
def __init__(
|
||||
self,
|
||||
haemo_dict: dict[str, BaseRaw],
|
||||
self,
|
||||
haemo_dict: dict[str, BaseRaw],
|
||||
epochs_dict: dict[str, Epochs],
|
||||
cha_dict: dict[str, DataFrame],
|
||||
df_ind_dict: dict[str, DataFrame],
|
||||
design_matrix_dict: dict[str, DataFrame],
|
||||
@@ -36,10 +38,11 @@ class ExportToCSVWidget(CSVUIMixin, FlaresBaseWidget):
|
||||
fir_feature_dict: dict[str, dict[str, Any]],
|
||||
qc_dict: dict[str, dict[str, Any]],
|
||||
) -> None:
|
||||
|
||||
|
||||
super().__init__("ExportToCSV")
|
||||
self.setWindowTitle(f"Export To CSV Viewer - {APP_NAME.upper()}")
|
||||
self.haemo_dict = haemo_dict
|
||||
self.epochs_dict = epochs_dict
|
||||
self.cha_dict = cha_dict
|
||||
self.df_ind_dict = df_ind_dict
|
||||
self.design_matrix = design_matrix_dict
|
||||
@@ -48,20 +51,19 @@ class ExportToCSVWidget(CSVUIMixin, FlaresBaseWidget):
|
||||
self.config_dict = config_dict
|
||||
self.fir_feature_dict = fir_feature_dict
|
||||
self.qc_dict = qc_dict
|
||||
|
||||
|
||||
self.setup_csv_ui(["0 (Export Data to CSV)", "1 (CSV for SPARKS)", "2 (Export Configuration to CSV)", "3 (Paragraph of Configuration)", "4 (Export FIR Waveform Features to CSV)",
|
||||
"5 (Export Quality Control Metrics to CSV)",
|
||||
"6 (Export Master Consolidated Matrix [All Participants into 1 CSV])"
|
||||
"5 (Export Quality Control Metrics to CSV)", "6 (Export Master Consolidated Matrix [All Participants into 1 CSV])"
|
||||
])
|
||||
|
||||
|
||||
|
||||
|
||||
def process_request(self):
|
||||
selected_display_names = self._get_checked_items(self.participant_dropdown)
|
||||
selected_file_paths: list[str] = []
|
||||
for display_name in selected_display_names:
|
||||
for fp, short_label in self.participant_map.items():
|
||||
expected_display = f"{short_label} ({os.path.basename(fp)})"
|
||||
if display_name == expected_display:
|
||||
if display_name == expected_display:
|
||||
selected_file_paths.append(fp)
|
||||
break
|
||||
|
||||
@@ -74,7 +76,7 @@ class ExportToCSVWidget(CSVUIMixin, FlaresBaseWidget):
|
||||
return
|
||||
|
||||
output_dir = QFileDialog.getExistingDirectory(self, "Select Output Folder for CSV Exports")
|
||||
|
||||
|
||||
if not output_dir:
|
||||
print("Export cancelled: No folder selected.")
|
||||
return
|
||||
@@ -120,78 +122,78 @@ class ExportToCSVWidget(CSVUIMixin, FlaresBaseWidget):
|
||||
magic_string = self.gen_magic_str(first_params)
|
||||
self.placeholder_label.setText(magic_string)
|
||||
|
||||
# elif idx == 4:
|
||||
# # FIR Waveform Features Export
|
||||
# fir_data = self.fir_feature_dict.get(file_path)
|
||||
# if fir_data and isinstance(fir_data, dict):
|
||||
# names = fir_data.get("feature_names", [])
|
||||
# vals = fir_data.get("features", [])
|
||||
# chans = fir_data.get("feature_channels", [])
|
||||
elif idx == 4:
|
||||
# FIR Waveform Features Export
|
||||
fir_data = self.fir_feature_dict.get(file_path)
|
||||
if fir_data:
|
||||
names = fir_data.get("feature_names", [])
|
||||
vals = fir_data.get("features", [])
|
||||
chans = fir_data.get("feature_channels", [])
|
||||
|
||||
# fir_df = DataFrame({
|
||||
# "Feature_Name": names,
|
||||
# "Channel": chans if len(chans) == len(names) else ["N/A"] * len(names),
|
||||
# "Value": vals
|
||||
# })
|
||||
# save_path = os.path.join(output_dir, f"{base_filename}_fir_features.csv")
|
||||
# fir_df.to_csv(save_path, index=False)
|
||||
# success_count += 1
|
||||
fir_df = DataFrame({
|
||||
"Feature_Name": names,
|
||||
"Channel": chans if len(chans) == len(names) else ["N/A"] * len(names),
|
||||
"Value": vals
|
||||
})
|
||||
save_path = os.path.join(output_dir, f"{base_filename}_fir_features.csv")
|
||||
fir_df.to_csv(save_path, index=False)
|
||||
success_count += 1
|
||||
|
||||
# elif idx == 5:
|
||||
# # Quality Control (QC) Metrics Export
|
||||
# qc_data = self.qc_dict.get(file_path)
|
||||
# if qc_data and isinstance(qc_data, dict):
|
||||
# qc_df = DataFrame(list(qc_data.items()), columns=["Metric", "Value"])
|
||||
# save_path = os.path.join(output_dir, f"{base_filename}_qc_metrics.csv")
|
||||
# qc_df.to_csv(save_path, index=False)
|
||||
# success_count += 1
|
||||
elif idx == 5:
|
||||
# Quality Control (QC) Metrics Export
|
||||
qc_data = self.qc_dict.get(file_path)
|
||||
if qc_data and isinstance(qc_data, dict):
|
||||
qc_df = DataFrame(list(qc_data.items()), columns=["Metric", "Value"])
|
||||
save_path = os.path.join(output_dir, f"{base_filename}_qc_metrics.csv")
|
||||
qc_df.to_csv(save_path, index=False)
|
||||
success_count += 1
|
||||
|
||||
# elif idx == 6:
|
||||
# # Master Consolidated Matrix (1 single CSV combining all selected participants)
|
||||
# save_path = os.path.join(output_dir, f"{APP_NAME}_master_consolidated.csv")
|
||||
# if not os.path.exists(save_path):
|
||||
# master_rows: list[dict[str, Any]] = []
|
||||
# for fp in selected_file_paths:
|
||||
# abs_path = os.path.abspath(fp)
|
||||
# grp = self.group_dict.get(fp, "Unknown")
|
||||
# row: dict[str, Any] = {"Participant": abs_path, "Group": grp}
|
||||
elif idx == 6:
|
||||
# Master Consolidated Matrix (1 single CSV combining all selected participants)
|
||||
save_path = os.path.join(output_dir, f"{APP_NAME}_master_consolidated.csv")
|
||||
if not os.path.exists(save_path):
|
||||
master_rows: list[dict[str, Any]] = []
|
||||
for fp in selected_file_paths:
|
||||
abs_path = os.path.abspath(fp)
|
||||
grp = self.group_dict.get(fp, "Unknown")
|
||||
row: dict[str, Any] = {"Participant": abs_path, "Group": grp}
|
||||
|
||||
# # QC Metrics
|
||||
# qc_info = self.qc_dict.get(fp, {})
|
||||
# if isinstance(qc_info, dict):
|
||||
# for mk, mv in qc_info.items():
|
||||
# row[f"QC_{mk}"] = mv
|
||||
# QC Metrics
|
||||
qc_info = self.qc_dict.get(fp, {})
|
||||
if isinstance(qc_info, dict):
|
||||
for mk, mv in qc_info.items():
|
||||
row[f"QC_{mk}"] = mv
|
||||
|
||||
# # FIR Features
|
||||
# fir_info = self.fir_feature_dict.get(fp, {})
|
||||
# print("1")
|
||||
# if isinstance(fir_info, dict):
|
||||
# print("2")
|
||||
# f_names = fir_info.get("feature_names", [])
|
||||
# f_vals = fir_info.get("features", [])
|
||||
# print("3")
|
||||
# if len(f_names) == len(f_vals):
|
||||
# print("4")
|
||||
# for fn, fv in zip(f_names, f_vals):
|
||||
# row[f"FIR_{fn}"] = fv
|
||||
# FIR Features
|
||||
fir_info = self.fir_feature_dict.get(fp, {})
|
||||
print("1")
|
||||
if isinstance(fir_info, dict):
|
||||
print("2")
|
||||
f_names = fir_info.get("feature_names", [])
|
||||
f_vals = fir_info.get("features", [])
|
||||
print("3")
|
||||
if len(f_names) == len(f_vals):
|
||||
print("4")
|
||||
for fn, fv in zip(f_names, f_vals):
|
||||
row[f"FIR_{fn}"] = fv
|
||||
|
||||
# master_rows.append(row)
|
||||
master_rows.append(row)
|
||||
|
||||
# if master_rows:
|
||||
# df_master = DataFrame(master_rows)
|
||||
# df_master.to_csv(save_path, index=False)
|
||||
# success_count += 1
|
||||
if master_rows:
|
||||
df_master = DataFrame(master_rows)
|
||||
df_master.to_csv(save_path, index=False)
|
||||
success_count += 1
|
||||
|
||||
else:
|
||||
print(f"No method defined for index {idx}")
|
||||
|
||||
|
||||
except Exception as e:
|
||||
print(f"Failed to export {file_path} (Type {idx}): {e}")
|
||||
|
||||
# 4. Final Notification
|
||||
if success_count > 0:
|
||||
QMessageBox.information(self, "Export Complete", f"Successfully saved {success_count} CSV files to:\n{output_dir}")
|
||||
|
||||
|
||||
# # If SPARKS export was included, show the Event Window once at the end
|
||||
# if 1 in selected_indexes:
|
||||
# win = UpdateEventsWindow(
|
||||
@@ -203,62 +205,62 @@ class ExportToCSVWidget(CSVUIMixin, FlaresBaseWidget):
|
||||
|
||||
|
||||
def gen_magic_str(self, all_params: dict[str, str]) -> str:
|
||||
|
||||
|
||||
magic_str = "To start, the data was loaded into the application. "
|
||||
if all_params['DOWNSAMPLE']:
|
||||
magic_str += f"The data was downsampled to {all_params['DOWNSAMPLE_FREQUENCY']}hz. "
|
||||
else:
|
||||
magic_str += "The data was not downsampled and was retained at its original sampling frequency. "
|
||||
|
||||
|
||||
if all_params['TRIM']:
|
||||
magic_str += f"The data was then trimmed to only keep {all_params['SECONDS_TO_KEEP']} seconds before the first event, as the earlier data with no events would not be needed. "
|
||||
else:
|
||||
magic_str += "The data was not trimmed and was retained at its original length. "
|
||||
|
||||
|
||||
if all_params['OPTODE_PLACEMENT']:
|
||||
magic_str += f"A visualization check of the optode locations in 3D space was performed to ensure that they were at the correct location. "
|
||||
|
||||
|
||||
if all_params['SHORT_CHANNELS']:
|
||||
magic_str += f"A short channel(s) was specified with the maximum length of a short channel being {all_params['SHORT_CHANNELS_THRESHOLD']} metres. Channels that were over this distance but under {all_params['LONG_CHANNELS_THRESHOLD']} metres were retained. "
|
||||
else:
|
||||
magic_str += f"No short channel was specified. Channels between the lengths of {all_params['SHORT_CHANNELS_THRESHOLD']} and {all_params['LONG_CHANNELS_THRESHOLD']} meters were used with all other channles being discarded. "
|
||||
|
||||
|
||||
if all_params['HEART_RATE']:
|
||||
magic_str += f"The heart rate of the participant was attempted to be calculated. {all_params['SECONDS_TO_STRIP_HR']} seconds were ignored from the start of the file to avoid motion artifacts. "
|
||||
magic_str += f"The heart rate had hard limits of {all_params['MAX_LOW_HR']} to {all_params['MAX_HIGH_HR']} and was smoothed across {all_params['SMOOTHING_WINDOW_HR']} samples. "
|
||||
else:
|
||||
magic_str += "The heart rate of the participants was not attempted to be calculated. "
|
||||
|
||||
|
||||
if all_params['SCI']:
|
||||
magic_str += f"The Scalp Coupling Index was calculated over {all_params['SCI_TIME_WINDOW']} second windows. The threshold value was {all_params['SCI_THRESHOLD']}. "
|
||||
else:
|
||||
magic_str += "Scalp Coupling Index was not used. "
|
||||
|
||||
|
||||
if all_params['SNR']:
|
||||
magic_str += f"The Signal to Noise Ratio was calculated. The threshold value was set to {all_params['SNR_THRESHOLD']}db. "
|
||||
else:
|
||||
magic_str += "The Signal to Noise Ratio was not used. "
|
||||
|
||||
|
||||
if all_params['PSP']:
|
||||
magic_str += f"Peak Spectral Power was calculated over {all_params['PSP_TIME_WINDOW']} second windows. The threshold value was {all_params['PSP_THRESHOLD']}. "
|
||||
else:
|
||||
magic_str += "Peak Spectral Power was not used. "
|
||||
|
||||
|
||||
if all_params['COEFF_VAR']:
|
||||
magic_str += f"The Coefficient of Variation was calculated. The threshold value was set to {all_params['COEFF_VAR_THRESHOLD']}. "
|
||||
else:
|
||||
magic_str += "The Coefficient of Variation was not used. "
|
||||
|
||||
|
||||
if all_params['MAD']:
|
||||
magic_str += f"Median Absolute Deviation was calculated. The threshold value was set to {all_params['MAD_THRESHOLD']}. "
|
||||
else:
|
||||
magic_str += "Median Absolute Deviation was not used. "
|
||||
|
||||
|
||||
if all_params['PSD_NOISE']:
|
||||
magic_str += f"Power Spectral Density Noise was calculated with a target frequency divisor of {all_params['TARGET_FREQ_DIV']} and a decibal limit of {all_params['DB_LIMIT']}. "
|
||||
else:
|
||||
magic_str += f"Power Spectral Density Noise was not used. "
|
||||
|
||||
|
||||
magic_str += "More coming soon."
|
||||
|
||||
return magic_str
|
||||
Reference in new issue
Block a user