From afe4945975f71c7479bf13adc744c6d6eb06f4e7 Mon Sep 17 00:00:00 2001 From: Thierry Zamofing Date: Mon, 31 Oct 2022 12:50:35 +0100 Subject: [PATCH] initial application framework --- furkaRIXS.py | 179 +++++++++++++++++++++++++++++++++++++++++++++++++++ furkaRIXS.ui | 156 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 335 insertions(+) create mode 100755 furkaRIXS.py create mode 100644 furkaRIXS.ui diff --git a/furkaRIXS.py b/furkaRIXS.py new file mode 100755 index 0000000..3c40da9 --- /dev/null +++ b/furkaRIXS.py @@ -0,0 +1,179 @@ +#!/usr/bin/env python +# *-----------------------------------------------------------------------* +# | | +# | Copyright (c) 2022 by Paul Scherrer Institute (http://www.psi.ch) | +# | Based on Zac great first implementation | +# | Author Thierry Zamofing (thierry.zamofing@psi.ch) | +# *-----------------------------------------------------------------------* +""" +SwissMx experiment application. + Based on Zac great first implementation + + +bitmask for simulation: + 0x01: backlight + 0x02: illumination + 0x04: zoom + 0x08: camera + 0x10: Deltatau motors + 0x20: SmarAct motors + +""" +import logging +logging.basicConfig(level=logging.DEBUG, format='%(levelname)s:%(module)s:%(lineno)d:%(funcName)s:%(message)s ') + +_log = logging.getLogger("furkaRIXS") + +import time +class timestamp(): + def __init__(self): + self.t=time.time() + def log(self,txt): + t=time.time() + print(txt+f'{t-self.t:6.3g}') + self.t=t +ts=timestamp() +ts.log('Import part 1/8:') +import sys, os, time +import matplotlib as mpl +import matplotlib.pyplot as plt +mpl.use('Qt5Agg') # needed to avoid blocking of ui ! +ts.log('Import part 2/8:') +ts.log('Import part 3/8:') +import qtawesome +from PyQt5 import QtCore, QtGui,QtWidgets +from PyQt5.uic import loadUiType +from PyQt5.QtCore import Qt, pyqtSlot, QSize, QRegExp, pyqtSignal, QObject, QThread, QRectF,QT_VERSION_STR +from PyQt5.QtGui import QKeySequence, QPixmap, QRegExpValidator, QFont +from PyQt5.QtWidgets import ( + QAction, QApplication, QDoubleSpinBox, QFileDialog, QFormLayout, QGridLayout, QGroupBox, QHBoxLayout, QLabel, QLineEdit, + QMessageBox, QPlainTextEdit, QProgressBar, QProgressDialog, QPushButton, QShortcut, QSizePolicy, QSpinBox, + QSplashScreen, QTextBrowser, QToolBox, QVBoxLayout, QWidget,) +ts.log('Import part 4/8:') +#from epics_widgets.MotorTweak import MotorTweak +#from epics_widgets.SmaractMotorTweak import SmaractMotorTweak +#from epics_widgets.SimMotorTweak import SimMotorTweak +ts.log('Import part 5/8:') +import numpy as np +np.set_printoptions(suppress=True,linewidth=196) +import pyqtgraph as pg +pg.setConfigOptions(antialias=True,imageAxisOrder='row-major') +ts.log('Import part 6/8:') +import epics +from epics.ca import pend_event + +def get_version(path='.'): + #sys.stdout.write('getVersion() -> using git command -> ') + p = subprocess.Popen(f'git -C {path} describe --match ''*.*.*'' --long --tags --dirty', shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) + retval = p.wait() + res=p.stdout.readline() + p.stdout.close() + #res=res.decode()[1:-1].split('-',2) + res=res.decode()[:-1].split('-',2) + ver='.'.join(res[:2]) + gitcmt=res[2][1:] + return (ver,gitcmt) + +def sigint_handler(*args): + """Handler for the SIGINT signal.""" + app=QApplication.instance() + app.quit() + + +Ui_MainWindow, QMainWindow = loadUiType("furkaRIXS.ui") +class WndFurkaRIXS(QMainWindow, Ui_MainWindow): + def __init__(self,): + super(WndSwissMx, self).__init__() + self.setupUi(self) + + app=QApplication.instance() + + title = "Furka RIXS - Furka Resonant inelastic X-ray scattering spectrodscopy" + self.setWindowTitle(title) + + #self.init_settings() + #self.setup_sliders() + #self.init_graphics() + #self.init_actions() + + + +if __name__=="__main__": + def main(): + #_log.info(f'Version: pyqtgraph:{pg.__version__} matplotlib:{mpl.__version__} numpy:{np.__version__} epics:{epics.__version__} qt:{QT_VERSION_STR}' ) + _log.info(f'Version: pyqtgraph:{pg.__version__} epics:{epics.__version__} qt:{QT_VERSION_STR}' ) + import argparse, socket + hostname=socket.gethostname() + if hostname=='ganymede': + #use EPICS locally + #os.environ['EPICS_CA_ADDR_LIST']='localhost' + #use EPICS if connected to ESC network + os.environ['EPICS_CA_ADDR_LIST'] ='129.129.244.255 sf-saresc-cagw.psi.ch:5062 sf-saresc-cagw.psi.ch:5066' + epilog=__doc__ #+'\nExamples:'+''.join(map(lambda s:cmd+s, exampleCmd))+'\n' + parser=argparse.ArgumentParser(epilog=epilog, formatter_class=argparse.RawDescriptionHelpFormatter) + parser.add_argument("--sim", "-s", type=lambda x: int(x,0), help="simulate devices (see bitmasks) default=0x%(default)x", default=0) + args = parser.parse_args() + _log.info('Arguments:{}'.format(args.__dict__)) + + from PyQt5.QtWidgets import QApplication + + # set app icon + #app = QApplication(sys.argv) + #app_icon = QtGui.QIcon() + #app_icon.addFile("artwork/logo/16x16.png", QtCore.QSize(16, 16)) + #app_icon.addFile("artwork/logo/24x24.png", QtCore.QSize(24, 24)) + #app_icon.addFile("artwork/logo/32x32.png", QtCore.QSize(32, 32)) + #app_icon.addFile("artwork/logo/48x48.png", QtCore.QSize(48, 48)) + #app_icon.addFile("artwork/logo/256x256.png", QtCore.QSize(256, 256)) + #app.setWindowIcon(app_icon) + + #startupWin=StartupSplash() + + app._args=args + + #startupWin.set(5, f'load settings') + #app._cfg=cfg=AppCfg() + + #app._geometry=geometry.geometry() + #app._geometry._lut_pix2pos=cfg.value(cfg.GEO_PIX2POS) + + #app._geometry._opt_ctr=cfg.value(cfg.GEO_OPT_CTR) + + #startupWin.set(15, f'connect backlight') + #pfx=app._cfg.value(AppCfg.GBL_DEV_PREFIX)[0] + #dft_pos_bklgt=app._cfg.value(AppCfg.DFT_POS_BKLGT) + + #if args.sim&0x01: + # app._backlight = backlight.Backlight(None,dft_pos_bklgt) + #else: + # app._backlight = backlight.Backlight(f'{pfx}:MOT_BLGT',dft_pos_bklgt) + #startupWin.set(20, f'connect illumination') + #if args.sim&0x02: + # app._illumination = illumination.IlluminationControl(None) + #else: + # app._illumination = illumination.IlluminationControl() + #startupWin.set(40, f'connect zoom') + #if args.sim&0x04: + # app._zoom = zoom.QopticZoom(None) + #else: + # app._zoom = zoom.QopticZoom() + #startupWin.set(60, f'connect camera') + #if args.sim&0x08: + # app._camera = camera.epics_cam(None) + # app._camera.sim_gen(mode=1) + #else: + # app._camera = camera.epics_cam() + ##app._camera.run() is called in center_piece_update + + #startupWin.set(60, f'start main window') + + app._mainWnd=wnd=WndFurkaRIXS() + wnd.show() + #startupWin._wnd.finish(wnd) + + # needed so pycharm can restart application + signal.signal(signal.SIGINT, sigint_handler) + + #main.update_user_and_storage() #ZAC: orig. code + sys.exit(app.exec_()) + main() diff --git a/furkaRIXS.ui b/furkaRIXS.ui new file mode 100644 index 0000000..15d3369 --- /dev/null +++ b/furkaRIXS.ui @@ -0,0 +1,156 @@ + + + MainWindow + + + + 0 + 0 + 888 + 863 + + + + + 0 + 0 + + + + + + 0 + 0 + + + + + 160000 + 160000 + + + + + + + Qt::Horizontal + + + + + + + PushButton + + + + + + + + + + + PushButton + + + + + + + + + + + PushButton + + + + + + + + + + + + + 0 + 0 + 888 + 22 + + + + + Help + + + + + + &Advanced + + + + + &View + + + + + &File + + + + + + + + + + + + + + toolBar + + + TopToolBarArea + + + false + + + + + Preferences + + + + + About + + + + + Quit + + + Ctrl+Q + + + + + Home Fast Stages + + + + + P-Group + + + + + +