188 lines
4.9 KiB
Python
188 lines
4.9 KiB
Python
from enum import Enum
|
|
from typing import Annotated, Literal, Tuple, List, Optional
|
|
|
|
from pydantic import BaseModel, Field
|
|
|
|
from aaredaqlib.coordinate import Coordinate
|
|
from aaredaqlib.diffraction_geometry import DiffractionGeometry
|
|
from aaredaqlib.sample_geometry import SampleGeometryModel
|
|
|
|
class TokenData(BaseModel):
|
|
sub: str # Username
|
|
pgroups: List[str]
|
|
session: int
|
|
staff: bool = False
|
|
|
|
class DewarAddress(BaseModel):
|
|
segment: Literal["A", "B", "C", "D", "E", "F", "X", "R"]
|
|
pos: Annotated[int, Field(ge=1, le=5)]
|
|
|
|
|
|
class SampleDewarAddress(BaseModel):
|
|
puck: DewarAddress
|
|
pin: Annotated[int, Field(ge=1, le=16)]
|
|
|
|
|
|
# From the database for puck loading
|
|
class PuckInfo(BaseModel):
|
|
db_id: int
|
|
puck_name: str
|
|
dewar_name: str
|
|
user: str = ""
|
|
location: Optional[DewarAddress] = None
|
|
|
|
|
|
# From TELL to database after loading
|
|
class PuckLoadedInfo(BaseModel):
|
|
puck_name: str
|
|
location: DewarAddress
|
|
|
|
|
|
# From database to TELL after loading
|
|
class SampleShortInfo(BaseModel):
|
|
db_id: int
|
|
puck_name: str
|
|
dewar_name: str
|
|
sample_name: str
|
|
user: str = ""
|
|
pin: Annotated[int, Field(ge=1, le=16)]
|
|
location: DewarAddress | None = None
|
|
priority: Optional[float] = 1.0
|
|
comment: Optional[str] = None
|
|
mount_count: int = 0
|
|
def tell_address(self) -> SampleDewarAddress:
|
|
return SampleDewarAddress(puck=self.location, pin=self.pin)
|
|
|
|
def loc_str(self) -> str:
|
|
if self.location is None:
|
|
return "-"
|
|
else:
|
|
return f"{self.location.segment}{self.location.pos}-{self.pin}"
|
|
|
|
def loc_str_sort(self) -> str:
|
|
if self.location is None:
|
|
return ""
|
|
else:
|
|
return f"{self.location.segment}{self.location.pos}-{self.pin:02d}"
|
|
|
|
|
|
class SampleShortInfoList(BaseModel):
|
|
s: List[SampleShortInfo]
|
|
|
|
|
|
class BeamMarkCoeffModel(BaseModel):
|
|
"""
|
|
Model to calculate beam center for a given zoom level based on a quadratic approximation
|
|
For both x and y it contains tuple of coefficients a, b, c (a*zoom^2 + b*zoom + c)
|
|
Default is beam center in 1000,1000 at any zoom level
|
|
"""
|
|
|
|
coeff_x: Tuple[float, float, float] = (0, 0, 1000.0)
|
|
coeff_y: Tuple[float, float, float] = (0, 0, 1000.0)
|
|
|
|
def apply(self, zoom: float):
|
|
return Coordinate(
|
|
x=self.coeff_x[0] * zoom**2 + self.coeff_x[1] * zoom + self.coeff_x[2],
|
|
y=self.coeff_y[0] * zoom**2 + self.coeff_y[1] * zoom + self.coeff_y[2],
|
|
)
|
|
|
|
|
|
class LoopCenteringZoomModelElem(BaseModel):
|
|
zoom_value: float
|
|
sam_cam_gain: float
|
|
sam_cam_exp: float
|
|
|
|
|
|
class LoopCenteringZoomModel(BaseModel):
|
|
z: List[LoopCenteringZoomModelElem]
|
|
|
|
|
|
# zoom gain exp (X06DA)
|
|
# 1 50 0.05
|
|
# 200 50 0.05
|
|
# 500 70 0.05
|
|
# 700 150 0.05
|
|
# 800 100 0.10
|
|
# 1000 200 0.10
|
|
|
|
|
|
def def_loop_centering_zoom() -> LoopCenteringZoomModel:
|
|
return LoopCenteringZoomModel(
|
|
z=[
|
|
LoopCenteringZoomModelElem(
|
|
zoom_value=200, sam_cam_gain=50.0, sam_cam_exp=0.05
|
|
)
|
|
]
|
|
)
|
|
|
|
|
|
class BeamlineStateEnum(Enum):
|
|
Maintenance = 1
|
|
SampleExchange = 2
|
|
SampleAlignment = 3
|
|
DataCollection = 4
|
|
DewarTransfer = 5
|
|
XrayFluorescence = 6
|
|
BeamLocation = 7
|
|
Moving = 8
|
|
RobotSampleExchange = 9
|
|
# Busy state is used whenever transition between two states happen or mounting/data collection procedure happens
|
|
|
|
|
|
class SessionsStateEnum(Enum):
|
|
OwnedByYou = 1
|
|
OwnedByElse = 2
|
|
Vacant = 3
|
|
|
|
class SampleCameraSettings(BaseModel):
|
|
gain: float
|
|
exposure: float
|
|
|
|
class AutofocusSettings(BaseModel):
|
|
center_x_pxl: float
|
|
center_y_pxl: float
|
|
radius_pxl: float
|
|
z_range_um: float
|
|
z_steps: int
|
|
|
|
class BeamlineStatus(BaseModel):
|
|
ring_current_mA: float
|
|
light: Annotated[float, Field(ge=0.0, le=100.0)]
|
|
cryojet_K: float
|
|
shutter_open: bool
|
|
flux_ph_s: float
|
|
sample_camera: SampleCameraSettings
|
|
|
|
class SessionStatus(BaseModel):
|
|
session: SessionsStateEnum = SessionsStateEnum.Vacant
|
|
current_pgroup: str | None = None
|
|
staff: bool = False
|
|
|
|
class DAQStatusModel(BaseModel):
|
|
geom: SampleGeometryModel
|
|
diffraction: DiffractionGeometry
|
|
bl: BeamlineStatus
|
|
state: BeamlineStateEnum
|
|
busy: bool
|
|
sample: SampleShortInfo | None = None
|
|
session: SessionStatus
|
|
|
|
class BeamlineSettingsModel(BaseModel):
|
|
# Float properties
|
|
cryojet_park_position: float | None = 12.0
|
|
cryojet_measurement_position: float | None = 5.0
|
|
|
|
dtz_max: float | None = 1600.0
|
|
dtz_min: float | None = 120.0
|
|
dtz_collection: float | None = 130.0
|
|
dtz_park: float | None = 150.0
|
|
dtz_wash_sample_distance: float | None = 150.0
|
|
dtz_bsz_safety_margin: float | None = 50.0
|
|
bsz: float | None = 25.0
|
|
|
|
camera_max_magnification: float | None = 1.0
|
|
camera_min_magnification: float | None = 500.0
|
|
camera_translation_factor_a: float | None = 0.00253
|
|
camera_translation_factor_b: float | None = 255.0
|
|
|
|
cryojet_in_use: bool | None = True |