cleanup
This commit is contained in:
222
swissmx.py
222
swissmx.py
@@ -45,20 +45,10 @@ ts=timestamp()
|
||||
ts.log('Import part 1/8:')
|
||||
import sys, os, time
|
||||
import json, re
|
||||
import random, signal,threading
|
||||
|
||||
import random, signal, subprocess
|
||||
import matplotlib as mpl
|
||||
mpl.use('Qt5Agg') # needed to avoid blocking of ui !
|
||||
|
||||
#import Wigis #ZAC: orig. code
|
||||
#import jungfrau_widget #ZAC: orig. code
|
||||
#import bernina_pulse_picker #ZAC: orig. code
|
||||
#import storage #ZAC: orig. code
|
||||
#from zmq_escape import zescape #ZAC: orig. code
|
||||
#from helicalscan import HelicalScanGui #ZAC: orig. code
|
||||
# publisher = pubber.Publisher()
|
||||
|
||||
|
||||
TASK_JUNGFRAU_SETTINGS = "jungfrau_settings"
|
||||
TASK_SETUP_GEOMETRY_CALIB = "geometry_calib"
|
||||
TASK_SETUP_PPM_CALIBRATION_TBOX = "ppm_calibration_tbox"
|
||||
@@ -78,17 +68,12 @@ import ModuleFixTarget
|
||||
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
|
||||
|
||||
ts.log('Import part 3/8:')
|
||||
import qtawesome
|
||||
import qutilities
|
||||
from PyQt5 import QtCore, QtGui
|
||||
from PyQt5.QtCore import Qt, pyqtSlot, QSize, QRegExp, pyqtSignal, QObject, QThread, QRectF
|
||||
from PyQt5.QtCore import Qt, pyqtSlot, QSize, QRegExp, pyqtSignal, QObject, QThread, QRectF,QT_VERSION_STR
|
||||
from PyQt5.QtGui import QKeySequence, QPixmap, QRegExpValidator, QFont
|
||||
from PyQt5.QtWidgets import (
|
||||
QAction, QApplication, QDoubleSpinBox, QFileDialog, QFormLayout, QGridLayout, QGroupBox, QHBoxLayout, QLabel, QLineEdit,
|
||||
@@ -96,20 +81,11 @@ from PyQt5.QtWidgets import (
|
||||
QSplashScreen, QTextBrowser, QToolBox, QVBoxLayout, QWidget,)
|
||||
from PyQt5.uic import loadUiType
|
||||
ts.log('Import part 4/8:')
|
||||
import CustomROI as CstROI
|
||||
import pyqtUsrObj as UsrGO
|
||||
|
||||
#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 epics_widgets.SimMotorTweak import SimMotorTweak
|
||||
ts.log('Import part 5/8:')
|
||||
#import matplotlib as mpl
|
||||
#import matplotlib.pyplot as plt
|
||||
import numpy as np
|
||||
np.set_printoptions(suppress=True,linewidth=196)
|
||||
import pyqtgraph as pg
|
||||
@@ -128,47 +104,24 @@ import deltatau
|
||||
import detector
|
||||
ts.log('Import part 8/8:')
|
||||
|
||||
|
||||
#_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" #ZAC: orig. code
|
||||
#BROKER_PORT = 61613 #ZAC: orig. code
|
||||
|
||||
# sample_camera = camera.camera_server(basename="SARES20-PROF142-M1")
|
||||
|
||||
#_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 tdstamp():
|
||||
return time.strftime("%Y%m%dH%H%M%S")
|
||||
|
||||
def datestamp():
|
||||
return time.strftime("%Y%m%d")
|
||||
|
||||
def get_version(path='.'):
|
||||
#sys.stdout.write('getVersion() -> using git command -> ')
|
||||
p = subprocess.Popen(f'git -C {path} describe --match ''*.*.*'' --long --tags --dirty', shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
|
||||
retval = p.wait()
|
||||
res=p.stdout.readline()
|
||||
p.stdout.close()
|
||||
#res=res.decode()[1:-1].split('-',2)
|
||||
res=res.decode()[:-1].split('-',2)
|
||||
ver='.'.join(res[:2])
|
||||
gitcmt=res[2][1:]
|
||||
return (ver,gitcmt)
|
||||
|
||||
def sigint_handler(*args):
|
||||
"""Handler for the SIGINT signal."""
|
||||
app=QApplication.instance()
|
||||
@@ -177,7 +130,6 @@ def sigint_handler(*args):
|
||||
class AcquisitionAbortedException(Exception):
|
||||
pass
|
||||
|
||||
|
||||
class Sequencer(QObject):
|
||||
finished = pyqtSignal()
|
||||
timeoutExpired = pyqtSignal()
|
||||
@@ -260,13 +212,6 @@ class WndSwissMx(QMainWindow, Ui_MainWindow):
|
||||
QtGui.QFontDatabase.addApplicationFont("fonts/Inconsolata-Bold.ttf")
|
||||
QtGui.QFontDatabase.addApplicationFont("fonts/Baloo-Regular.ttf")
|
||||
|
||||
# TODO: Cleanup many member functions that are unused or obsolete
|
||||
self._pv_shutter = None # epics.PV('X06SA-ES-MD2:SHUTTER')
|
||||
self._has_pulse_picker = False
|
||||
self._at_x06sa = False
|
||||
self._at_cristalina = True
|
||||
self._at_lab_eh060 = False
|
||||
|
||||
self.init_settings()
|
||||
|
||||
# self.create_escape_toolbar()
|
||||
@@ -333,13 +278,13 @@ class WndSwissMx(QMainWindow, Ui_MainWindow):
|
||||
|
||||
self.init_actions()
|
||||
#self.prepare_microscope_page()
|
||||
self.prepare_left_tabs()
|
||||
self.prepare_wd_tabs_left()
|
||||
#self.update_beam_marker(qoptic_zoom.get_sp()) #ZAC: orig. code
|
||||
self._centerpiece_stack.setCurrentIndex(0)
|
||||
self._centerpiece_stack.currentChanged.connect(self.cb_update_center_widget)
|
||||
self._OLD_init_validators()
|
||||
self._wd_stack.setCurrentIndex(0)
|
||||
self._wd_stack.currentChanged.connect(self.cb_update_center_widget)
|
||||
#self._OLD_init_validators()
|
||||
#self.init_settings_tracker() ? not needed, was for TELL ?
|
||||
self._OLD_wire_storage()
|
||||
#self._OLD_wire_storage()
|
||||
|
||||
self.cb_update_center_widget(0) # start camera updater
|
||||
curzoom = app._zoom.get_val()
|
||||
@@ -364,7 +309,7 @@ class WndSwissMx(QMainWindow, Ui_MainWindow):
|
||||
sz = [int(s) for s in cfg.value(cfg.WINDOW_SPLITTER)]
|
||||
else:
|
||||
sz=(500, 1200)
|
||||
self._main_splitter.setSizes(sz)
|
||||
self._wd_splitter.setSizes(sz)
|
||||
|
||||
#if AppCfg.BEAM_MARKER_POSITIONS in keys:
|
||||
# self._beam_markers = s.value(AppCfg.BEAM_MARKER_POSITIONS)
|
||||
@@ -523,11 +468,11 @@ class WndSwissMx(QMainWindow, Ui_MainWindow):
|
||||
self.toolBar.addAction(action)
|
||||
|
||||
# icon = qtawesome.icon("material.shutter_speed")
|
||||
action = QAction("Use Pulse Picker", self)
|
||||
action.setCheckable(True)
|
||||
action.setChecked(cfg.option(AppCfg.ACTIVATE_PULSE_PICKER))
|
||||
action.triggered.connect(lambda: cfg.toggle_option(AppCfg.ACTIVATE_PULSE_PICKER))
|
||||
self.toolBar.addAction(action)
|
||||
#action = QAction("Use Pulse Picker", self)
|
||||
#action.setCheckable(True)
|
||||
#action.setChecked(cfg.option(AppCfg.ACTIVATE_PULSE_PICKER))
|
||||
#action.triggered.connect(lambda: cfg.toggle_option(AppCfg.ACTIVATE_PULSE_PICKER))
|
||||
#self.toolBar.addAction(action)
|
||||
|
||||
icon = qtawesome.icon("material.timeline")
|
||||
action = QAction(icon, "Add Line", self)
|
||||
@@ -575,9 +520,9 @@ class WndSwissMx(QMainWindow, Ui_MainWindow):
|
||||
self.toolBar.widgetForAction(action).setAccessibleName("action_DataCollection")
|
||||
|
||||
self.actionQuit.triggered.connect(self.cb_really_quit)
|
||||
self.actionPreferences.triggered.connect(self._OLD_openPreferencesDialog)
|
||||
self.actionPreferences.triggered.connect(self.cb_modify_app_param)
|
||||
self.actionHome_Fast_Stages.triggered.connect(self.cb_deltatau_home_faststages)
|
||||
self.actionUser_Storage.triggered.connect(self._OLD_update_user_and_storage)
|
||||
self.actionAbout.triggered.connect(self.cb_about)
|
||||
|
||||
self.shortcut = QShortcut(QKeySequence(Qt.CTRL + Qt.SHIFT + Qt.Key_L), self)
|
||||
self.shortcut.activated.connect(self._OLD_roi_add_line)
|
||||
@@ -601,6 +546,12 @@ class WndSwissMx(QMainWindow, Ui_MainWindow):
|
||||
self.shortcut.activated.connect(self._OLD_camera_pause_toggle)
|
||||
|
||||
# adding a menu entry to one of the menus
|
||||
#action = QAction("parameters", self)
|
||||
#action.setToolTip("modify application parameters")
|
||||
#action.setStatusTip("modify application parameters")
|
||||
#action.triggered.connect(self.cb_modify_app_param)
|
||||
#self.menuAdvanced.addAction(action)
|
||||
|
||||
#action = QAction("geometry", self)
|
||||
#action.setToolTip("Update optical center, beam marker size etc.")
|
||||
#action.setStatusTip("Update optical center, beam marker size etc.")
|
||||
@@ -631,14 +582,6 @@ class WndSwissMx(QMainWindow, Ui_MainWindow):
|
||||
#action.triggered.connect(cfg.dlg_deltatau_parameters)
|
||||
#self.menuAdvanced.addAction(action)
|
||||
|
||||
action = QAction("parameters", self)
|
||||
action.setToolTip("modify application parameters")
|
||||
action.setStatusTip("modify application parameters")
|
||||
|
||||
action.triggered.connect(self.cb_modify_app_param)
|
||||
|
||||
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")
|
||||
@@ -665,7 +608,7 @@ class WndSwissMx(QMainWindow, Ui_MainWindow):
|
||||
_log.info('disconnect PV callback')
|
||||
cfg.setValue(cfg.WINDOW_GEOMETRY, self.saveGeometry())
|
||||
cfg.setValue(cfg.WINDOW_STATE, self.saveState())
|
||||
cfg.setValue(cfg.WINDOW_SPLITTER, self._main_splitter.sizes())
|
||||
cfg.setValue(cfg.WINDOW_SPLITTER, self._wd_splitter.sizes())
|
||||
cfg.setValue('last_active', time.time())
|
||||
_log.info('save settings')
|
||||
#QMainWindow.closeEvent(self, event)
|
||||
@@ -755,19 +698,13 @@ class WndSwissMx(QMainWindow, Ui_MainWindow):
|
||||
self.setStyleSheet(sheet.read())
|
||||
|
||||
def setup_sliders(self):
|
||||
cont = self._rightmost
|
||||
cont = self._wd_right
|
||||
self._tweak_container = QWidget()
|
||||
self._tweak_container.setLayout(QVBoxLayout())
|
||||
cont.layout().addWidget(self._tweak_container)
|
||||
layout = self._tweak_container.layout()
|
||||
layout.setSpacing(0)
|
||||
layout.setContentsMargins(0, 0, 0, 0)
|
||||
if self._at_x06sa:
|
||||
zoom_base = "ESBMX-SAMCAM" # fetura IOC by Jose Gabadinho
|
||||
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
|
||||
|
||||
self.zoombox = zoom.Zoom()
|
||||
self.zoombox.init_settings()
|
||||
@@ -1506,46 +1443,44 @@ class WndSwissMx(QMainWindow, Ui_MainWindow):
|
||||
|
||||
def cb_esc_sample_exchange(self):
|
||||
app=QApplication.instance()
|
||||
self._esc_state ="busy"
|
||||
steps = []
|
||||
#if option(CRYOJET_MOTION_ENABLED):
|
||||
# steps.append(lambda: self.move_cryojet_nozzle("out"))
|
||||
steps.extend(
|
||||
[
|
||||
steps=[
|
||||
lambda:self.move_detector("out"),
|
||||
lambda: self.move_post_tube("out"),
|
||||
lambda: app._backlight.move("out", wait=True),
|
||||
lambda: app._backlight.move("out"),
|
||||
lambda: self.move_collimator("out"),
|
||||
]
|
||||
)
|
||||
self.esc_run_steps(steps, "Transitioning to Sample Exchange")
|
||||
self._esc_state ="ManualSampleExchange"
|
||||
self.esc_run_steps(steps, "Transitioning to Sample Exchange","ManualSampleExchange")
|
||||
|
||||
def cb_esc_sample_alignment(self):
|
||||
app=QApplication.instance()
|
||||
self._esc_state ="busy"
|
||||
steps = [
|
||||
# lambda: sample_selection.tell.set_current(30.0),
|
||||
lambda: self.move_collimator("ready")
|
||||
lambda: self.move_collimator("ready"),
|
||||
lambda:self.move_detector("out"),
|
||||
lambda:self.move_post_tube("out"),
|
||||
lambda:app._backlight.move("in"),
|
||||
lambda:self.move_collimator("out"),
|
||||
]
|
||||
#if option(CRYOJET_MOTION_ENABLED):
|
||||
# steps.extend([lambda: self.move_cryojet_nozzle("in")])
|
||||
steps.extend([lambda: self.move_post_tube("out"), lambda: app._backlight.move("in")])
|
||||
self.esc_run_steps(steps, "Transitioning to Sample Alignment")
|
||||
self._esc_state ="SampleAlignment"
|
||||
#steps.extend([lambda: self.move_post_tube("out"), lambda: app._backlight.move("in")])
|
||||
self.esc_run_steps(steps, "Transitioning to Sample Alignment","SampleAlignment")
|
||||
|
||||
def cb_esc_data_collection(self):
|
||||
app=QApplication.instance()
|
||||
self._esc_state ="busy"
|
||||
steps = [
|
||||
# lambda: sample_selection.tell.set_current(30.0),
|
||||
lambda: app._backlight.move("out"),
|
||||
lambda: self.move_post_tube("in"),
|
||||
lambda: self.move_collimator("in"),
|
||||
lambda:self.move_detector("in"),
|
||||
]
|
||||
#if option(CRYOJET_MOTION_ENABLED):
|
||||
# steps.extend([lambda: self.move_cryojet_nozzle("in")])
|
||||
self.esc_run_steps(steps, "Transitioning to Data Collection")
|
||||
self._esc_state ="DataCollection"
|
||||
self.esc_run_steps(steps, "Transitioning to Data Collection","DataCollection")
|
||||
|
||||
def cb_really_quit(self):
|
||||
"""called when user Ctrl-Q the app"""
|
||||
@@ -1555,9 +1490,43 @@ class WndSwissMx(QMainWindow, Ui_MainWindow):
|
||||
|
||||
def cb_deltatau_home_faststages(self):
|
||||
pfx=QApplication.instance()._cfg.value(AppCfg.GBL_DEV_PREFIX)[0]
|
||||
_log.warning("homing fast stages")
|
||||
_log.info("homing fast stages")
|
||||
epics.PV(f"{pfx}1:ASYN.AOUT").put(b"enable plc 1")
|
||||
|
||||
def cb_about(self):
|
||||
try:
|
||||
ver,gitcmt=get_version()
|
||||
v_SMX=f'{ver} git:{gitcmt}'
|
||||
except:
|
||||
v_SMX='git version failed'
|
||||
try:
|
||||
ver,gitcmt=get_version('..')
|
||||
v_SMXT=f'{ver} git:{gitcmt}'
|
||||
except:
|
||||
v_SMXT='git version failed'
|
||||
|
||||
txt=f'''About Swissmx:
|
||||
|
||||
SwissMX: {v_SMX}
|
||||
SwissMXTools: {v_SMXT}
|
||||
|
||||
qt:{QT_VERSION_STR}
|
||||
pyqtgraph:{pg.__version__}
|
||||
numpy:{np.__version__}
|
||||
matplotlib:{mpl.__version__}
|
||||
epics:{epics.__version__}
|
||||
|
||||
Copyright (c) 2022 by Paul Scherrer Institute
|
||||
(http://www.psi.ch)
|
||||
|
||||
Based on Zac great first implementation
|
||||
Author Thierry Zamofing (thierry.zamofing@psi.ch)
|
||||
'''
|
||||
|
||||
QMessageBox.about(self, "SwissMX", txt)
|
||||
pass
|
||||
|
||||
|
||||
def cb_testcode(self):
|
||||
try:
|
||||
tc=self._testCode
|
||||
@@ -1602,8 +1571,8 @@ class WndSwissMx(QMainWindow, Ui_MainWindow):
|
||||
#print(vb.childGroup.childItems())
|
||||
pass
|
||||
|
||||
def prepare_left_tabs(self):
|
||||
tabs = self._left_tabs
|
||||
def prepare_wd_tabs_left(self):
|
||||
tabs = self._wd_tabs_left
|
||||
tabs.currentChanged.connect(self.cb_switch_task)
|
||||
|
||||
setup_tab = self._tab_setup
|
||||
@@ -1832,8 +1801,8 @@ class WndSwissMx(QMainWindow, Ui_MainWindow):
|
||||
|
||||
|
||||
def cb_switch_task(self, index=0):
|
||||
stack = self._centerpiece_stack
|
||||
task = self._left_tabs.currentWidget().accessibleName()
|
||||
stack = self._wd_stack
|
||||
task = self._wd_tabs_left.currentWidget().accessibleName()
|
||||
setup_task = self._setup_toolbox.currentWidget().accessibleName()
|
||||
method = self._tabs_daq_methods.currentWidget().accessibleName()
|
||||
|
||||
@@ -1992,7 +1961,6 @@ class WndSwissMx(QMainWindow, Ui_MainWindow):
|
||||
dt_misc = cfg.value(AppCfg.DT_MISC)
|
||||
|
||||
geo = app._geometry
|
||||
verbose=0xff
|
||||
fn='/tmp/shapepath'
|
||||
try:
|
||||
dt=app._deltatau
|
||||
@@ -2006,12 +1974,9 @@ class WndSwissMx(QMainWindow, Ui_MainWindow):
|
||||
sp=dt._shapepath
|
||||
sp.verbose=dt_misc['verbose']
|
||||
sp.points=kwargs['points']
|
||||
#sp.gen_grid_points(w=15, h=15, pitch=3, rnd=0, ofs=(0, +2000))
|
||||
#sp.gen_grid_points(w=5, h=10, pitch=1, rnd=0, ofs=(0, 0));sp.sort_points(False, 10);sp.points
|
||||
#sp.sort_points(False, 15);
|
||||
sp.meta['pt2pt_time']=dt_misc['pt2pt_time']
|
||||
sp.setup_gather()
|
||||
sp.setup_sync(verbose=verbose&32, timeOfs=0.05)
|
||||
sp.setup_sync(verbose=sp.verbose&0x20, timeOfs=0.05)
|
||||
try:
|
||||
p=geo._fitPlane
|
||||
sp.setup_coord_trf(cz=f'{p[0]:+.18g}X{p[1]:+.18g}Y{p[2]:+.18g}') # reset to shape path system
|
||||
@@ -2037,7 +2002,8 @@ class WndSwissMx(QMainWindow, Ui_MainWindow):
|
||||
plt.show(block=False)
|
||||
#plt.show(block=True)
|
||||
|
||||
def esc_run_steps(self, steps, title):
|
||||
def esc_run_steps(self, steps, title, esc_state):
|
||||
self._esc_state ="busy"
|
||||
with pg.ProgressDialog(title, 0, len(steps)) as dlg:
|
||||
for step in steps:
|
||||
step()
|
||||
@@ -2045,8 +2011,7 @@ class WndSwissMx(QMainWindow, Ui_MainWindow):
|
||||
if dlg.wasCanceled():
|
||||
QMessageBox.warning(self, "escape steps", "ABORTED" + title)
|
||||
break
|
||||
|
||||
#backlight="{'pos_in': -10.0, 'pos_out': 0.0}"
|
||||
self._esc_state = esc_state
|
||||
|
||||
def move_post_tube(self, pos):
|
||||
# post_sample_tube="{'x_up': -0.2, 'y_up': 0.0, 'x_down': 0.0, 'y_down': 0.0, 'x_out_delta': 0.0, 'y_out_delta': 0.0, 'z_in': 0.0, 'z_out': 0.0}"
|
||||
@@ -3554,7 +3519,7 @@ class WndSwissMx(QMainWindow, Ui_MainWindow):
|
||||
self.re_connect_collect_button()
|
||||
|
||||
def _OLD_create_escape_toolbar(self):
|
||||
cont = self._rightmost
|
||||
cont = self._wd_right
|
||||
w = QGroupBox("Escape")
|
||||
layout = QHBoxLayout()
|
||||
w.setLayout(layout)
|
||||
@@ -3725,7 +3690,6 @@ class WndSwissMx(QMainWindow, Ui_MainWindow):
|
||||
|
||||
if __name__=="__main__":
|
||||
def main():
|
||||
from PyQt5.QtCore import QT_VERSION_STR
|
||||
#_log.info(f'Version: pyqtgraph:{pg.__version__} matplotlib:{mpl.__version__} numpy:{np.__version__} epics:{epics.__version__} qt:{QT_VERSION_STR}' )
|
||||
_log.info(f'Version: pyqtgraph:{pg.__version__} epics:{epics.__version__} qt:{QT_VERSION_STR}' )
|
||||
import argparse, socket
|
||||
|
||||
Reference in New Issue
Block a user