moving ROI with stage and zoom
This commit is contained in:
@@ -141,8 +141,8 @@ class EmblWidget(QWidget):
|
||||
def __init__(self, parent):
|
||||
super(EmblWidget, self).__init__(parent)
|
||||
|
||||
parent.pixelsPerMillimeter.connect(self.save_ppm)
|
||||
parent.beamCameraCoordinatesChanged.connect(self.save_beam_coordinates)
|
||||
#parent.pixelsPerMillimeter.connect(self.save_ppm)
|
||||
#parent.beamCameraCoordinatesChanged.connect(self.save_beam_coordinates)
|
||||
self.setLayout(QVBoxLayout())
|
||||
|
||||
w = QWidget()
|
||||
|
||||
@@ -22,13 +22,15 @@ _log = logging.getLogger(__name__)
|
||||
#logger.setLevel(logging.INFO)
|
||||
|
||||
class SimMotor:
|
||||
def __init__(self,motor_base, short_name):
|
||||
def __init__(self,rec_name, short_name):
|
||||
self._llm = -10
|
||||
self._hlm = 10
|
||||
self._prec = 5
|
||||
self._twv = 0.1
|
||||
self._units = 'mm'
|
||||
self._pos = 3.1415
|
||||
self._short_name=short_name
|
||||
self._rec_name=rec_name
|
||||
|
||||
class SimMotorTweak(QWidget, Ui_MotorTweak):
|
||||
event_val = pyqtSignal(str, dict)
|
||||
@@ -54,12 +56,9 @@ class SimMotorTweak(QWidget, Ui_MotorTweak):
|
||||
self._templates = {}
|
||||
|
||||
|
||||
def connect_motor(self, motor_base, short_name=None, *args, **kwargs):
|
||||
self.label.setToolTip('{} => {}'.format(motor_base, motor_base))
|
||||
self.motor=SimMotor(motor_base, short_name)
|
||||
|
||||
twv=0.1
|
||||
|
||||
def connect_motor(self, rec_name, short_name=None, *args, **kwargs):
|
||||
self.label.setToolTip('{} => {}'.format(rec_name, short_name))
|
||||
self.motor=SimMotor(rec_name, short_name)
|
||||
self.set_motor_validator()
|
||||
self._drive_val.setText(str(self.motor._pos))
|
||||
self._drive_val.returnPressed.connect(self.move_motor_to_position)
|
||||
@@ -69,7 +68,7 @@ class SimMotorTweak(QWidget, Ui_MotorTweak):
|
||||
|
||||
tweak_min = kwargs.get("tweak_min", 0.0001)
|
||||
tweak_max = kwargs.get("tweak_max", 20.0)
|
||||
self._tweak_val.setText(str(twv))
|
||||
self._tweak_val.setText(str(self.motor._twv))
|
||||
self._tweak_val.setValidator(QDoubleValidator(tweak_min, tweak_max, 4, self._tweak_val))
|
||||
#self._tweak_val.editingFinished.connect(lambda m=self._pv_tweak_val: m.put(self._tweak_val.text()))
|
||||
self.tweak_forward.clicked.connect(lambda m: self.move_relative(float(self._tweak_val.text())))
|
||||
@@ -108,6 +107,7 @@ class SimMotorTweak(QWidget, Ui_MotorTweak):
|
||||
sleep(delay)
|
||||
_log.debug('{} rel move => {}'.format(self.motor._short_name, dist))
|
||||
self.update_label()
|
||||
self.emit_signals(source_field='VAL')
|
||||
|
||||
def get_position(self):
|
||||
return self.motor._pos
|
||||
@@ -148,23 +148,24 @@ class SimMotorTweak(QWidget, Ui_MotorTweak):
|
||||
_log.debug('{} abs move => {}'.format(self.motor._short_name, drive))
|
||||
self.motor._pos=drive
|
||||
self.update_label()
|
||||
self.emit_signals(source_field='VAL')
|
||||
|
||||
def emit_signals(self, **kw):
|
||||
field = kw['source_field']
|
||||
if field == 'VAL':
|
||||
self.event_val.emit(self._pvname, kw)
|
||||
self.event_val.emit(self.motor._rec_name, kw)
|
||||
elif field == 'RBV':
|
||||
self.event_readback.emit(self._pvname, kw)
|
||||
self.event_readback.emit(self.motor._rec_name, kw)
|
||||
elif field == 'LVIO':
|
||||
self.event_soft_limit.emit(self._pvname, kw)
|
||||
self.event_soft_limit.emit(self.motor._rec_name, kw)
|
||||
elif field == 'HLS':
|
||||
self.event_high_hard_limit.emit(self._pvname, kw)
|
||||
self.event_axis_fault.emit(self._pvname, kw)
|
||||
self.event_high_hard_limit.emit(self.motor._rec_name, kw)
|
||||
self.event_axis_fault.emit(self.motor._rec_name, kw)
|
||||
elif field == 'LVIO':
|
||||
self.event_low_hard_limit.emit(self._pvname, kw)
|
||||
self.event_axis_fault.emit(self._pvname, kw)
|
||||
self.event_low_hard_limit.emit(self.motor._rec_name, kw)
|
||||
self.event_axis_fault.emit(self.motor._rec_name, kw)
|
||||
elif field == 'STAT':
|
||||
self.event_axis_fault.emit(self._pvname, kw)
|
||||
self.event_axis_fault.emit(self.motor._rec_name, kw)
|
||||
|
||||
|
||||
def set_val_on_status_change(self, **kw):
|
||||
|
||||
@@ -168,7 +168,7 @@ class geometry:
|
||||
pix2pos[0, 1]=np.interp(zoom, K, AA[:, 0, 1])
|
||||
pix2pos[1, 0]=np.interp(zoom, K, AA[:, 1, 0])
|
||||
pix2pos[1, 1]=np.interp(zoom, K, AA[:, 1, 1])
|
||||
_log.debug('interpolation array:{}'.format(tuple(pix2pos.ravel())))
|
||||
_log.debug(f'{zoom} -> {pix2pos.ravel()}')
|
||||
|
||||
def update_pix2pos(self, meas):
|
||||
# calculates _lut_pix2pos out of measurements
|
||||
|
||||
106
swissmx.py
106
swissmx.py
@@ -180,19 +180,19 @@ class Sequencer(QObject):
|
||||
Ui_MainWindow, QMainWindow = loadUiType("swissmx.ui")
|
||||
|
||||
class Main(QMainWindow, Ui_MainWindow):
|
||||
pixelsPerMillimeter = pyqtSignal(float)
|
||||
beamCameraCoordinatesChanged = pyqtSignal(float, float)
|
||||
#pixelsPerMillimeter = pyqtSignal(float)
|
||||
#beamCameraCoordinatesChanged = pyqtSignal(float, float)
|
||||
addGridRequest = pyqtSignal(float, float)
|
||||
zoomChanged = pyqtSignal(float)
|
||||
#zoomChanged = pyqtSignal(float)
|
||||
folderChanged = pyqtSignal(str)
|
||||
prefixChanged = pyqtSignal(str)
|
||||
projectChanged = pyqtSignal(str)
|
||||
gridUpdated = pyqtSignal(int) # index in self._grids
|
||||
gonioMoveRequest = pyqtSignal(float, float, float, float, float)
|
||||
fast_x_position = pyqtSignal(float)
|
||||
fast_y_position = pyqtSignal(float)
|
||||
fast_dx_position = pyqtSignal(float)
|
||||
fast_dy_position = pyqtSignal(float)
|
||||
#fast_x_position = pyqtSignal(float)
|
||||
#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
|
||||
appendPrelocatedPosition = pyqtSignal(float, float, float, float)
|
||||
appendPrelocatedFiducial = pyqtSignal(bool, float, float, float, float)
|
||||
@@ -346,18 +346,21 @@ class Main(QMainWindow, Ui_MainWindow):
|
||||
#--- beam marker ---
|
||||
bm_sz=np.array((50, 40)) # it is immidiatly repositioned in zoom_changed_cb
|
||||
self._goBeamMarker=bm=UsrGO.Marker(-opt_ctr-bm_sz/2,bm_sz,mode=0)
|
||||
self.vb.addItem(bm)
|
||||
vb.addItem(bm)
|
||||
|
||||
#--- opctical center ----
|
||||
oc_sz=np.array((50,50))
|
||||
self._goOptCtr=obj=UsrGO.Marker(-opt_ctr-oc_sz/2, oc_sz,mode=1)
|
||||
bm.setTransform(tr) # assign transform
|
||||
self.vb.addItem(obj)
|
||||
vb.addItem(obj)
|
||||
|
||||
#--- testing scan grid ---
|
||||
vi=UsrGO.Grid((120, -100), (200, 150), (30, 22), 2)
|
||||
vi.setTransform(tr) # assign transform
|
||||
self.vb.addItem(vi)
|
||||
self.track_objects() # first call is needed to initialize the structure self._goTracked
|
||||
go=UsrGO.Grid((120, -100), (200, 150), (30, 22), 2)
|
||||
go.setTransform(tr) # assign transform
|
||||
vb.addItem(go)
|
||||
self._goTracked['objLst'].append(go)
|
||||
self.track_objects() #tracking now the objects
|
||||
#UsrGO.obj_tree(vb)
|
||||
|
||||
|
||||
@@ -1037,7 +1040,7 @@ class Main(QMainWindow, Ui_MainWindow):
|
||||
return
|
||||
|
||||
def zoom_changed_cb(self, value):
|
||||
self.zoomChanged.emit(value)
|
||||
#self.zoomChanged.emit(value)
|
||||
app=QApplication.instance()
|
||||
cfg=app._cfg
|
||||
geo=app._geometry
|
||||
@@ -1055,8 +1058,73 @@ class Main(QMainWindow, Ui_MainWindow):
|
||||
bm.setPos(bm_pos,finish=False)
|
||||
bm.setSize(bm_sz)
|
||||
_log.debug(f"zoom->{value} beam marker pos:{bm_pos} sz:{bm_sz})")
|
||||
self.track_objects()
|
||||
#self.update_beam_marker(value)
|
||||
|
||||
def track_objects(self):
|
||||
#self._goTracked= dictionary with infos about tracked objects
|
||||
# objLst = list of objects to track
|
||||
# state = (zoom, fx, fy) (created at first call of self.track_objects() )
|
||||
app=QApplication.instance()
|
||||
geo=app._geometry
|
||||
zoom = app._zoom.get()
|
||||
fast_x=self.tweakers["fast_x"];fast_y=self.tweakers["fast_y"]
|
||||
fx=fast_x.get_position()
|
||||
fy=fast_y.get_position()
|
||||
try:
|
||||
tracked=self._goTracked
|
||||
zoom_old,fx_old,fy_old=tracked['state']
|
||||
except AttributeError: # at initialization
|
||||
self._goTracked={'objLst':list(), 'state':(zoom,fx,fy)}
|
||||
return
|
||||
_log.debug(f"zoom:{zoom_old}->{zoom} fx:{fx_old}->{fx} fy:{fy_old}->{fy}")
|
||||
opt_ctr=geo._opt_ctr
|
||||
if zoom_old!=zoom:
|
||||
geo.interp_zoom(zoom_old)
|
||||
pix2pos_old=geo._pix2pos
|
||||
geo.interp_zoom(zoom)
|
||||
pix2pos_new=geo._pix2pos
|
||||
for o in tracked['objLst']:
|
||||
# names consists of abrevations
|
||||
# part 0: po=position sz=size dt=delta
|
||||
# part 1: px=pixel eu=engineering units (e.g. mm)
|
||||
po_px=o.pos()
|
||||
sz_px=o.size()
|
||||
tr=o.transform()
|
||||
geo._pix2pos=pix2pos_old
|
||||
dt_px=-opt_ctr-po_px
|
||||
dt_eu=geo.pix2pos(dt_px)
|
||||
sz_eu=geo.pix2pos(sz_px)
|
||||
|
||||
geo._pix2pos=pix2pos_new
|
||||
dt_px2=geo.pos2pix(dt_eu)
|
||||
sz_px2=geo.pos2pix(sz_eu)
|
||||
po_px2=-opt_ctr-dt_px2
|
||||
o.setPos(po_px2)
|
||||
o.setSize(sz_px2)
|
||||
|
||||
#np.asarray(self._pix2pos*np.mat(p).T).ravel()
|
||||
geo.interp_zoom(zoom)
|
||||
|
||||
if fx_old!=fx or fy_old!=fy:
|
||||
p1=geo.pos2pix((fx_old,fy_old))
|
||||
p2=geo.pos2pix((fx,fy))
|
||||
d=p2-p1
|
||||
|
||||
for o in tracked['objLst']:
|
||||
pos=o.pos()
|
||||
sz=o.size()
|
||||
tr=o.transform()
|
||||
o.setPos(pos+d)
|
||||
tracked['state']=(zoom, fx, fy)
|
||||
#imgPos=self._goImg.mapFromScene(event.scenePos())
|
||||
#x=imgPos.x();y=imgPos.y()
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
def append_to_beam_markers(self, x, y, zoom):
|
||||
self._beam_markers[zoom] = (x, y)
|
||||
_log.info("beam markers {}".format(self._beam_markers))
|
||||
@@ -1195,7 +1263,7 @@ class Main(QMainWindow, Ui_MainWindow):
|
||||
pos=event.scenePos()
|
||||
_log.debug(f'move to position :scene pos {pos}')
|
||||
geo=app._geometry
|
||||
geo.interp_zoom(1)
|
||||
#geo.interp_zoom(1)
|
||||
bm=self._goBeamMarker
|
||||
p1=self._goImg.mapFromScene(pos)
|
||||
p2=bm.pos()+bm.size()/2
|
||||
@@ -1657,9 +1725,11 @@ 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))
|
||||
|
||||
self.tweakers["fast_x"].event_val.connect(lambda rec_name, kw: self.track_objects())
|
||||
self.tweakers["fast_y"].event_val.connect(lambda rec_name, kw: self.track_objects())
|
||||
# layout.addStretch()
|
||||
|
||||
def axis_fault(self, pvname, kw):
|
||||
@@ -1968,7 +2038,7 @@ class Main(QMainWindow, Ui_MainWindow):
|
||||
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, rec, alias=None, label=None, mtype="epics_motor", layout=None, **kwargs):
|
||||
app = QApplication.instance()
|
||||
sim=app._args.sim
|
||||
if mtype == "epics_motor":
|
||||
@@ -1981,7 +2051,7 @@ class Main(QMainWindow, Ui_MainWindow):
|
||||
m=SimMotorTweak()
|
||||
else:
|
||||
m = SmaractMotorTweak()
|
||||
m.connect_motor(pv, label, **kwargs)
|
||||
m.connect_motor(rec, label, **kwargs)
|
||||
self.tweakers[alias] = m
|
||||
return m
|
||||
|
||||
|
||||
Reference in New Issue
Block a user