From 22fcad62c18165578362e0f9938860984d91f4de Mon Sep 17 00:00:00 2001 From: Thierry Zamofing Date: Wed, 17 Aug 2022 12:04:51 +0200 Subject: [PATCH] moving ROI with stage and zoom --- EmblModule.py | 4 +- epics_widgets/SimMotorTweak.py | 33 +++++----- geometry.py | 2 +- swissmx.py | 106 +++++++++++++++++++++++++++------ 4 files changed, 108 insertions(+), 37 deletions(-) diff --git a/EmblModule.py b/EmblModule.py index a0e26fa..7f54300 100755 --- a/EmblModule.py +++ b/EmblModule.py @@ -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() diff --git a/epics_widgets/SimMotorTweak.py b/epics_widgets/SimMotorTweak.py index 7337169..360f20b 100644 --- a/epics_widgets/SimMotorTweak.py +++ b/epics_widgets/SimMotorTweak.py @@ -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): diff --git a/geometry.py b/geometry.py index ff9c396..295dd7f 100755 --- a/geometry.py +++ b/geometry.py @@ -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 diff --git a/swissmx.py b/swissmx.py index bbcbcaf..b4944ef 100755 --- a/swissmx.py +++ b/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