Source code for quicknxs.ui.compare_plots
# -*- coding: utf-8 -*-
# pylint: disable=bare-except
"""
Widget to compare different reflectivities.
"""
import logging
import os
import sys
import matplotlib.pyplot as plt
import numpy as np
from PyQt5 import QtCore, QtGui, QtWidgets
from quicknxs.interfaces import load_ui
from quicknxs.interfaces.data_handling.processing_workflow import ProcessingWorkflow
[docs]
class CompareWidget(QtWidgets.QWidget):
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):
"""
Read data file
:param str file_path: file to load
"""
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(QtGui.QColor("#ffffff"))
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()