GUI: Save fluorescence scan as CSV

This commit is contained in:
2025-12-05 11:17:33 +01:00
parent 49ad78bc58
commit 2f95d522f0
+46 -4
View File
@@ -38,6 +38,13 @@ class FluorescencePanel(QWidget):
self.chart_view.setRenderHint(QPainter.Antialiasing)
grid.addWidget(self.chart_view, 0, 0)
# Enable context menu on chart view
self.chart_view.setContextMenuPolicy(Qt.CustomContextMenu)
self.chart_view.customContextMenuRequested.connect(self._show_context_menu)
self._last_x_keV = None
self._last_y_counts = None
# Average dead time label
self.avg_dead_label = QLabel("Average dead time: -")
self.avg_dead_label.setAlignment(Qt.AlignLeft)
@@ -104,6 +111,39 @@ class FluorescencePanel(QWidget):
logger.debug(f"eventFilter error: {e}")
return False
def _show_context_menu(self, pos):
try:
from PySide6.QtWidgets import QMenu, QFileDialog
menu = QMenu(self.chart_view)
act_save_csv = menu.addAction("Save spectrum as CSV...")
global_pos = self.chart_view.mapToGlobal(pos)
action = menu.exec(global_pos)
if action == act_save_csv:
if self.series.count() == 0:
logger.info("No data to save.")
return
# Prefer cached arrays; fall back to reading from series
x_vals = self._last_x_keV
y_vals = self._last_y_counts
if x_vals is None or y_vals is None or len(x_vals) != self.series.count():
x_vals = [self.series.at(i).x() for i in range(self.series.count())]
y_vals = [self.series.at(i).y() for i in range(self.series.count())]
path, _ = QFileDialog.getSaveFileName(self, "Save Spectrum CSV", "spectrum.csv", "CSV files (*.csv)")
if not path:
return
try:
import csv
with open(path, "w", newline="") as f:
writer = csv.writer(f)
writer.writerow(["Energy_keV", "Counts"])
for x, y in zip(x_vals, y_vals):
writer.writerow([f"{x:.6f}", f"{y:.6f}"])
logger.info(f"Spectrum saved to {path}")
except Exception as e:
logger.error(f"Failed to save CSV: {e}")
except Exception as e:
logger.error(f"Context menu error: {e}")
def _update_vline(self, x_val: float):
# Draw vertical line spanning current Y axis range at x_val
try:
@@ -145,11 +185,13 @@ class FluorescencePanel(QWidget):
self._marker.setVisible(False)
self._vline.setVisible(False)
self._vline.clear()
self._last_x_keV = None
self._last_y_counts = None
# Update average dead time label (if provided)
try:
if hasattr(f, "average_dead_time") and f.average_dead_time is not None:
self.avg_dead_label.setText(f"Average dead time: {f.average_dead_time*100.0:.3f}%")
self.avg_dead_label.setText(f"Average dead time: {f.average_dead_time * 100.0:.3f}%")
else:
self.avg_dead_label.setText("Average dead time: -")
except Exception:
@@ -166,18 +208,18 @@ class FluorescencePanel(QWidget):
order = np.argsort(x)
x = x[order]
y = y[order]
# Cache arrays for export
self._last_x_keV = x.tolist()
self._last_y_counts = y.tolist()
# Append data
for xi, yi in zip(x, y):
self.series.append(float(xi), float(yi))
# Peak info (highest Y)
if y.size:
max_idx = int(np.argmax(y))
peak_keV = float(x[max_idx])
peak_counts = float(y[max_idx])
self.peak_info_label.setText(f"Peak: {peak_keV:.3f} keV, {peak_counts:.3f} counts")
# Axes
xmin = float(np.min(x)) if x.size else -1.0
xmax = float(np.max(x)) if x.size else 1.0