Server: Combine helical and rotation data collection in one data structure
This commit is contained in:
@@ -1,6 +0,0 @@
|
||||
from aaredaqlib.coordinate import SmargonCoordinate
|
||||
from aaredaqlib.rotation_scan import RotationScanRequest
|
||||
|
||||
|
||||
class HelicalScanRequest(RotationScanRequest):
|
||||
end: SmargonCoordinate
|
||||
@@ -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)]
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
+15
-31
@@ -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()
|
||||
|
||||
|
||||
+19
-13
@@ -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,
|
||||
|
||||
@@ -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"],
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user