add app_utils for motion_assert, contextMenu og GraphItem, further fixes
This commit is contained in:
@@ -220,7 +220,7 @@ class WndFixTarget(QWidget):
|
|||||||
# def contextMenuEvent(self, event) is called... but this requests to overload the function
|
# def contextMenuEvent(self, event) is called... but this requests to overload the function
|
||||||
# and to build an own context menu
|
# and to build an own context menu
|
||||||
# much simpler is to use Qt.ActionsContextMenu
|
# much simpler is to use Qt.ActionsContextMenu
|
||||||
# and to handle the context in the parent plass
|
# and to handle the context in the parent class
|
||||||
|
|
||||||
tree.setContextMenuPolicy(Qt.ActionsContextMenu)
|
tree.setContextMenuPolicy(Qt.ActionsContextMenu)
|
||||||
|
|
||||||
|
|||||||
20
Readme.md
20
Readme.md
@@ -325,6 +325,12 @@ avoid constand RBV event:
|
|||||||
caput SAR-ESPMX:MOT_FX 0.001
|
caput SAR-ESPMX:MOT_FX 0.001
|
||||||
caput SAR-ESPMX:MOT_FY 0.001
|
caput SAR-ESPMX:MOT_FY 0.001
|
||||||
---------- TODO ----------
|
---------- TODO ----------
|
||||||
|
|
||||||
|
caput SAR-ESPMX:MOT_FX.VELO 16
|
||||||
|
caput SAR-ESPMX:MOT_FY.VELO 16
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
-faster autofocus:
|
-faster autofocus:
|
||||||
- move at constant speed and acquire as fast as possible instead stop and go motion
|
- move at constant speed and acquire as fast as possible instead stop and go motion
|
||||||
|
|
||||||
@@ -335,8 +341,18 @@ caput SAR-ESPMX:MOT_FY 0.001
|
|||||||
|
|
||||||
- automation: towards automatic alignement
|
- automation: towards automatic alignement
|
||||||
|
|
||||||
|
if idx==0:
|
||||||
|
#go=UsrGO.Fiducial(bm_pos+bm_sz/2-(20, 20), (40, 40),(fx,fy,bz))
|
||||||
|
l=.120
|
||||||
|
go=UsrGO.Fiducial((fx-l/2,fy-l/2), (l, l),bz)
|
||||||
|
go.sigRegionChangeFinished.connect(self.cb_fiducial_update_z)
|
||||||
|
grp=self._goTracked
|
||||||
|
grp.addItem(go)
|
||||||
|
mft._tree.setData(grp.childItems())
|
||||||
|
|
||||||
|
|
||||||
|
="geometry/find_fiducial"
|
||||||
|
GEO_FND_FID,GEO_AUTOFOC="geometry/autofocus"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -92,7 +92,7 @@ class AppCfg(QSettings):
|
|||||||
if AppCfg.GEO_BEAM_SZ not in keys:
|
if AppCfg.GEO_BEAM_SZ not in keys:
|
||||||
dflt.append((AppCfg.GEO_BEAM_SZ, [30.2, 25.6]))
|
dflt.append((AppCfg.GEO_BEAM_SZ, [30.2, 25.6]))
|
||||||
if AppCfg.GEO_BEAM_POS not in keys:
|
if AppCfg.GEO_BEAM_POS not in keys:
|
||||||
dflt.append((AppCfg.GEO_BEAM_POS, [23.4, -54.2]))
|
dflt.append((AppCfg.GEO_BEAM_POS, [23.4, 54.2]))
|
||||||
if AppCfg.GEO_FND_FID not in keys:
|
if AppCfg.GEO_FND_FID not in keys:
|
||||||
dflt.append((AppCfg.GEO_FND_FID, {'sz':101, 'brd':8, 'pitch':120, 'mode':0}))
|
dflt.append((AppCfg.GEO_FND_FID, {'sz':101, 'brd':8, 'pitch':120, 'mode':0}))
|
||||||
if AppCfg.GEO_AUTOFOC not in keys:
|
if AppCfg.GEO_AUTOFOC not in keys:
|
||||||
@@ -308,11 +308,12 @@ verbose bits:
|
|||||||
]},
|
]},
|
||||||
{'name': AppCfg.DFT_POS_BKLGT, 'title':'Back Light reference positions', 'type':'group','expanded':False, 'children':[
|
{'name': AppCfg.DFT_POS_BKLGT, 'title':'Back Light reference positions', 'type':'group','expanded':False, 'children':[
|
||||||
{'name':'pos_in', 'title':'In position', 'value':dft_pos_bklgt.get('pos_in',0), 'type':'float', 'limits':(-30000, 10 ),'step':10, 'decimals':5, 'suffix':'ustep'},
|
{'name':'pos_in', 'title':'In position', 'value':dft_pos_bklgt.get('pos_in',0), 'type':'float', 'limits':(-30000, 10 ),'step':10, 'decimals':5, 'suffix':'ustep'},
|
||||||
{'name':'pos_out','title':'Out position', 'value':dft_pos_bklgt.get('pos_out',0), 'type':'float', 'limits':(-1000, 10 ),'step':10, 'decimals':5, 'suffix':'ustep'},
|
{'name':'pos_out', 'title':'Out position', 'value':dft_pos_bklgt.get('pos_out',0), 'type':'float', 'limits':(-30000, 10 ),'step':10, 'decimals':5, 'suffix':'ustep'},
|
||||||
|
{'name':'pos_diode','title':'Diode pos', 'value':dft_pos_bklgt.get('pos_diode', 0), 'type':'float','limits':(-30000, 10), 'step':10, 'decimals':5, 'suffix':'ustep'},
|
||||||
]},
|
]},
|
||||||
{'name': AppCfg.DFT_POS_DET, 'title':'detector reference positions', 'type':'group','expanded':False, 'children':[
|
{'name': AppCfg.DFT_POS_DET, 'title':'detector reference positions', 'type':'group','expanded':False, 'children':[
|
||||||
{'name':'pos_in', 'title':'In position', 'value':dft_pos_det.get('pos_in',0), 'type':'float', 'limits':(-20, 20 ),'step':0.1, 'decimals':5, 'suffix':' mm'},
|
{'name':'pos_in', 'title':'In position', 'value':dft_pos_det.get('pos_in',0), 'type':'float', 'limits':(-200, 200),'step':0.1, 'decimals':5, 'suffix':' mm'},
|
||||||
{'name':'pos_out','title':'Out position', 'value':dft_pos_det.get('pos_out',0), 'type':'float', 'limits':(-20, 20 ),'step':0.1, 'decimals':5, 'suffix':' mm'},
|
{'name':'pos_out','title':'Out position', 'value':dft_pos_det.get('pos_out',0), 'type':'float', 'limits':(-200, 200),'step':0.1, 'decimals':5, 'suffix':' mm'},
|
||||||
{'name':'set_in', 'title':'use current position as "in"', 'type':'action'},
|
{'name':'set_in', 'title':'use current position as "in"', 'type':'action'},
|
||||||
{'name':'set_out', 'title':'use current position as "out"', 'type':'action'},
|
{'name':'set_out', 'title':'use current position as "out"', 'type':'action'},
|
||||||
]},
|
]},
|
||||||
|
|||||||
89
app_utils.py
89
app_utils.py
@@ -1,36 +1,16 @@
|
|||||||
import time
|
import time
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
import enum
|
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
_log=logging.getLogger(__name__)
|
||||||
logger.setLevel(logging.DEBUG)
|
|
||||||
|
|
||||||
from epics.ca import pend_event
|
from epics.ca import pend_event
|
||||||
|
|
||||||
class DeltatauMotorStatus(enum.Flag):
|
|
||||||
"""names are taken from motorx_all.ui"""
|
|
||||||
DIRECTION = enum.auto()
|
|
||||||
MOTION_IS_COMPLETE = enum.auto()
|
|
||||||
PLUS_LIMIT_SWITCH = enum.auto()
|
|
||||||
HOME_SWITCH = enum.auto()
|
|
||||||
UNUSED_1 = enum.auto()
|
|
||||||
CLOSED_LOOP_POSITION = enum.auto()
|
|
||||||
SLIP_STALL_DETECTED = enum.auto()
|
|
||||||
AT_HOME_POSITION = enum.auto()
|
|
||||||
ENCODER_IS_PRESENT = enum.auto()
|
|
||||||
PROBLEM = enum.auto()
|
|
||||||
MOVING = enum.auto()
|
|
||||||
GAIN_SUPPORT = enum.auto()
|
|
||||||
COMMUNICATION_ERROR = enum.auto()
|
|
||||||
MINUS_LIMIT_SWITCH = enum.auto()
|
|
||||||
MOTOR_HAS_BEEN_HOMED = enum.auto()
|
|
||||||
|
|
||||||
AT_SWITCH = MINUS_LIMIT_SWITCH | PLUS_LIMIT_SWITCH
|
|
||||||
|
|
||||||
class PositionsNotReached(Exception):
|
class PositionsNotReached(Exception):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
def assert_tweaker_positions(targets, timeout=60.0):
|
def assert_tweaker_positions(targets, timeout=60.0):
|
||||||
"""
|
"""
|
||||||
wait for each of the given motors to have specified positions within tolerance
|
wait for each of the given motors to have specified positions within tolerance
|
||||||
@@ -41,32 +21,33 @@ def assert_tweaker_positions(targets, timeout=60.0):
|
|||||||
:return: None
|
:return: None
|
||||||
:raises: PositionsNotReached
|
:raises: PositionsNotReached
|
||||||
"""
|
"""
|
||||||
num_motors = len(targets)
|
num_motors=len(targets)
|
||||||
|
|
||||||
timeisup = timeout + time.time()
|
timeisup=timeout+time.time()
|
||||||
|
|
||||||
while time.time() < timeisup:
|
while time.time()<timeisup:
|
||||||
count = 0
|
count=0
|
||||||
summary = []
|
summary=[]
|
||||||
for i, m in enumerate(targets):
|
for i, m in enumerate(targets):
|
||||||
motor, target, tolerance = m
|
motor, target, tolerance=m
|
||||||
#name = motor.short_name
|
name=motor.short_name
|
||||||
#pend_event()
|
pend_event()
|
||||||
cur = motor.get_rbv()
|
cur=motor.get_position()
|
||||||
done = motor.is_done()
|
done=motor.is_done()
|
||||||
#logger.debug("check {}[done={}]: {} == {}".format(name, done, cur, target))
|
_log.debug("check {}[done={}]: {} == {}".format(name, done, cur, target))
|
||||||
#summary.append("{}[done={}]: {} == {}".format(name, done, cur, target))
|
summary.append("{}[done={}]: {} == {}".format(name, done, cur, target))
|
||||||
if done and tolerance >= abs(cur - target):
|
if done and tolerance>=abs(cur-target):
|
||||||
count += 1
|
count+=1
|
||||||
#pend_event(0.1)
|
pend_event(0.1)
|
||||||
|
|
||||||
if count == num_motors:
|
if count==num_motors:
|
||||||
break
|
break
|
||||||
#pend_event(0.1)
|
pend_event(0.1)
|
||||||
|
|
||||||
if count != num_motors:
|
if count!=num_motors:
|
||||||
raise PositionsNotReached("failed to reach target positions: {}".format("#".join(summary)))
|
raise PositionsNotReached("failed to reach target positions: {}".format("#".join(summary)))
|
||||||
|
|
||||||
|
|
||||||
def assert_motor_positions(targets, timeout=60.0):
|
def assert_motor_positions(targets, timeout=60.0):
|
||||||
"""
|
"""
|
||||||
wait for each of the given motors to have specified positions within tolerance
|
wait for each of the given motors to have specified positions within tolerance
|
||||||
@@ -77,28 +58,28 @@ def assert_motor_positions(targets, timeout=60.0):
|
|||||||
:return: None
|
:return: None
|
||||||
:raises: PositionsNotReached
|
:raises: PositionsNotReached
|
||||||
"""
|
"""
|
||||||
num_motors = len(targets)
|
num_motors=len(targets)
|
||||||
|
|
||||||
timeisup = timeout + time.time()
|
timeisup=timeout+time.time()
|
||||||
|
|
||||||
while time.time() < timeisup:
|
while time.time()<timeisup:
|
||||||
count = 0
|
count=0
|
||||||
summary = []
|
summary=[]
|
||||||
for i, m in enumerate(targets):
|
for i, m in enumerate(targets):
|
||||||
motor, target, tolerance = m
|
motor, target, tolerance=m
|
||||||
name = motor._prefix
|
name=motor._prefix
|
||||||
pend_event()
|
pend_event()
|
||||||
cur = motor.get_position(readback=True)
|
cur=motor.get_position(readback=True)
|
||||||
done = motor.done_moving
|
done=motor.done_moving
|
||||||
logger.debug("check {}[done={}]: {} == {}".format(name, done, cur, target))
|
_log.debug("check {}[done={}]: {} == {}".format(name, done, cur, target))
|
||||||
summary.append("{}[done={}]: {} == {}".format(name, done, cur, target))
|
summary.append("{}[done={}]: {} == {}".format(name, done, cur, target))
|
||||||
if done and tolerance >= abs(cur - target):
|
if done and tolerance>=abs(cur-target):
|
||||||
count += 1
|
count+=1
|
||||||
pend_event(0.1)
|
pend_event(0.1)
|
||||||
|
|
||||||
if count == num_motors:
|
if count==num_motors:
|
||||||
break
|
break
|
||||||
pend_event()
|
pend_event()
|
||||||
|
|
||||||
if count != num_motors:
|
if count!=num_motors:
|
||||||
raise PositionsNotReached("failed to reach target positions: {}".format("#".join(summary)))
|
raise PositionsNotReached("failed to reach target positions: {}".format("#".join(summary)))
|
||||||
|
|||||||
10
backlight.py
10
backlight.py
@@ -14,13 +14,13 @@ import epics
|
|||||||
#from app_utils import assert_motor_positions
|
#from app_utils import assert_motor_positions
|
||||||
|
|
||||||
class Backlight(object):
|
class Backlight(object):
|
||||||
def __init__(self, prefix: str='SAR-EXPMX:MOT_BLGT'):
|
def __init__(self, prefix: str='SAR-EXPMX:MOT_BLGT',pos={'pos_in':-29000,'pos_out':0,'pos_diode':0}):
|
||||||
if prefix is None:
|
if prefix is None:
|
||||||
self._sim={'pos':'out'}
|
self._sim={'pos':'out'}
|
||||||
_log.info('simulated mode:{}'.format(self._sim))
|
_log.info('simulated mode:{}'.format(self._sim))
|
||||||
return #simulated mode
|
return #simulated mode
|
||||||
self._mot = epics.Motor(prefix)
|
self._mot = epics.Motor(prefix)
|
||||||
self._pos = {'in':-29000,'out':0}
|
self._pos = pos
|
||||||
|
|
||||||
def is_pos(self,strPos):
|
def is_pos(self,strPos):
|
||||||
try:
|
try:
|
||||||
@@ -29,7 +29,7 @@ class Backlight(object):
|
|||||||
_log.info('simulated mode:{}'.format(strPos))
|
_log.info('simulated mode:{}'.format(strPos))
|
||||||
return self._sim['pos']==strPos
|
return self._sim['pos']==strPos
|
||||||
m.refresh()
|
m.refresh()
|
||||||
return abs(m.readback - self._pos[strPos]) < 10
|
return abs(m.readback - self._pos['pos_'+strPos]) < 10
|
||||||
|
|
||||||
def move(self, strPos, wait=False):
|
def move(self, strPos, wait=False):
|
||||||
try:
|
try:
|
||||||
@@ -40,7 +40,7 @@ class Backlight(object):
|
|||||||
return
|
return
|
||||||
m=self._mot
|
m=self._mot
|
||||||
_log.debug("backlight to {}".format(strPos))
|
_log.debug("backlight to {}".format(strPos))
|
||||||
target=self._pos[strPos]
|
target=self._pos['pos_'+strPos]
|
||||||
m.move(target, ignore_limits=True, wait=wait)
|
m.move(target, ignore_limits=True, wait=wait)
|
||||||
|
|
||||||
|
|
||||||
@@ -55,7 +55,7 @@ if __name__ == "__main__":
|
|||||||
parser.add_argument("-t", "--test", help="test sequence", action="store_true")
|
parser.add_argument("-t", "--test", help="test sequence", action="store_true")
|
||||||
|
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
os.environ['EPICS_CA_ADDR_LIST'] = '129.129.244.255 sf-saresc-cagw.psi.ch:5062 sf-saresc-cagw.psi.ch:5066'
|
os.environ['EPICS_CA_ADDR_LIST']='129.129.244.255 sf-saresc-cagw.psi.ch:5062 sf-saresc-cagw.psi.ch:5066'
|
||||||
_log.info('Arguments:{}'.format(args.__dict__))
|
_log.info('Arguments:{}'.format(args.__dict__))
|
||||||
|
|
||||||
bl = Backlight()
|
bl = Backlight()
|
||||||
|
|||||||
@@ -217,7 +217,8 @@ class epics_cam(object):
|
|||||||
_log.info('simulated mode:{}'.format(exp))
|
_log.info('simulated mode:{}'.format(exp))
|
||||||
self._sim['exp']=exp
|
self._sim['exp']=exp
|
||||||
return
|
return
|
||||||
pv_exp.put(exp, wait=True)
|
self.update_params((pv_exp,exp))
|
||||||
|
#pv_exp.put(exp, wait=True)
|
||||||
|
|
||||||
def get_exposure(self):
|
def get_exposure(self):
|
||||||
try:
|
try:
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ from PyQt5.uic import loadUiType
|
|||||||
from epics import Motor
|
from epics import Motor
|
||||||
from epics.ca import pend_event
|
from epics.ca import pend_event
|
||||||
|
|
||||||
from app_utils import DeltatauMotorStatus, assert_motor_positions
|
from app_utils import assert_motor_positions
|
||||||
|
|
||||||
Ui_MotorTweak, QWidget = loadUiType('epics_widgets/MotorTweak.ui')
|
Ui_MotorTweak, QWidget = loadUiType('epics_widgets/MotorTweak.ui')
|
||||||
SPMG_STOP = 0
|
SPMG_STOP = 0
|
||||||
@@ -138,12 +138,6 @@ class MotorTweak(QWidget, Ui_MotorTweak):
|
|||||||
self._val=v=m.get('VAL')
|
self._val=v=m.get('VAL')
|
||||||
return v
|
return v
|
||||||
|
|
||||||
def is_homed(self):
|
|
||||||
m=self._motor
|
|
||||||
m.refresh()
|
|
||||||
status = DeltatauMotorStatus(m.motor_status)
|
|
||||||
return bool(DeltatauMotorStatus.MOTOR_HAS_BEEN_HOMED & status)
|
|
||||||
|
|
||||||
def move_abs(self, drive=None, wait=False, assert_position=False):
|
def move_abs(self, drive=None, wait=False, assert_position=False):
|
||||||
if drive is None:
|
if drive is None:
|
||||||
drive = float(self._drive_val.text())
|
drive = float(self._drive_val.text())
|
||||||
|
|||||||
@@ -7,8 +7,7 @@ from PyQt5.QtWidgets import QMenu, QInputDialog, QAction
|
|||||||
from PyQt5.uic import loadUiType
|
from PyQt5.uic import loadUiType
|
||||||
from epics import PV
|
from epics import PV
|
||||||
from epics.ca import pend_event
|
from epics.ca import pend_event
|
||||||
|
from motor_utils import assert_tweaker_positions
|
||||||
#from app_utils import assert_tweaker_positions #ZAC: orig. code
|
|
||||||
|
|
||||||
Ui_MotorTweak, QWidget = loadUiType('epics_widgets/MotorTweak.ui')
|
Ui_MotorTweak, QWidget = loadUiType('epics_widgets/MotorTweak.ui')
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|||||||
@@ -85,7 +85,7 @@ class Jungfrau:
|
|||||||
_log.warning(f'Jungfrau not connected: {e}')
|
_log.warning(f'Jungfrau not connected: {e}')
|
||||||
self._daq=None
|
self._daq=None
|
||||||
self._pv_pulse_id=epics.PV('SAR-EXPMX-EVR0:RX-PULSEID')
|
self._pv_pulse_id=epics.PV('SAR-EXPMX-EVR0:RX-PULSEID')
|
||||||
|
self._pv_pulse_id.connect()
|
||||||
|
|
||||||
def acquire(self,run_name, n_pulses, wait=False):
|
def acquire(self,run_name, n_pulses, wait=False):
|
||||||
if self._daq is not None:
|
if self._daq is not None:
|
||||||
@@ -94,4 +94,6 @@ class Jungfrau:
|
|||||||
|
|
||||||
def gather_upload(self):
|
def gather_upload(self):
|
||||||
self._pulse_id_end=self._pv_pulse_id.value
|
self._pulse_id_end=self._pv_pulse_id.value
|
||||||
|
_log.debug(f'pulse_id: {self._pulse_id_start}..{self._pulse_id_end}')
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -20,6 +20,8 @@ from pyqtgraph.Qt import QtCore, QtGui
|
|||||||
import numpy as np
|
import numpy as np
|
||||||
from PyQt5.QtGui import QPolygon,QPolygonF
|
from PyQt5.QtGui import QPolygon,QPolygonF
|
||||||
from PyQt5.QtCore import Qt,QPointF,QLineF
|
from PyQt5.QtCore import Qt,QPointF,QLineF
|
||||||
|
from PyQt5.QtWidgets import QMenu
|
||||||
|
|
||||||
|
|
||||||
def itr2str(itr):
|
def itr2str(itr):
|
||||||
return '('+', '.join(tuple(map(lambda x:f'{x:.6g}', itr)))+')'
|
return '('+', '.join(tuple(map(lambda x:f'{x:.6g}', itr)))+')'
|
||||||
@@ -145,10 +147,28 @@ class Marker(pg.ROI):
|
|||||||
p.setTransform(tr)
|
p.setTransform(tr)
|
||||||
return ofx,ofy
|
return ofx,ofy
|
||||||
|
|
||||||
|
class UsrROI(pg.ROI):
|
||||||
class Fiducial(pg.ROI):
|
def __init__(self, pos, size, **kargs):
|
||||||
def __init__(self, pos, size, z:float, **kargs):
|
|
||||||
pg.ROI.__init__(self, pos, size, **kargs)
|
pg.ROI.__init__(self, pos, size, **kargs)
|
||||||
|
|
||||||
|
def cb_toggle_movable(self):
|
||||||
|
self.translatable=not self.translatable
|
||||||
|
|
||||||
|
def contextMenuEvent(self, event):
|
||||||
|
#pg.ROI.contextMenuEvent(self,event)
|
||||||
|
_log.debug('ContextMenu')
|
||||||
|
menu = QMenu("ctx")
|
||||||
|
act=menu.addAction('locked')
|
||||||
|
act.setCheckable(True)
|
||||||
|
act.setChecked(not self.translatable)
|
||||||
|
act.triggered.connect(self.cb_toggle_movable)
|
||||||
|
#menu.addAction('center in view')
|
||||||
|
#menu.addAction('delete')
|
||||||
|
menu.exec(event.screenPos())
|
||||||
|
|
||||||
|
class Fiducial(UsrROI):
|
||||||
|
def __init__(self, pos, size, z:float, **kargs):
|
||||||
|
UsrROI.__init__(self, pos, size, **kargs)
|
||||||
self._z=z
|
self._z=z
|
||||||
|
|
||||||
def paint(self, p, *args):
|
def paint(self, p, *args):
|
||||||
@@ -195,7 +215,7 @@ class Fiducial(pg.ROI):
|
|||||||
return jsn
|
return jsn
|
||||||
|
|
||||||
|
|
||||||
class Grid(pg.ROI):
|
class Grid(UsrROI):
|
||||||
'''a grid'''
|
'''a grid'''
|
||||||
|
|
||||||
def __init__( self, pos=(0,0), size=(30,20), cnt=(6,4), fiducialSize=.2, **kargs):
|
def __init__( self, pos=(0,0), size=(30,20), cnt=(6,4), fiducialSize=.2, **kargs):
|
||||||
@@ -271,7 +291,7 @@ class Grid(pg.ROI):
|
|||||||
return pts
|
return pts
|
||||||
|
|
||||||
|
|
||||||
class Path(pg.ROI):
|
class Path(UsrROI):
|
||||||
'''
|
'''
|
||||||
a path object with fiducials
|
a path object with fiducials
|
||||||
path=np.array(n,2) of path points
|
path=np.array(n,2) of path points
|
||||||
@@ -347,7 +367,7 @@ class Path(pg.ROI):
|
|||||||
}
|
}
|
||||||
return jsn
|
return jsn
|
||||||
|
|
||||||
class FixTargetFrame(pg.ROI):
|
class FixTargetFrame(UsrROI):
|
||||||
'''fixed target frame'''
|
'''fixed target frame'''
|
||||||
tpl={
|
tpl={
|
||||||
'test':{
|
'test':{
|
||||||
@@ -664,7 +684,7 @@ if __name__=='__main__':
|
|||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
obj_info(o)
|
obj_info(o)
|
||||||
print(o.state)
|
#print(o.state)
|
||||||
|
|
||||||
|
|
||||||
## Create image to display
|
## Create image to display
|
||||||
@@ -689,7 +709,7 @@ if __name__=='__main__':
|
|||||||
w=pg.GraphicsLayoutWidget(show=True, size=(1000, 800), border=True)
|
w=pg.GraphicsLayoutWidget(show=True, size=(1000, 800), border=True)
|
||||||
w.setWindowTitle('pyqtgraph example: ROI Examples')
|
w.setWindowTitle('pyqtgraph example: ROI Examples')
|
||||||
|
|
||||||
vb=w.addViewBox(row=1, col=0, lockAspect=True,invertY=False)
|
vb=w.addViewBox(row=1, col=0, lockAspect=True,invertY=False,enableMenu=False)
|
||||||
vb.enableAutoRange(enable=False)
|
vb.enableAutoRange(enable=False)
|
||||||
try:
|
try:
|
||||||
g=pg.GridItem(pen=(0, 255, 0), textPen=(0, 255, 0)) # green grid and labels
|
g=pg.GridItem(pen=(0, 255, 0), textPen=(0, 255, 0)) # green grid and labels
|
||||||
@@ -748,9 +768,13 @@ if __name__=='__main__':
|
|||||||
vi=FixTargetFrame((400,-200),(400,400),tpl='12.5x12.5')
|
vi=FixTargetFrame((400,-200),(400,400),tpl='12.5x12.5')
|
||||||
vb.addItem(vi)
|
vb.addItem(vi)
|
||||||
|
|
||||||
vi=Fiducial((0,200),(40,40),3)
|
vi=Fiducial((0,200),(40,40),3,movable=False,removable=True)
|
||||||
vb.addItem(vi)
|
vb.addItem(vi)
|
||||||
|
|
||||||
|
vi=pg.PolyLineROI([(22, -19), (40, -30), (23, -10), (22, -19)], closed=True)
|
||||||
|
vb.addItem(vi)
|
||||||
|
|
||||||
|
|
||||||
viRoi=pg.ROI([-200, -200], [100, 80],movable=True, rotatable=True, resizable=True)
|
viRoi=pg.ROI([-200, -200], [100, 80],movable=True, rotatable=True, resizable=True)
|
||||||
|
|
||||||
viRoi.addFreeHandle(pos=[.7, .5], axes=None, item=None, name=None, index=None) # rechteck , frei beweglich ??? verschwinden anch bewegung
|
viRoi.addFreeHandle(pos=[.7, .5], axes=None, item=None, name=None, index=None) # rechteck , frei beweglich ??? verschwinden anch bewegung
|
||||||
|
|||||||
67
swissmx.py
67
swissmx.py
@@ -5,7 +5,7 @@
|
|||||||
# | Based on Zac great first implementation |
|
# | Based on Zac great first implementation |
|
||||||
# | Author Thierry Zamofing (thierry.zamofing@psi.ch) |
|
# | Author Thierry Zamofing (thierry.zamofing@psi.ch) |
|
||||||
# *-----------------------------------------------------------------------*
|
# *-----------------------------------------------------------------------*
|
||||||
'''
|
"""
|
||||||
SwissMx experiment application.
|
SwissMx experiment application.
|
||||||
Based on Zac great first implementation
|
Based on Zac great first implementation
|
||||||
|
|
||||||
@@ -18,7 +18,7 @@ bitmask for simulation:
|
|||||||
0x10: Deltatau motors
|
0x10: Deltatau motors
|
||||||
0x20: SmarAct motors
|
0x20: SmarAct motors
|
||||||
|
|
||||||
'''
|
"""
|
||||||
import logging
|
import logging
|
||||||
logging.basicConfig(level=logging.DEBUG, format='%(levelname)s:%(module)s:%(lineno)d:%(funcName)s:%(message)s ')
|
logging.basicConfig(level=logging.DEBUG, format='%(levelname)s:%(module)s:%(lineno)d:%(funcName)s:%(message)s ')
|
||||||
|
|
||||||
@@ -439,9 +439,6 @@ class WndSwissMx(QMainWindow, Ui_MainWindow):
|
|||||||
self.shortcut = QShortcut(QKeySequence(Qt.CTRL + Qt.Key_S), self)
|
self.shortcut = QShortcut(QKeySequence(Qt.CTRL + Qt.Key_S), self)
|
||||||
self.shortcut.activated.connect(self.cb_save_cam_image)
|
self.shortcut.activated.connect(self.cb_save_cam_image)
|
||||||
|
|
||||||
self.shortcut = QShortcut(QKeySequence(Qt.CTRL + Qt.SHIFT + Qt.Key_T), self)
|
|
||||||
self.shortcut.activated.connect(lambda: qutilities.toggle_warn(SKIP_ESCAPE_TRANSITIONS_IF_SAFE))
|
|
||||||
|
|
||||||
for k in range(10):
|
for k in range(10):
|
||||||
qkey = k + Qt.Key_0
|
qkey = k + Qt.Key_0
|
||||||
self.shortcut = QShortcut(QKeySequence(Qt.CTRL + Qt.SHIFT + qkey), self)
|
self.shortcut = QShortcut(QKeySequence(Qt.CTRL + Qt.SHIFT + qkey), self)
|
||||||
@@ -632,11 +629,12 @@ class WndSwissMx(QMainWindow, Ui_MainWindow):
|
|||||||
_log.debug('TODO: check to not connect smultiple igNewCamImg')
|
_log.debug('TODO: check to not connect smultiple igNewCamImg')
|
||||||
if index > 0: # not showing camera image
|
if index > 0: # not showing camera image
|
||||||
_log.warning("listening to zescape")
|
_log.warning("listening to zescape")
|
||||||
self.timer.stop()
|
pass
|
||||||
zescape.start_listening()
|
#self.timer.stop()
|
||||||
self.timer = QtCore.QTimer(self)
|
#zescape.start_listening()
|
||||||
self.timer.timeout.connect(self.check_zescape)
|
#self.timer = QtCore.QTimer(self)
|
||||||
self.timer.start(20)
|
#self.timer.timeout.connect(self.check_zescape)
|
||||||
|
#self.timer.start(20)
|
||||||
else:
|
else:
|
||||||
app=QApplication.instance()
|
app=QApplication.instance()
|
||||||
try:
|
try:
|
||||||
@@ -1461,15 +1459,16 @@ class WndSwissMx(QMainWindow, Ui_MainWindow):
|
|||||||
vb.removeItem(go)
|
vb.removeItem(go)
|
||||||
tmpGoLst.clear()
|
tmpGoLst.clear()
|
||||||
|
|
||||||
n=int(p.shape[0]/100)+1
|
# adding debug fiducials
|
||||||
for i in range(0,p.shape[0],n):
|
#n=int(p.shape[0]/100)+1
|
||||||
fx,fy=p[i, :]/1000
|
#for i in range(0,p.shape[0],n):
|
||||||
fx=-fx #X axis has inverted sign !
|
# fx,fy=p[i, :]/1000
|
||||||
l=.06
|
# fx=-fx #X axis has inverted sign !
|
||||||
go=UsrGO.Fiducial((fx-l/2, fy-l/2), (l, l), i)
|
# l=.06
|
||||||
grp.addItem(go)
|
# go=UsrGO.Fiducial((fx-l/2, fy-l/2), (l, l), i)
|
||||||
tmpGoLst.append(go)
|
# grp.addItem(go)
|
||||||
mft._tree.setData(grp.childItems())
|
# tmpGoLst.append(go)
|
||||||
|
#mft._tree.setData(grp.childItems())
|
||||||
|
|
||||||
#_log.debug(f'first point:{p[0,:]}')
|
#_log.debug(f'first point:{p[0,:]}')
|
||||||
#_log.debug(f'step to 2nd point:{p[1,:]-p[0,:]}')
|
#_log.debug(f'step to 2nd point:{p[1,:]-p[0,:]}')
|
||||||
@@ -1541,7 +1540,7 @@ class WndSwissMx(QMainWindow, Ui_MainWindow):
|
|||||||
app=QApplication.instance()
|
app=QApplication.instance()
|
||||||
steps = [
|
steps = [
|
||||||
# lambda: sample_selection.tell.set_current(30.0),
|
# lambda: sample_selection.tell.set_current(30.0),
|
||||||
lambda: self.move_collimator("ready"),
|
lambda: self.move_collimator("out"),
|
||||||
lambda:self.move_detector("out"),
|
lambda:self.move_detector("out"),
|
||||||
lambda:self.move_post_tube("out"),
|
lambda:self.move_post_tube("out"),
|
||||||
lambda:app._backlight.move("in"),
|
lambda:app._backlight.move("in"),
|
||||||
@@ -2080,14 +2079,20 @@ Author Thierry Zamofing (thierry.zamofing@psi.ch)
|
|||||||
|
|
||||||
j=0
|
j=0
|
||||||
elif type(go)==UsrGO.Fiducial and go.size()[0]==0.12:
|
elif type(go)==UsrGO.Fiducial and go.size()[0]==0.12:
|
||||||
|
if j<ptFitTrf.shape[0]:
|
||||||
ptFitTrf[j]=go.pos()+go.size()/2
|
ptFitTrf[j]=go.pos()+go.size()/2
|
||||||
|
j+=1
|
||||||
ptFitPlane[i]=go.ctr()
|
ptFitPlane[i]=go.ctr()
|
||||||
i+=1;j+=1
|
i+=1
|
||||||
app=QApplication.instance()
|
app=QApplication.instance()
|
||||||
geo=app._geometry
|
geo=app._geometry
|
||||||
if n>=3:
|
if n>=3:
|
||||||
geo.least_square_plane(ptFitPlane)
|
geo.least_square_plane(ptFitPlane)
|
||||||
|
|
||||||
|
def cb_progress(self,i,sz,dlg):
|
||||||
|
dlg.setValue(int(sz*90/i))
|
||||||
|
if dlg.wasCanceled():
|
||||||
|
raise AttributeError('canceled')
|
||||||
|
|
||||||
def daq_collect(self, **kwargs):# points, visualizer_method, visualizer_params):
|
def daq_collect(self, **kwargs):# points, visualizer_method, visualizer_params):
|
||||||
#def _OLD_daq_collect_points(self, points, visualizer_method, visualizer_params):
|
#def _OLD_daq_collect_points(self, points, visualizer_method, visualizer_params):
|
||||||
@@ -2134,14 +2139,21 @@ Author Thierry Zamofing (thierry.zamofing@psi.ch)
|
|||||||
sp.setup_coord_trf() # reset to shape path system
|
sp.setup_coord_trf() # reset to shape path system
|
||||||
# sp.meta['pt2pt_time']=10 #put between setup_sync and setup_motion to have more motion points than FEL syncs
|
# sp.meta['pt2pt_time']=10 #put between setup_sync and setup_motion to have more motion points than FEL syncs
|
||||||
dlg.setLabelText("Download motion program");dlg+=5
|
dlg.setLabelText("Download motion program");dlg+=5
|
||||||
|
|
||||||
|
try:
|
||||||
|
sp.comm.gpascii._cb_func=lambda i, sz:self.cb_progress(i, sz, dlg)
|
||||||
|
except AttributeError:
|
||||||
|
pass
|
||||||
|
|
||||||
sp.setup_motion(fnPrg=fn+'.prg', mode=3, scale=1., dwell=10)
|
sp.setup_motion(fnPrg=fn+'.prg', mode=3, scale=1., dwell=10)
|
||||||
dlg.setLabelText("Homing and get ready");dlg+=35
|
if dlg.wasCanceled():
|
||||||
|
return
|
||||||
|
dlg.setLabelText("Homing and get ready");dlg+=5
|
||||||
sp.homing() # homing if needed
|
sp.homing() # homing if needed
|
||||||
sp.run() # start motion program
|
sp.run() # start motion program
|
||||||
sp.wait_armed() # wait until motors are at first position
|
sp.wait_armed() # wait until motors are at first position
|
||||||
|
|
||||||
sp.trigger(0.5) # send a start trigger (if needed) after given time
|
sp.trigger(0.5) # send a start trigger (if needed) after given time
|
||||||
#PV with the current pulse
|
|
||||||
# [sf-lc7a ~]$ caget
|
|
||||||
jf.acquire('filename.tmp',sp.points.shape[0])
|
jf.acquire('filename.tmp',sp.points.shape[0])
|
||||||
if not dt._comm is None:
|
if not dt._comm is None:
|
||||||
dlg.setLabelText("run motion/acquisition")
|
dlg.setLabelText("run motion/acquisition")
|
||||||
@@ -3906,10 +3918,13 @@ if __name__=="__main__":
|
|||||||
app._geometry._opt_ctr=cfg.value(cfg.GEO_OPT_CTR)
|
app._geometry._opt_ctr=cfg.value(cfg.GEO_OPT_CTR)
|
||||||
|
|
||||||
startupWin.set(15, f'connect backlight')
|
startupWin.set(15, f'connect backlight')
|
||||||
|
pfx=app._cfg.value(AppCfg.GBL_DEV_PREFIX)[0]
|
||||||
|
dft_pos_bklgt=app._cfg.value(AppCfg.DFT_POS_BKLGT)
|
||||||
|
|
||||||
if args.sim&0x01:
|
if args.sim&0x01:
|
||||||
app._backlight = backlight.Backlight(None)
|
app._backlight = backlight.Backlight(None,dft_pos_bklgt)
|
||||||
else:
|
else:
|
||||||
app._backlight = backlight.Backlight()
|
app._backlight = backlight.Backlight(f'{pfx}:MOT_BLGT',dft_pos_bklgt)
|
||||||
startupWin.set(20, f'connect illumination')
|
startupWin.set(20, f'connect illumination')
|
||||||
if args.sim&0x02:
|
if args.sim&0x02:
|
||||||
app._illumination = illumination.IlluminationControl(None)
|
app._illumination = illumination.IlluminationControl(None)
|
||||||
|
|||||||
Reference in New Issue
Block a user