#!/usr/bin/env python3 from matplotlib.backends.backend_qt5agg import\ FigureCanvasQTAgg as FigureCanvas from matplotlib.figure import Figure from PyQt5 import QtCore from PyQt5 import QtWidgets from PyQt5 import QtGui from PyQt5 import QtPrintSupport import matplotlib import numpy as np import prasopes.datatools as dt import prasopes.graphtools as gt import prasopes.filetools as ft import prasopes.config as cf import prasopes.drltools as drl import os.path import logging matplotlib.use("Qt5Agg") logger = logging.getLogger('reactivityLogger') def update_parselect(augCanvas, parselect): index = parselect.currentIndex() if index == -1: index = cf.settings().value("reactivity/index", type=int) parlist = [ ": ".join([str(i), j]) for i,j in enumerate(augCanvas.ms['params'][0])] parselect.clear() parselect.addItems(parlist) if index <= len(parlist): parselect.setCurrentIndex(index) def pop_dial(augCanvas, drls, graph, labels, parselect, coef1, coef2): logger.debug("populating reactivity dialog") # Do not do anything when data set is not populated if len(augCanvas.ds) == 0: return update_parselect(augCanvas, parselect) graph.clear() gt.pop_plot([0], [0], graph, labels) names, times, intensities = drl.get_daughterset(augCanvas.ds, drls) if len(names) < 2: return params = augCanvas.ms['params'][1] parlen = len(params) pressures = [] lastpos = 0 for time in times: toavg = [] for i in range(lastpos,parlen): if float(params[i][0]) == time: toavg.append((float(params[i][parselect.currentIndex()]) -coef1.value())*coef2.value()) lastpos = i elif float(params[i][0]) > time and i > 0: # i>0 condition to handle possibility of invalid first scan. # (was observed in-wild on TSQ once) break if len(toavg) != 0: pressures.append([time, np.average(toavg)]) if len(pressures) == 0: QtWidgets.QMessageBox.critical(None, "No times loaded", "Did not located any valid parameters.\n" "It is either start of the acquisition,\n" "or the timestamps has been corrupted.") return nptpressures = np.asarray(pressures).T[0] goodtimes = np.where([t in nptpressures for t in times]) for i in range(1,len(intensities)): relint = np.divide(intensities[i], np.clip(np.sum( intensities, 0), np.finfo(np.float32).eps, None), dtype=np.float64) graph.plot(np.asarray(pressures).T[1], relint[goodtimes], label=names[i], color=(gt.colors[i % len(gt.colors)] / 255), marker=".", markersize=2, linestyle="None") graph.autoscale(True) graph.figure.canvas.draw() def main_window(parent, augCanvas, update_signal, drls): """constructs a dialog window""" reactlabels = dict(name="", xlabel="pressure (mT)", ylabel="rel intensity") def onclose(widget, event, update_fnc): logger.debug("ZCE window custom close routine called") update_signal.signal.disconnect(update_fnc) QtWidgets.QDialog.closeEvent(widget, event) def update_fnc(): pop_dial(augCanvas, drls, dialspect, reactlabels, parselect, coef1, coef2) dial_widget = QtWidgets.QDialog( parent, windowTitle='TSQ reactivity interpreter') dial_widget.closeEvent = lambda event: onclose( dial_widget, event, update_fnc) update_signal.signal.connect(update_fnc) dial_graph = Figure(figsize=(5, 2), dpi=100, facecolor="None") dialspect = dial_graph.add_subplot(111, facecolor=(1, 1, 1, 0.8)) graph_canvas = FigureCanvas(dial_graph) graph_canvas.setStyleSheet("background-color:transparent;") graph_canvas.setAutoFillBackground(False) gt.zoom_factory(dialspect, 1.15, reactlabels) gt.pan_factory(dialspect, reactlabels) parlabel = QtWidgets.QLabel("Parameter: ") parselect = QtWidgets.QComboBox() parselect.currentIndexChanged.connect(lambda x: cf.settings().setValue("reactivity/index", x)) formula = QtWidgets.QLabel( "Formula for the x-axis: (Parameter - a) * b") label1 = QtWidgets.QLabel("a: ", alignment=130) coef1 = QtWidgets.QDoubleSpinBox( decimals=4, minimum=float("-inf"), maximum=float("inf")) coef1.setValue(cf.settings().value("reactivity/coef1", type=float)) coef1.valueChanged.connect(lambda x: cf.settings().setValue("reactivity/coef1", x)) label2 = QtWidgets.QLabel("b: ", alignment=130) coef2 = QtWidgets.QDoubleSpinBox( decimals=4, minimum=float("-inf"), maximum=float("inf")) coef2.setValue(cf.settings().value("reactivity/coef2", type=float)) coef2.valueChanged.connect(lambda x: cf.settings().setValue("reactivity/coef2", x)) pushbtn = QtWidgets.QPushButton("Recalculate") pushbtn.clicked.connect(lambda: pop_dial( augCanvas, drls, dialspect, reactlabels, parselect, coef1, coef2)) param_layout = QtWidgets.QHBoxLayout() [param_layout.addWidget(i) for i in [parlabel, parselect]] param_layout.addStretch() coef_layout = QtWidgets.QHBoxLayout() for i in [label1, coef1, label2, coef2]: coef_layout.addWidget(i) dial_layout = QtWidgets.QVBoxLayout(dial_widget) dial_layout.addWidget(graph_canvas) dial_layout.addLayout(param_layout) dial_layout.addWidget(formula) dial_layout.addLayout(coef_layout) dial_layout.addWidget(pushbtn) dial_widget.setFocus() dial_widget.show() pop_dial(augCanvas, drls, dialspect, reactlabels, parselect, coef1, coef2)