mirror of
https://github.com/rjNemo/xafsManager
synced 2026-06-06 02:36:42 +00:00
Interface v0 done
This commit is contained in:
parent
890e430aae
commit
85a661b417
19 changed files with 23938 additions and 23 deletions
129
.gitignore
vendored
Normal file
129
.gitignore
vendored
Normal file
|
|
@ -0,0 +1,129 @@
|
|||
# Byte-compiled / optimized / DLL files
|
||||
__pycache__/
|
||||
*.py[cod]
|
||||
*$py.class
|
||||
|
||||
# C extensions
|
||||
*.so
|
||||
|
||||
# Distribution / packaging
|
||||
.Python
|
||||
build/
|
||||
develop-eggs/
|
||||
dist/
|
||||
downloads/
|
||||
eggs/
|
||||
.eggs/
|
||||
lib/
|
||||
lib64/
|
||||
parts/
|
||||
sdist/
|
||||
var/
|
||||
wheels/
|
||||
pip-wheel-metadata/
|
||||
share/python-wheels/
|
||||
*.egg-info/
|
||||
.installed.cfg
|
||||
*.egg
|
||||
MANIFEST
|
||||
|
||||
# PyInstaller
|
||||
# Usually these files are written by a python script from a template
|
||||
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
||||
*.manifest
|
||||
*.spec
|
||||
|
||||
# Installer logs
|
||||
pip-log.txt
|
||||
pip-delete-this-directory.txt
|
||||
|
||||
# Unit test / coverage reports
|
||||
htmlcov/
|
||||
.tox/
|
||||
.nox/
|
||||
.coverage
|
||||
.coverage.*
|
||||
.cache
|
||||
nosetests.xml
|
||||
coverage.xml
|
||||
*.cover
|
||||
*.py,cover
|
||||
.hypothesis/
|
||||
.pytest_cache/
|
||||
|
||||
# Translations
|
||||
*.mo
|
||||
*.pot
|
||||
|
||||
# Django stuff:
|
||||
*.log
|
||||
local_settings.py
|
||||
db.sqlite3
|
||||
db.sqlite3-journal
|
||||
|
||||
# Flask stuff:
|
||||
instance/
|
||||
.webassets-cache
|
||||
|
||||
# Scrapy stuff:
|
||||
.scrapy
|
||||
|
||||
# Sphinx documentation
|
||||
docs/_build/
|
||||
|
||||
# PyBuilder
|
||||
target/
|
||||
|
||||
# Jupyter Notebook
|
||||
.ipynb_checkpoints
|
||||
|
||||
# IPython
|
||||
profile_default/
|
||||
ipython_config.py
|
||||
|
||||
# pyenv
|
||||
.python-version
|
||||
|
||||
# pipenv
|
||||
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
|
||||
# However, in case of collaboration, if having platform-specific dependencies or dependencies
|
||||
# having no cross-platform support, pipenv may install dependencies that don't work, or not
|
||||
# install all needed dependencies.
|
||||
#Pipfile.lock
|
||||
|
||||
# PEP 582; used by e.g. github.com/David-OConnor/pyflow
|
||||
__pypackages__/
|
||||
|
||||
# Celery stuff
|
||||
celerybeat-schedule
|
||||
celerybeat.pid
|
||||
|
||||
# SageMath parsed files
|
||||
*.sage.py
|
||||
|
||||
# Environments
|
||||
.env
|
||||
.venv
|
||||
env/
|
||||
venv/
|
||||
ENV/
|
||||
env.bak/
|
||||
venv.bak/
|
||||
|
||||
# Spyder project settings
|
||||
.spyderproject
|
||||
.spyproject
|
||||
|
||||
# Rope project settings
|
||||
.ropeproject
|
||||
|
||||
# mkdocs documentation
|
||||
/site
|
||||
|
||||
# mypy
|
||||
.mypy_cache/
|
||||
.dmypy.json
|
||||
dmypy.json
|
||||
|
||||
# Pyre type checker
|
||||
.pyre/
|
||||
12
EXAFS_Monitor/README.md
Normal file
12
EXAFS_Monitor/README.md
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
# EXAFS_Monitor
|
||||
|
||||
Live EXAFS data plotting ang simple analysis
|
||||
|
||||
Dependencies: pyqtgraph, pyzmq
|
||||
|
||||
|
||||
* monitor_gui_sub.py - plotting, analysis
|
||||
|
||||
* monitor_data_pub.py - data sending
|
||||
|
||||
* .dat - data file examples
|
||||
0
EXAFS_Monitor/__init__.py
Normal file
0
EXAFS_Monitor/__init__.py
Normal file
1036
EXAFS_Monitor/data/CuSO4_01M_flow_0001.dat
Normal file
1036
EXAFS_Monitor/data/CuSO4_01M_flow_0001.dat
Normal file
File diff suppressed because it is too large
Load diff
2207
EXAFS_Monitor/data/CuSO4_01M_flow_0002.dat
Normal file
2207
EXAFS_Monitor/data/CuSO4_01M_flow_0002.dat
Normal file
File diff suppressed because it is too large
Load diff
2392
EXAFS_Monitor/data/CuSO4_01M_flow_0003.dat
Normal file
2392
EXAFS_Monitor/data/CuSO4_01M_flow_0003.dat
Normal file
File diff suppressed because it is too large
Load diff
4246
EXAFS_Monitor/data/CuSO4_01M_flow_0004.dat
Normal file
4246
EXAFS_Monitor/data/CuSO4_01M_flow_0004.dat
Normal file
File diff suppressed because it is too large
Load diff
4218
EXAFS_Monitor/data/CuSO4_01M_flow_0005.dat
Normal file
4218
EXAFS_Monitor/data/CuSO4_01M_flow_0005.dat
Normal file
File diff suppressed because it is too large
Load diff
4250
EXAFS_Monitor/data/CuSO4_01M_flow_0006.dat
Normal file
4250
EXAFS_Monitor/data/CuSO4_01M_flow_0006.dat
Normal file
File diff suppressed because it is too large
Load diff
3927
EXAFS_Monitor/data/CuSO4_01M_flow_0007.dat
Normal file
3927
EXAFS_Monitor/data/CuSO4_01M_flow_0007.dat
Normal file
File diff suppressed because it is too large
Load diff
35
EXAFS_Monitor/monitor_data.py
Normal file
35
EXAFS_Monitor/monitor_data.py
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
#!/usr/bin/env python2
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
@author: murzinv
|
||||
"""
|
||||
|
||||
import zmq
|
||||
from time import sleep
|
||||
|
||||
port = "6400"
|
||||
context = zmq.Context()
|
||||
socket = context.socket(zmq.PUB)
|
||||
socket.bind("tcp://*:%s" % port)
|
||||
socket.setsockopt(zmq.LINGER, 1000)
|
||||
|
||||
n = 5
|
||||
while True:
|
||||
n = n % 7 + 1
|
||||
with open("data/CuSO4_01M_flow_000%d.dat" % n, "r") as f:
|
||||
socket.send_string("test")
|
||||
sleep(0.5)
|
||||
socket.send_string("clear")
|
||||
print(f.name)
|
||||
sleep(0.5)
|
||||
socket.send_string(f.name)
|
||||
f.readlines(15)
|
||||
line = f.readline()
|
||||
while line:
|
||||
splitted = line.split()
|
||||
print(splitted)
|
||||
message = " ".join(
|
||||
[splitted[0], splitted[5], splitted[6], splitted[7], splitted[8]])
|
||||
socket.send_string(message)
|
||||
line = f.readline()
|
||||
sleep(0.05)
|
||||
425
EXAFS_Monitor/monitor_gui.py
Normal file
425
EXAFS_Monitor/monitor_gui.py
Normal file
|
|
@ -0,0 +1,425 @@
|
|||
import zmq
|
||||
import os, sys
|
||||
import numpy as np
|
||||
from scipy.optimize import curve_fit
|
||||
from scipy.interpolate import LSQUnivariateSpline
|
||||
from scipy.ndimage import gaussian_filter1d
|
||||
from scipy.integrate import simps
|
||||
import pyqtgraph as pg
|
||||
from pyqtgraph.Qt import QtCore, QtGui
|
||||
from time import time
|
||||
|
||||
FPS_LIMIT = 10
|
||||
EXAFS_SLOWDOWN_FACTOR = 10
|
||||
|
||||
class ZeroMQ_Listener(QtCore.QObject):
|
||||
message = QtCore.pyqtSignal(list)
|
||||
def __init__(self):
|
||||
QtCore.QObject.__init__(self)
|
||||
self.context = zmq.Context()
|
||||
self.socket = self.context.socket(zmq.SUB)
|
||||
self.socket.connect ("tcp://127.0.0.1:6400")
|
||||
self.socket.setsockopt_string(zmq.SUBSCRIBE, "")
|
||||
self.running = True
|
||||
|
||||
def loop(self):
|
||||
buf = []
|
||||
t0 = time()
|
||||
while self.running:
|
||||
try:
|
||||
string = self.socket.recv()
|
||||
buf.append(string)
|
||||
if time() - t0 > 1./FPS_LIMIT:
|
||||
self.message.emit(buf[:])
|
||||
buf = []
|
||||
t0 = time()
|
||||
except:
|
||||
pass
|
||||
|
||||
def finish(self):
|
||||
self.socket.close()
|
||||
self.context.term()
|
||||
|
||||
|
||||
class EXAFS_Extractor(QtCore.QObject):
|
||||
message = QtCore.pyqtSignal(list)
|
||||
def __init__(self):
|
||||
QtCore.QObject.__init__(self)
|
||||
self.running = True
|
||||
self.pre1 = -150
|
||||
self.pre2 = -50
|
||||
self.post1 = 50
|
||||
|
||||
def victoreen(self, e, c ,d):
|
||||
f = 1.23986e4/e
|
||||
return c*f**3 - d*f**4
|
||||
|
||||
def find_e0_idx(self, e, mu):
|
||||
d = gaussian_filter1d(np.gradient(mu) / np.gradient(e), 3)
|
||||
return np.argmax(d), d
|
||||
|
||||
def pre_edge(self, e, idx, mu):
|
||||
idx1 = np.abs(e[idx] + self.pre1 - e).argmin()
|
||||
idx2 = np.abs(e[idx] + self.pre2 - e).argmin()
|
||||
popt, pcov = curve_fit(self.victoreen, e[idx1:idx2], mu[idx1:idx2])
|
||||
return self.victoreen(e, popt[0], popt[1])
|
||||
|
||||
def post_edge(self, e, idx, mu, pre, kw = 2):
|
||||
# k indexes starts from e0
|
||||
f = 0.262467 # magic number for calculation of k
|
||||
k = np.sqrt(f * (e[idx:]-e[idx]))
|
||||
kmin_idx = np.abs(e[idx] + self.post1 - e).argmin() - idx
|
||||
fun_fit = (mu[idx:] - pre[idx:]) * k**kw
|
||||
n_knots = int(2.0*(k.max() - k.min() ) / np.pi) + 1
|
||||
knots = np.linspace(k[kmin_idx], k[-2], n_knots)
|
||||
spl = LSQUnivariateSpline(k, fun_fit, knots)
|
||||
post = spl(k[kmin_idx:])/(k[kmin_idx:])**kw
|
||||
edge_step = post[0]
|
||||
norm = mu - pre
|
||||
norm[idx + kmin_idx:] += -post + edge_step
|
||||
norm /= edge_step
|
||||
chi = norm[idx:] - 1
|
||||
return k, gaussian_filter1d(chi*k*k, 3)
|
||||
|
||||
def hann_win(self, k, kmin, kmax, dk):
|
||||
win = np.empty_like(k)
|
||||
for i in range (len(k)):
|
||||
if (k[i] < (kmin - 0.5*dk)):
|
||||
win[i] = 0.0
|
||||
elif (k[i] >= (kmin - 0.5*dk)) and (k[i] <= (kmin + 0.5*dk)):
|
||||
win[i] = 0.5*(1.0 - np.cos(np.pi*(k[i] - kmin + 0.5*dk)/dk ) )
|
||||
elif (k[i] > (kmin + 0.5*dk)) and (k[i] < (kmax - 0.5*dk)):
|
||||
win[i] = 1.0
|
||||
elif (k[i] >= (kmax - 0.5*dk)) and (k[i] <= (kmax + 0.5*dk)):
|
||||
win[i] = 0.5*(1.0 + np.cos(np.pi*(k[i] - kmax + 0.5*dk)/dk ) )
|
||||
elif (k[i] >(kmax + 0.5*dk)):
|
||||
win[i] = 0.0
|
||||
return win
|
||||
|
||||
def make_ft(self, k, chi, r):
|
||||
ft_im = np.empty_like(r)
|
||||
ft_re = np.empty_like(r)
|
||||
ft_mag = np.empty_like(r)
|
||||
win = self.hann_win(k, 2.0, max(k) - 1., 1.0)
|
||||
for i in range (len(r)):
|
||||
ft_im[i] = simps (np.sin(2.0*k*r[i])*chi*win, k)
|
||||
ft_re[i] = simps (np.cos(2.0*k*r[i])*chi*win, k)
|
||||
ft_mag[i] = 1.0/np.sqrt(np.pi)*np.sqrt((ft_im[i]*ft_im[i] + ft_re[i]*ft_re[i]))
|
||||
return ft_mag
|
||||
|
||||
def calculate(self, list_data):
|
||||
e, mu1, mu2 = np.array(list_data[0]), np.array(list_data[1]), np.array(list_data[2])
|
||||
e0_idx1, e0_idx2, deriv1, deriv2 = None, None, [], []
|
||||
try:
|
||||
e0_idx1, deriv1 = self.find_e0_idx(e, mu1)
|
||||
pre_edge1 = self.pre_edge(e, e0_idx1, mu1)
|
||||
k1, chi1 = self.post_edge(e, e0_idx1, mu1, pre_edge1)
|
||||
except:
|
||||
k1, chi1 = [], []
|
||||
try:
|
||||
e0_idx2, deriv2 = self.find_e0_idx(e, mu2)
|
||||
pre_edge2 = self.pre_edge(e, e0_idx2, mu2)
|
||||
k2, chi2 = self.post_edge(e, e0_idx2, mu2, pre_edge2)
|
||||
except:
|
||||
k2, chi2 = [], []
|
||||
r1, ft_mag1, r2, ft_mag2 = [], [], [], []
|
||||
if len(k1) > 0:
|
||||
try:
|
||||
r1 = np.arange(0.0, 6.0, 0.02)
|
||||
ft_mag1 = self.make_ft(k1, chi1, r1)
|
||||
except:
|
||||
r1, ft_mag1 = [], []
|
||||
if len(k2) > 0:
|
||||
try:
|
||||
r2 = np.arange(0.0, 6.0, 0.02)
|
||||
ft_mag2 = self.make_ft(k2, chi2, r2)
|
||||
except:
|
||||
r2, ft_mag2 = [], []
|
||||
self.message.emit([e0_idx1, deriv1, k1, chi1, r1, ft_mag1, e0_idx2, deriv2, k2, chi2, r2, ft_mag2, e])
|
||||
|
||||
class MonitorWidget(QtGui.QWidget):
|
||||
message_data = QtCore.pyqtSignal(list)
|
||||
def __init__(self, app):
|
||||
QtGui.QWidget.__init__(self)
|
||||
self.app = app
|
||||
|
||||
self.thread = QtCore.QThread()
|
||||
self.zeromq_listener = ZeroMQ_Listener()
|
||||
self.zeromq_listener.moveToThread(self.thread)
|
||||
self.thread.started.connect(self.zeromq_listener.loop)
|
||||
self.zeromq_listener.message.connect(self.signal_received)
|
||||
QtCore.QTimer.singleShot(0, self.thread.start)
|
||||
|
||||
self.thread2 = QtCore.QThread()
|
||||
self.exafs_extractor = EXAFS_Extractor()
|
||||
self.exafs_extractor.moveToThread(self.thread2)
|
||||
self.exafs_extractor.message.connect(self.update_exafs)
|
||||
self.message_data.connect(self.exafs_extractor.calculate)
|
||||
QtCore.QTimer.singleShot(1, self.thread2.start)
|
||||
|
||||
self.layout = QtGui.QGridLayout()
|
||||
self.pw1 = pg.PlotWidget(title='I0 [counts] / Energy[eV]')
|
||||
self.pw2 = pg.PlotWidget(title='I1 [counts] / Energy[eV]')
|
||||
self.pw3 = pg.PlotWidget(title='I2 [counts] / Energy[eV]')
|
||||
self.pw4 = pg.PlotWidget(title='IP [counts] / Energy[eV]')
|
||||
|
||||
self.hbl = QtGui.QHBoxLayout()
|
||||
self.flabel = QtGui.QLabel("N/A")
|
||||
self.flabel.setStyleSheet("color: #fff")
|
||||
self.fbtn = QtGui.QPushButton("Open data folder")
|
||||
self.fbtn.clicked.connect(self.open_folder)
|
||||
self.fbtn.setSizePolicy(QtGui.QSizePolicy.Maximum, QtGui.QSizePolicy.Maximum)
|
||||
self.fbtn.setStyleSheet('''
|
||||
QPushButton{
|
||||
color: #777; font-family:'Arial';
|
||||
font-weight: bold;
|
||||
font-size:16px;
|
||||
border: 2px solid #777;
|
||||
border-radius: 10px;
|
||||
min-width: 200px;
|
||||
padding: 7px;
|
||||
outline: none;
|
||||
}'''
|
||||
)
|
||||
self.viewlabel = QtGui.QLabel("Currents")
|
||||
self.viewlabel.setAlignment(QtCore.Qt.AlignCenter)
|
||||
self.viewlabel.setStyleSheet('''QLabel{
|
||||
color: #fff; font-family:'Arial';
|
||||
font-weight: bold;
|
||||
font-size:16px;
|
||||
min-width: 200px;
|
||||
max-width: 200px;
|
||||
outline: none;
|
||||
}'''
|
||||
)
|
||||
self.btn = QtGui.QPushButton("Switch to XANES")
|
||||
self.btn.clicked.connect(self.switchView)
|
||||
self.view = 0
|
||||
self.btn.setSizePolicy(QtGui.QSizePolicy.Maximum, QtGui.QSizePolicy.Maximum)
|
||||
self.btn.setStyleSheet('''
|
||||
QPushButton{
|
||||
color: #777; font-family:'Arial';
|
||||
font-weight: bold;
|
||||
font-size:16px;
|
||||
border: 2px solid #777;
|
||||
border-radius: 10px;
|
||||
min-width: 200px;
|
||||
padding: 7px;
|
||||
outline: none;
|
||||
}'''
|
||||
)
|
||||
self.hbl.addWidget(self.fbtn)
|
||||
self.hbl.addWidget(self.flabel)
|
||||
self.hbl.addWidget(self.viewlabel)
|
||||
self.hbl.addWidget(self.btn)
|
||||
self.datafilename = None
|
||||
|
||||
self.layout.addLayout(self.hbl, 0, 0, 1, 2)
|
||||
self.layout.addWidget(self.pw1, 1, 0)
|
||||
self.layout.addWidget(self.pw2, 1, 1)
|
||||
self.layout.addWidget(self.pw3, 2, 0)
|
||||
self.layout.addWidget(self.pw4, 2, 1)
|
||||
self.setLayout(self.layout)
|
||||
self.app = app
|
||||
|
||||
self.counter = 0
|
||||
self.energy = []
|
||||
self.denergy = []
|
||||
self.data_i0 = []
|
||||
self.data_i1 = []
|
||||
self.data_i2 = []
|
||||
self.data_ip = []
|
||||
self.mu = []
|
||||
self.muf = []
|
||||
self.dmu = []
|
||||
self.dmuf = []
|
||||
self.k = []
|
||||
self.kf = []
|
||||
self.chi = []
|
||||
self.chif = []
|
||||
self.r = []
|
||||
self.ft_mag = []
|
||||
self.rf = []
|
||||
self.ft_magf = []
|
||||
self.e0i = None
|
||||
self.e0if = None
|
||||
self.curve1 = self.pw1.plot(self.energy, self.data_i0, pen = "b")
|
||||
self.curve2 = self.pw2.plot(self.energy, self.data_i1, pen = "g")
|
||||
self.curve3 = self.pw3.plot(self.energy, self.data_i2, pen = "r")
|
||||
self.curve4 = self.pw4.plot(self.energy, self.data_ip, pen = "c")
|
||||
self.pen_orchid = pg.mkPen(color=(230, 170, 250))
|
||||
self.pen_lime = pg.mkPen(color=(190, 250, 0))
|
||||
self.text2 = pg.TextItem("", anchor=(0.5, 2))
|
||||
self.arrow2 = pg.ArrowItem(angle=-90)
|
||||
self.text4 = pg.TextItem("", anchor=(0.5, 2))
|
||||
self.arrow4 = pg.ArrowItem(angle=-90)
|
||||
|
||||
def signal_received(self, message_buf):
|
||||
for message in message_buf:
|
||||
if message == "test":
|
||||
pass
|
||||
elif message == "clear":
|
||||
self.counter = 0
|
||||
self.energy = []
|
||||
self.denergy = []
|
||||
self.data_i0 = []
|
||||
self.data_i1 = []
|
||||
self.data_i2 = []
|
||||
self.data_ip = []
|
||||
self.mu = []
|
||||
self.muf = []
|
||||
self.dmu = []
|
||||
self.dmuf = []
|
||||
self.k = []
|
||||
self.chi = []
|
||||
self.kf = []
|
||||
self.chif = []
|
||||
self.r = []
|
||||
self.rf = []
|
||||
self.ft_mag = []
|
||||
self.ft_magf = []
|
||||
self.e0i = None
|
||||
self.e0if = None
|
||||
self.updatePlot()
|
||||
elif (message[-4:] == ".dat") or (message[-4:] == ".nxs"):
|
||||
self.flabel.setText(message)
|
||||
self.datafilename = message
|
||||
else:
|
||||
data = [float(v) for v in message.split()]
|
||||
self.energy.append(data[0])
|
||||
self.data_i0.append(data[1])
|
||||
self.data_i1.append(data[2])
|
||||
self.data_i2.append(data[3])
|
||||
self.data_ip.append(data[4])
|
||||
self.mu.append(np.log(data[1]/data[2]))
|
||||
self.muf.append(data[4]/data[1])
|
||||
self.updatePlot()
|
||||
if not self.counter%EXAFS_SLOWDOWN_FACTOR:
|
||||
self.message_data.emit([self.energy, self.mu, self.muf])
|
||||
self.counter += 1
|
||||
self.app.processEvents()
|
||||
|
||||
def switchView(self):
|
||||
self.view = (self.view + 1)%3
|
||||
if self.view == 0:
|
||||
self.viewlabel.setText("Currents")
|
||||
self.btn.setText("Switch to XANES")
|
||||
self.pw1.setTitle("I0 [counts] / Energy[eV]")
|
||||
self.pw2.setTitle("I1 [counts] / Energy[eV]")
|
||||
self.pw3.setTitle("I2 [counts] / Energy[eV]")
|
||||
self.pw4.setTitle("IP [counts] / Energy[eV]")
|
||||
self.pw2.removeItem(self.text2)
|
||||
self.pw2.removeItem(self.arrow2)
|
||||
self.pw4.removeItem(self.text4)
|
||||
self.pw4.removeItem(self.arrow4)
|
||||
elif self.view == 1:
|
||||
self.viewlabel.setText("XANES")
|
||||
self.btn.setText("Switch to EXAFS")
|
||||
self.pw1.setTitle("mu trans. / Energy[eV]")
|
||||
self.pw2.setTitle("deriv. mu trans. / Energy[eV]")
|
||||
self.pw3.setTitle("mu fluo. / Energy[eV]")
|
||||
self.pw4.setTitle("deriv. mu fluo. / Energy[eV]")
|
||||
elif self.view == 2:
|
||||
self.viewlabel.setText("EXAFS")
|
||||
self.btn.setText("Switch to Currents")
|
||||
self.pw1.setTitle(u"\u03C7" + "(k)*k^2 trans. / k[" + u"\u212B" + "^-1]")
|
||||
self.pw2.setTitle("| FT(" + u"\u03C7" + "(k)*k^2 trans." + ") | / R[" + u"\u212B" + "]")
|
||||
self.pw3.setTitle(u"\u03C7" + "(k)*k^2 fluo. / k[" + u"\u212B" + "^-1]")
|
||||
self.pw4.setTitle("| FT(" + u"\u03C7" + "(k)*k^2 fluo." + ") | / R[" + u"\u212B" + "]")
|
||||
self.pw2.removeItem(self.text2)
|
||||
self.pw2.removeItem(self.arrow2)
|
||||
self.pw4.removeItem(self.text4)
|
||||
self.pw4.removeItem(self.arrow4)
|
||||
|
||||
#https://github.com/pyqtgraph/pyqtgraph/issues/821
|
||||
self.pw1.getAxis('left').textWidth = 0
|
||||
self.pw1.getAxis('left')._updateWidth()
|
||||
self.pw2.getAxis('left').textWidth = 0
|
||||
self.pw2.getAxis('left')._updateWidth()
|
||||
self.pw3.getAxis('left').textWidth = 0
|
||||
self.pw3.getAxis('left')._updateWidth()
|
||||
self.pw4.getAxis('left').textWidth = 0
|
||||
self.pw4.getAxis('left')._updateWidth()
|
||||
|
||||
self.pw1.enableAutoRange()
|
||||
self.pw2.enableAutoRange()
|
||||
self.pw3.enableAutoRange()
|
||||
self.pw4.enableAutoRange()
|
||||
self.updatePlot()
|
||||
|
||||
def updatePlot(self):
|
||||
if self.view == 0:
|
||||
self.curve1.setData(self.energy, self.data_i0)
|
||||
self.curve1.setPen("b")
|
||||
self.curve2.setData(self.energy, self.data_i1)
|
||||
self.curve2.setPen("g")
|
||||
self.curve3.setData(self.energy, self.data_i2)
|
||||
self.curve3.setPen("r")
|
||||
self.curve4.setData(self.energy, self.data_ip)
|
||||
self.curve4.setPen("c")
|
||||
elif self.view == 1:
|
||||
self.curve1.setData(self.energy, self.mu)
|
||||
self.curve1.setPen(self.pen_lime)
|
||||
self.curve2.setData(self.denergy, self.dmu)
|
||||
self.curve2.setPen(self.pen_lime)
|
||||
self.pw2.removeItem(self.text2)
|
||||
self.pw2.removeItem(self.arrow2)
|
||||
if self.e0i is not None:
|
||||
self.text2.setText("%.2f"%self.denergy[self.e0i])
|
||||
self.text2.setPos(self.denergy[self.e0i], self.dmu[self.e0i])
|
||||
self.arrow2.setPos(self.denergy[self.e0i], self.dmu[self.e0i])
|
||||
self.pw2.addItem(self.text2)
|
||||
self.pw2.addItem(self.arrow2)
|
||||
self.pw4.removeItem(self.text4)
|
||||
self.pw4.removeItem(self.arrow4)
|
||||
self.curve3.setData(self.energy, self.muf)
|
||||
self.curve3.setPen(self.pen_orchid)
|
||||
self.curve4.setData(self.denergy, self.dmuf)
|
||||
self.curve4.setPen(self.pen_orchid)
|
||||
if self.e0if is not None:
|
||||
self.text4.setText("%.2f"%self.denergy[self.e0if])
|
||||
self.text4.setPos(self.denergy[self.e0if], self.dmuf[self.e0if])
|
||||
self.arrow4.setPos(self.denergy[self.e0if], self.dmuf[self.e0if])
|
||||
self.pw4.addItem(self.text4)
|
||||
self.pw4.addItem(self.arrow4)
|
||||
elif self.view == 2:
|
||||
self.curve1.setData(self.k, self.chi)
|
||||
self.curve1.setPen(self.pen_lime)
|
||||
self.curve2.setData(self.r, self.ft_mag)
|
||||
self.curve2.setPen(self.pen_lime)
|
||||
self.curve3.setData(self.kf, self.chif)
|
||||
self.curve3.setPen(self.pen_orchid)
|
||||
self.curve4.setData(self.rf, self.ft_magf)
|
||||
self.curve4.setPen(self.pen_orchid)
|
||||
|
||||
def update_exafs(self, data_list):
|
||||
self.e0i, self.dmu = data_list[0], data_list[1][:]
|
||||
self.k, self.chi = data_list[2][:], data_list[3][:]
|
||||
self.r, self.ft_mag = data_list[4][:], data_list[5][:]
|
||||
self.e0if, self.dmuf = data_list[6], data_list[7][:]
|
||||
self.kf, self.chif = data_list[8][:], data_list[9][:]
|
||||
self.rf, self.ft_magf = data_list[10][:], data_list[11][:]
|
||||
self.denergy = data_list[12][:]
|
||||
self.updatePlot()
|
||||
|
||||
def open_folder(self):
|
||||
if self.datafilename:
|
||||
os.system('xdg-open "%s"' %os.path.dirname(self.datafilename))
|
||||
|
||||
def closeEvent(self, event):
|
||||
self.zeromq_listener.running = False
|
||||
self.zeromq_listener.finish()
|
||||
self.thread.quit()
|
||||
self.thread.wait()
|
||||
self.thread2.quit()
|
||||
self.thread2.wait()
|
||||
self.app.processEvents()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
app = QtGui.QApplication([])
|
||||
mw = MonitorWidget(app)
|
||||
mw.setStyleSheet("background-color: #000")
|
||||
mw.setWindowTitle("Data monitor")
|
||||
mw.show()
|
||||
sys.exit(app.exec_())
|
||||
10
README.md
10
README.md
|
|
@ -6,9 +6,13 @@ Author: Ruidy Nemausat
|
|||
|
||||
Graphical User Interface allowing to:
|
||||
|
||||
- create measurement sequences
|
||||
- visualize live data
|
||||
- quick treatment
|
||||
- create measurement sequences: choose between step and continuous
|
||||
- visualize live step-scan data, after each scan continuous-scan data
|
||||
- quick treatment: visualisation in E, k and R spaces
|
||||
|
||||
## Notes
|
||||
|
||||
- `pyuic5 main.ui > main_gui.py` ⚠️ Change main class name to MainGui afterwards
|
||||
|
||||
## Architecture
|
||||
|
||||
|
|
|
|||
267
main.ui
Normal file
267
main.ui
Normal file
|
|
@ -0,0 +1,267 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>widget</class>
|
||||
<widget class="QWidget" name="widget">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>798</width>
|
||||
<height>575</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>P65 XAFS Scan Manager</string>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<item>
|
||||
<widget class="QToolBox" name="toolBox">
|
||||
<property name="whatsThis">
|
||||
<string>P65 XAFS Scan Manager</string>
|
||||
</property>
|
||||
<property name="accessibleName">
|
||||
<string>P65 XAFS Scan Manager</string>
|
||||
</property>
|
||||
<property name="accessibleDescription">
|
||||
<string>P65 XAFS Scan Manager</string>
|
||||
</property>
|
||||
<property name="currentIndex">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<widget class="QWidget" name="scanParameterPage">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>774</width>
|
||||
<height>483</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="accessibleName">
|
||||
<string/>
|
||||
</property>
|
||||
<attribute name="label">
|
||||
<string>Scan Parameters</string>
|
||||
</attribute>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="0" column="0">
|
||||
<widget class="QPushButton" name="pushButton">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>75</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Add</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QPushButton" name="pushButton_3">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>75</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Copy</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="2">
|
||||
<widget class="QPushButton" name="pushButton_2">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>75</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Remove</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="3">
|
||||
<widget class="QPushButton" name="pushButton_7">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>16777215</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Clear</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0" colspan="4">
|
||||
<widget class="QListWidget" name="listWidget">
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Scan #1</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0" colspan="2">
|
||||
<widget class="QPushButton" name="pushButton_4">
|
||||
<property name="text">
|
||||
<string>Start</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="2" colspan="2">
|
||||
<widget class="QPushButton" name="pushButton_5">
|
||||
<property name="text">
|
||||
<string>Pause</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="DataStoragePage">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>774</width>
|
||||
<height>483</height>
|
||||
</rect>
|
||||
</property>
|
||||
<attribute name="label">
|
||||
<string>Data Storage</string>
|
||||
</attribute>
|
||||
<widget class="QSpinBox" name="spinBox">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>420</x>
|
||||
<y>60</y>
|
||||
<width>48</width>
|
||||
<height>24</height>
|
||||
</rect>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QWidget" name="">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>12</x>
|
||||
<y>12</y>
|
||||
<width>192</width>
|
||||
<height>157</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_2">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Maximum">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>20</pointsize>
|
||||
<weight>75</weight>
|
||||
<bold>true</bold>
|
||||
<kerning>true</kerning>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Data Storage</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QTableWidget" name="tableWidget_2">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Maximum">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>180</width>
|
||||
<height>80</height>
|
||||
</size>
|
||||
</property>
|
||||
<row>
|
||||
<property name="text">
|
||||
<string>Location</string>
|
||||
</property>
|
||||
</row>
|
||||
<row>
|
||||
<property name="text">
|
||||
<string>Folder Name</string>
|
||||
</property>
|
||||
</row>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>Value</string>
|
||||
</property>
|
||||
</column>
|
||||
<item row="0" column="0">
|
||||
<property name="text">
|
||||
<string>UserBeamtime</string>
|
||||
</property>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<property name="text">
|
||||
<string>P.I.</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QPushButton" name="pushButton_6">
|
||||
<property name="text">
|
||||
<string>Save</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections>
|
||||
<connection>
|
||||
<sender>pushButton_6</sender>
|
||||
<signal>clicked()</signal>
|
||||
<receiver>spinBox</receiver>
|
||||
<slot>stepUp()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>174</x>
|
||||
<y>231</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>448</x>
|
||||
<y>158</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
</connections>
|
||||
</ui>
|
||||
263
mainWindow.ui
Normal file
263
mainWindow.ui
Normal file
|
|
@ -0,0 +1,263 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>MainWindow</class>
|
||||
<widget class="QMainWindow" name="MainWindow">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>800</width>
|
||||
<height>600</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>MainWindow</string>
|
||||
</property>
|
||||
<widget class="QWidget" name="centralwidget">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<item>
|
||||
<widget class="QToolBox" name="toolBox">
|
||||
<property name="whatsThis">
|
||||
<string>P65 XAFS Scan Manager</string>
|
||||
</property>
|
||||
<property name="accessibleName">
|
||||
<string>P65 XAFS Scan Manager</string>
|
||||
</property>
|
||||
<property name="accessibleDescription">
|
||||
<string>P65 XAFS Scan Manager</string>
|
||||
</property>
|
||||
<property name="currentIndex">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<widget class="QWidget" name="scanParameterPage">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>776</width>
|
||||
<height>465</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="accessibleName">
|
||||
<string/>
|
||||
</property>
|
||||
<attribute name="label">
|
||||
<string>Scan Parameters</string>
|
||||
</attribute>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="0" column="0">
|
||||
<widget class="QPushButton" name="pushButton">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>75</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Add</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QPushButton" name="pushButton_3">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>75</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Copy</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="2">
|
||||
<widget class="QPushButton" name="pushButton_2">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>75</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Remove</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="3">
|
||||
<widget class="QPushButton" name="pushButton_7">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>16777215</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Clear</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0" colspan="4">
|
||||
<widget class="QListWidget" name="listWidget">
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Scan #1</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0" colspan="2">
|
||||
<widget class="QPushButton" name="pushButton_4">
|
||||
<property name="text">
|
||||
<string>Start</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="2" colspan="2">
|
||||
<widget class="QPushButton" name="pushButton_5">
|
||||
<property name="text">
|
||||
<string>Pause</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="DataStoragePage">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>98</width>
|
||||
<height>28</height>
|
||||
</rect>
|
||||
</property>
|
||||
<attribute name="label">
|
||||
<string>Data Storage</string>
|
||||
</attribute>
|
||||
<widget class="QSpinBox" name="spinBox">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>420</x>
|
||||
<y>60</y>
|
||||
<width>48</width>
|
||||
<height>24</height>
|
||||
</rect>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QWidget" name="layoutWidget">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>12</x>
|
||||
<y>12</y>
|
||||
<width>192</width>
|
||||
<height>157</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_2">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Maximum">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>20</pointsize>
|
||||
<weight>75</weight>
|
||||
<bold>true</bold>
|
||||
<kerning>true</kerning>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Data Storage</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QTableWidget" name="tableWidget_2">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Maximum">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>180</width>
|
||||
<height>80</height>
|
||||
</size>
|
||||
</property>
|
||||
<row>
|
||||
<property name="text">
|
||||
<string>Location</string>
|
||||
</property>
|
||||
</row>
|
||||
<row>
|
||||
<property name="text">
|
||||
<string>Folder Name</string>
|
||||
</property>
|
||||
</row>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>Value</string>
|
||||
</property>
|
||||
</column>
|
||||
<item row="0" column="0">
|
||||
<property name="text">
|
||||
<string>UserBeamtime</string>
|
||||
</property>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<property name="text">
|
||||
<string>P.I.</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QPushButton" name="pushButton_6">
|
||||
<property name="text">
|
||||
<string>Save</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QMenuBar" name="menubar">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>800</width>
|
||||
<height>22</height>
|
||||
</rect>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QStatusBar" name="statusbar"/>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
151
main_gui.py
Normal file
151
main_gui.py
Normal file
|
|
@ -0,0 +1,151 @@
|
|||
from PyQt5 import QtCore, QtGui, QtWidgets
|
||||
|
||||
|
||||
class MainGui(object):
|
||||
def setupUi(self, widget):
|
||||
widget.setObjectName("widget")
|
||||
widget.resize(798, 575)
|
||||
self.horizontalLayout_2 = QtWidgets.QHBoxLayout(widget)
|
||||
self.horizontalLayout_2.setObjectName("horizontalLayout_2")
|
||||
self.toolBox = QtWidgets.QToolBox(widget)
|
||||
self.toolBox.setObjectName("toolBox")
|
||||
self.scanParameterPage = QtWidgets.QWidget()
|
||||
self.scanParameterPage.setGeometry(QtCore.QRect(0, 0, 774, 483))
|
||||
self.scanParameterPage.setAccessibleName("")
|
||||
self.scanParameterPage.setObjectName("scanParameterPage")
|
||||
self.horizontalLayout = QtWidgets.QHBoxLayout(self.scanParameterPage)
|
||||
self.horizontalLayout.setObjectName("horizontalLayout")
|
||||
self.gridLayout = QtWidgets.QGridLayout()
|
||||
self.gridLayout.setObjectName("gridLayout")
|
||||
self.pushButton = QtWidgets.QPushButton(self.scanParameterPage)
|
||||
self.pushButton.setMaximumSize(QtCore.QSize(75, 16777215))
|
||||
self.pushButton.setObjectName("pushButton")
|
||||
self.gridLayout.addWidget(self.pushButton, 0, 0, 1, 1)
|
||||
self.pushButton_3 = QtWidgets.QPushButton(self.scanParameterPage)
|
||||
self.pushButton_3.setMinimumSize(QtCore.QSize(0, 0))
|
||||
self.pushButton_3.setMaximumSize(QtCore.QSize(75, 16777215))
|
||||
self.pushButton_3.setObjectName("pushButton_3")
|
||||
self.gridLayout.addWidget(self.pushButton_3, 0, 1, 1, 1)
|
||||
self.pushButton_2 = QtWidgets.QPushButton(self.scanParameterPage)
|
||||
self.pushButton_2.setMaximumSize(QtCore.QSize(75, 16777215))
|
||||
self.pushButton_2.setObjectName("pushButton_2")
|
||||
self.gridLayout.addWidget(self.pushButton_2, 0, 2, 1, 1)
|
||||
self.pushButton_7 = QtWidgets.QPushButton(self.scanParameterPage)
|
||||
self.pushButton_7.setMaximumSize(QtCore.QSize(16777215, 16777215))
|
||||
self.pushButton_7.setObjectName("pushButton_7")
|
||||
self.gridLayout.addWidget(self.pushButton_7, 0, 3, 1, 1)
|
||||
self.listWidget = QtWidgets.QListWidget(self.scanParameterPage)
|
||||
self.listWidget.setObjectName("listWidget")
|
||||
item = QtWidgets.QListWidgetItem()
|
||||
self.listWidget.addItem(item)
|
||||
self.gridLayout.addWidget(self.listWidget, 1, 0, 1, 4)
|
||||
self.pushButton_4 = QtWidgets.QPushButton(self.scanParameterPage)
|
||||
self.pushButton_4.setObjectName("pushButton_4")
|
||||
self.gridLayout.addWidget(self.pushButton_4, 2, 0, 1, 2)
|
||||
self.pushButton_5 = QtWidgets.QPushButton(self.scanParameterPage)
|
||||
self.pushButton_5.setObjectName("pushButton_5")
|
||||
self.gridLayout.addWidget(self.pushButton_5, 2, 2, 1, 2)
|
||||
self.horizontalLayout.addLayout(self.gridLayout)
|
||||
self.toolBox.addItem(self.scanParameterPage, "")
|
||||
self.DataStoragePage = QtWidgets.QWidget()
|
||||
self.DataStoragePage.setGeometry(QtCore.QRect(0, 0, 774, 483))
|
||||
self.DataStoragePage.setObjectName("DataStoragePage")
|
||||
self.spinBox = QtWidgets.QSpinBox(self.DataStoragePage)
|
||||
self.spinBox.setGeometry(QtCore.QRect(420, 60, 48, 24))
|
||||
self.spinBox.setObjectName("spinBox")
|
||||
self.widget = QtWidgets.QWidget(self.DataStoragePage)
|
||||
self.widget.resize(192, 157)
|
||||
self.widget.setObjectName("widget")
|
||||
self.gridLayout_2 = QtWidgets.QGridLayout(self.widget)
|
||||
self.gridLayout_2.setContentsMargins(0, 0, 0, 0)
|
||||
self.gridLayout_2.setObjectName("gridLayout_2")
|
||||
self.label_2 = QtWidgets.QLabel(self.widget)
|
||||
sizePolicy = QtWidgets.QSizePolicy(
|
||||
QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Maximum)
|
||||
sizePolicy.setHorizontalStretch(0)
|
||||
sizePolicy.setVerticalStretch(0)
|
||||
sizePolicy.setHeightForWidth(
|
||||
self.label_2.sizePolicy().hasHeightForWidth())
|
||||
self.label_2.setSizePolicy(sizePolicy)
|
||||
font = QtGui.QFont()
|
||||
font.setPointSize(20)
|
||||
font.setBold(True)
|
||||
font.setWeight(75)
|
||||
font.setKerning(True)
|
||||
self.label_2.setFont(font)
|
||||
self.label_2.setObjectName("label_2")
|
||||
self.gridLayout_2.addWidget(self.label_2, 0, 0, 1, 1)
|
||||
self.tableWidget_2 = QtWidgets.QTableWidget(self.widget)
|
||||
sizePolicy = QtWidgets.QSizePolicy(
|
||||
QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Maximum)
|
||||
sizePolicy.setHorizontalStretch(0)
|
||||
sizePolicy.setVerticalStretch(0)
|
||||
sizePolicy.setHeightForWidth(
|
||||
self.tableWidget_2.sizePolicy().hasHeightForWidth())
|
||||
self.tableWidget_2.setSizePolicy(sizePolicy)
|
||||
self.tableWidget_2.setMinimumSize(QtCore.QSize(0, 0))
|
||||
self.tableWidget_2.setMaximumSize(QtCore.QSize(180, 80))
|
||||
self.tableWidget_2.setObjectName("tableWidget_2")
|
||||
self.tableWidget_2.setColumnCount(1)
|
||||
self.tableWidget_2.setRowCount(2)
|
||||
item = QtWidgets.QTableWidgetItem()
|
||||
self.tableWidget_2.setVerticalHeaderItem(0, item)
|
||||
item = QtWidgets.QTableWidgetItem()
|
||||
self.tableWidget_2.setVerticalHeaderItem(1, item)
|
||||
item = QtWidgets.QTableWidgetItem()
|
||||
self.tableWidget_2.setHorizontalHeaderItem(0, item)
|
||||
item = QtWidgets.QTableWidgetItem()
|
||||
self.tableWidget_2.setItem(0, 0, item)
|
||||
item = QtWidgets.QTableWidgetItem()
|
||||
self.tableWidget_2.setItem(1, 0, item)
|
||||
self.gridLayout_2.addWidget(self.tableWidget_2, 1, 0, 1, 1)
|
||||
self.pushButton_6 = QtWidgets.QPushButton(self.widget)
|
||||
self.pushButton_6.setObjectName("pushButton_6")
|
||||
self.gridLayout_2.addWidget(self.pushButton_6, 2, 0, 1, 1)
|
||||
self.toolBox.addItem(self.DataStoragePage, "")
|
||||
self.horizontalLayout_2.addWidget(self.toolBox)
|
||||
|
||||
self.retranslateUi(widget)
|
||||
self.toolBox.setCurrentIndex(0)
|
||||
self.pushButton_6.clicked.connect(self.spinBox.stepUp)
|
||||
QtCore.QMetaObject.connectSlotsByName(widget)
|
||||
|
||||
def retranslateUi(self, widget):
|
||||
_translate = QtCore.QCoreApplication.translate
|
||||
widget.setWindowTitle(_translate("widget", "P65 XAFS Scan Manager"))
|
||||
self.toolBox.setWhatsThis(_translate(
|
||||
"widget", "P65 XAFS Scan Manager"))
|
||||
self.toolBox.setAccessibleName(
|
||||
_translate("widget", "P65 XAFS Scan Manager"))
|
||||
self.toolBox.setAccessibleDescription(
|
||||
_translate("widget", "P65 XAFS Scan Manager"))
|
||||
self.pushButton.setText(_translate("widget", "Add"))
|
||||
self.pushButton_3.setText(_translate("widget", "Copy"))
|
||||
self.pushButton_2.setText(_translate("widget", "Remove"))
|
||||
self.pushButton_7.setText(_translate("widget", "Clear"))
|
||||
__sortingEnabled = self.listWidget.isSortingEnabled()
|
||||
self.listWidget.setSortingEnabled(False)
|
||||
item = self.listWidget.item(0)
|
||||
item.setText(_translate("widget", "Scan #1"))
|
||||
self.listWidget.setSortingEnabled(__sortingEnabled)
|
||||
self.pushButton_4.setText(_translate("widget", "Start"))
|
||||
self.pushButton_5.setText(_translate("widget", "Pause"))
|
||||
self.toolBox.setItemText(self.toolBox.indexOf(
|
||||
self.scanParameterPage), _translate("widget", "Scan Parameters"))
|
||||
self.label_2.setText(_translate("widget", "Data Storage"))
|
||||
item = self.tableWidget_2.verticalHeaderItem(0)
|
||||
item.setText(_translate("widget", "Location"))
|
||||
item = self.tableWidget_2.verticalHeaderItem(1)
|
||||
item.setText(_translate("widget", "Folder Name"))
|
||||
item = self.tableWidget_2.horizontalHeaderItem(0)
|
||||
item.setText(_translate("widget", "Value"))
|
||||
__sortingEnabled = self.tableWidget_2.isSortingEnabled()
|
||||
self.tableWidget_2.setSortingEnabled(False)
|
||||
item = self.tableWidget_2.item(0, 0)
|
||||
item.setText(_translate("widget", "UserBeamtime"))
|
||||
item = self.tableWidget_2.item(1, 0)
|
||||
item.setText(_translate("widget", "P.I."))
|
||||
self.tableWidget_2.setSortingEnabled(__sortingEnabled)
|
||||
self.pushButton_6.setText(_translate("widget", "Save"))
|
||||
self.toolBox.setItemText(self.toolBox.indexOf(
|
||||
self.DataStoragePage), _translate("widget", "Data Storage"))
|
||||
|
|
@ -1,20 +0,0 @@
|
|||
"""
|
||||
Last change: Tuesday dec 17 2019
|
||||
|
||||
@author: Ruidy Nemausat
|
||||
|
||||
"""
|
||||
import sys
|
||||
from PyQt5.QtWidgets import QApplication, QWidget
|
||||
|
||||
|
||||
def main():
|
||||
app = QApplication(sys.argv)
|
||||
w = QWidget()
|
||||
w.setWindowTitle("P65 XAFS Scan Manager")
|
||||
w.show()
|
||||
sys.exit(app.exec_())
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
212
qexafs.ui
Normal file
212
qexafs.ui
Normal file
|
|
@ -0,0 +1,212 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>Form</class>
|
||||
<widget class="QWidget" name="Form">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>230</width>
|
||||
<height>460</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Form</string>
|
||||
</property>
|
||||
<widget class="QWidget" name="">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>12</x>
|
||||
<y>12</y>
|
||||
<width>212</width>
|
||||
<height>427</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="0" column="0" colspan="2">
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Maximum">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>20</pointsize>
|
||||
<weight>75</weight>
|
||||
<bold>true</bold>
|
||||
<kerning>true</kerning>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Scan Parameters</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0" colspan="2">
|
||||
<widget class="QTableWidget" name="tableWidget">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Maximum">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>350</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>200</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="autoFillBackground">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<row>
|
||||
<property name="text">
|
||||
<string>Energy</string>
|
||||
</property>
|
||||
</row>
|
||||
<row>
|
||||
<property name="text">
|
||||
<string>Edge </string>
|
||||
</property>
|
||||
</row>
|
||||
<row>
|
||||
<property name="text">
|
||||
<string>Start Scan</string>
|
||||
</property>
|
||||
</row>
|
||||
<row>
|
||||
<property name="text">
|
||||
<string>End Scan</string>
|
||||
</property>
|
||||
</row>
|
||||
<row>
|
||||
<property name="text">
|
||||
<string>Total Scan Time</string>
|
||||
</property>
|
||||
</row>
|
||||
<row>
|
||||
<property name="text">
|
||||
<string>Time per Point</string>
|
||||
</property>
|
||||
</row>
|
||||
<row>
|
||||
<property name="text">
|
||||
<string>Undulator Offset</string>
|
||||
</property>
|
||||
</row>
|
||||
<row>
|
||||
<property name="text">
|
||||
<string>Sample Name</string>
|
||||
</property>
|
||||
</row>
|
||||
<row>
|
||||
<property name="text">
|
||||
<string>Sample Position</string>
|
||||
</property>
|
||||
</row>
|
||||
<row>
|
||||
<property name="text">
|
||||
<string>Motor Position</string>
|
||||
</property>
|
||||
</row>
|
||||
<row>
|
||||
<property name="text">
|
||||
<string>Number of Scans</string>
|
||||
</property>
|
||||
</row>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>Value</string>
|
||||
</property>
|
||||
</column>
|
||||
<item row="0" column="0">
|
||||
<property name="text">
|
||||
<string>7112</string>
|
||||
</property>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<property name="text">
|
||||
<string>Fe_K</string>
|
||||
</property>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<property name="text">
|
||||
<string>150</string>
|
||||
</property>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<property name="text">
|
||||
<string>1000</string>
|
||||
</property>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<property name="text">
|
||||
<string>180</string>
|
||||
</property>
|
||||
</item>
|
||||
<item row="5" column="0">
|
||||
<property name="text">
|
||||
<string>0.1</string>
|
||||
</property>
|
||||
</item>
|
||||
<item row="6" column="0">
|
||||
<property name="text">
|
||||
<string>50</string>
|
||||
</property>
|
||||
</item>
|
||||
<item row="7" column="0">
|
||||
<property name="text">
|
||||
<string>Fe_foil</string>
|
||||
</property>
|
||||
</item>
|
||||
<item row="8" column="0">
|
||||
<property name="text">
|
||||
<string>0</string>
|
||||
</property>
|
||||
</item>
|
||||
<item row="9" column="0">
|
||||
<property name="text">
|
||||
<string>0</string>
|
||||
</property>
|
||||
</item>
|
||||
<item row="10" column="0">
|
||||
<property name="text">
|
||||
<string>1</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QPushButton" name="pushButton">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Maximum">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Add Scan</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QPushButton" name="pushButton_2">
|
||||
<property name="text">
|
||||
<string>Cancel</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
161
xafs_GUI.py
Normal file
161
xafs_GUI.py
Normal file
|
|
@ -0,0 +1,161 @@
|
|||
"""
|
||||
@author: Ruidy Nemausat
|
||||
"""
|
||||
|
||||
from EXAFS_Monitor.monitor_gui import MonitorWidget
|
||||
import sys
|
||||
from PyQt5.QtWidgets import QApplication, QWidget, QMainWindow
|
||||
from main_gui import MainGui
|
||||
from functools import partial
|
||||
|
||||
|
||||
class XafsManager(QWidget, MainGui):
|
||||
"""
|
||||
Graphical-User Interface for P65 beamline
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
"""
|
||||
constructor: initializes GUI layout from MainGui class
|
||||
"""
|
||||
super().__init__()
|
||||
self.setupUi(self)
|
||||
|
||||
# self.pushButton.clicked.connect(self.listWidget)
|
||||
|
||||
# self.connect(
|
||||
# self.loadLast,
|
||||
# SIGNAL("clicked()"),
|
||||
# partial(self.readLast)
|
||||
# )
|
||||
|
||||
# self.connect(
|
||||
# self.add2list,
|
||||
# SIGNAL("clicked()"),
|
||||
# partial(self.make_dict, scanListe)
|
||||
# )
|
||||
|
||||
# self.connect(
|
||||
# self.start,
|
||||
# SIGNAL("clicked()"),
|
||||
# partial(self.startScans)
|
||||
# )
|
||||
|
||||
# self.connect(
|
||||
# self.clearList,
|
||||
# SIGNAL("clicked()"),
|
||||
# partial(self.clearScans, scanListe)
|
||||
# )
|
||||
# Defines a single scan and returns the parameter as a dictionary object
|
||||
# def make_dict(self, scanListe):
|
||||
# # Collect all the input
|
||||
# edge_n = str(self.edge_name.text())
|
||||
# if str(edge_n) == "":
|
||||
# showMessageBox(self, "Edge Name")
|
||||
# dsPar = str(self.ds_param.text())
|
||||
# """if str(dsPar) == "":
|
||||
# EXAFS_GUI_common.showMessageBox(self,"DS parameter")"""
|
||||
# edge_e = str(self.edge_energy.text())
|
||||
# if str(edge_e) == "":
|
||||
# showMessageBox(self, "Edge energy")
|
||||
# sam_p = str(self.sam_pos.text())
|
||||
# if str(sam_p) == "":
|
||||
# showMessageBox(self, "Sample Position")
|
||||
# sam_n = str(self.sam_name.text())
|
||||
# if str(sam_n) == "":
|
||||
# showMessageBox(self, "Sample Name")
|
||||
# sam_r = str(self.sam_rep.text())
|
||||
# if str(sam_r) == "":
|
||||
# showMessageBox(self, "Number of repetitions")
|
||||
# motor_n = str(self.motor_number.text())
|
||||
# if str(motor_n) == "":
|
||||
# showMessageBox(self, "Motor number")
|
||||
# # there is always a value, so no check
|
||||
# keith1 = str(self.keith_1.value())
|
||||
# keith2 = str(self.keith_2.value())
|
||||
# keith3 = str(self.keith_3.value())
|
||||
# keith4 = str(self.keith_4.value())
|
||||
# cont_s = str(self.cont_start.text())
|
||||
# if str(cont_s) == "":
|
||||
# showMessageBox(self, "Energy start")
|
||||
# if float(cont_s) < 0: # Correct automatically if users insert a negative value
|
||||
# cont_s = str(float(cont_s) * -1)
|
||||
# print(cont_s)
|
||||
# cont_en = str(self.cont_stop.text())
|
||||
# if str(cont_en) == "":
|
||||
# showMessageBox(self, "Energy scan end")
|
||||
# cont_t = str(self.cont_tot_time.text())
|
||||
# if str(cont_t) == "":
|
||||
# showMessageBox(self, "Time per scan")
|
||||
# tpp = str(self.timepp.text())
|
||||
# if str(tpp) == "":
|
||||
# showMessageBox(self, "Time per point")
|
||||
# und_o = str(self.und_off.text())
|
||||
# if str(und_o) == "":
|
||||
# showMessageBox(self, "Undulator offset")
|
||||
# data_d = str(self.data_dir.text())
|
||||
# if str(data_d) == "":
|
||||
# showMessageBox(self, "Data directory")
|
||||
# type_t = self.type_trans.isChecked()
|
||||
# type_p = self.type_pips.isChecked()
|
||||
# type_x = self.type_Xia.isChecked()
|
||||
# which_d = str(self.StorageChooser.currentText())
|
||||
# ds_1 = self.do_something_1.isChecked()
|
||||
# ds_2 = self.do_something_2.isChecked()
|
||||
|
||||
# # Write the input into a dictionary
|
||||
# scan_spec = {
|
||||
# "edge_n": edge_n,
|
||||
# "dsPar": dsPar,
|
||||
# "edge_e": edge_e,
|
||||
# "sam_p": sam_p,
|
||||
# "sam_n": sam_n,
|
||||
# "sam_r": sam_r,
|
||||
# "keith1": keith1,
|
||||
# "keith2": keith2,
|
||||
# "keith3": keith3,
|
||||
# "keith4": keith4,
|
||||
# "motor_n": motor_n,
|
||||
# "cont_s": cont_s,
|
||||
# "cont_en": cont_en,
|
||||
# "cont_t": cont_t,
|
||||
# "tpp": tpp,
|
||||
# "und_o": und_o,
|
||||
# "data_d": data_d,
|
||||
# "type_t": type_t,
|
||||
# "type_p": type_p,
|
||||
# "type_x": type_x,
|
||||
# "which_d": which_d,
|
||||
# "ds_1": ds_1,
|
||||
# "ds_2": ds_2
|
||||
# }
|
||||
# with open(path + '/last_cont_scan.json', 'w') as f3:
|
||||
# # Use to restore last scan's settings
|
||||
# json.dump(scan_spec, f3, indent=2)
|
||||
# scanListe.append(scan_spec)
|
||||
# print("Make my scan...")
|
||||
# if os.path.isfile(path + "/ListOfScans.json"):
|
||||
# os.remove(path + "/ListOfScans.json")
|
||||
# with open(path + '/ListOfScans.json', 'a') as f1:
|
||||
# json.dump(scanListe, f1, indent=2)
|
||||
# print(scanListe)
|
||||
|
||||
# return scanListe
|
||||
|
||||
def showMessageBox(self, missing):
|
||||
QMessageBox.information(
|
||||
self, "Problem!!!", "Missing parameter: " + missing)
|
||||
|
||||
|
||||
def main():
|
||||
"""
|
||||
Displays a XafsManager window
|
||||
"""
|
||||
app = QApplication(sys.argv)
|
||||
x = XafsManager()
|
||||
x.show()
|
||||
sys.exit(app.exec_())
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Loading…
Reference in a new issue