feat: connect beam steering routine to GUI
CI / lint (pull_request) Successful in 52s
CI / test (3.12) (pull_request) Successful in 1m1s
CI / test (3.11) (pull_request) Successful in 1m3s
CI / test (3.13) (pull_request) Successful in 1m5s
CI / test-with-beamline-plugins (pxii_bec) (pull_request) Successful in 1m11s
CI / test-with-beamline-plugins (pxi_bec) (pull_request) Successful in 1m15s
CI / test-with-beamline-plugins (pxiii_bec) (pull_request) Successful in 1m18s
CI / test-with-coverage (pull_request) Successful in 1m49s
CI / lint (push) Successful in 33s
Docs build and publish / docker (push) Successful in 19s
CI / coverage-analysis (pull_request) Failing after 6s
CI / test (3.11) (push) Canceled after 51s
CI / test-with-beamline-plugins (pxiii_bec) (push) Canceled after 37s
CI / test (3.12) (push) Canceled after 47s
CI / test-with-beamline-plugins (pxii_bec) (push) Canceled after 41s
CI / test (3.13) (push) Canceled after 46s
CI / test-with-beamline-plugins (pxi_bec) (push) Canceled after 42s
CI / test-with-coverage (push) Canceled after 36s
CI / coverage-analysis (push) Canceled after 0s
Build and Publish / release (push) Successful in 26s
CI / lint (pull_request) Successful in 52s
CI / test (3.12) (pull_request) Successful in 1m1s
CI / test (3.11) (pull_request) Successful in 1m3s
CI / test (3.13) (pull_request) Successful in 1m5s
CI / test-with-beamline-plugins (pxii_bec) (pull_request) Successful in 1m11s
CI / test-with-beamline-plugins (pxi_bec) (pull_request) Successful in 1m15s
CI / test-with-beamline-plugins (pxiii_bec) (pull_request) Successful in 1m18s
CI / test-with-coverage (pull_request) Successful in 1m49s
CI / lint (push) Successful in 33s
Docs build and publish / docker (push) Successful in 19s
CI / coverage-analysis (pull_request) Failing after 6s
CI / test (3.11) (push) Canceled after 51s
CI / test-with-beamline-plugins (pxiii_bec) (push) Canceled after 37s
CI / test (3.12) (push) Canceled after 47s
CI / test-with-beamline-plugins (pxii_bec) (push) Canceled after 41s
CI / test (3.13) (push) Canceled after 46s
CI / test-with-beamline-plugins (pxi_bec) (push) Canceled after 42s
CI / test-with-coverage (push) Canceled after 36s
CI / coverage-analysis (push) Canceled after 0s
Build and Publish / release (push) Successful in 26s
This commit was merged in pull request #147.
This commit is contained in:
@@ -3486,6 +3486,23 @@ class AareDAQ:
|
||||
finally:
|
||||
self._cfg.state_busy = False
|
||||
|
||||
def steer_beam_available(self) -> bool:
|
||||
return "beam_steering" in self._devs.bec_worker.dev
|
||||
|
||||
def steer_beam(self, x: int | None, y: int | None):
|
||||
"""Run the routine to move the beam to the sample location. Update the location if provided."""
|
||||
if "beam_steering" not in self._devs.bec_worker.dev:
|
||||
raise BECCommunicationError("Beam steering device does not exist in the BEC config.")
|
||||
self._cfg.try_set_busy(timeout=360)
|
||||
try:
|
||||
if x is not None:
|
||||
self._devs.bec_worker.dev.beam_steering.sample_loc_x_px.set(x).wait()
|
||||
if y is not None:
|
||||
self._devs.bec_worker.dev.beam_steering.sample_loc_y_px.set(y).wait()
|
||||
self._devs.bec_worker.dev.beam_steering.trigger().wait()
|
||||
finally:
|
||||
self._cfg.state_busy = False
|
||||
|
||||
def fluorimeter_take_spectrum(
|
||||
self, fm: FluorescenceSpectrumParameterModel
|
||||
) -> FluorescenceSpectrumOutputModel:
|
||||
|
||||
@@ -482,6 +482,42 @@ async def mono_pitch_scan(plot: bool = False, token: str = Depends(oauth2_scheme
|
||||
return "OK"
|
||||
|
||||
|
||||
@app.get("/beamline/steer_beam_available")
|
||||
async def steer_beam_available(token: str = Depends(oauth2_scheme)):
|
||||
"""
|
||||
Check if the beam centring routine is available.
|
||||
|
||||
Args:
|
||||
token: OAuth2 access token.
|
||||
|
||||
Returns:
|
||||
"OK" on success.
|
||||
"""
|
||||
auth.parse_token(token)
|
||||
return daq.steer_beam_available()
|
||||
|
||||
|
||||
@app.post("/beamline/steer_beam")
|
||||
async def steer_beam(
|
||||
x: int | None = None, y: int | None = None, token: str = Depends(oauth2_scheme)
|
||||
):
|
||||
"""
|
||||
Adjust the mirrors to move the beam to the box. Staff only.
|
||||
|
||||
Args:
|
||||
x (int, optional): x-coordinate in sample camera pixels to steer to
|
||||
y (int, optional): y-coordinate in sample camera pixels to steer to
|
||||
token: OAuth2 access token.
|
||||
|
||||
Returns:
|
||||
"OK" on success.
|
||||
"""
|
||||
logger.debug("Running beam steering routine")
|
||||
auth.check_jwt_staff(cfg, auth.parse_token(token))
|
||||
daq.steer_beam(x, y)
|
||||
return "OK"
|
||||
|
||||
|
||||
@app.put("/beamline/change_energy")
|
||||
async def change_energy(value: float, plot: bool = False, token: str = Depends(oauth2_scheme)):
|
||||
"""
|
||||
|
||||
@@ -938,6 +938,11 @@ class MainWindow(QMainWindow):
|
||||
self.daq.polled_devices_status.connect(self._portrait_alert_primary)
|
||||
self.daq.detector_error.connect(self._portrait_alert_secondary)
|
||||
|
||||
if hasattr(self, "monochromator_panel"):
|
||||
self.daq.steer_beam_available.connect(
|
||||
self.monochromator_panel.update_beam_steering_available
|
||||
)
|
||||
|
||||
self.daq.baton_status_changed.connect(self.status_bar.update_baton_status)
|
||||
self.daq.baton_status_changed.connect(self._on_baton_status_changed)
|
||||
self.daq.baton_request_result.connect(self._on_baton_request_result)
|
||||
@@ -988,6 +993,7 @@ class MainWindow(QMainWindow):
|
||||
|
||||
if self._decoded_token.staff:
|
||||
self.monochromator_panel.mono_pitch_scan.connect(self.daq.mono_pitch_scan)
|
||||
self.monochromator_panel.move_beam_to_box.connect(self.daq.steer_beam)
|
||||
self.monochromator_panel.change_energy.connect(self.daq.change_energy)
|
||||
self.monochromator_panel.open_shutter.connect(self.daq.open_shutter)
|
||||
self.monochromator_panel.close_shutter.connect(self.daq.close_shutter)
|
||||
@@ -1240,6 +1246,11 @@ class MainWindow(QMainWindow):
|
||||
dock.installEventFilter(self)
|
||||
dock.topLevelChanged.connect(self._on_dock_top_level_changed)
|
||||
|
||||
self.prompt_init_state()
|
||||
|
||||
def prompt_init_state(self):
|
||||
self.daq.update_steer_beam_available()
|
||||
|
||||
def _setup_global_shortcuts(self) -> None:
|
||||
self._shortcut_manual_sample = QAction("Expand Manual Sample", self)
|
||||
self._shortcut_manual_sample.setShortcut(QKeySequence("Ctrl+M"))
|
||||
|
||||
@@ -9,8 +9,8 @@ from aare.gui.widgets.title_label import TitleLabel
|
||||
class MonochromatorPanel(QWidget):
|
||||
mono_pitch_scan = Signal()
|
||||
change_energy = Signal(float)
|
||||
move_beam_to_box = Signal()
|
||||
open_shutter = Signal()
|
||||
move_beam_to_box = Signal()
|
||||
close_shutter = Signal()
|
||||
|
||||
def __init__(self, parent=None):
|
||||
@@ -68,16 +68,21 @@ class MonochromatorPanel(QWidget):
|
||||
self.close_shutter_button.clicked.connect(self.close_shutter.emit)
|
||||
grid_layout.addWidget(self.close_shutter_button, 4, 2)
|
||||
|
||||
# TODO(wire backend): no DAQ endpoint exists yet for moving the beam
|
||||
# to the box center — shown disabled as WIP until the operation is
|
||||
# defined server-side; then drop "(WIP)", enable, and connect the
|
||||
# signal in main_window.
|
||||
self.move_beam_to_box_button = QPushButton("Move Beam to Box (center) (WIP)", parent=self)
|
||||
self.move_beam_to_box_button.setToolTip("Coming soon — not functional yet.")
|
||||
self.move_beam_to_box_button.setEnabled(False)
|
||||
self.move_beam_to_box_button = QPushButton("Move Beam to Box", parent=self)
|
||||
self.move_beam_to_box_button.clicked.connect(self.move_beam_to_box.emit)
|
||||
self._move_beam_tooltip = "Adjust VFM and HFM motors to stear the beam."
|
||||
self.set_beam_to_box_button_state(False, self._move_beam_tooltip)
|
||||
grid_layout.addWidget(self.move_beam_to_box_button, 5, 0, 1, 3)
|
||||
|
||||
@Slot(bool)
|
||||
def update_beam_steering_available(self, enabled: bool):
|
||||
msg = self._move_beam_tooltip if enabled else "Beam steering unavailable."
|
||||
self.set_beam_to_box_button_state(enabled, msg)
|
||||
|
||||
def set_beam_to_box_button_state(self, enabled: bool, tooltip: str):
|
||||
self.move_beam_to_box_button.setEnabled(enabled)
|
||||
self.move_beam_to_box_button.setToolTip(tooltip)
|
||||
|
||||
def set_theme(self, theme: str) -> None:
|
||||
"""Adopt the theme's flag colors and re-render the shutter status."""
|
||||
self._colors = status_colors(theme)
|
||||
|
||||
@@ -131,6 +131,8 @@ class DAQWorker(QObject):
|
||||
baton_incoming_request = Signal(dict)
|
||||
baton_timeout_checked = Signal(dict)
|
||||
|
||||
steer_beam_available = Signal(bool)
|
||||
|
||||
def __init__(self, base_url: str | None, token: str, parent=None):
|
||||
"""
|
||||
Initialize the DAQWorker.
|
||||
@@ -799,6 +801,22 @@ class DAQWorker(QObject):
|
||||
def mono_pitch_scan(self):
|
||||
self.generic_post("beamline/mono_pitch_scan")
|
||||
|
||||
@Slot()
|
||||
def steer_beam(self):
|
||||
self.generic_post("beamline/steer_beam")
|
||||
|
||||
def update_steer_beam_available(self):
|
||||
"""Check if beam steering is supported by the server. The result is emitted from DaqWorker.steer_beam_available when ready"""
|
||||
if self._base_url is None:
|
||||
return False
|
||||
request = QNetworkRequest(QUrl(f"{self._base_url}/beamline/steer_beam_available"))
|
||||
request.setRawHeader(b"Authorization", f"Bearer {self._token}".encode())
|
||||
reply = self._net_manager.get(request)
|
||||
reply.finished.connect(lambda: self._update_steer_beam_available(reply))
|
||||
|
||||
def _update_steer_beam_available(self, reply: QNetworkReply):
|
||||
self.steer_beam_available.emit(json.loads(bytes(reply.readAll().data())))
|
||||
|
||||
@Slot(float)
|
||||
def change_energy(self, value: float):
|
||||
self.generic_put(f"beamline/change_energy?value={value:.3f}")
|
||||
|
||||
Reference in New Issue
Block a user