diff --git a/common/src/aaredaqlib/helical_geometry.py b/common/src/aaredaqlib/helical_geometry.py deleted file mode 100644 index 610e30c6..00000000 --- a/common/src/aaredaqlib/helical_geometry.py +++ /dev/null @@ -1,6 +0,0 @@ -from aaredaqlib.coordinate import SmargonCoordinate -from aaredaqlib.rotation_scan import RotationScanRequest - - -class HelicalScanRequest(RotationScanRequest): - end: SmargonCoordinate diff --git a/common/src/aaredaqlib/raster_grid.py b/common/src/aaredaqlib/raster_grid.py index 58c0d2ca..9b9e5670 100644 --- a/common/src/aaredaqlib/raster_grid.py +++ b/common/src/aaredaqlib/raster_grid.py @@ -1,7 +1,7 @@ import math from typing import Annotated -from pydantic import Field, AfterValidator +from pydantic import Field, AfterValidator, BaseModel from aaredaqlib.coordinate import Coordinate, positive_coords, SmargonCoordinate from aaredaqlib.sample_geometry import SampleGeometryModel @@ -13,7 +13,7 @@ def normalize_angle(angle_deg: float) -> float: return normalized_angle -class RasterGridRequest(ScanRequest): +class RasterGridRequest(BaseModel): # Number of grid elements n_x: Annotated[int, Field(ge=1)] n_y: Annotated[int, Field(ge=1)] diff --git a/common/src/aaredaqlib/rotation_scan.py b/common/src/aaredaqlib/rotation_scan.py index 2853a6c6..56905511 100644 --- a/common/src/aaredaqlib/rotation_scan.py +++ b/common/src/aaredaqlib/rotation_scan.py @@ -1,9 +1,11 @@ +from pydantic import BaseModel + from aaredaqlib.coordinate import SmargonCoordinate -from aaredaqlib.scan_request import ScanRequest -class RotationScanRequest(ScanRequest): +class RotationScanRequest(BaseModel): start: SmargonCoordinate | None = None # None = start where you are + end: SmargonCoordinate | None = None start_omega_deg: float = 0 omega_incr_deg: float diff --git a/common/src/aaredaqlib/scan_request.py b/common/src/aaredaqlib/scan_request.py index d799670a..3bcaf3d3 100644 --- a/common/src/aaredaqlib/scan_request.py +++ b/common/src/aaredaqlib/scan_request.py @@ -2,14 +2,18 @@ from abc import abstractmethod, ABC from pydantic import BaseModel -class ScanRequest(ABC, BaseModel): +from aaredaqlib.raster_grid import RasterGridRequest +from aaredaqlib.rotation_scan import RotationScanRequest +from aaredaqlib.screening_scan import ScreeningScanRequest + + +class ScanRequest(BaseModel): dtz: float transmission: float file_prefix: str exp_time_s: float + image_number: int - @abstractmethod - def get_image_number(self) -> int: - pass + measurement: RasterGridRequest | ScreeningScanRequest | RotationScanRequest diff --git a/common/src/aaredaqlib/screening_scan.py b/common/src/aaredaqlib/screening_scan.py index 24c1f743..5e0fc8a2 100644 --- a/common/src/aaredaqlib/screening_scan.py +++ b/common/src/aaredaqlib/screening_scan.py @@ -1,7 +1,7 @@ -from aaredaqlib.scan_request import ScanRequest +from pydantic import BaseModel -class ScreeningScanRequest(ScanRequest): +class ScreeningScanRequest(BaseModel): omega_start_deg: float omega_step_deg: float steps: int diff --git a/daq/src/aaredaq/daq.py b/daq/src/aaredaq/daq.py index c1e43152..b766a1cf 100644 --- a/daq/src/aaredaq/daq.py +++ b/daq/src/aaredaq/daq.py @@ -6,7 +6,6 @@ import cv2 import numpy as np import redis from aaredaqlib.coordinate import Coordinate, SmargonCoordinate -from aaredaqlib.helical_geometry import HelicalScanRequest from aaredaqlib.models import ( SampleShortInfo, PuckLoadedInfo, @@ -232,41 +231,26 @@ class AareDAQ: self.__cfg.state_busy = False raise e - def measure_helical(self, h: HelicalScanRequest) -> float: - start = time.perf_counter() - - self.__cfg.try_set_busy(timeout=ceil(h.time_sec + 360)) - self.__set_state(BeamlineStateEnum.DataCollection) - - try: - self.__devs.smargon.target = h.start - self.__devs.aerotech.measure_standard( - h.omega_start, h.total_omega, h.time_sec - ) - - smargon_time_step = h.time_sec / float(h.steps) - pos_step = (h.end.sh_mm - h.start.sh_mm) * (1.0 / float(h.steps)) - - for i in range(h.steps): - self.__devs.smargon.target = SmargonCoordinate( - sh_mm=h.start.sh_mm + pos_step * i - ) - time.sleep(smargon_time_step) - - self.__devs.aerotech.wait_scan_done(h.time_sec + 60) - self.__devs.aerotech.reset() - self.__cfg.state_busy = False - except Exception as e: - self.__cfg.state_busy = False - raise e - end = time.perf_counter() - return end - start - def __rotation(self, request: RotationScanRequest): self.__set_state(BeamlineStateEnum.DataCollection) + if request.start is not None: + self.__devs.smargon.target = request.start + self.__devs.smargon.wait() + self.__devs.aerotech.measure_standard( request.start_omega_deg, request.total_omega_deg, request.total_time_sec ) + + if request.start is not None and request.end is not None: + smargon_time_step = request.time_sec / float(request.steps) + pos_step = (request.end.sh_mm - request.start.sh_mm) * (1.0 / float(request.steps)) + + for i in range(request.steps): + self.__devs.smargon.target = SmargonCoordinate( + sh_mm=request.start.sh_mm + pos_step * i + ) + time.sleep(smargon_time_step) + self.__devs.aerotech.wait_scan_done(request.total_time_sec + 60) self.__devs.aerotech.reset() diff --git a/daq/src/aaredaq/server.py b/daq/src/aaredaq/server.py index 3521b697..5c1bba3e 100644 --- a/daq/src/aaredaq/server.py +++ b/daq/src/aaredaq/server.py @@ -5,7 +5,6 @@ import cv2 import urllib3 import uvicorn from aaredaqlib.coordinate import SmargonCoordinate, Coordinate -from aaredaqlib.helical_geometry import HelicalScanRequest from aaredaqlib.models import SampleShortInfo, DAQStatusModel, BeamlineStateEnum, BeamlineSettingsModel, \ SampleShortInfoList, SessionStatus from aaredaqlib.raster_grid import RasterGridRequest @@ -44,7 +43,7 @@ async def status(token: str = Depends(oauth2_scheme)) -> DAQStatusModel: data = auth.parse_token(token) auth.check_jwt_ro(cfg, data) ret = daq.status - ret.session = SessionStatus(current_pgroup = cfg.pgroup, + ret.session = SessionStatus(current_pgroup=cfg.pgroup, session=cfg.session_state(data.session), staff=data.staff) return ret @@ -85,36 +84,42 @@ async def smargon(val: SmargonCoordinate, token: str = Depends(oauth2_scheme)): daq.smargon = val return "OK" + @app.post("/beamline/tweak_abr_meas_pos") async def tweak_abr_meas_pos(val: Coordinate, token: str = Depends(oauth2_scheme)): auth.check_jwt_staff(auth.parse_token(token)) daq.tweak_abr_meas_pos(val) return "OK" + @app.post("/beamline/save_abr_meas_pos") async def save_abr_meas_pos(token: str = Depends(oauth2_scheme)): auth.check_jwt_staff(auth.parse_token(token)) daq.save_abr_meas_pos() return "OK" + @app.post("/beam_center/mark") async def mark_beam_center(x: float, y: float, token: str = Depends(oauth2_scheme)): auth.check_jwt_staff(auth.parse_token(token)) daq.mark_beam(x, y) return "OK" + @app.post("/beam_center/clear") async def clear_beam_center(token: str = Depends(oauth2_scheme)): auth.check_jwt_staff(auth.parse_token(token)) daq.clear_mark_beam() return "OK" + @app.post("/shutter/close") async def close_shutter(token: str = Depends(oauth2_scheme)): auth.check_jwt_rw(cfg, auth.parse_token(token)) daq.close_shutter() return "OK" + async def get_image(token: str = Depends(oauth2_scheme)): auth.check_jwt_ro(cfg, auth.parse_token(token)) @@ -141,16 +146,17 @@ async def sample(token: str = Depends(oauth2_scheme)) -> SampleShortInfo: sample_name="Other user sample", puck_name="", dewar_name="", - db_id = -1, - pin = sample.pin, + db_id=-1, + pin=sample.pin, location=sample.location ) + @app.post("/tell/mount") async def mount(dbid: int, token: str = Depends(oauth2_scheme)): token_data = auth.parse_token(token) auth.check_jwt_rw(cfg, auth.parse_token(token)) - #st = daq.sample_spreadsheet + # st = daq.sample_spreadsheet st = SampleShortInfoList(s=[]) index = -1 @@ -230,19 +236,13 @@ async def screening(val: ScreeningScanRequest, token: str = Depends(oauth2_schem return "OK" -@app.post("/scan/helical") -async def helical(val: HelicalScanRequest, token: str = Depends(oauth2_scheme)): - auth.check_jwt_rw(cfg, auth.parse_token(token)) - daq.measure_helical(val) - return "OK" - - @app.post("/scan/auto") async def auto(s: SampleShortInfo, token: str = Depends(oauth2_scheme)): auth.check_jwt_rw(cfg, auth.parse_token(token)) runtime = daq.measure(s) return f"{runtime:0.3f}" + # ALC routines @app.post("/alc/background") async def alc_background(token: str = Depends(oauth2_scheme)) -> str: @@ -257,11 +257,14 @@ async def alc_center_loop(token: str = Depends(oauth2_scheme)) -> str: daq.auto_loop_center() return "OK" + @app.post("/alc/ml_bounding_box") -async def alc_ml_bounding_box(token: str = Depends(oauth2_scheme), move: bool = False, filename: str = "") -> Tuple[float, float, float, float] | None: +async def alc_ml_bounding_box(token: str = Depends(oauth2_scheme), move: bool = False, filename: str = "") -> Tuple[ + float, float, float, float] | None: auth.check_jwt_rw(cfg, auth.parse_token(token)) return daq.ml_bounding_box(move=move) + # Access management @app.get("/access/pgroup") async def pgroup(token: str = Depends(oauth2_scheme)) -> str: @@ -301,16 +304,19 @@ async def force_current_session(token: str = Depends(oauth2_scheme)) -> str: auth.force_current_sesion(cfg, data) return "OK" + @app.get("/beamline/settings") async def get_settings(token: str = Depends(oauth2_scheme)) -> BeamlineSettingsModel: auth.check_jwt_staff(auth.parse_token(token)) return cfg.settings + @app.put("/beamline/settings") async def put_settings(s: BeamlineSettingsModel, token: str = Depends(oauth2_scheme)): auth.check_jwt_staff(auth.parse_token(token)) cfg.settings = s + LOGGING_CONFIG = { "version": 1, "disable_existing_loggers": False, diff --git a/gui/src/aaregui/panels/data_collection_settings.py b/gui/src/aaregui/panels/data_collection_settings.py index 171c318b..24c28a1a 100644 --- a/gui/src/aaregui/panels/data_collection_settings.py +++ b/gui/src/aaregui/panels/data_collection_settings.py @@ -7,7 +7,6 @@ from PySide6.QtWidgets import ( QPushButton, QWidget, ) -from aaredaqlib.helical_geometry import HelicalScanRequest from aaredaqlib.rotation_scan import RotationScanRequest from aaredaqlib.sample_geometry import SampleGeometryModel from aaredaqlib.screening_scan import ScreeningScanRequest @@ -84,9 +83,6 @@ class DataCollectionSettings(QFrame): return s = ScreeningScanRequest( - - - omega_start_deg=self.screening.start_angle.value, exp_time_s=self.screening.image_time_enter.value, omega_step_deg=data["omega_step_deg"], diff --git a/gui/src/aaregui/panels/file_path_panel.py b/gui/src/aaregui/panels/file_path_panel.py index 2c4d26c7..66881866 100644 --- a/gui/src/aaregui/panels/file_path_panel.py +++ b/gui/src/aaregui/panels/file_path_panel.py @@ -10,12 +10,12 @@ class FilePathPanel(QWidget): grid_layout.addWidget(TitleLabel("Dataset path", self), 0, 0, 1, 2) - grid_layout.addWidget(QLabel("File prefix", parent=self), 1, 0) - self.file_prefix_edit = QLineEdit(parent=self) - self.file_prefix_edit.setStyleSheet("background-color: rgb(255, 255, 255);") - grid_layout.addWidget(self.file_prefix_edit, 1, 1) - - grid_layout.addWidget(QLabel("Directory", parent=self), 2, 0) + grid_layout.addWidget(QLabel("Directory", parent=self), 1, 0) self.directory_edit = QLineEdit(parent=self) self.directory_edit.setStyleSheet("background-color: rgb(255, 255, 255);") - grid_layout.addWidget(self.directory_edit, 2, 1) + grid_layout.addWidget(self.directory_edit, 1, 1) + + grid_layout.addWidget(QLabel("File prefix", parent=self), 2, 0) + self.file_prefix_edit = QLineEdit(parent=self) + self.file_prefix_edit.setStyleSheet("background-color: rgb(255, 255, 255);") + grid_layout.addWidget(self.file_prefix_edit, 2, 1)