small rewrite to impose dry principles
This commit is contained in:
1 parent
ffa14693b3
commit
12afc5d3bc
14 files changed
+1825
-1716
No files matched your search
@@ -0,0 +1,123 @@
|
||||
"""
|
||||
Filename: exporttocsv.py
|
||||
Description: Logic for the Export To CSV analysis window
|
||||
|
||||
Author: Tyler de Zeeuw
|
||||
License: GPL-3.0
|
||||
"""
|
||||
|
||||
# Built-in imports
|
||||
import os
|
||||
|
||||
# External library imports
|
||||
import numpy as np
|
||||
import pandas as pd
|
||||
|
||||
from PySide6.QtWidgets import QFileDialog, QMessageBox
|
||||
|
||||
from src.shared.flaresbasewidget import CSVUIMixin, FlaresBaseWidget
|
||||
from src.shared.shareddata import APP_NAME
|
||||
|
||||
|
||||
class ExportToCSVWidget(CSVUIMixin, FlaresBaseWidget):
|
||||
def __init__(self, haemo_dict, cha_dict, df_ind, design_matrix, group, contrast_results_dict):
|
||||
super().__init__("ExportToCSV")
|
||||
self.setWindowTitle(f"Export To CSV Viewer - {APP_NAME.upper()}")
|
||||
self.haemo_dict = haemo_dict
|
||||
self.cha_dict = cha_dict
|
||||
self.df_ind = df_ind
|
||||
self.design_matrix = design_matrix
|
||||
self.group = group
|
||||
self.contrast_results_dict = contrast_results_dict
|
||||
|
||||
self.setup_csv_ui(["0 (Export Data to CSV)", "1 (CSV for SPARKS)",])
|
||||
|
||||
|
||||
def process_request(self):
|
||||
# TODO: Move this into flares for the call?
|
||||
selected_display_names = self._get_checked_items(self.participant_dropdown)
|
||||
selected_file_paths = []
|
||||
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:
|
||||
selected_file_paths.append(fp)
|
||||
break
|
||||
|
||||
selected_indexes = [
|
||||
int(s.split(" ")[0]) for s in self._get_checked_items(self.image_index_dropdown)
|
||||
]
|
||||
|
||||
if not selected_file_paths or not selected_indexes:
|
||||
QMessageBox.warning(self, "Selection Missing", "Please select at least one participant and one export type.")
|
||||
return
|
||||
|
||||
# 2. ASK ONCE: Select Output Directory
|
||||
output_dir = QFileDialog.getExistingDirectory(self, "Select Output Folder for CSV Exports")
|
||||
|
||||
if not output_dir:
|
||||
print("Export cancelled: No folder selected.")
|
||||
return
|
||||
|
||||
success_count = 0
|
||||
|
||||
# Pass the necessary arguments to each method
|
||||
for file_path in selected_file_paths:
|
||||
base_filename = os.path.splitext(os.path.basename(file_path))[0]
|
||||
haemo_obj = self.haemo_dict.get(file_path)
|
||||
if haemo_obj is None:
|
||||
continue
|
||||
|
||||
cha = self.cha_dict.get(file_path)
|
||||
|
||||
for idx in selected_indexes:
|
||||
try:
|
||||
if idx == 0:
|
||||
save_path = os.path.join(output_dir, f"{base_filename}_exported.csv")
|
||||
if cha is not None:
|
||||
cha.to_csv(save_path)
|
||||
success_count += 1
|
||||
|
||||
|
||||
elif idx == 1:
|
||||
# SPARKS Export
|
||||
save_path = os.path.join(output_dir, f"{base_filename}_sparks.csv")
|
||||
if haemo_obj is not None:
|
||||
raw = haemo_obj
|
||||
data, times = raw.get_data(return_times=True)
|
||||
ann_col = np.full(times.shape, "", dtype=object)
|
||||
|
||||
if raw.annotations is not None and len(raw.annotations) > 0:
|
||||
for onset, duration, desc in zip(
|
||||
raw.annotations.onset,
|
||||
raw.annotations.duration,
|
||||
raw.annotations.description
|
||||
):
|
||||
mask = (times >= onset) & (times < onset + duration)
|
||||
ann_col[mask] = desc
|
||||
|
||||
df = pd.DataFrame(data.T, columns=raw.ch_names)
|
||||
df.insert(0, "annotation", ann_col)
|
||||
df.insert(0, "time", times)
|
||||
df.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(
|
||||
# parent=self,
|
||||
# mode=EventUpdateMode.WRITE_JSON,
|
||||
# caller="Video Alignment Tool"
|
||||
# )
|
||||
# win.show()
|
||||
|
||||
Reference in new issue
Block a user