diff --git a/app_config.py b/app_config.py index ed004c0..6e370f1 100644 --- a/app_config.py +++ b/app_config.py @@ -11,7 +11,7 @@ settings = QSettings("Paul Scherrer Institut", "SwissMX") inst_folder = Path(__file__).absolute().parent config_file = inst_folder / "swissmx.yaml" -configs = yaml.load(config_file.read_text()) +configs = yaml.load(config_file.read_text(),Loader=yaml.FullLoader) endstation = configs["configure_for"] appsconf = configs[endstation] diff --git a/swissmx.py b/swissmx.py index 609c6a7..5d35538 100755 --- a/swissmx.py +++ b/swissmx.py @@ -1,28 +1,44 @@ -#!/usr/bin/env python3 -import time, os -import json -import random -import re -import signal -import threading +#!/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 + -from epics.ca import pend_event -from matplotlib import pyplot +bitmask for simulation: + 0x01: backlight + 0x02: illumination + 0x04: zoom + 0x08: camera + 0x10: Deltatau motors + 0x20: SmarAct motors + +''' +import logging +logging.getLogger('PyQt5.uic').setLevel(logging.INFO) +logging.getLogger('requests').setLevel(logging.INFO) +logging.getLogger('urllib3').setLevel(logging.INFO) +logging.getLogger('paramiko').setLevel(logging.INFO) +logging.getLogger('matplotlib').setLevel(logging.INFO) +logging.basicConfig(level=logging.DEBUG, format='%(levelname)s:%(module)s:%(lineno)d:%(funcName)s:%(message)s ') +_log = logging.getLogger("swissmx") + +import sys, os, time +import json, re +import random, signal #import Wigis #ZAC: orig. code -import app_utils #import jungfrau_widget #ZAC: orig. code #import bernina_pulse_picker #ZAC: orig. code -import qutilities #import storage #ZAC: orig. code - -from app_config import settings, appsconf, option, toggle_option, simulated - -# publisher = pubber.Publisher() - #from zmq_escape import zescape #ZAC: orig. code - #from helicalscan import HelicalScanGui #ZAC: orig. code +# publisher = pubber.Publisher() SKIP_ESCAPE_TRANSITIONS_IF_SAFE = "escape/skip_transitions_if_safe" @@ -33,7 +49,6 @@ 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" @@ -47,109 +62,6 @@ EXPERIMENT_UID = "experiment/uid" ACTIVATE_PULSE_PICKER = "scanning/activate_pulse_picker" - -import logging -logging.getLogger("PyQt5.uic").setLevel(logging.CRITICAL) -logging.getLogger("requests").setLevel(logging.CRITICAL) -logging.getLogger("urllib3").setLevel(logging.CRITICAL) -logging.getLogger("paramiko").setLevel(logging.CRITICAL) -logging.basicConfig(level=logging.DEBUG, format='%(levelname)s:%(module)s:%(lineno)d:%(funcName)s:%(message)s ') -logger = logging.getLogger("swissmx") - -#import PrelocatedCoordinatesModel #ZAC: orig. code -#from EmblModule import EmblWidget #ZAC: orig. code -#from HelicalTable import HelicalTableWidget #ZAC: orig. code -#from Wigis import Spinner, Checkbox #ZAC: orig. code -import camera -import epics -import numpy as np - -#from exceptions import * #ZAC: orig. code - -#import qoptic #ZAC: orig. code - -from backlight import Backlight - -backlight = Backlight() - -#import mx_swissfel #ZAC: orig. code - -#swissfel = mx_swissfel.SwissFELMachine() #ZAC: orig. code - -import qtawesome - -#from bernina_pulse_picker import pulsePicker #ZAC: orig. code - -from PyQt5 import QtCore, QtGui -from PyQt5.QtCore import Qt, pyqtSlot, QSize, QRegExp, pyqtSignal, QObject, QThread -from PyQt5.QtGui import QKeySequence, QPixmap, QRegExpValidator -from PyQt5.QtWidgets import ( - QLabel, - QGroupBox, - QVBoxLayout, - QPushButton, - QWidget, - QHBoxLayout, - QGridLayout, - QDoubleSpinBox, - QLineEdit, - QSpinBox, - QFormLayout, - QShortcut, - QMessageBox, - QAction, - QSplashScreen, - QProgressBar, - QSizePolicy, - QToolBox, - QPlainTextEdit, - QTextBrowser, - QProgressDialog, - QFileDialog, -) -from PyQt5.uic import loadUiType - -from CustomROI import BeamMark -#from CustomROI import BeamMark, Grid, CrystalCircle #ZAC: orig. code -#from GenericDialog import GenericDialog #ZAC: orig. code -#from dialogs.PreferencesDialog import PreferencesDialog #ZAC: orig. code -#from epics_widgets import zoom #ZAC: orig. code -from epics_widgets.MotorTweak import MotorTweak -from epics_widgets.SmaractMotorTweak import SmaractMotorTweak -import zoom - - -_URL = "http://PC12288:8080" -# import TellClient - -# tell = TellClient.TellClient(_URL) - -#import eventer #ZAC: orig. code - -#from detector_control import jungfrau_detector #ZAC: orig. code - -#from findxtal import findObj #ZAC: orig. code - -import pyqtgraph as pg -import pyqtgraph.exporters - -#if simulated: #ZAC: orig. code #ZAC: orig. code -# logger.warning("simulation mode enabled") -# qoptic_zoom = qoptic.FeturaClientBogus() -#else: -# qoptic_zoom = qoptic.FeturaClient() - -pg.setConfigOption("antialias", True) -#from epics_widgets import MotorTweak - -Ui_MainWindow, QMainWindow = loadUiType("swissmx.ui") - -#user = getpass.getuser() #ZAC: orig. code -#home = os.path.expanduser("~") -#just_quit = user in ["e10003", "gac-esbmx"] - -#folders = storage.Folders() #ZAC: orig. code - TASK_JUNGFRAU_SETTINGS = "jungfrau_settings" TASK_SETUP_PPM_CALIBRATION = "ppm_calibration" TASK_SETUP_PPM_CALIBRATION_TBOX = "ppm_calibration_tbox" @@ -165,31 +77,82 @@ TASK_HELICAL = "helical" TASK_EMBL = "embl" -#from deltatau import DeltaTau, shapepath, helical, DebugPlot #ZAC: orig. code +#import PrelocatedCoordinatesModel #ZAC: orig. code +#from EmblModule import EmblWidget #ZAC: orig. code +#from HelicalTable import HelicalTableWidget #ZAC: orig. code +#from Wigis import Spinner, Checkbox #ZAC: orig. code +#from exceptions import * #ZAC: orig. code +#import qoptic #ZAC: orig. code +#import mx_swissfel #ZAC: orig. code +#swissfel = mx_swissfel.SwissFELMachine() #ZAC: orig. code +#from bernina_pulse_picker import pulsePicker #ZAC: orig. code +import qtawesome +import qutilities +from PyQt5 import QtCore, QtGui +from PyQt5.QtCore import Qt, pyqtSlot, QSize, QRegExp, pyqtSignal, QObject, QThread +from PyQt5.QtGui import QKeySequence, QPixmap, QRegExpValidator +from PyQt5.QtWidgets import ( + QAction, QApplication, QDoubleSpinBox, QFormLayout, QGridLayout, QGroupBox, QHBoxLayout, QLabel, QLineEdit, + QMessageBox, QPlainTextEdit, QProgressBar, QProgressDialog, QPushButton, QShortcut, QSizePolicy, QSpinBox, + QSplashScreen, QTextBrowser, QToolBox, QVBoxLayout, QWidget,) +from PyQt5.uic import loadUiType + +from CustomROI import BeamMark +#from CustomROI import BeamMark, Grid, CrystalCircle #ZAC: orig. code +#from GenericDialog import GenericDialog #ZAC: orig. code +#from dialogs.PreferencesDialog import PreferencesDialog #ZAC: orig. code +#from epics_widgets import zoom #ZAC: orig. code +from epics_widgets.MotorTweak import MotorTweak +from epics_widgets.SmaractMotorTweak import SmaractMotorTweak + +from matplotlib import pyplot +import numpy as np +import pyqtgraph as pg +import pyqtgraph.exporters +pg.setConfigOption("antialias", True) + +import app_utils +from app_config import settings, appsconf, option, toggle_option, simulated + +import epics +from epics.ca import pend_event +import camera,backlight,zoom,illumination + + +#_URL = "http://PC12288:8080" +# import TellClient +# tell = TellClient.TellClient(_URL) + +#import eventer #ZAC: orig. code +#from detector_control import jungfrau_detector #ZAC: orig. code +#from findxtal import findObj #ZAC: orig. code + +#if simulated: #ZAC: orig. code #ZAC: orig. code +# _log.warning("simulation mode enabled") +# qoptic_zoom = qoptic.FeturaClientBogus() +#else: +# qoptic_zoom = qoptic.FeturaClient() + +#from epics_widgets import MotorTweak + + +#user = getpass.getuser() #ZAC: orig. code +#home = os.path.expanduser("~") +#just_quit = user in ["e10003", "gac-esbmx"] + +#folders = storage.Folders() #ZAC: orig. code + +#from deltatau import DeltaTau, shapepath, helical, DebugPlot #ZAC: orig. code #delta_tau = DeltaTau() #ZAC: orig. code - -BROKER_SERVER = "127.0.0.1" -BROKER_PORT = 61613 +#BROKER_SERVER = "127.0.0.1" #ZAC: orig. code +#BROKER_PORT = 61613 #ZAC: orig. code # sample_camera = camera.camera_server(basename="SARES20-PROF142-M1") -logger.info( - f"connecting to microscope to camera server: {appsconf['microscope']['sample_camera']['pv_prefix']} " -) -#sample_camera = camera.camera_server( #ZAC: orig. code -# basename=appsconf["microscope"]["sample_camera"]["pv_prefix"] -#) - -#sample_camera = camera.epics_cam(appsconf["microscope"]["sample_camera"]["pv_prefix"]) -sample_camera = camera.epics_cam(None) -sample_camera.sim_gen(mode=0) -sample_camera.run() -# sample_camera.set_transformations([camera.Transforms.FLIP_LR, camera.Transforms.ROTATE_270]) - - - +#_log.info(f"connecting to microscope to camera server: {appsconf['microscope']['sample_camera']['pv_prefix']} ") +#sample_camera = camera.camera_server(basename=appsconf["microscope"]["sample_camera"]["pv_prefix"]) #ZAC: orig. code def print_transform(t): m11 = t.m11() @@ -228,11 +191,12 @@ class Sequencer(QObject): def run_sequence(self): num_steps = len(self.steps) for n, step in enumerate(self.steps): - logger.info("runing step {}/{}".format(n, num_steps)) + _log.info("runing step {}/{}".format(n, num_steps)) step() - logger.info("emiting finished") + _log.info("emiting finished") self.finished.emit() +Ui_MainWindow, QMainWindow = loadUiType("swissmx.ui") class Main(QMainWindow, Ui_MainWindow): pixelsPerMillimeter = pyqtSignal(float) @@ -248,9 +212,7 @@ class Main(QMainWindow, Ui_MainWindow): fast_y_position = pyqtSignal(float) fast_dx_position = pyqtSignal(float) fast_dy_position = pyqtSignal(float) - fiducialPositionSelected = pyqtSignal( - float, float, float, float - ) # camx, camy, gonx, gony + fiducialPositionSelected = pyqtSignal(float, float, float, float) # camx, camy, gonx, gony appendPrelocatedPosition = pyqtSignal(float, float, float, float) appendPrelocatedFiducial = pyqtSignal(bool, float, float, float, float) increaseRunNumberRequest = pyqtSignal() @@ -267,19 +229,13 @@ class Main(QMainWindow, Ui_MainWindow): self.setWindowTitle(title) self._do_quit = False - qtawesome.load_font( - "material", - "MaterialIcons-Regular.ttf", - "MaterialIcons-Regular.json", - "fonts/", - ) + qtawesome.load_font("material", "MaterialIcons-Regular.ttf", "MaterialIcons-Regular.json", "fonts/",) QtGui.QFontDatabase.addApplicationFont("fonts/Inconsolata-Bold.ttf") QtGui.QFontDatabase.addApplicationFont("fonts/Baloo-Regular.ttf") self._pv_shutter = None # epics.PV('X06SA-ES-MD2:SHUTTER') self._has_pulse_picker = False - self._has_camera = True self._at_x06sa = False self._at_cristalina = True self._at_lab_eh060 = False @@ -375,7 +331,7 @@ class Main(QMainWindow, Ui_MainWindow): self.center_piece_update(0) # start camera updater #curzoom = qoptic_zoom.get_position(cached=False) #ZAC: orig. code - #logger.debug(f"starting app with zoom at {curzoom}") + #_log.debug(f"starting app with zoom at {curzoom}") #self.zoom_changed_cb(curzoom) self._tabs_daq_methods.currentChanged.connect(self.switch_task) self.switch_task() @@ -441,7 +397,7 @@ class Main(QMainWindow, Ui_MainWindow): self.img.setImage(img) def init_settings_tracker(self): - logger.info("configuring widget persistence") + _log.info("configuring widget persistence") fields = { # 'folder': (self._label_folder, str), "project": (self._le_project, str), @@ -456,49 +412,33 @@ class Main(QMainWindow, Ui_MainWindow): value = settings.value(key) try: wset, wget = widget.setText, widget.text - logger.debug("tracking text field {}".format(key)) + _log.debug("tracking text field {}".format(key)) except AttributeError: - logger.debug("tracking {} number field {}".format(conv, key)) + _log.debug("tracking {} number field {}".format(conv, key)) wset, wget = widget.setValue, lambda fget=widget.value: conv(fget()) except Exception as e: - logger.error(e) + _log.error(e) try: wset(conv(value)) except Exception as e: - logger.debug(e) - logger.warning( - 'failed for "{}" updating field of type {} with {}'.format( - key, type(widget), value - ) - ) + _log.debug(e) + _log.warning('failed for "{}" updating field of type {} with {}'.format( key, type(widget), value)) finally: - # logger.debug('wget = {}; wset = {}'.format(wget, wset)) - widget.editingFinished.connect( - lambda w=widget, k=key, func_get=wget: self.persist_setting( - k, func_get() - ) - ) + # _log.debug('wget = {}; wset = {}'.format(wget, wset)) + widget.editingFinished.connect(lambda w=widget, k=key, func_get=wget: self.persist_setting(k, func_get() ) ) #self.storage_cascade_prefix(None) #ZAC: orig. code def init_validators(self): identifier_regex = QRegExp("[a-z-A-Z_0-9%]+") - self._le_project.setValidator( - QRegExpValidator(identifier_regex, self._le_project) - ) - self._le_prefix.setValidator( - QRegExpValidator(identifier_regex, self._le_prefix) - ) + self._le_project.setValidator(QRegExpValidator(identifier_regex, self._le_project)) + self._le_prefix.setValidator(QRegExpValidator(identifier_regex, self._le_prefix)) def wire_storage(self): self._le_prefix.textChanged.connect(self.storage_cascade_prefix) - self._le_prefix.textChanged.connect( - lambda newtext: self.prefixChanged.emit(newtext) - ) + self._le_prefix.textChanged.connect(lambda newtext: self.prefixChanged.emit(newtext)) self._le_project.textChanged.connect(self.storage_cascade_prefix) - self._le_project.textChanged.connect( - lambda newtext: self.projectChanged.emit(newtext) - ) + self._le_project.textChanged.connect(lambda newtext: self.projectChanged.emit(newtext)) self._le_prefix.editingFinished.connect(self.prepare_daq_folder) self._le_project.editingFinished.connect(self.prepare_daq_folder) self.increaseRunNumberRequest.connect(self.increase_run_number) @@ -506,7 +446,7 @@ class Main(QMainWindow, Ui_MainWindow): def storage_cascade_prefix(self, val): prefix = self._le_prefix.text() if 0 == len(prefix): - logger.warning("empty prefix is not accepted") + _log.warning("empty prefix is not accepted") self._le_prefix.setAccessibleName("invalid_input") self._le_prefix.blockSignals(True) self._le_prefix.setText("INVALID=>" + prefix) @@ -544,41 +484,37 @@ class Main(QMainWindow, Ui_MainWindow): os.makedirs(folder, 0o750, exist_ok=True) except: msg = "Failed to create folder: {}".format(folder) - logger.warning(msg) - QMessageBox.warning( - self, - "Screenshot: failed to create folder", - "Failed to create output folder for screenshot!\n\n\tScreenshot not taken!", - ) + _log.warning(msg) + QMessageBox.warning(self, "Screenshot: failed to create folder", "Failed to create output folder for screenshot!\n\n\tScreenshot not taken!",) raise fname = os.path.join(folders.pgroup_folder, ".latest_raw") try: with open(fname, "w") as f: f.write(folders.raw_folder) - logger.info("wrote: {}".format(fname)) + _log.info("wrote: {}".format(fname)) except: - logger.warning("failed writing {}".format(fname)) + _log.warning("failed writing {}".format(fname)) fname = os.path.join(folders.pgroup_folder, ".latest_res") try: with open(fname, "w") as f: f.write(folders.res_folder) - logger.info("wrote: {}".format(fname)) + _log.info("wrote: {}".format(fname)) except: - logger.warning("failed writing {}".format(fname)) + _log.warning("failed writing {}".format(fname)) def persist_setting(self, s, v): - logger.debug("persisting {} = {}".format(s, v)) + _log.debug("persisting {} = {}".format(s, v)) settings.setValue(s, v) def method_changed(self, index): method = self._tabs_daq_methods.currentWidget().accessibleName() - logger.info("method now => {}".format(method)) + _log.info("method now => {}".format(method)) def center_piece_update(self, index): if index > 0: # not showing camera image - logger.warning("listening to zescape") + _log.warning("listening to zescape") self.timer.stop() zescape.start_listening() self.timer = QtCore.QTimer(self) @@ -586,7 +522,7 @@ class Main(QMainWindow, Ui_MainWindow): self.timer.start(20) else: #zescape.stop_listening() #ZAC: orig. code - logger.warning("re-starting timer on camera update") + _log.warning("re-starting timer on camera update") try: self.timer.stop() except: @@ -600,14 +536,14 @@ class Main(QMainWindow, Ui_MainWindow): if msg is None: return if "current" in msg: - logger.warning(f"current state: {self._escape_current_state}") + _log.warning(f"current state: {self._escape_current_state}") zescape.reply(self._escape_current_state) elif "goto" in msg: state = msg.split()[1].lower() - logger.warning(f"TELL requests to go to {state}") + _log.warning(f"TELL requests to go to {state}") try: if "sampleexchange" in state: - logger.debug( + _log.debug( f"moving to mount with offset = {self._pin_mounting_offset}" ) self.move_gonio_to_mount_position(offset=self._pin_mounting_offset) @@ -619,24 +555,24 @@ class Main(QMainWindow, Ui_MainWindow): else: # JSON data = json.loads(msg) if "sampleName" in data: - logger.debug(f"TELL SAMPLE DATA => {data}") + _log.debug(f"TELL SAMPLE DATA => {data}") self.tell2storage(data) zescape.reply("ack") elif "pin_offset" in data: - logger.debug(f"TELL pin offset => {data}") + _log.debug(f"TELL pin offset => {data}") self._pin_mounting_offset = data["pin_offset"] zescape.reply("ack") elif "get_pin_offset" in data: - logger.debug(f"TELL get pin offset => {data}") + _log.debug(f"TELL get pin offset => {data}") zescape.reply_json({"pin_offset": self._pin_mounting_offset}) def tell2storage(self, sample): - logger.debug(f"2 TELL SAMPLE DATA => {type(sample)}") + _log.debug(f"2 TELL SAMPLE DATA => {type(sample)}") self._le_prefix.setText(sample["sampleName"]) self._le_project.setText(sample["sampleFolder"]) tstf = folders.get_prefixed_file("_newsample") self.storage_cascade_prefix(None) - logger.warning(f"sample info: {tstf}") + _log.warning(f"sample info: {tstf}") def switch_task(self, index=0): stack = self._centerpiece_stack @@ -644,11 +580,7 @@ class Main(QMainWindow, Ui_MainWindow): setup_task = self._setup_toolbox.currentWidget().accessibleName() method = self._tabs_daq_methods.currentWidget().accessibleName() - logger.debug( - "Task switching: top_tabs={} exp.method={} setup_task={}".format( - task, method, setup_task - ) - ) + _log.debug("Task switching: top_tabs={} exp.method={} setup_task={}".format(task, method, setup_task)) if task == "task_experiment": stack.setCurrentIndex(0) @@ -660,17 +592,13 @@ class Main(QMainWindow, Ui_MainWindow): active_task = TASK_SAMPLE_SELECTION stack.setCurrentIndex(1) else: - logger.error("BUG: un-handled task") - QMessageBox.warning( - self, - "BUG unhandled task!", - "unhandled task: top_tabs={} method={}".format(task, method), - ) + _log.error("BUG: un-handled task") + QMessageBox.warning(self, "BUG unhandled task!", "unhandled task: top_tabs={} method={}".format(task, method),) self.set_active_task(active_task) self._status_task.setText(active_task) def set_active_task(self, task): - logger.info("TASK == {}".format(task)) + _log.info("TASK == {}".format(task)) self._active_task = task def active_task(self): @@ -709,9 +637,7 @@ class Main(QMainWindow, Ui_MainWindow): # add layouts exp_tab.setLayout(QVBoxLayout()) setup_tab.setLayout(QVBoxLayout()) - setup_tab.setSizePolicy( - QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) - ) + setup_tab.setSizePolicy(QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)) self._setup_toolbox = tbox = QToolBox() tbox.setSizePolicy(QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Ignored)) # tbox.setMinimumWidth(itemWidget.sizeHint().width()) @@ -808,33 +734,19 @@ class Main(QMainWindow, Ui_MainWindow): #) #ZAC: orig. code grp.layout().addWidget(but, 1, 0) but = QPushButton("Turn 90 CW") - #but.clicked.connect( - # lambda bogus, n=camera.Transforms.ROTATE_270: self.modify_camera_transform( - # n - # ) - #) #ZAC: orig. code + #but.clicked.connect(lambda bogus, n=camera.Transforms.ROTATE_270: self.modify_camera_transform(n)) #ZAC: orig. code grp.layout().addWidget(but) but = QPushButton("Turn 180 CCW") - #but.clicked.connect( - # lambda bogus, n=camera.Transforms.ROTATE_180: self.modify_camera_transform( - # n - # ) - #) #ZAC: orig. code + #but.clicked.connect(lambda bogus, n=camera.Transforms.ROTATE_180: self.modify_camera_transform(n)) #ZAC: orig. code grp.layout().addWidget(but) but = QPushButton("Transpose") - #but.clicked.connect( - # lambda bogus, n=camera.Transforms.TRANSPOSE: self.modify_camera_transform(n) - #) #ZAC: orig. code + #but.clicked.connect(lambda bogus, n=camera.Transforms.TRANSPOSE: self.modify_camera_transform(n)) #ZAC: orig. code grp.layout().addWidget(but) but = QPushButton("Flip L/R") - #but.clicked.connect( - # lambda bogus, n=camera.Transforms.FLIP_LR: self.modify_camera_transform(n) - #) #ZAC: orig. code + #but.clicked.connect(lambda bogus, n=camera.Transforms.FLIP_LR: self.modify_camera_transform(n)) #ZAC: orig. code grp.layout().addWidget(but) but = QPushButton("Flip U/D") - #but.clicked.connect( - # lambda bogus, n=camera.Transforms.FLIP_UD: self.modify_camera_transform(n) - #) #ZAC: orig. code + #but.clicked.connect(lambda bogus, n=camera.Transforms.FLIP_UD: self.modify_camera_transform(n)) #ZAC: orig. code grp.layout().addWidget(but) row = grp.layout().rowCount() self._label_transforms = QLabel() @@ -919,7 +831,7 @@ class Main(QMainWindow, Ui_MainWindow): pulsePicker.close() jungfrau_detector.abort() delta_tau.abort() - logger.debug("aborting measurement") + _log.debug("aborting measurement") def trigger_detector(self, **kwargs): if self._pv_shutter is not None: @@ -1004,28 +916,28 @@ class Main(QMainWindow, Ui_MainWindow): ok = True except: ok = False - logger.warning("beam marker not defined") + _log.warning("beam marker not defined") return - logger.debug("updating beam mark to {:.1f}x{:.1f}".format(bx, by)) + _log.debug("updating beam mark to {:.1f}x{:.1f}".format(bx, by)) self.beamCameraCoordinatesChanged.emit(bx, by) def update_beam_marker_fitters(self): if len(self._beam_markers) > 2: - logger.debug("defining beam marker") + _log.debug("defining beam marker") bx = [(n, x[0]) for n, x in self._beam_markers.items()] by = [(n, x[1]) for n, x in self._beam_markers.items()] nbx = np.asarray(bx).T nby = np.asarray(by).T bx_coefs = np.polyfit(nbx[0], nbx[1], 3) by_coefs = np.polyfit(nby[0], nby[1], 3) - logger.debug(".... beam marker X coeficients {}".format(bx_coefs)) - logger.debug(".... beam marker Y coeficients {}".format(by_coefs)) + _log.debug(".... beam marker X coeficients {}".format(bx_coefs)) + _log.debug(".... beam marker Y coeficients {}".format(by_coefs)) self.beamx_fitter = np.poly1d(bx_coefs) self.beamy_fitter = np.poly1d(by_coefs) def update_ppm_fitters(self, calib=None): if calib is not None: - logger.info("received new calibration for PPM") + _log.info("received new calibration for PPM") self._zoom_to_ppm = calib # self._zoom_to_ppm = { # FIXME: eventually automate @@ -1049,15 +961,11 @@ class Main(QMainWindow, Ui_MainWindow): else: order = 4 - logger.debug( - "polynomial fitting using {} data points of order {}".format( - num_points, order - ) - ) + _log.debug("polynomial fitting using {} data points of order {}".format(num_points, order)) bx = [(z, ppm) for z, ppm in self._zoom_to_ppm.items()] nbx = np.asarray(bx).T bx_coefs = np.polyfit(nbx[0], nbx[1], order) - logger.debug(".... ppm fitting coeficients {}".format(bx_coefs)) + _log.debug(".... ppm fitting coeficients {}".format(bx_coefs)) self.ppm_fitter = np.poly1d(bx_coefs) def getFastX(self): @@ -1071,9 +979,9 @@ class Main(QMainWindow, Ui_MainWindow): try: ppm = self.ppm_fitter(value) except AttributeError as e: - logger.warning(e) + _log.warning(e) else: - logger.debug("zoom callback zoomChanged.emit({}), pixelsPerMillimeter.emit({})".format(value, ppm)) + _log.debug("zoom callback zoomChanged.emit({}), pixelsPerMillimeter.emit({})".format(value, ppm)) self.pixelsPerMillimeter.emit(ppm) self.update_beam_marker(value) @@ -1085,13 +993,13 @@ class Main(QMainWindow, Ui_MainWindow): try: ppm_fitter = self.ppm_fitter(self.getZoom()) except Exception as e: - logger.error("garbage in getPpm()") + _log.error("garbage in getPpm()") traceback.print_exc() return ppm_fitter def append_to_beam_markers(self, x, y, zoom): self._beam_markers[zoom] = (x, y) - logger.info("beam markers {}".format(self._beam_markers)) + _log.info("beam markers {}".format(self._beam_markers)) settings.setValue(BEAM_MARKER_POSITIONS, self._beam_markers) self.update_beam_marker_fitters() @@ -1105,10 +1013,10 @@ class Main(QMainWindow, Ui_MainWindow): w, h = roi.size() # area = roi.getArrayRegion(self._im, self.img) # sum = np.sum(area) - # logger.info('{} => sum {}'.format((x,y), sum)) + # _log.info('{} => sum {}'.format((x,y), sum)) bx, by = x + w / 2., y + h / 2. - logger.info("beam pos {}".format((bx, by))) - logger.info("marker pos = {} ; size = {}".format((x, y), (w, h))) + _log.info("beam pos {}".format((bx, by))) + _log.info("marker pos = {} ; size = {}".format((x, y), (w, h))) def toggle_mouse_tracking(self): if self._mouse_tracking: @@ -1158,29 +1066,20 @@ class Main(QMainWindow, Ui_MainWindow): "\u23FA{:>}:{:<.0f}" "\u23FA{:>}:{:>6.1f} {:<.1f} \u00B5" "\u23FA{:>}:{:>7.3f} {:<.3f} mm".format( - "Beam at", - bx, - by, - "Pixel coord ", - x, - y, - "PPM", - ppm, - "Distance to beam", - 1000 * dx, - 1000 * dy, - "Stage", - fx, - fy, + "Beam at", bx, by, + "Pixel coord ", x, y, + "PPM", ppm, + "Distance to beam", 1000 * dx, 1000 * dy, + "Stage", fx, fy, ) ) def mouse_click_event(self, event): fx_motor, fy_motor, bx_motor, bz_motor, omega_motor = self.get_gonio_tweakers() - logger.debug("{}".format(event)) - logger.debug(" pos {}".format(event.pos())) - logger.debug("screen pos {}".format(event.screenPos())) - logger.debug("scene pos {}".format(event.scenePos())) + _log.debug("{}".format(event)) + _log.debug(" pos {}".format(event.pos())) + _log.debug("screen pos {}".format(event.screenPos())) + _log.debug("scene pos {}".format(event.scenePos())) task = self.active_task() @@ -1190,7 +1089,7 @@ class Main(QMainWindow, Ui_MainWindow): return pos = event.scenePos() zoom_level = qoptic_zoom.get_position() - logger.debug(" zoom {}".format(zoom_level)) + _log.debug(" zoom {}".format(zoom_level)) try: ppm = self.ppm_fitter(zoom_level) @@ -1207,10 +1106,10 @@ class Main(QMainWindow, Ui_MainWindow): a = np.asarray([x, y]) b = np.asarray([bx, by]) pixel_dist = np.linalg.norm(a - b) - logger.debug("distance to beam: {:.1f} pixels".format(pixel_dist)) + _log.debug("distance to beam: {:.1f} pixels".format(pixel_dist)) omega = omega_motor.motor.get_position() - logger.debug("omega at {:.03f} degrees".format(omega)) + _log.debug("omega at {:.03f} degrees".format(omega)) fx = fx_motor.motor.get_position() fy = fy_motor.motor.get_position() @@ -1219,30 +1118,30 @@ class Main(QMainWindow, Ui_MainWindow): fx += dx fy += dy - logger.debug("click at : {:.3f} {:.3f}".format(x, y)) - logger.debug("beam at : {:.3f} {:.3f}".format(bx, by)) - logger.debug("gonio at : {:.3f} {:.3f}".format(fx, fy)) + _log.debug("click at : {:.3f} {:.3f}".format(x, y)) + _log.debug("beam at : {:.3f} {:.3f}".format(bx, by)) + _log.debug("gonio at : {:.3f} {:.3f}".format(fx, fy)) # publisher.submit( # {"event": "gonio", "data": self.get_gonio_positions(as_json=True)} # ) - logger.debug("TASK = {}".format(task)) + _log.debug("TASK = {}".format(task)) # Click without modifers moves clicked position to beam mark if task not in (TASK_SETUP_PPM_CALIBRATION, TASK_SETUP_BEAM_CENTER): if not (ctrl or shft or alt): if ppm == 0: - logger.warning("PPM is not defined - do the PPM calibration") + _log.warning("PPM is not defined - do the PPM calibration") if task == TASK_HELICAL: dx = (x - bx) / ppm dy = -(y - by) / ppm - logger.info("moving base_X, fast_Y {:.3f}, {:.3f}".format(dx, dy)) + _log.info("moving base_X, fast_Y {:.3f}, {:.3f}".format(dx, dy)) bx_motor.move_relative(dx) fy_motor.move_relative(dy) else: dx = np.cos(omega * np.pi / 180) * (x - bx) / ppm dy = -(y - by) / ppm - logger.info("moving fast x/y to {:.3f}, {:.3f}".format(dx, dy)) + _log.info("moving fast x/y to {:.3f}, {:.3f}".format(dx, dy)) fx_motor.move_relative(dx) fy_motor.move_relative(dy) self.fast_dx_position.emit(dx) @@ -1252,7 +1151,7 @@ class Main(QMainWindow, Ui_MainWindow): # CTRL-Click always just moves Z if ctrl and not (shft or alt): mm = np.sign(y - by) * pixel_dist / 10000. - logger.debug("moving Z stage by {:.3f} mm".format(mm)) + _log.debug("moving Z stage by {:.3f} mm".format(mm)) bz_motor.move_relative(mm) return @@ -1263,30 +1162,26 @@ class Main(QMainWindow, Ui_MainWindow): b = self._ppm_click pixel_dist = np.linalg.norm(a - b) ppm = pixel_dist / feature_dist - logger.debug("calib save a {}".format(a)) - logger.debug("calib save b {}".format(b)) - logger.debug(" feature {}".format(feature_dist)) - logger.debug("a -> b pixels {}".format(pixel_dist)) - logger.debug(" ppm({}) {}".format(zoom_level, pixel_dist)) + _log.debug("calib save a {}".format(a)) + _log.debug("calib save b {}".format(b)) + _log.debug(" feature {}".format(feature_dist)) + _log.debug("a -> b pixels {}".format(pixel_dist)) + _log.debug(" ppm({}) {}".format(zoom_level, pixel_dist)) self._zoom_to_ppm[zoom_level] = ppm settings.setValue(CAMERA_ZOOM_TO_PPM, self._zoom_to_ppm) self._ppm_click = None - logger.debug("ppm data so far {}".format(self._zoom_to_ppm)) + _log.debug("ppm data so far {}".format(self._zoom_to_ppm)) else: - logger.debug("calib save b {}".format(a)) + _log.debug("calib save b {}".format(a)) self._ppm_click = a return elif task == TASK_SETUP_BEAM_CENTER: if ctrl and not (shft or alt): - logger.info( - "beam mark add: zoom {} => {:.1f} {:.1f}".format( - zoom_level, x, y - ) - ) + _log.info("beam mark add: zoom {} => {:.1f} {:.1f}".format(zoom_level, x, y)) self.append_to_beam_markers(x, y, zoom_level) else: - logger.warning("click combination not available") + _log.warning("click combination not available") elif task == TASK_POINT_SHOOT: pass elif task == TASK_GRID: @@ -1297,16 +1192,16 @@ class Main(QMainWindow, Ui_MainWindow): omegacos = option(DELTATAU_OMEGACOS) if omegacos: fx = fx / np.cos(omega * np.pi / 180) - logger.info( + _log.info( "selectin fiducial (omegacos): {:.3f}, {:.3f}".format(fx, fy) ) else: - logger.info("selectin fiducial: {:.3f}, {:.3f}".format(fx, fy)) + _log.info("selectin fiducial: {:.3f}, {:.3f}".format(fx, fy)) self.fiducialPositionSelected.emit(x, y, fx, fy) elif shft and alt: self.appendPrelocatedPosition.emit(x, y, fx, fy) elif task == TASK_HELICAL: - logger.info("no action associated ") + _log.info("no action associated ") elif task == TASK_EMBL: pass else: @@ -1447,9 +1342,7 @@ class Main(QMainWindow, Ui_MainWindow): t_cz = float(settings.value(bmark + "/mount_cz")) t_omega = float(settings.value(bmark + "/mount_omega")) except: - raise IncompleteConfiguration( - "TELL sample changer mount position is not configured!!!" - ) + raise IncompleteConfiguration("TELL sample changer mount position is not configured!!!") fx.move(t_fx, wait=True, ignore_limits=True) fy.move(t_fy, wait=True, ignore_limits=True) cx.move(t_cx, wait=True, ignore_limits=True) @@ -1468,20 +1361,8 @@ class Main(QMainWindow, Ui_MainWindow): def lock_goniometer(self): # tell.set_in_mount_position(True) - res = QMessageBox.question( - self, - "", - "Mount a sample from console and click ok once the sample is mounted.", - QMessageBox.Ok, - QMessageBox.Ok, - ) - res = QMessageBox.question( - self, - "", - "Is the sample is mounted?", - QMessageBox.Yes | QMessageBox.No, - QMessageBox.No, - ) + res = QMessageBox.question(self, "", "Mount a sample from console and click ok once the sample is mounted.", QMessageBox.Ok, QMessageBox.Ok,) + res = QMessageBox.question(self, "", "Is the sample is mounted?", QMessageBox.Yes | QMessageBox.No, QMessageBox.No,) if res in (QMessageBox.Yes, QMessageBox.No): # tell.set_in_mount_position(False) pass @@ -1498,15 +1379,11 @@ class Main(QMainWindow, Ui_MainWindow): ) bmark = "bookmark_{}".format(key) if key == 0: - ans = QMessageBox.question( - self, - "Override TELL mount position", - "This will overwrite the positions used for TELL MOUNTING!!!\n\n\tContinue ?", - ) + ans = QMessageBox.question(self, "Override TELL mount position", "This will overwrite the positions used for TELL MOUNTING!!!\n\n\tContinue ?",) if ans != QMessageBox.Yes: return - logger.info( + _log.info( "saving bookmark {}: {}, {}, {}, {}, {}".format( bmark, fx.get_position(), @@ -1559,9 +1436,7 @@ class Main(QMainWindow, Ui_MainWindow): if 1e9 < x_pos + y_pos + dx + dy: raise IncompleteConfiguration("COLLIMATOR configuration is incomplete!") - logger.info( - "moving collimator {} to X,Y = {:.3f}, {:.3f}".format(pos, x_pos, y_pos) - ) + _log.info("moving collimator {} to X,Y = {:.3f}, {:.3f}".format(pos, x_pos, y_pos)) if pos == "out": cy.move_motor_to_position(y_pos + dy, assert_position=True) @@ -1584,9 +1459,7 @@ class Main(QMainWindow, Ui_MainWindow): to_pos = settings.value(key, 1e10, type=float) if to_pos > 1e9: - raise IncompleteConfiguration( - f"CRYOJET configuration is incomplete! Missing {key}" - ) + raise IncompleteConfiguration(f"CRYOJET configuration is incomplete! Missing {key}") cx.move_motor_to_position(to_pos, assert_position=True) def setup_sliders(self): @@ -1602,16 +1475,10 @@ class Main(QMainWindow, Ui_MainWindow): elif self._at_lab_eh060: zoom_base = "/dev/ttyUSB0" # direct connection using fetura.py package elif self._at_cristalina: - zoom_base = ( - "rest://pc12818.psi.ch:9999" - ) # direct connection using fetura.py package + zoom_base = ("rest://pc12818.psi.ch:9999") # direct connection using fetura.py package - if self._has_camera: - samcam = sample_camera - else: - samcam = None self.zoombox = zoom.Zoom() - self.zoombox.configure(camera=samcam) + self.zoombox.configure() self.zoombox.zoomChanged.connect(self.zoom_changed_cb) self.zoombox.moveBacklight.connect(self.safe_backlight_move) @@ -1620,56 +1487,7 @@ class Main(QMainWindow, Ui_MainWindow): toolbox = QToolBox() layout.addWidget(toolbox) - qutilities.add_item_to_toolbox( - toolbox, - "Fast Stage", - widget_list=[ - # self.get_tweaker('SAR-EXPMX:MOT_BLGT', alias='backlight', label='backlight'), - self.get_tweaker("SAR-EXPMX:MOT_FY", alias="fast_y", label="fast Y"), - self.get_tweaker("SAR-EXPMX:MOT_FX", alias="fast_x", label="fast X"), - self.get_tweaker( - "SAR-EXPMX:MOT_ROT_Y", - alias="omega", - label="omega", - tweak_min=0.001, - tweak_max=180.0, - ), - self.get_tweaker("SAR-EXPMX:MOT_CX", alias="base_x", label="base X"), - self.get_tweaker("SAR-EXPMX:MOT_CZ", alias="base_z", label="base Z"), - ], - ) - - # qutilities.add_item_to_toolbox( - # toolbox, - # "Wedge Mover", - # widget_list=[ - # self.get_tweaker( - # "SAR-EXPMX:MOT_WEDGE1", alias="wedge_1", label="wedge_1" - # ), - # self.get_tweaker( - # "SAR-EXPMX:MOT_WEDGE2", alias="wedge_2", label="wedge_2" - # ), - # self.get_tweaker( - # "SAR-EXPMX:MOT_WEDGE3", alias="wedge_3", label="wedge_3" - # ), - # self.get_tweaker( - # "SAR-EXPMX:MOT_WEDGE4", alias="wedge_4", label="wedge_4" - # ), - # self.get_tweaker( - # "SAR-EXPMX:MOT_WEDGEX", alias="wedge_x", label="wedge_x" - # ), - # self.get_tweaker( - # "SAR-EXPMX:MOT_WEDGEY", alias="wedge_y", label="wedge_y" - # ), - # self.get_tweaker( - # "SAR-EXPMX:MOT_WEDGEA", alias="wedge_a", label="wedge_a" - # ), - # self.get_tweaker( - # "SAR-EXPMX:MOT_WEDGEB", alias="wedge_b", label="wedge_b" - # ), - # ], - # ) - # + self.build_faststage_group(toolbox) # self.build_slits_group(toolbox) self.build_collimator_group(toolbox) self.build_posttube_group(toolbox) @@ -1680,12 +1498,8 @@ class Main(QMainWindow, Ui_MainWindow): for key, tweaker in self.tweakers.items(): tweaker.event_axis_fault.connect(self.axis_fault) - self.tweakers["fast_x"].event_readback.connect( - lambda alias, value, kw: self.fast_x_position.emit(value) - ) - self.tweakers["fast_y"].event_readback.connect( - lambda alias, value, kw: self.fast_y_position.emit(value) - ) + self.tweakers["fast_x"].event_readback.connect(lambda alias, value, kw: self.fast_x_position.emit(value)) + self.tweakers["fast_y"].event_readback.connect(lambda alias, value, kw: self.fast_y_position.emit(value)) # layout.addStretch() @@ -1693,18 +1507,18 @@ class Main(QMainWindow, Ui_MainWindow): """ swissmx - {'pvname': 'SAR-EXPMX:MOT_FY.STAT', 'value': 0, 'char_value': 'NO_ALARM', 'status': 0, 'ftype': 17, 'chid': 38980392, 'host': 'SAR-CPPM-EXPMX1.psi.ch:5064', 'count': 1, 'access': 'read-only', 'write_access': False, 'read_access': True, - 'severity': 0, + 'severity': 0, 'timestamp': 1537867290.914189, 'precision': None, 'units': None, 'enum_strs': ('NO_ALARM', 'READ', 'WRITE', 'HIHI', 'HIGH', 'LOLO', 'LOW', 'STATE', 'COS', 'COMM', 'TIMEOUT', 'HWLIMIT', 'CALC', 'SCAN', 'LINK', 'SOFT'), 'upper_disp_limit': None, 'lower_disp_limit': None, 'upper_alarm_limit': None, 'lower_alarm_limit': None, 'lower_warning_limit': None, 'upper_warning_limit': None, 'upper_ctrl_limit': None, 'lower_ctrl_limit': None, 'nelm': 1, 'type': 'time_enum', 'typefull': 'time_enum', 'motor_field': 'STAT', 'source_field': 'STAT', 'cb_info': (1, ), 'alias': 'fast Y'} - - :param pvname: - :param kw: - :return: + + :param pvname: + :param kw: + :return: """ - logger.debug(f"AXIS FAULT: {kw}") + _log.debug(f"AXIS FAULT: {kw}") if kw["severity"]: msg = f"axis {pvname} has a fault" - logger.critical(msg) - logger.critical(f"{kw}") + _log.critical(msg) + _log.critical(f"{kw}") else: msg = "" self._message_critical_fault.setText(msg) @@ -1718,23 +1532,37 @@ class Main(QMainWindow, Ui_MainWindow): ], ) - def build_collimator_group(self, toolbox): - qutilities.add_item_to_toolbox( - toolbox, - "Collimator", + def build_faststage_group(self, toolbox): + qutilities.add_item_to_toolbox(toolbox,"Fast Stage", widget_list=[ - self.get_tweaker( - "SARES30-ESBMX1", - alias="colli_x", - label="colli X", - mtype="smaract_motor", - ), - self.get_tweaker( - "SARES30-ESBMX2", - alias="colli_y", - label="colli Y", - mtype="smaract_motor", - ), + # self.get_tweaker('SAR-EXPMX:MOT_BLGT', alias='backlight', label='backlight'), + self.get_tweaker("SAR-EXPMX:MOT_FY", alias="fast_y", label="fast Y"), + self.get_tweaker("SAR-EXPMX:MOT_FX", alias="fast_x", label="fast X"), + self.get_tweaker("SAR-EXPMX:MOT_ROT_Y",alias="omega",label="omega",tweak_min=0.001,tweak_max=180.0,), + self.get_tweaker("SAR-EXPMX:MOT_CX", alias="base_x", label="base X"), + self.get_tweaker("SAR-EXPMX:MOT_CZ", alias="base_z", label="base Z"), + ], + ) + + def build_wegde_group(self, toolbox): + qutilities.add_item_to_toolbox(toolbox,"Wedge Mover", + widget_list=[ + self.get_tweaker("SAR-EXPMX:MOT_WEDGE1", alias="wedge_1", label="wedge_1"), + self.get_tweaker("SAR-EXPMX:MOT_WEDGE2", alias="wedge_2", label="wedge_2"), + self.get_tweaker("SAR-EXPMX:MOT_WEDGE3", alias="wedge_3", label="wedge_3"), + self.get_tweaker("SAR-EXPMX:MOT_WEDGE4", alias="wedge_4", label="wedge_4"), + self.get_tweaker("SAR-EXPMX:MOT_WEDGEX", alias="wedge_x", label="wedge_x"), + self.get_tweaker("SAR-EXPMX:MOT_WEDGEY", alias="wedge_y", label="wedge_y"), + self.get_tweaker("SAR-EXPMX:MOT_WEDGEA", alias="wedge_a", label="wedge_a"), + self.get_tweaker("SAR-EXPMX:MOT_WEDGEB", alias="wedge_b", label="wedge_b"), + ], + ) + + def build_collimator_group(self, toolbox): + qutilities.add_item_to_toolbox(toolbox,"Collimator", + widget_list=[ + self.get_tweaker("SARES30-ESBMX1", alias="colli_x", label="colli X", mtype="smaract_motor",), + self.get_tweaker("SARES30-ESBMX2", alias="colli_y", label="colli Y", mtype="smaract_motor",), ], ) @@ -1743,30 +1571,10 @@ class Main(QMainWindow, Ui_MainWindow): toolbox, "Slits", widget_list=[ - self.get_tweaker( - "SARES30-ESBMX10", - alias="slit_right", - label="left", - mtype="smaract_motor", - ), - self.get_tweaker( - "SARES30-ESBMX11", - alias="slit_left", - label="right", - mtype="smaract_motor", - ), - self.get_tweaker( - "SARES30-ESBMX12", - alias="slit_bottom", - label="bottom", - mtype="smaract_motor", - ), - self.get_tweaker( - "SARES30-ESBMX13", - alias="slit_top", - label="top", - mtype="smaract_motor", - ), + self.get_tweaker("SARES30-ESBMX10", alias="slit_right", label="left", mtype="smaract_motor", ), + self.get_tweaker("SARES30-ESBMX11", alias="slit_left", label="right", mtype="smaract_motor",), + self.get_tweaker("SARES30-ESBMX12", alias="slit_bottom", label="bottom", mtype="smaract_motor",), + self.get_tweaker("SARES30-ESBMX13",alias="slit_top",label="top",mtype="smaract_motor",), ], ) @@ -1775,44 +1583,18 @@ class Main(QMainWindow, Ui_MainWindow): toolbox, "X-Ray Eye", widget_list=[ - self.get_tweaker( - "SARES30-ESBMX14", alias="xeye_x", label="X", mtype="smaract_motor" - ), - self.get_tweaker( - "SARES30-ESBMX15", alias="xeye_y", label="Y", mtype="smaract_motor" - ), + self.get_tweaker("SARES30-ESBMX14", alias="xeye_x", label="X", mtype="smaract_motor"), + self.get_tweaker("SARES30-ESBMX15", alias="xeye_y", label="Y", mtype="smaract_motor"), ], ) def build_posttube_group(self, toolbox): widgets = [ - self.get_tweaker( - "SARES30-ESBMX4", - alias="tube_usx", - label="upstream X", - mtype="smaract_motor", - ), - self.get_tweaker( - "SARES30-ESBMX6", - alias="tube_usy", - label="upstream Y", - mtype="smaract_motor", - ), - self.get_tweaker( - "SARES30-ESBMX5", - alias="tube_dsx", - label="downstream X", - mtype="smaract_motor", - ), - self.get_tweaker( - "SARES30-ESBMX7", - alias="tube_dsy", - label="downstream Y", - mtype="smaract_motor", - ), - self.get_tweaker( - "SARES30-ESBMX8", alias="tube_z", label="tube Z", mtype="smaract_motor" - ), + self.get_tweaker("SARES30-ESBMX4", alias="tube_usx", label="upstream X", mtype="smaract_motor",), + self.get_tweaker("SARES30-ESBMX6", alias="tube_usy", label="upstream Y", mtype="smaract_motor",), + self.get_tweaker("SARES30-ESBMX5", alias="tube_dsx", label="downstream X", mtype="smaract_motor",), + self.get_tweaker("SARES30-ESBMX7", alias="tube_dsy", label="downstream Y", mtype="smaract_motor",), + self.get_tweaker("SARES30-ESBMX8", alias="tube_z", label="tube Z", mtype="smaract_motor"), ] c = QWidget() c.setLayout(QGridLayout()) @@ -1911,15 +1693,12 @@ class Main(QMainWindow, Ui_MainWindow): xd = x_down + dx z = tz_out - app_utils.assert_tweaker_positions( - [ + app_utils.assert_tweaker_positions([ (usy, yu, 0.1), (dsy, yd, 0.1), (usx, xu, 0.1), (dsx, xd, 0.1), - (tbz, z, 0.1), - ], - timeout=2.0, + (tbz, z, 0.1),],timeout=2.0, ) def move_post_tube(self, dir): @@ -1938,7 +1717,7 @@ class Main(QMainWindow, Ui_MainWindow): tz_out = settings.value("post_sample_tube/z_out") if x_up is None: msg = "SwissMX *POST-SAMPLE-TUBE* configuration is incomplete!!!" - logger.warning(msg) + _log.warning(msg) QMessageBox.warning(self, "post tube not configured", msg) return x_up = float(x_up) @@ -1958,107 +1737,81 @@ class Main(QMainWindow, Ui_MainWindow): tube_z = self.tweakers["tube_z"] if dir == "in": - logger.info("move post sample tube in") + _log.info("move post sample tube in") usy.move_motor_to_position(y_up) dsy.move_motor_to_position(y_down) usx.move_motor_to_position(x_up) dsx.move_motor_to_position(x_down) try: - app_utils.assert_tweaker_positions( - [ + app_utils.assert_tweaker_positions([ (usy, y_up, 0.1), (dsy, y_down, 0.1), (usx, x_up, 0.1), - (dsx, x_down, 0.1), - ], - timeout=10.0, + (dsx, x_down, 0.1), ],timeout=10.0, ) except app_utils.PositionsNotReached as e: - logger.warning("failed to move post sample tube {}".format(dir)) - logger.warning(e) - QMessageBox.warning( - self, - "failed to move post sample tube XY {in}", - "failed to move post sample tube XY {in}", - ) + _log.warning("failed to move post sample tube {}".format(dir)) + _log.warning(e) + QMessageBox.warning(self, "failed to move post sample tube XY {in}", "failed to move post sample tube XY {in}",) raise tube_z.move_motor_to_position(tz_in, wait=True) try: app_utils.assert_tweaker_positions([(tube_z, tz_in, 0.1)]) except app_utils.PositionsNotReached as e: - logger.warning("failed to move post sample tube Z {in}") - logger.warning(e) - QMessageBox.warning( - self, - "failed to move post sample tube Z {in}", - "failed to move post sample tube Z {in}", - ) + _log.warning("failed to move post sample tube Z {in}") + _log.warning(e) + QMessageBox.warning(self, "failed to move post sample tube Z {in}", "failed to move post sample tube Z {in}",) raise elif dir == "out": - logger.info("move post sample tube out") + _log.info("move post sample tube out") tube_z.move_motor_to_position(tz_out, wait=True) try: app_utils.assert_tweaker_positions([(tube_z, tz_out, 0.1)]) except app_utils.PositionsNotReached as e: - logger.warning("failed to move post sample tube {out}") - logger.warning(e) - QMessageBox.warning( - self, - "failed to move post sample tube Z {out}", - "failed to move post sample tube Z {out}", - ) + _log.warning("failed to move post sample tube {out}") + _log.warning(e) + QMessageBox.warning(self,"failed to move post sample tube Z {out}","failed to move post sample tube Z {out}",) raise usy.move_motor_to_position(y_up + dy) dsy.move_motor_to_position(y_down + dy) usx.move_motor_to_position(x_up + dx) dsx.move_motor_to_position(x_down + dx) try: - app_utils.assert_tweaker_positions( - [ + app_utils.assert_tweaker_positions([ (usy, y_up + dy, 0.1), (dsy, y_down + dy, 0.1), (usx, x_up + dx, 0.1), - (dsx, x_down + dx, 0.1), - ], - timeout=10.0, + (dsx, x_down + dx, 0.1), ], timeout=10.0, ) except app_utils.PositionsNotReached as e: - logger.warning("failed to move post sample tube {}".format(dir)) - logger.warning(e) - QMessageBox.warning( - self, - "failed to move post sample tube XY {out}", - "failed to move post sample tube XY {out}", - ) + _log.warning("failed to move post sample tube {}".format(dir)) + _log.warning(e) + QMessageBox.warning(self,"failed to move post sample tube XY {out}","failed to move post sample tube XY {out}",) raise elif dir == "x-pos": - logger.info( - "tamdem move post sample tube X-pos by {} mm".format(tandem_twv) - ) + _log.info("tamdem move post sample tube X-pos by {} mm".format(tandem_twv)) usx.move_relative(tandem_twv) dsx.move_relative(tandem_twv) elif dir == "x-neg": - logger.info("tamdem move post sample tube X-neg {} mm".format(tandem_twv)) + _log.info("tamdem move post sample tube X-neg {} mm".format(tandem_twv)) usx.move_relative(-tandem_twv) dsx.move_relative(-tandem_twv) elif dir == "up": - logger.info("tamdem move post sample tube UP {} mm".format(tandem_twv)) + _log.info("tamdem move post sample tube UP {} mm".format(tandem_twv)) usy.move_relative(tandem_twv) dsy.move_relative(tandem_twv) elif dir == "down": - logger.info("tamdem move post sample tube DOWN {} mm".format(tandem_twv)) + _log.info("tamdem move post sample tube DOWN {} mm".format(tandem_twv)) usy.move_relative(-tandem_twv) dsy.move_relative(-tandem_twv) - def get_tweaker( - self, pv, alias=None, label=None, mtype="epics_motor", layout=None, **kwargs - ): + def get_tweaker(self, pv, alias=None, label=None, mtype="epics_motor", layout=None, **kwargs): if mtype == "epics_motor": m = MotorTweak() else: m = SmaractMotorTweak() - m.connect_motor(pv, label, **kwargs) + #m.connect_motor(pv, label, **kwargs) #ZAC: orig. code self.tweakers[alias] = m return m @@ -2070,7 +1823,7 @@ class Main(QMainWindow, Ui_MainWindow): else: m = SmaractMotorTweak() layout.addWidget(m) - m.connect_motor(pv, label) + #m.connect_motor(pv, label)#ZAC: orig. code self.tweakers[alias] = m def done_sliding(self): @@ -2079,41 +1832,33 @@ class Main(QMainWindow, Ui_MainWindow): @pyqtSlot() def saveSampleCameraScreenshot(self): outf = self.get_screenshot_filename() - logger.info("saving original clean screenshot: {}".format(outf)) + _log.info("saving original clean screenshot: {}".format(outf)) try: sample_camera.saveimage(outf) except Exception as e: - logger.warning(e) - QMessageBox.warning( - self, "Screenshot: failed to save image", "Failed to save screenshot!" - ) + _log.warning(e) + QMessageBox.warning(self, "Screenshot: failed to save image", "Failed to save screenshot!") @pyqtSlot() def saveSampleCameraScreenshotView(self): outf = self.get_screenshot_filename() - logger.info("saving view screenshot: {}".format(outf)) + _log.info("saving view screenshot: {}".format(outf)) exporter = pg.exporters.ImageExporter(self.vb) # set export parameters if needed - exporter.parameters()[ - "width" - ] = 2000 # (note this also affects height parameter) + exporter.parameters()["width"] = 2000 # (note this also affects height parameter) # save to file try: exporter.export(outf) except Exception as e: - logger.warning(e) - QMessageBox.warning( - self, - "Screenshot: failed to save viewer image", - "Failed to save screenshot of viewer!", - ) + _log.warning(e) + QMessageBox.warning(self, "Screenshot: failed to save viewer image", "Failed to save screenshot of viewer!",) def get_screenshot_filename(self): global folders - logger.info("taking screenhot") + _log.info("taking screenhot") prefix = folders.prefix folder = folders.res_folder base = time.strftime("{}_%Y%m%d_%H%M%S.png".format(prefix)) @@ -2122,12 +1867,8 @@ class Main(QMainWindow, Ui_MainWindow): os.makedirs(folder, 0o750, exist_ok=True) except: msg = "Failed to create folder: {}".format(folder) - logger.warning(msg) - QMessageBox.warning( - self, - "Screenshot: failed to create folder", - "Failed to create output folder for screenshot!\n\n\tScreenshot not taken!", - ) + _log.warning(msg) + QMessageBox.warning(self, "Screenshot: failed to create folder", "Failed to create output folder for screenshot!\n\n\tScreenshot not taken!",) raise outf = os.path.join(folder, base) return outf @@ -2140,15 +1881,7 @@ class Main(QMainWindow, Ui_MainWindow): ystep = self._sb_grid_y_step.value() xoffset = self._sb_grid_x_offset.value() yoffset = self._sb_grid_y_offset.value() - grid = Grid( - x_step=xstep, - y_step=ystep, - x_offset=xoffset, - y_offset=yoffset, - gonio_xy=(gx, gy), - grid_index=grid_index, - parent=self, - ) + grid = Grid( x_step=xstep, y_step=ystep, x_offset=xoffset, y_offset=yoffset, gonio_xy=(gx, gy), grid_index=grid_index, parent=self,) self._grids.append(grid) grid.calculate_gonio_xy() grid.sigRemoveRequested.connect(lambda g=grid: self.remove_grid(g)) @@ -2187,9 +1920,7 @@ class Main(QMainWindow, Ui_MainWindow): doc += "[{:8.3f}, {:8.3f}],\n".format(x, y) doc += "]" self._grid_inspect_area.setPlainText(doc) - m = "Number of points: {}\nEstimated Time: {:.1f} minutes".format( - num_points, num_points * etime / 60. - ) + m = "Number of points: {}\nEstimated Time: {:.1f} minutes".format(num_points, num_points * etime / 60.) self._label_grid_parameters.setText(m) def daq_embl_collect_points(self): @@ -2199,9 +1930,7 @@ class Main(QMainWindow, Ui_MainWindow): method = "trajectory" xp = (1000 * points).astype(int) # microns then round int params = (xp[:, 0].tolist(), xp[:, 1].tolist()) - self.daq_collect_points( - points, visualizer_method=method, visualizer_params=params - ) + self.daq_collect_points(points, visualizer_method=method, visualizer_params=params) def daq_prelocated_collect_points(self): points = [] @@ -2213,9 +1942,7 @@ class Main(QMainWindow, Ui_MainWindow): method = "trajectory" xp = (1000 * points).astype(int) # microns then round int params = (xp[:, 0].tolist(), xp[:, 1].tolist()) - self.daq_collect_points( - points, visualizer_method=method, visualizer_params=params - ) + self.daq_collect_points(points, visualizer_method=method, visualizer_params=params) def daq_grid_collect_grid(self): grid = self._grids[0] # FIXME one grid at a time only @@ -2223,9 +1950,7 @@ class Main(QMainWindow, Ui_MainWindow): method = "grid" params = grid._grid_dimensions # params = ([grid._grid_dimensions[0]], [grid._grid_dimensions[1]]) # FIXME something wrong here< - self.daq_collect_points( - points, visualizer_method=method, visualizer_params=params - ) + self.daq_collect_points(points, visualizer_method=method, visualizer_params=params) def daq_grid_findxtals(self): feature_size = self._sb_findxtals_feature_size.value() @@ -2241,21 +1966,17 @@ class Main(QMainWindow, Ui_MainWindow): box.setText("Jungfrau save data disabled!") box.setInformativeText("Jungfrau save data is disabled!") box.setIcon(QMessageBox.Warning) - box.setDetailedText( - "Choose to abort, enable and continue, or continue without saving raw data" - ) + box.setDetailedText("Choose to abort, enable and continue, or continue without saving raw data") btContinue = box.addButton("Continue", QMessageBox.YesRole) btAbort = box.addButton("OMG! Abort", QMessageBox.NoRole) - btEnable = box.addButton( - "Enable save and continue", QMessageBox.YesRole - ) + btEnable = box.addButton("Enable save and continue", QMessageBox.YesRole) box.exec_() ans = box.clickedButton() if ans == btEnable: jungfrau_detector.set_save_raw(True) return True elif ans == btAbort: - logger.info("not doing helical scan") + _log.info("not doing helical scan") return False return True return True @@ -2266,16 +1987,10 @@ class Main(QMainWindow, Ui_MainWindow): folders.make_if_needed() - if ( - option(ACTIVATE_PULSE_PICKER) - and not jungfrau_detector.is_running_detector() - ): - if QMessageBox.No == QMessageBox.question( - self, - "X-rays but no Jungfrau", - "X-rays will be used bu the Jungfrau will not run.\n\n\tContinue?", - ): - logger.warning("user forgot to turn on the jungfrau") + if ( option(ACTIVATE_PULSE_PICKER) and not jungfrau_detector.is_running_detector()): + if QMessageBox.No == QMessageBox.question(self, "X-rays but no Jungfrau", + "X-rays will be used bu the Jungfrau will not run.\n\n\tContinue?",): + _log.warning("user forgot to turn on the jungfrau") return if option(ACTIVATE_PULSE_PICKER) or not option(SKIP_ESCAPE_TRANSITIONS_IF_SAFE): @@ -2303,11 +2018,9 @@ class Main(QMainWindow, Ui_MainWindow): maxacq_points = 116508 samp_time = 0.0002 # s overhead_time = 0.1 - acq_per = int( - np.ceil((etime * ntrigger + overhead_time) / (maxacq_points * samp_time)) - ) - logger.info(f"gather acquisotion period = {acq_per}") - logger.info(f"velocity scale {vscale}") + acq_per = int(np.ceil((etime * ntrigger + overhead_time) / (maxacq_points * samp_time))) + _log.info(f"gather acquisotion period = {acq_per}") + _log.info(f"velocity scale {vscale}") shapepath.setup_gather(acq_per=acq_per) shapepath.setup_sync(verbose=True) shapepath.setup_coord_trf() @@ -2315,7 +2028,7 @@ class Main(QMainWindow, Ui_MainWindow): if TASK_GRID == task: width, height = visualizer_params - logger.debug(f"grid: {width} x {height}") + _log.debug(f"grid: {width} x {height}") details_1 = [width] details_2 = [height] shapepath.sort_points(xy=False, grp_sz=height) @@ -2391,7 +2104,7 @@ class Main(QMainWindow, Ui_MainWindow): break time.sleep(0.1) self.qprogress.setLabelText(f"Acquiring GRID {p:.0f} / {ntrigger}") - logger.warning(f"motion complete!") + _log.warning(f"motion complete!") # sample_camera.stop_camera() # sample_camera.switch_to_trigger(False) # sample_camera.save_buffer_series(folders.prefix) @@ -2441,14 +2154,14 @@ class Main(QMainWindow, Ui_MainWindow): try: self.step() except Exception as e: - logger.debug(" +> step exception") + _log.debug(" +> step exception") self.exception = str(e) self.errorHappened.emit(str(e)) self.finito.emit() for n, step in enumerate(steps): - logger.info(f"running step {step.title}") + _log.info(f"running step {step.title}") dlg.setLabelText(f"{title}
{step.title}") dlg.setValue(n) thread = QThread() @@ -2471,7 +2184,7 @@ class Main(QMainWindow, Ui_MainWindow): break if dlg.wasCanceled(): - logger.error(f"sequence {title} was cancelled by user") + _log.error(f"sequence {title} was cancelled by user") raise AcquisitionAbortedException(f"sequence {title} was cancelled by user") if at_end is not None: @@ -2482,9 +2195,7 @@ class Main(QMainWindow, Ui_MainWindow): self.qprogress.reset() if self._thread.isRunning(): self._thread.quit() - shapepath.gather_upload( - os.path.join(folders.res_folder, folders.prefix + ".npz") - ) + shapepath.gather_upload(os.path.join(folders.res_folder, folders.prefix + ".npz")) if option(DELTATAU_SHOW_PLOTS): dp = DebugPlot(shapepath) @@ -2497,19 +2208,15 @@ class Main(QMainWindow, Ui_MainWindow): if option(ACTIVATE_PULSE_PICKER) or not option(SKIP_ESCAPE_TRANSITIONS_IF_SAFE): self.escape_goToSampleAlignment() - sequence = { - "delta tau program": shapepath.prg, - "points": shapepath.points.tolist(), - "timestamp": tdstamp(), - } + sequence = {"delta tau program": shapepath.prg, "points": shapepath.points.tolist(), "timestamp": tdstamp(),} sfname = folders.get_prefixed_file("_ScanInfo.json") try: with open(sfname, "w") as sf: - logger.info("writing scan info into: {}".format(sfname)) + _log.info("writing scan info into: {}".format(sfname)) sf.write(json.dumps(sequence)) except: - logger.warning(f"failed to write scan info to {sfname}") + _log.warning(f"failed to write scan info to {sfname}") self.re_connect_collect_button() jungfrau_detector.abort() @@ -2535,21 +2242,15 @@ class Main(QMainWindow, Ui_MainWindow): }] ] """ - logger.info("executing collection") + _log.info("executing collection") htab = self._helical_scan_table num_h = htab.scanHorizontalCount() num_v = htab.scanVerticalCount() - if ( - settings.value(ACTIVATE_PULSE_PICKER) - and not jungfrau_detector.is_running_detector() - ): - if QMessageBox.No == QMessageBox.question( - self, - "X-rays but no Jungfrau", - "X-rays will be used bu the Jungfrau will not run.\n\n\tContinue?", - ): - logger.warning("user forgot to turn on the jungfrau") + if ( settings.value(ACTIVATE_PULSE_PICKER) and not jungfrau_detector.is_running_detector()): + if QMessageBox.No == QMessageBox.question(self, "X-rays but no Jungfrau", + "X-rays will be used bu the Jungfrau will not run.\n\n\tContinue?",): + _log.warning("user forgot to turn on the jungfrau") return if option(ACTIVATE_PULSE_PICKER) or not option(SKIP_ESCAPE_TRANSITIONS_IF_SAFE): @@ -2558,7 +2259,7 @@ class Main(QMainWindow, Ui_MainWindow): folders.make_if_needed() data = htab.get_data() - logger.debug(data) + _log.debug(data) start, end = data[0] FX, FY, BX, BZ, O = range(5) x = ( @@ -2576,9 +2277,9 @@ class Main(QMainWindow, Ui_MainWindow): return saveRaw = jungfrau_detector.is_saving_data() - logger.debug(f"x = {x}") - logger.debug(f"y = {y}") - logger.debug(f"z = {z}") + _log.debug(f"x = {x}") + _log.debug(f"y = {y}") + _log.debug(f"z = {z}") oscillationAngle = settings.value("oscillationAngle", type=float) exposureTime = 1000 * settings.value("exposureTime", type=float) @@ -2604,7 +2305,7 @@ class Main(QMainWindow, Ui_MainWindow): hRng = (-blastRadius * num_h, blastRadius * num_h) w_start = 1000 * htab.startAngle() wRng = (w_start, w_start + (totalRange * 1000)) - logger.info( + _log.info( f"helical params mode={mode}, cnthor={num_h}, cntvert={num_v}, hrng={hRng}, wrng={wRng}" ) helical.setup_motion( @@ -2662,9 +2363,7 @@ class Main(QMainWindow, Ui_MainWindow): sequencer_steps.append(lambda: helical.wait_armed()) if settings.value(ACTIVATE_PULSE_PICKER): - sequencer_steps.extend( - [lambda: pulsePicker.open(), lambda: pend_event(0.1)] - ) + sequencer_steps.extend([lambda: pulsePicker.open(), lambda: pend_event(0.1)]) sequencer_steps.append(lambda: helical.trigger()) @@ -2675,7 +2374,7 @@ class Main(QMainWindow, Ui_MainWindow): break time.sleep(0.1) self.qprogress.setLabelText(f"Acquiring HELICAL {p:.0f} / {n_frames}") - logger.warning(f"helical motion complete!") + _log.warning(f"helical motion complete!") sequencer_steps.append(motion_progress) @@ -2712,7 +2411,7 @@ class Main(QMainWindow, Ui_MainWindow): hsgui.interactive_anim() def complete_daq(self): - logger.info("daq completed: cleaning up") + _log.info("daq completed: cleaning up") try: self.qprogress.reset() except: @@ -2741,7 +2440,7 @@ class Main(QMainWindow, Ui_MainWindow): self.gridUpdated.connect(self.daq_grid_update) def re_connect_collect_button(self, callback=None, **kwargs): - logger.debug("re_connect_collect_button() {} => {}".format(callback, kwargs)) + _log.debug("re_connect_collect_button() {} => {}".format(callback, kwargs)) return # button = self._button_collect # if callback is None: @@ -2767,7 +2466,7 @@ class Main(QMainWindow, Ui_MainWindow): self._eigerwaitthread._is_aborted = True except: pass - logger.warning("aborting grid scan") + _log.warning("aborting grid scan") self.abort_measurement() delta_tau.abort() jungfrau_detector.disarm() @@ -2854,16 +2553,12 @@ class Main(QMainWindow, Ui_MainWindow): icon = qtawesome.icon("material.photo_camera") action = QAction(icon, "Save View", self) - action.setToolTip( - "(Ctrl+S) Take a screenshot of the currently visible sample image, including markers. Saves in current folder." - ) + action.setToolTip("(Ctrl+S) Take a screenshot of the currently visible sample image, including markers. Saves in current folder.") action.triggered.connect(self.saveSampleCameraScreenshotView) self.toolBar.addAction(action) action = QAction(icon, "Save Original", self) - action.setToolTip( - "(Ctrl+Shift+S) Take a screenshot of the sample image, without markers. Saves in current folder." - ) + action.setToolTip("(Ctrl+Shift+S) Take a screenshot of the sample image, without markers. Saves in current folder.") action.triggered.connect(self.saveSampleCameraScreenshot) self.toolBar.addAction(action) @@ -2892,9 +2587,7 @@ class Main(QMainWindow, Ui_MainWindow): icon = qtawesome.icon("material.play_for_work") action = QAction(icon, "TELL Mount", self) - action.setToolTip( - "BookMark(0) => Move stages CZ, CX, FX, FY, and Omega to Tell sample changer mount position" - ) + action.setToolTip("BookMark(0) => Move stages CZ, CX, FX, FY, and Omega to Tell sample changer mount position") action.triggered.connect(self.escape_goToTellMountPosition) self.toolBar.addAction(action) @@ -2953,12 +2646,8 @@ class Main(QMainWindow, Ui_MainWindow): # adding a menu entry to one of the menus action = QAction("Beam Marker Size", self) - action.setToolTip( - "Update the beam marker size on GUI; *not* the actual beam size!" - ) - action.setStatusTip( - "Update the beam marker size on GUI; *not* the actual beam size!" - ) + action.setToolTip("Update the beam marker size on GUI; *not* the actual beam size!") + action.setStatusTip("Update the beam marker size on GUI; *not* the actual beam size!") action.triggered.connect(self.set_beam_size_marker_dialog) self.menuAdvanced.addAction(action) @@ -2975,12 +2664,8 @@ class Main(QMainWindow, Ui_MainWindow): self.menuAdvanced.addAction(action) action = QAction("Cryojet Reference Positions", self) - action.setToolTip( - "Update the reference positions for the cryojet nozzle position" - ) - action.setStatusTip( - "Update the reference positions for the cryojet nozzle position" - ) + action.setToolTip("Update the reference positions for the cryojet nozzle position") + action.setStatusTip("Update the reference positions for the cryojet nozzle position") action.triggered.connect(self.set_cryojet_positions_dialog) self.menuAdvanced.addAction(action) @@ -3008,7 +2693,7 @@ class Main(QMainWindow, Ui_MainWindow): m.disconnect_signals() self.vb.removeItem(m) except Exception as e: - logger.warning("maybe failed removing markers: {}".format(e)) + _log.warning("maybe failed removing markers: {}".format(e)) self._marker_rois = [] def pause_all_markers(self): @@ -3032,9 +2717,7 @@ class Main(QMainWindow, Ui_MainWindow): if not is_fiducial: if not (add_xtals and draw_xtals): continue - logger.debug( - f"adding {'fiducial' if is_fiducial else 'xtal'} mark #{n}: {is_fiducial} {gx:.3f}, {gy:.3f}, {cx:.1f}, {cy:.1f}" - ) + _log.debug(f"adding {'fiducial' if is_fiducial else 'xtal'} mark #{n}: {is_fiducial} {gx:.3f}, {gy:.3f}, {cx:.1f}, {cy:.1f}") m = CrystalCircle( gonio_xy=(gx, gy), parent=self, @@ -3050,11 +2733,11 @@ class Main(QMainWindow, Ui_MainWindow): c.follow_stage() def daq_method_prelocated_set_fiducial(self, camx, camy, gx, gy): - logger.debug(f"camx, camy: {camx}, {camy}, fx, fy: {gx, gy}") + _log.debug(f"camx, camy: {camx}, {camy}, fx, fy: {gx, gy}") self.prelocationModule.set_fiducial_coords(camx, camy, gx, gy) def daq_method_prelocated_append_data(self, x, y, gx, gy): - logger.debug("appending to model: {} {}".format((x, y), (gx, gy))) + _log.debug("appending to model: {} {}".format((x, y), (gx, gy))) self.prelocationModule.append_data((x, y, gx, gy)) self.daq_method_prelocated_update_markers() @@ -3062,29 +2745,19 @@ class Main(QMainWindow, Ui_MainWindow): row = roi.get_model_row() pos = roi.pos() self.prelocationModule.set_data_camera(row, pos) - logger.debug("updating row {} => {}".format(row, pos)) + _log.debug("updating row {} => {}".format(row, pos)) def daq_method_prelocated_add_reference(self): self._references.append(pg.CircleROI()) def build_daq_methods_prelocated_tab(self): tab = self._tab_daqmethod_prelocated - self.prelocationModule = PrelocatedCoordinatesModel.PrelocatedCoordinates( - parent=self - ) + self.prelocationModule = PrelocatedCoordinatesModel.PrelocatedCoordinates(parent=self) tab.layout().addWidget(self.prelocationModule) - self.prelocationModule.prefixSelected.connect( - lambda prefix: self._le_prefix.setText(prefix) - ) - self.prelocationModule.dataFileLoaded.connect( - self.daq_method_prelocated_update_markers - ) - self.prelocationModule.prelocatedDataUpdated.connect( - self.daq_method_prelocated_update_markers - ) - self.prelocationModule.markersDeleted.connect( - self.daq_method_prelocated_remove_markers - ) + self.prelocationModule.prefixSelected.connect(lambda prefix: self._le_prefix.setText(prefix)) + self.prelocationModule.dataFileLoaded.connect(self.daq_method_prelocated_update_markers) + self.prelocationModule.prelocatedDataUpdated.connect(self.daq_method_prelocated_update_markers) + self.prelocationModule.markersDeleted.connect(self.daq_method_prelocated_remove_markers) self.fiducialPositionSelected.connect(self.daq_method_prelocated_set_fiducial) self.appendPrelocatedPosition.connect(self.daq_method_prelocated_append_data) self.prelocationModule.moveFastStageRequest.connect(self.move_fast_stage) @@ -3092,7 +2765,7 @@ class Main(QMainWindow, Ui_MainWindow): tab.layout().addWidget(self._preloc_inspect_area) def move_fast_stage(self, x, y): - logger.info(f"received request to move gonio to x, y = {x:.3f}, {y:.3f} mm") + _log.info(f"received request to move gonio to x, y = {x:.3f}, {y:.3f} mm") fx_motor, fy_motor, bx_motor, bz_motor, omega_motor = self.get_gonio_tweakers() fx_motor.move_motor_to_position(x) fy_motor.move_motor_to_position(y) @@ -3117,9 +2790,9 @@ class Main(QMainWindow, Ui_MainWindow): ) if d.exec(): results = d.results - logger.info("Updating beamsize to {}".format(results)) + _log.info("Updating beamsize to {}".format(results)) w, h = results["width"], results["height"] - logger.debug("types {}".format(type(w))) + _log.debug("types {}".format(type(w))) settings.setValue(BEAM_SIZE, (w, h)) self._beammark.set_beam_size((w, h)) settings.sync() @@ -3186,7 +2859,7 @@ class Main(QMainWindow, Ui_MainWindow): ) if d.exec(): results = d.results - logger.info("setting post-sample-tube displacements {}".format(results)) + _log.info("setting post-sample-tube displacements {}".format(results)) for k, v in results.items(): settings.setValue(k, v) settings.sync() @@ -3224,7 +2897,7 @@ class Main(QMainWindow, Ui_MainWindow): ) if d.exec(): results = d.results - logger.info("setting collimator reference positions {}".format(results)) + _log.info("setting collimator reference positions {}".format(results)) for k, v in results.items(): settings.setValue(k, v) settings.sync() @@ -3256,7 +2929,7 @@ class Main(QMainWindow, Ui_MainWindow): ) if d.exec(): results = d.results - logger.info("setting back light reference positions {}".format(results)) + _log.info("setting back light reference positions {}".format(results)) for k, v in results.items(): settings.setValue(k, v) settings.sync() @@ -3270,21 +2943,13 @@ class Main(QMainWindow, Ui_MainWindow): message="Enter reference positions for the cryojet nozzle position", inputs={ CRYOJET_NOZZLE_IN: ("In position", p_in, Spinner(p_in, min=3, max=15)), - CRYOJET_NOZZLE_OUT: ( - "Out position", - p_out, - Spinner(p_out, min=-1000, max=10), - ), - CRYOJET_MOTION_ENABLED: ( - "Move Cryojet in Transitions", - motion_enabled, - Checkbox(motion_enabled, "move cryojet"), - ), + CRYOJET_NOZZLE_OUT: ("Out position",p_out,Spinner(p_out, min=-1000, max=10),), + CRYOJET_MOTION_ENABLED: ("Move Cryojet in Transitions",motion_enabled,Checkbox(motion_enabled, "move cryojet"),), }, ) if d.exec(): results = d.results - logger.info("setting cryojet reference positions {}".format(results)) + _log.info("setting cryojet reference positions {}".format(results)) for k, v in results.items(): settings.setValue(k, v) settings.sync() @@ -3299,31 +2964,19 @@ class Main(QMainWindow, Ui_MainWindow): title="Delta Tau Parameters", message="These parameters affect the data collection.", inputs={ - DELTATAU_VELOCITY_SCALE: ( - "Velocity Scale (1=optimal, 0=zero vel at target)", - a, - Spinner(a, min=0, max=1, suffix=""), - ), - DELTATAU_SORT_POINTS: ( - "Sort pointshoot/prelocated coords", - b, - Checkbox(b, "sort points"), - ), - DELTATAU_SHOW_PLOTS: ( - "show plots after collection", - d, - Checkbox(d, "correct"), - ), - DELTATAU_OMEGACOS: ( - "preloc. correct omega tilt", - c, - Checkbox(c, "correct"), - ), + DELTATAU_VELOCITY_SCALE: ("Velocity Scale (1=optimal, 0=zero vel at target)", a, + Spinner(a, min=0, max=1, suffix=""),), + DELTATAU_SORT_POINTS: ("Sort pointshoot/prelocated coords", b, + Checkbox(b, "sort points"),), + DELTATAU_SHOW_PLOTS: ("show plots after collection", d, + Checkbox(d, "correct"),), + DELTATAU_OMEGACOS: ( "preloc. correct omega tilt", c, + Checkbox(c, "correct"),), }, ) if d.exec(): results = d.results - logger.info("setting delta tau parameters {}".format(results)) + _log.info("setting delta tau parameters {}".format(results)) for k, v in results.items(): settings.setValue(k, v) settings.sync() @@ -3343,22 +2996,17 @@ class Main(QMainWindow, Ui_MainWindow): title="TELL Settings", message="These control some features of the TELL sample changer", inputs={ - AUTODRY_ENABLED: ("Auto dry", enabled, Checkbox(enabled, "enabled")), - AUTODRY_MAXMOUNTS: ( - "Max. num. mounts between dry", - maxmounts, - Spinner(maxmounts, decimals=0, min=1, max=100, suffix=" mounts"), - ), - AUTODRY_MAXTIME: ( - "Max. time between dry", - maxtime, - Spinner(maxtime, decimals=1, min=0.5, max=5, suffix=" hours"), - ), + AUTODRY_ENABLED: ("Auto dry", enabled, + Checkbox(enabled, "enabled")), + AUTODRY_MAXMOUNTS: ("Max. num. mounts between dry",maxmounts, + Spinner(maxmounts, decimals=0, min=1, max=100, suffix=" mounts"),), + AUTODRY_MAXTIME: ("Max. time between dry",maxtime, + Spinner(maxtime, decimals=1, min=0.5, max=5, suffix=" hours"),), }, ) if d.exec(): results = d.results - logger.info("setting tell parameters {}".format(results)) + _log.info("setting tell parameters {}".format(results)) for k, v in results.items(): if k == AUTODRY_MAXTIME: v = v * SECS_HOURS @@ -3378,21 +3026,17 @@ class Main(QMainWindow, Ui_MainWindow): self.showMaximized() def show_window_configuration(self): - logger.debug("maximized? {}".format(self.isMaximized())) + _log.debug("maximized? {}".format(self.isMaximized())) def home_deltatau_faststages(self): - logger.warning("homing fast stages") + _log.warning("homing fast stages") epics.PV("SAR-EXPMX1:ASYN.AOUT").put(b"enable plc 1") def update_user_and_storage(self): global folders pgroup = settings.value(EXPERIMENT_PGROUP, "not_set_yet") - diag = GenericDialog( - title="P-group for experiment", - message="Enter the p-group to be used", - inputs={EXPERIMENT_PGROUP: ("P-group", pgroup, QLineEdit(pgroup))}, - use_buttons=False, - ) + diag = GenericDialog( title="P-group for experiment", message="Enter the p-group to be used", + inputs={EXPERIMENT_PGROUP: ("P-group", pgroup, QLineEdit(pgroup))}, use_buttons=False,) diag.setModal(True) run_user = getpass.getuser() @@ -3408,11 +3052,7 @@ class Main(QMainWindow, Ui_MainWindow): settings.setValue(k, v) settings.setValue(EXPERIMENT_UID, int(m["uid"])) else: - QMessageBox.critical( - self, - "wrong P-group format", - "P-groups are in the format:\n\n\t\tp?????\n\n\twhere ? = digit", - ) + QMessageBox.critical(self, "wrong P-group format", "P-groups are in the format:\n\n\t\tp?????\n\n\twhere ? = digit",) self.update_user_and_storage() return settings.sync() @@ -3424,17 +3064,9 @@ class Main(QMainWindow, Ui_MainWindow): pgroup = settings.value(EXPERIMENT_PGROUP) box = QMessageBox() box.setText("No Write Permission!") - box.setInformativeText( - "User {} has no write access to p-group {} folder:\n ➜ {}\n".format( - run_user, pgroup, folder - ) - ) + box.setInformativeText("User {} has no write access to p-group {} folder:\n ➜ {}\n".format(run_user, pgroup, folder)) box.setIcon(QMessageBox.Warning) - box.setDetailedText( - "The folder /sf/bernina/data/{pgroup}/res/ has to writable by the user {user}, currently running the SwissMX app.".format( - pgroup=pgroup, user=run_user - ) - ) + box.setDetailedText("The folder /sf/bernina/data/{pgroup}/res/ has to writable by the user {user}, currently running the SwissMX app.".format(pgroup=pgroup, user=run_user)) btIgnore = box.addButton("Ignore", QMessageBox.NoRole) btRetry = box.addButton("Le'me try again", QMessageBox.YesRole) box.exec_() @@ -3442,13 +3074,14 @@ class Main(QMainWindow, Ui_MainWindow): if ans == btRetry: self.update_user_and_storage() elif ans == btIgnore: - logger.warning("no write access to pgroup but user didn't care") + _log.warning("no write access to pgroup but user didn't care") self._label_pgroup.setText(settings.value(EXPERIMENT_PGROUP)) def init_settings(self): + app = QApplication.instance() # settings = Settings - global folders + #global folders s = settings keys = s.allKeys() @@ -3487,37 +3120,27 @@ class Main(QMainWindow, Ui_MainWindow): if BEAM_MARKER_POSITIONS in keys: self._beam_markers = s.value(BEAM_MARKER_POSITIONS) self.update_beam_marker_fitters() - logger.info("read beam markers {}".format(self._beam_markers)) + _log.info("read beam markers {}".format(self._beam_markers)) if BEAM_SIZE in keys: - logger.info( - "setting beamsize from stored settings: {}".format(s.value(BEAM_SIZE)) - ) + _log.info("setting beamsize from stored settings: {}".format(s.value(BEAM_SIZE))) else: - logger.warning("beam size may not reflect reality, please check") + _log.warning("beam size may not reflect reality, please check") s.setValue(BEAM_SIZE, (40, 20)) if CAMERA_TRANSFORMATIONS in keys: - sample_camera.set_transformations(s.value(CAMERA_TRANSFORMATIONS)) + app._camera.set_transformations(s.value(CAMERA_TRANSFORMATIONS)) if CAMERA_ZOOM_TO_PPM in keys: self._zoom_to_ppm = s.value(CAMERA_ZOOM_TO_PPM) - logger.info(f"{CAMERA_ZOOM_TO_PPM} updated: {self._zoom_to_ppm}") + _log.info(f"{CAMERA_ZOOM_TO_PPM} updated: {self._zoom_to_ppm}") self.update_ppm_fitters() def really_quit(self): """called when user Ctrl-Q the app""" global user, just_quit - if ( - just_quit - or QMessageBox.question( - self, - "", - "Are you sure you want to quit?", - QMessageBox.Yes | QMessageBox.No, - QMessageBox.No, - ) - == QMessageBox.Yes + if (just_quit + or QMessageBox.question(self, "", "Are you sure you want to quit?", QMessageBox.Yes | QMessageBox.No, QMessageBox.No,) == QMessageBox.Yes ): self._do_quit = True self.close() @@ -3528,14 +3151,7 @@ class Main(QMainWindow, Ui_MainWindow): if ( just_quit or self._do_quit - or QMessageBox.question( - self, - "", - "Are you sure you want to quit?", - QMessageBox.Yes | QMessageBox.No, - QMessageBox.No, - ) - == QMessageBox.Yes + or QMessageBox.question( self, "", "Are you sure you want to quit?", QMessageBox.Yes | QMessageBox.No, QMessageBox.No,) == QMessageBox.Yes ): sample_camera.disconnect() settings.setValue("window/geometry", self.saveGeometry()) @@ -3557,9 +3173,7 @@ class Main(QMainWindow, Ui_MainWindow): def set_app_icon(self): scriptDir = os.path.dirname(os.path.realpath(__file__)) - self.setWindowIcon( - QtGui.QIcon(os.path.join(scriptDir + os.path.sep + "logo.png")) - ) + self.setWindowIcon(QtGui.QIcon(os.path.join(scriptDir + os.path.sep + "logo.png"))) def set_widget_background_color(self, color): """change a widget's color @@ -3581,32 +3195,17 @@ class Main(QMainWindow, Ui_MainWindow): def sigint_handler(*args): """Handler for the SIGINT signal.""" - global app + app=QApplication.instance() app.quit() def main(): - global app - import sys import argparse parser = argparse.ArgumentParser() - parser.add_argument( - "--number", "-n", help="number; default=100", type=int, default=100 - ) - parser.add_argument( - "--float", "-f", help="float number; default=0.1", type=float, default=0.1 - ) - parser.add_argument( - "--prefix", "-p", help="prefix; default=dark", type=str, default="bogus" - ) - parser.add_argument( - "--local", - help="local instance for testing (avoids " "connecting to some things)", - action="store_true", - ) - parser.add_argument("--verbose", "-v", help="verbose flag", action="store_true") + 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__)) # needed so pycharm can restart application signal.signal(signal.SIGINT, sigint_handler) @@ -3617,6 +3216,26 @@ def main(): app = QApplication(sys.argv) + 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=0) + app._camera.run() + else: + app._camera = camera.epics_cam() + app._camera.run() + 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)) @@ -3643,6 +3262,8 @@ def main(): while time.time() < t + 0.1: app.processEvents() + + main = Main() main.show() splash.finish(main) @@ -3651,6 +3272,5 @@ def main(): if __name__ == "__main__": - app = None os.environ['EPICS_CA_ADDR_LIST'] ='129.129.244.255 sf-saresc-cagw.psi.ch:5062 sf-saresc-cagw.psi.ch:5066' main() diff --git a/zoom.py b/zoom.py index 0d8f88c..1e2568f 100755 --- a/zoom.py +++ b/zoom.py @@ -23,14 +23,16 @@ from PyQt5.QtWidgets import ( QGridLayout, QLabel, QDoubleSpinBox, - QComboBox, QSpinBox, QVBoxLayout, QHBoxLayout, QCheckBox, ) from PyQt5.uic import loadUiType + +import backlight, illumination, camera import epics +from app_config import settings Ui_Zoom, QWidget = loadUiType("zoom.ui") MIN_ZOOM = 1 @@ -330,14 +332,11 @@ if __name__ == "__main__": args = parser.parse_args() import sys - import backlight - import illumination - import camera _log.info('Arguments:{}'.format(args.__dict__)) os.environ['EPICS_CA_ADDR_LIST'] = '129.129.244.255 sf-saresc-cagw.psi.ch:5062 sf-saresc-cagw.psi.ch:5066' app = QApplication(sys.argv) - from app_config import settings, appsconf + from app_config import appsconf #from PyQt5 import QtGui #qtawesome.load_font("material","MaterialIcons-Regular.ttf","MaterialIcons-Regular.json","fonts/",)