180 lines
6.2 KiB
Python
Executable File
180 lines
6.2 KiB
Python
Executable File
#!/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()
|