Source code for quicknxs.ui.compare_plots
# -*- coding: utf-8 -*-
# pylint: disable=bare-except
import logging
import os
import sys
import matplotlib.pyplot as plt
import numpy as np
from qtpy import QtCore, QtGui, QtWidgets
from quicknxs.config.gui import QColors
from quicknxs.interfaces import load_ui
from quicknxs.interfaces.data_handling.processing_workflow import ProcessingWorkflow
[docs]
class CompareWidget(QtWidgets.QWidget):
"""Widget to compare different reflectivities."""
changing_table = False
def __init__(self, parent):
QtWidgets.QWidget.__init__(self, parent)
self._refl_color_map = plt.get_cmap("Set1")
self.ui = load_ui("ui_compare_widget.ui", self)
self.ui.compareList.verticalHeader().sectionMoved.connect(self.draw)
self.file_paths = {}
self.settings = QtCore.QSettings(".quicknxs")
current_dir = self.settings.value("current_directory", os.path.expanduser("~"))
self.active_folder = self.settings.value("compare_directory", current_dir)
self.data_manager = None
self.refl_data = None
self.show_preview = False
[docs]
def refl_preview(self, checked=True):
"""Call-back method for when the user toggles the preview check box."""
self.show_preview = checked
if checked:
self.update_preview()
self.draw()
[docs]
def update_preview(self):
"""Update the preview data."""
if self.data_manager:
workflow = ProcessingWorkflow(self.data_manager)
self.refl_data = workflow.get_output_data()
self.draw()
[docs]
def open_file(self):
"""Show Open-File dialog."""
filter_ = "Reflectivity (*.dat *.txt);;All (*.*)"
names, _ = QtWidgets.QFileDialog.getOpenFileNames(
self, "Open reflectivity file...", directory=self.active_folder, filter=filter_
)
if names:
self.active_folder = os.path.abspath(os.path.dirname(names[0]))
self.settings.setValue("compare_directory", self.active_folder)
for name in names:
self.read_file(name)
self.ui.compareList.resizeColumnToContents(1)
self.ui.compareList.resizeColumnToContents(2)
self.draw()
# Make sure the Open button is reset
self.ui.pushButton_2.setDown(False)
[docs]
def read_file(self, file_path: str):
"""Read a data file."""
label = os.path.basename(file_path)
idx = self.ui.compareList.rowCount()
# Find a color
color_skip = 30
color_offset = int(idx / 255.0 * color_skip / 2.0)
color_id = (color_skip * idx + color_offset) % 255
color = "#" + "".join([r"%02x" % int(f * 255) for f in self._refl_color_map(color_id)[:-1]])
self.changing_table = True
self.ui.compareList.setRowCount(idx + 1)
item = QtWidgets.QTableWidgetItem(label)
item.setFlags(QtCore.Qt.ItemIsEnabled)
# Check that we can read the file
data = np.loadtxt(file_path, comments="#").transpose()
if len(data) == 0:
plotlabel = "Empty file"
else:
try:
plotlabel = label.split("REF_M_", 1)[1]
plotlabel = plotlabel.split("_Specular")[0] + " " + plotlabel.split("Specular_")[1].split(".")[0]
except:
plotlabel = label
self.ui.compareList.setItem(idx, 0, item)
item = QtWidgets.QTableWidgetItem(color)
item.setBackground(QtGui.QColor(color))
item.setForeground(QColors.white)
item.setFlags(QtCore.Qt.ItemIsEnabled)
self.ui.compareList.setItem(idx, 1, item)
self.ui.compareList.setItem(idx, 2, QtWidgets.QTableWidgetItem(plotlabel))
self.file_paths[label] = os.path.abspath(file_path)
self.changing_table = False
[docs]
def clear_plot(self):
"""Remove all current plotted data."""
self.ui.compareList.setRowCount(0)
self.draw()
[docs]
def clear_item(self):
"""Remove all current plotted data."""
logging.error(self.ui.compareList.currentRow())
item_id = self.ui.compareList.currentRow()
if item_id >= 0:
self.ui.compareList.removeRow(item_id)
self.draw()
[docs]
def draw(self):
"""Draw data."""
if self.changing_table:
return
try:
self.ui.comparePlot.clear()
if self.show_preview and self.refl_data:
pol_states = self.refl_data["cross_sections"].keys()
for key in pol_states:
_data = self.refl_data[key]
data = _data.T
self.ui.comparePlot.errorbar(data[0], data[1], data[2], capsize=1, label=key)
header = self.ui.compareList.verticalHeader()
for i in range(self.ui.compareList.rowCount()):
idx = header.logicalIndex(i)
name = self.file_paths[self.ui.compareList.item(idx, 0).text()]
label = self.ui.compareList.item(idx, 2).text()
color = self.ui.compareList.item(idx, 1).text()
data = np.loadtxt(name, comments="#").transpose()
if len(data) == 0:
logging.error("No data for %s", name)
continue
self.ui.comparePlot.errorbar(data[0], data[1], data[2], capsize=1, label=label, color=color)
if self.refl_data or self.ui.compareList.rowCount() > 0:
self.ui.comparePlot.legend(frameon=False)
self.ui.comparePlot.canvas.ax.set_yscale("log")
self.ui.comparePlot.set_xlabel("Q$_z$ [Å$^{-1}$]")
self.ui.comparePlot.set_ylabel("R")
self.ui.comparePlot.draw()
except:
logging.error("CompareDialog: %s", sys.exc_info()[1])
[docs]
def edit_cell(self, row, column):
"""Cell editing call-back. Deal with color picking."""
if column == 1:
color_item = self.ui.compareList.item(row, column)
color = QtGui.QColor(color_item.text())
result = QtWidgets.QColorDialog.getColor(initial=color, parent=self)
if result.isValid():
color_item.setText(result.name())
color_item.setBackground(result)
[docs]
class CompareDialog(QtWidgets.QDialog):
"""A simple dialog window with a CompareWidget."""
def __init__(self, *args, **kwargs):
QtWidgets.QDialog.__init__(self, *args, **kwargs)
self.setWindowTitle("Reflectivity comparison")
self.cw = CompareWidget(self)
vbox = QtWidgets.QVBoxLayout(self)
vbox.addWidget(self.cw)
self.setLayout(vbox)
self.layout()