cleaner app starting, new application settings class
This commit is contained in:
@@ -8,7 +8,7 @@ from PyQt5.QtWidgets import QMenu, QAction, QSpinBox, QMenu
|
|||||||
from pyqtgraph import ROI, Point, RectROI, mkPen
|
from pyqtgraph import ROI, Point, RectROI, mkPen
|
||||||
from pyqtgraph import functions as fn
|
from pyqtgraph import functions as fn
|
||||||
|
|
||||||
from app_config import settings
|
from app_config import AppCfg# settings
|
||||||
|
|
||||||
from math import *
|
from math import *
|
||||||
|
|
||||||
|
|||||||
@@ -14,13 +14,13 @@ from pathlib import Path
|
|||||||
|
|
||||||
#import qsingleton #ZAC: orig. code
|
#import qsingleton #ZAC: orig. code
|
||||||
#from CoordinatesModel import CoordinatesModel #ZAC: orig. code
|
#from CoordinatesModel import CoordinatesModel #ZAC: orig. code
|
||||||
from app_config import settings, appsconf, option
|
from app_config import AppCfg #settings, option, appsconf
|
||||||
|
|
||||||
EMBL_RESULTS_TIMEOUT = "embl/results_timeout"
|
EMBL_RESULTS_TIMEOUT = "embl/results_timeout"
|
||||||
|
|
||||||
EMBL_SAVE_FILES = "embl/save_files"
|
EMBL_SAVE_FILES = "embl/save_files"
|
||||||
|
|
||||||
embl = appsconf["embl"]
|
#embl = appsconf["embl"]
|
||||||
|
|
||||||
#import imageio
|
#import imageio
|
||||||
import numpy as np
|
import numpy as np
|
||||||
@@ -72,6 +72,7 @@ class EmblMessage(QObject):
|
|||||||
|
|
||||||
def __init__(self, parent=None, **kwargs):
|
def __init__(self, parent=None, **kwargs):
|
||||||
super(EmblMessage, self).__init__(parent, **kwargs)
|
super(EmblMessage, self).__init__(parent, **kwargs)
|
||||||
|
return #ZAC: orig. code
|
||||||
if not embl["enabled"]:
|
if not embl["enabled"]:
|
||||||
return
|
return
|
||||||
context = zmq.Context()
|
context = zmq.Context()
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ logger = logging.getLogger(__name__)
|
|||||||
|
|
||||||
# from coord_library import conversions
|
# from coord_library import conversions
|
||||||
#import conversions #ZAC: orig. code
|
#import conversions #ZAC: orig. code
|
||||||
from app_config import settings
|
from app_config import AppCfg
|
||||||
|
|
||||||
#from storage import Folders #ZAC: orig. code
|
#from storage import Folders #ZAC: orig. code
|
||||||
#folders = Folders() #ZAC: orig. code
|
#folders = Folders() #ZAC: orig. code
|
||||||
|
|||||||
123
app_config.py
123
app_config.py
@@ -1,4 +1,3 @@
|
|||||||
|
|
||||||
#TODO:
|
#TODO:
|
||||||
# currently 2 settings/configs are used
|
# currently 2 settings/configs are used
|
||||||
# QSettings -> cat ~/.config/Paul\ Scherrer\ Institut/SwissMX.conf
|
# QSettings -> cat ~/.config/Paul\ Scherrer\ Institut/SwissMX.conf
|
||||||
@@ -6,54 +5,102 @@
|
|||||||
# QSettings are changed by program
|
# QSettings are changed by program
|
||||||
# #yaml is fixed and not altened by program
|
# #yaml is fixed and not altened by program
|
||||||
|
|
||||||
import yaml
|
|
||||||
from PyQt5.QtCore import QSettings
|
|
||||||
from pathlib import Path
|
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
logger = logging.getLogger(__name__)
|
_log = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
import os
|
||||||
|
from PyQt5.QtCore import QSettings
|
||||||
|
#import yaml
|
||||||
|
#from pathlib import Path
|
||||||
|
|
||||||
|
class AppCfg(QSettings):
|
||||||
|
SKIP_ESCAPE_TRANSITIONS_IF_SAFE="escape/skip_transitions_if_safe"
|
||||||
|
|
||||||
|
BEAM_MARKER_POSITIONS="beam/marker_positions"
|
||||||
|
BEAM_SIZE="beam/size"
|
||||||
|
|
||||||
|
CRYOJET_MOTION_ENABLED="cryojet/motion_enabled"
|
||||||
|
CRYOJET_NOZZLE_OUT="cryojet/nozzle_out"
|
||||||
|
CRYOJET_NOZZLE_IN="cryojet/nozzle_in"
|
||||||
|
|
||||||
|
DELTATAU_SHOW_PLOTS="deltatau/show_plots"
|
||||||
|
DELTATAU_OMEGACOS="deltatau/omegacos"
|
||||||
|
DELTATAU_SORT_POINTS="deltatau/sort_points"
|
||||||
|
DELTATAU_VELOCITY_SCALE="deltatau/velocity_scale"
|
||||||
|
|
||||||
|
CAMERA_TRANSFORMATIONS="camera/transformations"
|
||||||
|
CAMERA_ZOOM_TO_PPM="camera/zoom_to_ppm"
|
||||||
|
|
||||||
|
EXPERIMENT_PGROUP="experiment/pgroup"
|
||||||
|
EXPERIMENT_UID="experiment/uid"
|
||||||
|
|
||||||
|
ACTIVATE_PULSE_PICKER="scanning/activate_pulse_picker"
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
super(AppCfg, self).__init__("PSI", "SwissMX")
|
||||||
|
keys = self.allKeys()
|
||||||
|
if AppCfg.ACTIVATE_PULSE_PICKER not in keys:
|
||||||
|
self.setValue(AppCfg.ACTIVATE_PULSE_PICKER, False)
|
||||||
|
|
||||||
|
if AppCfg.SKIP_ESCAPE_TRANSITIONS_IF_SAFE not in keys:
|
||||||
|
self.setValue(AppCfg.SKIP_ESCAPE_TRANSITIONS_IF_SAFE, False)
|
||||||
|
|
||||||
|
if "hits/marker_size" not in keys:
|
||||||
|
self.setValue("hits/marker_size", 10)
|
||||||
|
|
||||||
|
if "graphs/show_auxiliary" not in keys:
|
||||||
|
self.setValue("graphs/show_auxiliary", False)
|
||||||
|
|
||||||
|
if "graphs/auxiliary_graph_index" not in keys:
|
||||||
|
self.setValue("graphs/auxiliary_graph_index", 0)
|
||||||
|
|
||||||
|
if "scan_request/last_location" not in keys:
|
||||||
|
d10 = os.path.join(os.path.expanduser("~"), "Data10")
|
||||||
|
self.setValue("scan_request/last_location", d10)
|
||||||
|
|
||||||
|
if AppCfg.BEAM_SIZE in keys:
|
||||||
|
_log.info("setting beamsize from stored settings: {}".format(self.value(AppCfg.BEAM_SIZE)))
|
||||||
|
else:
|
||||||
|
_log.warning("beam size may not reflect reality, please check")
|
||||||
|
self.setValue(AppCfg.BEAM_SIZE, (40, 20))
|
||||||
|
|
||||||
|
|
||||||
settings = QSettings("PSI", "SwissMX")
|
def option(self,key: str) -> bool:
|
||||||
|
try:
|
||||||
|
return self.value(key, type=bool)
|
||||||
|
except:
|
||||||
|
_log.error(f"option {key} not known")
|
||||||
|
return False
|
||||||
|
|
||||||
inst_folder = Path(__file__).absolute().parent
|
def toggle_option(self,key: str):
|
||||||
|
v = self.value(key, type=bool)
|
||||||
|
self.setValue(key, not v)
|
||||||
|
self.sync()
|
||||||
|
|
||||||
config_file = inst_folder / "swissmx.yaml"
|
|
||||||
configs = yaml.load(config_file.read_text(),Loader=yaml.FullLoader)
|
|
||||||
endstation = configs["configure_for"]
|
|
||||||
appsconf = configs[endstation]
|
|
||||||
|
|
||||||
simulated = appsconf.get("simulate", False)
|
#inst_folder = Path(__file__).absolute().parent
|
||||||
|
#config_file = inst_folder / "swissmx.yaml"
|
||||||
|
#configs = yaml.load(config_file.read_text(),Loader=yaml.FullLoader)
|
||||||
|
#endstation = configs["configure_for"]
|
||||||
|
#appsconf = configs[endstation]
|
||||||
|
#simulated = appsconf.get("simulate", False)
|
||||||
|
#logger.info(f"configuring for endstation: {endstation.upper()}")
|
||||||
|
|
||||||
logger.info(f"configuring for endstation: {endstation.upper()}")
|
#if simulated:
|
||||||
|
# logger.warning("SIMULATION is ACTIVE")
|
||||||
if simulated:
|
#css_file = inst_folder / "swissmx.css"
|
||||||
logger.warning("SIMULATION is ACTIVE")
|
|
||||||
css_file = inst_folder / "swissmx.css"
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def font(name: str) -> str:
|
#def font(name: str) -> str:
|
||||||
p = Path(__file__).absolute().parent / "fonts" / name
|
# p = Path(__file__).absolute().parent / "fonts" / name
|
||||||
return str(p)
|
# return str(p)
|
||||||
|
|
||||||
|
|
||||||
def logo(size: int = 0) -> str:
|
#def logo(size: int = 0) -> str:
|
||||||
p = Path(__file__).absolute().parent / "logos" / "logo.png"
|
# p = Path(__file__).absolute().parent / "logos" / "logo.png"
|
||||||
if size:
|
# if size:
|
||||||
p = Path(__file__).absolute().parent / "logos" / f"tell_logo_{size}x{size}.png"
|
# p = Path(__file__).absolute().parent / "logos" / f"tell_logo_{size}x{size}.png"
|
||||||
return str(p)
|
# return str(p)
|
||||||
|
|
||||||
|
|
||||||
def option(key: str) -> bool:
|
|
||||||
try:
|
|
||||||
return settings.value(key, type=bool)
|
|
||||||
except:
|
|
||||||
logger.error(f"option {key} not known")
|
|
||||||
return False
|
|
||||||
|
|
||||||
|
|
||||||
def toggle_option(key: str):
|
|
||||||
v = settings.value(key, type=bool)
|
|
||||||
settings.setValue(key, not v)
|
|
||||||
settings.sync()
|
|
||||||
|
|||||||
12
camera.py
12
camera.py
@@ -341,6 +341,15 @@ if __name__ == "__main__":
|
|||||||
exit(0)
|
exit(0)
|
||||||
n += 1
|
n += 1
|
||||||
else:
|
else:
|
||||||
|
def closeEvent(cam,evt):
|
||||||
|
print(args)
|
||||||
|
try:
|
||||||
|
pv=cam._pv['pic']
|
||||||
|
pv.clear_auto_monitor() # disconnect PV monitor callback -> program exit faster.
|
||||||
|
except AttributeError:
|
||||||
|
_log.warning('disconnect PV callback failed.')
|
||||||
|
|
||||||
|
|
||||||
class UIcamera(epics_cam):
|
class UIcamera(epics_cam):
|
||||||
|
|
||||||
def __init__(self, prefix="ESB-MX-CAM"):
|
def __init__(self, prefix="ESB-MX-CAM"):
|
||||||
@@ -446,7 +455,7 @@ if __name__ == "__main__":
|
|||||||
|
|
||||||
## Display the data and assign each frame a time value from 1.0 to 3.0
|
## Display the data and assign each frame a time value from 1.0 to 3.0
|
||||||
cam = UIcamera(prefix=args.prefix)
|
cam = UIcamera(prefix=args.prefix)
|
||||||
|
win.closeEvent=lambda x:closeEvent(cam, x)
|
||||||
|
|
||||||
#cam.set_binning(4,4)
|
#cam.set_binning(4,4)
|
||||||
#cam.run()
|
#cam.run()
|
||||||
@@ -470,3 +479,4 @@ if __name__ == "__main__":
|
|||||||
## Start Qt event loop unless running in interactive mode.
|
## Start Qt event loop unless running in interactive mode.
|
||||||
if (sys.flags.interactive != 1) or not hasattr(QtCore, 'PYQT_VERSION'):
|
if (sys.flags.interactive != 1) or not hasattr(QtCore, 'PYQT_VERSION'):
|
||||||
QtGui.QApplication.instance().exec_()
|
QtGui.QApplication.instance().exec_()
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
from PyQt5 import QtWidgets, QtGui
|
from PyQt5 import QtWidgets, QtGui
|
||||||
from PyQt5.QtWidgets import QWidget, QSizePolicy, QVBoxLayout, QDoubleSpinBox, QMessageBox
|
from PyQt5.QtWidgets import QWidget, QSizePolicy, QVBoxLayout, QDoubleSpinBox, QMessageBox
|
||||||
|
|
||||||
from app_config import option, toggle_option
|
from app_config import AppCfg #option, toggle_option
|
||||||
|
|
||||||
|
|
||||||
def toggle_warn(key):
|
def toggle_warn(key):
|
||||||
|
|||||||
236
swissmx.py
236
swissmx.py
@@ -28,6 +28,16 @@ logging.getLogger('matplotlib').setLevel(logging.INFO)
|
|||||||
logging.basicConfig(level=logging.DEBUG, format='%(levelname)s:%(module)s:%(lineno)d:%(funcName)s:%(message)s ')
|
logging.basicConfig(level=logging.DEBUG, format='%(levelname)s:%(module)s:%(lineno)d:%(funcName)s:%(message)s ')
|
||||||
_log = logging.getLogger("swissmx")
|
_log = logging.getLogger("swissmx")
|
||||||
|
|
||||||
|
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/7:')
|
||||||
import sys, os, time
|
import sys, os, time
|
||||||
import json, re
|
import json, re
|
||||||
import random, signal
|
import random, signal
|
||||||
@@ -40,27 +50,6 @@ import random, signal
|
|||||||
#from helicalscan import HelicalScanGui #ZAC: orig. code
|
#from helicalscan import HelicalScanGui #ZAC: orig. code
|
||||||
# publisher = pubber.Publisher()
|
# publisher = pubber.Publisher()
|
||||||
|
|
||||||
SKIP_ESCAPE_TRANSITIONS_IF_SAFE = "escape/skip_transitions_if_safe"
|
|
||||||
|
|
||||||
BEAM_MARKER_POSITIONS = "beam/marker_positions"
|
|
||||||
BEAM_SIZE = "beam/size"
|
|
||||||
|
|
||||||
CRYOJET_MOTION_ENABLED = "cryojet/motion_enabled"
|
|
||||||
CRYOJET_NOZZLE_OUT = "cryojet/nozzle_out"
|
|
||||||
CRYOJET_NOZZLE_IN = "cryojet/nozzle_in"
|
|
||||||
|
|
||||||
DELTATAU_SHOW_PLOTS = "deltatau/show_plots"
|
|
||||||
DELTATAU_OMEGACOS = "deltatau/omegacos"
|
|
||||||
DELTATAU_SORT_POINTS = "deltatau/sort_points"
|
|
||||||
DELTATAU_VELOCITY_SCALE = "deltatau/velocity_scale"
|
|
||||||
|
|
||||||
CAMERA_TRANSFORMATIONS = "camera/transformations"
|
|
||||||
CAMERA_ZOOM_TO_PPM = "camera/zoom_to_ppm"
|
|
||||||
|
|
||||||
EXPERIMENT_PGROUP = "experiment/pgroup"
|
|
||||||
EXPERIMENT_UID = "experiment/uid"
|
|
||||||
|
|
||||||
ACTIVATE_PULSE_PICKER = "scanning/activate_pulse_picker"
|
|
||||||
|
|
||||||
TASK_JUNGFRAU_SETTINGS = "jungfrau_settings"
|
TASK_JUNGFRAU_SETTINGS = "jungfrau_settings"
|
||||||
TASK_SETUP_PPM_CALIBRATION = "ppm_calibration"
|
TASK_SETUP_PPM_CALIBRATION = "ppm_calibration"
|
||||||
@@ -74,7 +63,7 @@ TASK_GRID = "grid"
|
|||||||
TASK_PRELOCATED = "prelocated"
|
TASK_PRELOCATED = "prelocated"
|
||||||
TASK_HELICAL = "helical"
|
TASK_HELICAL = "helical"
|
||||||
TASK_EMBL = "embl"
|
TASK_EMBL = "embl"
|
||||||
|
ts.log('Import part 2/7:')
|
||||||
import PrelocatedCoordinatesModel # ZAC: orig. code
|
import PrelocatedCoordinatesModel # ZAC: orig. code
|
||||||
from EmblModule import EmblWidget #ZAC: orig. code
|
from EmblModule import EmblWidget #ZAC: orig. code
|
||||||
from HelicalTable import HelicalTableWidget #ZAC: orig. code
|
from HelicalTable import HelicalTableWidget #ZAC: orig. code
|
||||||
@@ -84,7 +73,7 @@ from HelicalTable import HelicalTableWidget #ZAC: orig. code
|
|||||||
#import mx_swissfel #ZAC: orig. code
|
#import mx_swissfel #ZAC: orig. code
|
||||||
#swissfel = mx_swissfel.SwissFELMachine() #ZAC: orig. code
|
#swissfel = mx_swissfel.SwissFELMachine() #ZAC: orig. code
|
||||||
#from bernina_pulse_picker import pulsePicker #ZAC: orig. code
|
#from bernina_pulse_picker import pulsePicker #ZAC: orig. code
|
||||||
|
ts.log('Import part 3/7:')
|
||||||
import qtawesome
|
import qtawesome
|
||||||
import qutilities
|
import qutilities
|
||||||
from PyQt5 import QtCore, QtGui
|
from PyQt5 import QtCore, QtGui
|
||||||
@@ -95,7 +84,7 @@ from PyQt5.QtWidgets import (
|
|||||||
QMessageBox, QPlainTextEdit, QProgressBar, QProgressDialog, QPushButton, QShortcut, QSizePolicy, QSpinBox,
|
QMessageBox, QPlainTextEdit, QProgressBar, QProgressDialog, QPushButton, QShortcut, QSizePolicy, QSpinBox,
|
||||||
QSplashScreen, QTextBrowser, QToolBox, QVBoxLayout, QWidget,)
|
QSplashScreen, QTextBrowser, QToolBox, QVBoxLayout, QWidget,)
|
||||||
from PyQt5.uic import loadUiType
|
from PyQt5.uic import loadUiType
|
||||||
|
ts.log('Import part 4/7:')
|
||||||
import CustomROI as CstROI
|
import CustomROI as CstROI
|
||||||
#from CustomROI import BeamMark, Grid, CrystalCircle #ZAC: orig. code
|
#from CustomROI import BeamMark, Grid, CrystalCircle #ZAC: orig. code
|
||||||
#from GenericDialog import GenericDialog #ZAC: orig. code
|
#from GenericDialog import GenericDialog #ZAC: orig. code
|
||||||
@@ -104,21 +93,21 @@ import CustomROI as CstROI
|
|||||||
from epics_widgets.MotorTweak import MotorTweak
|
from epics_widgets.MotorTweak import MotorTweak
|
||||||
from epics_widgets.SmaractMotorTweak import SmaractMotorTweak
|
from epics_widgets.SmaractMotorTweak import SmaractMotorTweak
|
||||||
from epics_widgets.SimMotorTweak import SimMotorTweak
|
from epics_widgets.SimMotorTweak import SimMotorTweak
|
||||||
|
ts.log('Import part 5/7:')
|
||||||
|
|
||||||
from matplotlib import pyplot
|
from matplotlib import pyplot
|
||||||
import numpy as np
|
import numpy as np
|
||||||
import pyqtgraph as pg
|
import pyqtgraph as pg
|
||||||
import pyqtgraph.exporters
|
import pyqtgraph.exporters
|
||||||
# use antialias for draw lines, interpret image data as row-major instead of col-major
|
# use antialias for draw lines, interpret image data as row-major instead of col-major
|
||||||
pg.setConfigOptions(antialias=True,imageAxisOrder='row-major')
|
pg.setConfigOptions(antialias=True,imageAxisOrder='row-major')
|
||||||
|
ts.log('Import part 6/7:')
|
||||||
import app_utils
|
import app_utils
|
||||||
from app_config import settings, appsconf, option, toggle_option, simulated
|
from app_config import AppCfg #settings, option, toggle_option
|
||||||
|
|
||||||
import epics
|
import epics
|
||||||
from epics.ca import pend_event
|
from epics.ca import pend_event
|
||||||
import camera,backlight,zoom,illumination,geometry
|
import camera,backlight,zoom,illumination,geometry
|
||||||
|
ts.log('Import part 7/7:')
|
||||||
|
|
||||||
|
|
||||||
#_URL = "http://PC12288:8080"
|
#_URL = "http://PC12288:8080"
|
||||||
@@ -386,7 +375,9 @@ class Main(QMainWindow, Ui_MainWindow):
|
|||||||
tbox.layout().addWidget(htab)
|
tbox.layout().addWidget(htab)
|
||||||
|
|
||||||
def add_beam_marker(self):
|
def add_beam_marker(self):
|
||||||
w, h = settings.value(BEAM_SIZE)
|
app = QApplication.instance()
|
||||||
|
cfg = app._cfg
|
||||||
|
w, h = cfg.value(AppCfg.BEAM_SIZE)
|
||||||
self._beammark = CstROI.BeamMark([100, 100], (int(w), int(h)), parent=self)
|
self._beammark = CstROI.BeamMark([100, 100], (int(w), int(h)), parent=self)
|
||||||
self.vb.addItem(self._beammark)
|
self.vb.addItem(self._beammark)
|
||||||
|
|
||||||
@@ -422,6 +413,8 @@ class Main(QMainWindow, Ui_MainWindow):
|
|||||||
self.img.setImage(pic)
|
self.img.setImage(pic)
|
||||||
|
|
||||||
def init_settings_tracker(self):
|
def init_settings_tracker(self):
|
||||||
|
app=QApplication.instance()
|
||||||
|
cfg=app._cfg
|
||||||
_log.info("configuring widget persistence")
|
_log.info("configuring widget persistence")
|
||||||
fields = {
|
fields = {
|
||||||
# 'folder': (self._label_folder, str),
|
# 'folder': (self._label_folder, str),
|
||||||
@@ -434,7 +427,7 @@ class Main(QMainWindow, Ui_MainWindow):
|
|||||||
}
|
}
|
||||||
for key, f_config in fields.items():
|
for key, f_config in fields.items():
|
||||||
widget, conv = f_config
|
widget, conv = f_config
|
||||||
value = settings.value(key)
|
value = cfg.value(key)
|
||||||
try:
|
try:
|
||||||
wset, wget = widget.setText, widget.text
|
wset, wget = widget.setText, widget.text
|
||||||
_log.debug("tracking text field {}".format(key))
|
_log.debug("tracking text field {}".format(key))
|
||||||
@@ -530,8 +523,10 @@ class Main(QMainWindow, Ui_MainWindow):
|
|||||||
_log.warning("failed writing {}".format(fname))
|
_log.warning("failed writing {}".format(fname))
|
||||||
|
|
||||||
def persist_setting(self, s, v):
|
def persist_setting(self, s, v):
|
||||||
|
app=QApplication.instance()
|
||||||
|
cfg=app._cfg
|
||||||
_log.debug("persisting {} = {}".format(s, v))
|
_log.debug("persisting {} = {}".format(s, v))
|
||||||
settings.setValue(s, v)
|
cfg.setValue(s, v)
|
||||||
|
|
||||||
def method_changed(self, index):
|
def method_changed(self, index):
|
||||||
method = self._tabs_daq_methods.currentWidget().accessibleName()
|
method = self._tabs_daq_methods.currentWidget().accessibleName()
|
||||||
@@ -2477,8 +2472,8 @@ class Main(QMainWindow, Ui_MainWindow):
|
|||||||
self._grids = []
|
self._grids = []
|
||||||
tab = self._tab_daq_method_grid
|
tab = self._tab_daq_method_grid
|
||||||
layout = tab.layout() # gridlayout
|
layout = tab.layout() # gridlayout
|
||||||
self._sb_grid_x_step.setValue(30.0)
|
self._sb_grid_x_step.setValue(30)
|
||||||
self._sb_grid_y_step.setValue(30.0)
|
self._sb_grid_y_step.setValue(30)
|
||||||
self._bt_add_grid.clicked.connect(self.daq_grid_add_grid)
|
self._bt_add_grid.clicked.connect(self.daq_grid_add_grid)
|
||||||
self._bt_remove_all_grids.clicked.connect(self.daq_grid_remove_all)
|
self._bt_remove_all_grids.clicked.connect(self.daq_grid_remove_all)
|
||||||
self._find_targets_from_microscope_image.clicked.connect(
|
self._find_targets_from_microscope_image.clicked.connect(
|
||||||
@@ -2564,6 +2559,8 @@ class Main(QMainWindow, Ui_MainWindow):
|
|||||||
cont.layout().addWidget(w)
|
cont.layout().addWidget(w)
|
||||||
|
|
||||||
def init_actions(self):
|
def init_actions(self):
|
||||||
|
app = QApplication.instance()
|
||||||
|
cfg = app._cfg
|
||||||
self.toolBar.setToolButtonStyle(Qt.ToolButtonTextUnderIcon)
|
self.toolBar.setToolButtonStyle(Qt.ToolButtonTextUnderIcon)
|
||||||
|
|
||||||
self.shortcut = QShortcut(QKeySequence(Qt.CTRL + Qt.SHIFT + Qt.Key_S), self)
|
self.shortcut = QShortcut(QKeySequence(Qt.CTRL + Qt.SHIFT + Qt.Key_S), self)
|
||||||
@@ -2611,8 +2608,8 @@ class Main(QMainWindow, Ui_MainWindow):
|
|||||||
# icon = qtawesome.icon("material.shutter_speed")
|
# icon = qtawesome.icon("material.shutter_speed")
|
||||||
action = QAction("Use Pulse Picker", self)
|
action = QAction("Use Pulse Picker", self)
|
||||||
action.setCheckable(True)
|
action.setCheckable(True)
|
||||||
action.setChecked(option(ACTIVATE_PULSE_PICKER))
|
action.setChecked(cfg.option(AppCfg.ACTIVATE_PULSE_PICKER))
|
||||||
action.triggered.connect(lambda: toggle_option(ACTIVATE_PULSE_PICKER))
|
action.triggered.connect(lambda: cfg.toggle_option(AppCfg.ACTIVATE_PULSE_PICKER))
|
||||||
self.toolBar.addAction(action)
|
self.toolBar.addAction(action)
|
||||||
|
|
||||||
icon = qtawesome.icon("material.timeline")
|
icon = qtawesome.icon("material.timeline")
|
||||||
@@ -3120,60 +3117,33 @@ class Main(QMainWindow, Ui_MainWindow):
|
|||||||
|
|
||||||
def init_settings(self):
|
def init_settings(self):
|
||||||
app = QApplication.instance()
|
app = QApplication.instance()
|
||||||
# settings = Settings
|
cfg = app._cfg
|
||||||
#global folders
|
keys = cfg.allKeys()
|
||||||
s = settings
|
|
||||||
keys = s.allKeys()
|
|
||||||
|
|
||||||
if ACTIVATE_PULSE_PICKER not in keys:
|
|
||||||
settings.setValue(ACTIVATE_PULSE_PICKER, False)
|
|
||||||
|
|
||||||
if SKIP_ESCAPE_TRANSITIONS_IF_SAFE not in keys:
|
|
||||||
settings.setValue(SKIP_ESCAPE_TRANSITIONS_IF_SAFE, False)
|
|
||||||
|
|
||||||
#if EXPERIMENT_PGROUP not in keys:
|
#if EXPERIMENT_PGROUP not in keys:
|
||||||
# self.update_user_and_storage()
|
# self.update_user_and_storage()
|
||||||
|
|
||||||
if "hits/marker_size" not in keys:
|
|
||||||
settings.setValue("hits/marker_size", 10)
|
|
||||||
|
|
||||||
if "window/geometry" in keys:
|
if "window/geometry" in keys:
|
||||||
self.restoreGeometry(s.value("window/geometry", ""))
|
self.restoreGeometry(cfg.value("window/geometry", ""))
|
||||||
self.restoreState(s.value("window/windowState", ""))
|
self.restoreState(cfg.value("window/windowState", ""))
|
||||||
|
|
||||||
if "window/main_splitter" in keys:
|
if "window/main_splitter" in keys:
|
||||||
sizes = [int(s) for s in s.value("window/main_splitter")]
|
sizes = [int(s) for s in cfg.value("window/main_splitter")]
|
||||||
self._main_splitter.setSizes(sizes)
|
self._main_splitter.setSizes(sizes)
|
||||||
else:
|
else:
|
||||||
self._main_splitter.setSizes([500, 1200])
|
self._main_splitter.setSizes([500, 1200])
|
||||||
|
|
||||||
if "graphs/show_auxiliary" not in keys:
|
if AppCfg.BEAM_MARKER_POSITIONS in keys:
|
||||||
s.setValue("graphs/show_auxiliary", False)
|
self._beam_markers = s.value(AppCfg.BEAM_MARKER_POSITIONS)
|
||||||
|
|
||||||
if "graphs/auxiliary_graph_index" not in keys:
|
|
||||||
s.setValue("graphs/auxiliary_graph_index", 0)
|
|
||||||
|
|
||||||
if "scan_request/last_location" not in keys:
|
|
||||||
d10 = os.path.join(os.path.expanduser("~"), "Data10")
|
|
||||||
s.setValue("scan_request/last_location", d10)
|
|
||||||
|
|
||||||
if BEAM_MARKER_POSITIONS in keys:
|
|
||||||
self._beam_markers = s.value(BEAM_MARKER_POSITIONS)
|
|
||||||
self.update_beam_marker_fitters()
|
self.update_beam_marker_fitters()
|
||||||
_log.info("read beam markers {}".format(self._beam_markers))
|
_log.info("read beam markers {}".format(self._beam_markers))
|
||||||
|
|
||||||
if BEAM_SIZE in keys:
|
if AppCfg.CAMERA_TRANSFORMATIONS in keys:
|
||||||
_log.info("setting beamsize from stored settings: {}".format(s.value(BEAM_SIZE)))
|
app._camera.set_transformations(s.value(AppCfg.CAMERA_TRANSFORMATIONS))
|
||||||
else:
|
|
||||||
_log.warning("beam size may not reflect reality, please check")
|
|
||||||
s.setValue(BEAM_SIZE, (40, 20))
|
|
||||||
|
|
||||||
if CAMERA_TRANSFORMATIONS in keys:
|
if AppCfg.CAMERA_ZOOM_TO_PPM in keys:
|
||||||
app._camera.set_transformations(s.value(CAMERA_TRANSFORMATIONS))
|
self._zoom_to_ppm = s.value(AppCfg.CAMERA_ZOOM_TO_PPM)
|
||||||
|
_log.info(f"{AppCfg.CAMERA_ZOOM_TO_PPM} updated: {self._zoom_to_ppm}")
|
||||||
if CAMERA_ZOOM_TO_PPM in keys:
|
|
||||||
self._zoom_to_ppm = s.value(CAMERA_ZOOM_TO_PPM)
|
|
||||||
_log.info(f"{CAMERA_ZOOM_TO_PPM} updated: {self._zoom_to_ppm}")
|
|
||||||
self.update_ppm_fitters()
|
self.update_ppm_fitters()
|
||||||
|
|
||||||
def really_quit(self):
|
def really_quit(self):
|
||||||
@@ -3184,11 +3154,9 @@ class Main(QMainWindow, Ui_MainWindow):
|
|||||||
|
|
||||||
def closeEvent(self, event):
|
def closeEvent(self, event):
|
||||||
"""this is called when the user clicks the window's cross icon"""
|
"""this is called when the user clicks the window's cross icon"""
|
||||||
if (
|
if (self._do_quit or QMessageBox.question( self, "", "Are you sure you want to quit?", QMessageBox.Yes | QMessageBox.No, QMessageBox.No,) == QMessageBox.Yes):
|
||||||
self._do_quit
|
|
||||||
or QMessageBox.question( self, "", "Are you sure you want to quit?", QMessageBox.Yes | QMessageBox.No, QMessageBox.No,) == QMessageBox.Yes
|
|
||||||
):
|
|
||||||
app=QApplication.instance()
|
app=QApplication.instance()
|
||||||
|
cfg=app._cfg
|
||||||
try:
|
try:
|
||||||
pv=app._camera._pv['pic']
|
pv=app._camera._pv['pic']
|
||||||
pv.clear_auto_monitor() # disconnect PV monitor callback -> program exit faster.
|
pv.clear_auto_monitor() # disconnect PV monitor callback -> program exit faster.
|
||||||
@@ -3196,10 +3164,10 @@ class Main(QMainWindow, Ui_MainWindow):
|
|||||||
_log.warning('disconnect PV callback failed.')
|
_log.warning('disconnect PV callback failed.')
|
||||||
|
|
||||||
_log.info('disconnect PV callback')
|
_log.info('disconnect PV callback')
|
||||||
settings.setValue("window/geometry", self.saveGeometry())
|
cfg.setValue("window/geometry", self.saveGeometry())
|
||||||
settings.setValue("window/windowState", self.saveState())
|
cfg.setValue("window/windowState", self.saveState())
|
||||||
settings.setValue("window/main_splitter", self._main_splitter.sizes())
|
cfg.setValue("window/main_splitter", self._main_splitter.sizes())
|
||||||
settings.setValue("last_active", time.time())
|
cfg.setValue("last_active", time.time())
|
||||||
_log.info('save settings')
|
_log.info('save settings')
|
||||||
#QMainWindow.closeEvent(self, event)
|
#QMainWindow.closeEvent(self, event)
|
||||||
_log.info('closeEvent done')
|
_log.info('closeEvent done')
|
||||||
@@ -3242,6 +3210,27 @@ def sigint_handler(*args):
|
|||||||
app.quit()
|
app.quit()
|
||||||
|
|
||||||
|
|
||||||
|
class StartupSplash:
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
splash_pix = QPixmap("artwork/logo/256x256.png")
|
||||||
|
self._wnd=splash = QSplashScreen(splash_pix, Qt.WindowStaysOnTopHint)
|
||||||
|
splash.setWindowFlags(Qt.WindowStaysOnTopHint | Qt.FramelessWindowHint)
|
||||||
|
splash.setEnabled(False)
|
||||||
|
|
||||||
|
self._prgsBar=prgs=QProgressBar(splash)
|
||||||
|
prgs.setMaximum(100)
|
||||||
|
prgs.setGeometry(0, splash_pix.height() - 50, splash_pix.width(), 20)
|
||||||
|
|
||||||
|
splash.show()
|
||||||
|
|
||||||
|
def set(self,i,msg):
|
||||||
|
self._prgsBar.setValue(i)
|
||||||
|
self._wnd.showMessage(f"<font color='red'>{msg}</font></h1>", int(Qt.AlignBottom|Qt.AlignCenter), Qt.black)
|
||||||
|
app=QApplication.instance()
|
||||||
|
app.processEvents()
|
||||||
|
time.sleep(.1)
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
import argparse
|
import argparse
|
||||||
|
|
||||||
@@ -3253,38 +3242,11 @@ def main():
|
|||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
_log.info('Arguments:{}'.format(args.__dict__))
|
_log.info('Arguments:{}'.format(args.__dict__))
|
||||||
|
|
||||||
# needed so pycharm can restart application
|
|
||||||
signal.signal(signal.SIGINT, sigint_handler)
|
|
||||||
|
|
||||||
from PyQt5.QtWidgets import QApplication
|
from PyQt5.QtWidgets import QApplication
|
||||||
|
|
||||||
# set app icon
|
# set app icon
|
||||||
|
|
||||||
app = QApplication(sys.argv)
|
app = QApplication(sys.argv)
|
||||||
app._args=args
|
|
||||||
|
|
||||||
if args.sim&0x01:
|
|
||||||
app._backlight = backlight.Backlight(None)
|
|
||||||
else:
|
|
||||||
app._backlight = backlight.Backlight()
|
|
||||||
if args.sim&0x02:
|
|
||||||
app._illumination = illumination.IlluminationControl(None)
|
|
||||||
else:
|
|
||||||
app._illumination = illumination.IlluminationControl()
|
|
||||||
if args.sim&0x04:
|
|
||||||
app._zoom = zoom.QopticZoom(None)
|
|
||||||
else:
|
|
||||||
app._zoom = zoom.QopticZoom()
|
|
||||||
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
|
|
||||||
app._geometry=geometry.geometry()
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
app_icon = QtGui.QIcon()
|
app_icon = QtGui.QIcon()
|
||||||
app_icon.addFile("artwork/logo/16x16.png", QtCore.QSize(16, 16))
|
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/24x24.png", QtCore.QSize(24, 24))
|
||||||
@@ -3293,29 +3255,55 @@ def main():
|
|||||||
app_icon.addFile("artwork/logo/256x256.png", QtCore.QSize(256, 256))
|
app_icon.addFile("artwork/logo/256x256.png", QtCore.QSize(256, 256))
|
||||||
app.setWindowIcon(app_icon)
|
app.setWindowIcon(app_icon)
|
||||||
|
|
||||||
splash_pix = QPixmap("artwork/logo/256x256.png")
|
startupWin=StartupSplash()
|
||||||
splash = QSplashScreen(splash_pix, Qt.WindowStaysOnTopHint)
|
|
||||||
splash.setWindowFlags(Qt.WindowStaysOnTopHint | Qt.FramelessWindowHint)
|
|
||||||
splash.setEnabled(False)
|
|
||||||
|
|
||||||
progressBar = QProgressBar(splash)
|
#for i in range(1, 20):
|
||||||
progressBar.setMaximum(10)
|
# startupWin.set(i,f'sample startup text {i}')
|
||||||
progressBar.setGeometry(0, splash_pix.height() - 50, splash_pix.width(), 20)
|
# #app.processEvents()
|
||||||
|
# t = time.time()
|
||||||
|
# #while time.time() < t + 0.1:
|
||||||
|
# # app.processEvents()
|
||||||
|
|
||||||
splash.show()
|
#app._settings=QSettings("PSI", "SwissMX")
|
||||||
# splash.showMessage("<h1><font color='red'>Solid support scanning brought to you by</font></h1>", Qt.AlignTop | Qt.AlignCenter, Qt.black)
|
|
||||||
|
|
||||||
for i in range(1, 11):
|
app._args=args
|
||||||
progressBar.setValue(i)
|
|
||||||
t = time.time()
|
|
||||||
while time.time() < t + 0.1:
|
|
||||||
app.processEvents()
|
|
||||||
|
|
||||||
|
startupWin.set(5, f'load settings')
|
||||||
|
app._cfg=AppCfg()
|
||||||
|
app._geometry=geometry.geometry()
|
||||||
|
|
||||||
|
startupWin.set(15, f'connect backlight')
|
||||||
|
if args.sim&0x01:
|
||||||
|
app._backlight = backlight.Backlight(None)
|
||||||
|
else:
|
||||||
|
app._backlight = backlight.Backlight()
|
||||||
|
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')
|
||||||
|
|
||||||
main = Main()
|
main = Main()
|
||||||
main.show()
|
main.show()
|
||||||
splash.finish(main)
|
startupWin._wnd.finish(main)
|
||||||
|
|
||||||
|
# needed so pycharm can restart application
|
||||||
|
signal.signal(signal.SIGINT, sigint_handler)
|
||||||
|
|
||||||
#main.update_user_and_storage() #ZAC: orig. code
|
#main.update_user_and_storage() #ZAC: orig. code
|
||||||
sys.exit(app.exec_())
|
sys.exit(app.exec_())
|
||||||
|
|
||||||
|
|||||||
18
zoom.py
18
zoom.py
@@ -32,7 +32,7 @@ from PyQt5.uic import loadUiType
|
|||||||
|
|
||||||
import backlight, illumination, camera
|
import backlight, illumination, camera
|
||||||
import epics
|
import epics
|
||||||
from app_config import settings
|
from app_config import AppCfg #settings
|
||||||
|
|
||||||
Ui_Zoom, QWidget = loadUiType("zoom.ui")
|
Ui_Zoom, QWidget = loadUiType("zoom.ui")
|
||||||
MIN_ZOOM = 1
|
MIN_ZOOM = 1
|
||||||
@@ -50,19 +50,21 @@ class Zoom(QGroupBox, Ui_Zoom):
|
|||||||
self.setTitle("Sample Viewing")
|
self.setTitle("Sample Viewing")
|
||||||
|
|
||||||
def configure(self):
|
def configure(self):
|
||||||
keys = settings.allKeys()
|
app=QApplication.instance()
|
||||||
|
cfg=app._cfg
|
||||||
|
keys=cfg.allKeys()
|
||||||
if "sample_viewing/zoom_buttons" not in keys:
|
if "sample_viewing/zoom_buttons" not in keys:
|
||||||
settings.setValue("sample_viewing/zoom_buttons",
|
cfg.setValue("sample_viewing/zoom_buttons",
|
||||||
json.dumps([(1, "1"),(200, "200"),(400, "400"),(600, "600"),(800, "800"),(1000, "1000"),]),)
|
json.dumps([(1, "1"),(200, "200"),(400, "400"),(600, "600"),(800, "800"),(1000, "1000"),]),)
|
||||||
buttons = json.loads(settings.value("sample_viewing/zoom_buttons"))
|
buttons = json.loads(cfg.value("sample_viewing/zoom_buttons"))
|
||||||
|
|
||||||
if "backlight/backlight_pv" not in keys:
|
if "backlight/backlight_pv" not in keys:
|
||||||
settings.setValue("backlight/backlight_pv", "SAR-EXPMX:MOT_BLGT")
|
cfg.setValue("backlight/backlight_pv", "SAR-EXPMX:MOT_BLGT")
|
||||||
backlight_pv = settings.value("backlight/backlight_pv")
|
backlight_pv = cfg.value("backlight/backlight_pv")
|
||||||
|
|
||||||
if "sample_viewing/zoom_api" not in keys:
|
if "sample_viewing/zoom_api" not in keys:
|
||||||
settings.setValue("sample_viewing/zoom_api", "rest://pc12818.psi.ch:9999")
|
cfg.setValue("sample_viewing/zoom_api", "rest://pc12818.psi.ch:9999")
|
||||||
zoom_api = settings.value("sample_viewing/zoom_api")
|
zoom_api = cfg.value("sample_viewing/zoom_api")
|
||||||
|
|
||||||
#self.get_zoom_pv = PV(zoom_api + ":ZOOM-RBV", callback=self.zoom_update_cb)
|
#self.get_zoom_pv = PV(zoom_api + ":ZOOM-RBV", callback=self.zoom_update_cb)
|
||||||
#self.status_pv = PV(zoom_api + ":ZOOM-STATUS", callback=self.zoom_status_cb)
|
#self.status_pv = PV(zoom_api + ":ZOOM-STATUS", callback=self.zoom_status_cb)
|
||||||
|
|||||||
Reference in New Issue
Block a user