@@ -1,14 +1,12 @@
|
||||
import io
|
||||
from typing import List, Optional
|
||||
|
||||
import numpy as np
|
||||
import aareDBclient
|
||||
import cv2
|
||||
import numpy as np
|
||||
import requests
|
||||
from aareDBclient import SetTellPosition, SampleEventCreate, SetTellPositionRequest
|
||||
|
||||
from aaredaq.beamline import MXBeamline
|
||||
from aaredaq.models import (
|
||||
from aaredaqlib.models import (
|
||||
SampleShortInfo,
|
||||
PuckLoadedInfo,
|
||||
PuckInfo,
|
||||
@@ -16,6 +14,8 @@ from aaredaq.models import (
|
||||
SampleShortInfoList,
|
||||
)
|
||||
|
||||
from aaredaq.beamline import MXBeamline
|
||||
|
||||
|
||||
class AareWrapper:
|
||||
def __init__(
|
||||
|
||||
@@ -6,17 +6,18 @@ import numpy as np
|
||||
import redis
|
||||
import redis_lock
|
||||
from aaredaqlib.coordinate import Coordinate
|
||||
|
||||
from aaredaq.beamline import MXBeamline
|
||||
from aaredaq.models import (
|
||||
from aaredaqlib.models import (
|
||||
BeamlineSettingsModel,
|
||||
BeamCenterCoeffModel,
|
||||
LoopCenteringZoomModel,
|
||||
def_loop_centering_zoom,
|
||||
SampleShortInfo,
|
||||
SessionStatus,
|
||||
BeamlineStateEnum, SessionsStateEnum,
|
||||
)
|
||||
|
||||
from aaredaq.beamline import MXBeamline
|
||||
|
||||
ABR_POS_ALIGN_DEF = Coordinate(x=-18, y=-0.266, z=0)
|
||||
ABR_POS_MOUNT = Coordinate(x=-18, y=0, z=0)
|
||||
ABR_OMEGA_MOUNT = 0.0
|
||||
@@ -82,6 +83,10 @@ class BeamlineConfig:
|
||||
return None
|
||||
return int(tmp)
|
||||
|
||||
def session_status(self, session: int) -> SessionStatus:
|
||||
return SessionStatus(session=self.session_state(session),
|
||||
current_pgroup=self.pgroup)
|
||||
|
||||
def session_state(self, session: int) -> SessionsStateEnum:
|
||||
curr_session = self.active_session
|
||||
if curr_session is None:
|
||||
|
||||
+18
-11
@@ -7,6 +7,11 @@ import numpy as np
|
||||
import redis
|
||||
from aaredaqlib.coordinate import Coordinate, SmargonCoordinate
|
||||
from aaredaqlib.helical_geometry import HelicalScanRequest
|
||||
from aaredaqlib.models import (
|
||||
SampleShortInfo,
|
||||
PuckLoadedInfo,
|
||||
SampleShortInfoList,
|
||||
DAQStatusModel, BeamlineStatus, )
|
||||
from aaredaqlib.raster_grid import RasterGridRequest
|
||||
from aaredaqlib.rotation_scan import RotationScanRequest
|
||||
from aaredaqlib.sample_geometry import SampleGeometryModel
|
||||
@@ -18,11 +23,6 @@ from aaredaq.config import BeamlineConfig, ABR_POS_MOUNT
|
||||
from aaredaq.config import BeamlineStateEnum
|
||||
from aaredaq.devices import BeamlineDevices
|
||||
from aaredaq.mlbox import MlBox
|
||||
from aaredaq.models import (
|
||||
SampleShortInfo,
|
||||
PuckLoadedInfo,
|
||||
SampleShortInfoList,
|
||||
DAQStatusModel, )
|
||||
|
||||
|
||||
class TransformationInvalidException(Exception):
|
||||
@@ -331,7 +331,6 @@ class AareDAQ:
|
||||
self.__cfg.state_busy = False
|
||||
raise e
|
||||
|
||||
|
||||
@property
|
||||
def dtz(self) -> float:
|
||||
tmp = self.__cfg.dtz
|
||||
@@ -348,7 +347,7 @@ class AareDAQ:
|
||||
self.__cfg.state_busy = False
|
||||
raise RuntimeError("Cannot set dtz during data collection")
|
||||
elif state == BeamlineStateEnum.SampleAlignment:
|
||||
self.__devs.dtz.move(val)
|
||||
self.__devs.dtz = val
|
||||
self.__cfg.dtz = val
|
||||
self.__cfg.state_busy = False
|
||||
|
||||
@@ -705,16 +704,24 @@ class AareDAQ:
|
||||
self.__cfg.state_busy = False
|
||||
raise e
|
||||
|
||||
@property
|
||||
def beamline_status(self) -> BeamlineStatus:
|
||||
return BeamlineStatus(
|
||||
energy_keV=self.__devs,
|
||||
detector_distnace_mm=self.__devs.dtz.value,
|
||||
ring_current_mA=self.__devs.ring_current,
|
||||
light=self.light,
|
||||
cryojet_K=self.__devs.cryojet_temp
|
||||
)
|
||||
|
||||
@property
|
||||
def status(self) -> DAQStatusModel:
|
||||
# session_status should be set by FastAPI server
|
||||
# session should be set by FastAPI server
|
||||
return DAQStatusModel(
|
||||
geom=self.sample_geometry,
|
||||
state=self.state,
|
||||
busy=self.busy,
|
||||
light=self.light,
|
||||
current_pgroup=self.__cfg.pgroup,
|
||||
geom=self.sample_geometry,
|
||||
bl=self.beamline_status,
|
||||
sample=self.sample
|
||||
)
|
||||
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
from xml.sax.handler import property_dom_node
|
||||
|
||||
from aaredaqlib.coordinate import Coordinate
|
||||
from aaredaqlib.models import BeamlineStatus
|
||||
from epics import PV
|
||||
|
||||
from aaredaq.aaredb import AareWrapper
|
||||
@@ -30,6 +33,10 @@ class BeamlineDevices:
|
||||
self.tell = TellClient(beamline)
|
||||
self.smargon = smargon.Smargon(beamline)
|
||||
|
||||
self.__energy_pv = PV(f"{BEAMLINE}-OP_DCCM:ENERGY1")
|
||||
self.__ring_current_pv = PV(f"ARS07-DPCT-0100:CURR")
|
||||
self.__cryojet_temp = PV(f"{BEAMLINE}-ES-CRSM:TEMP_RBV")
|
||||
|
||||
self.magnet_position_sensor = PV(f"{BEAMLINE}-ES-DF1:CBOX-CMP1")
|
||||
self.magnet_position_sensor_readout = PV(f"{BEAMLINE}-ES-DF1:CBOX-USER1")
|
||||
|
||||
@@ -209,6 +216,18 @@ class BeamlineDevices:
|
||||
wait_position(self.gmy, pos.y, 0.005)
|
||||
wait_position(self.gmz, pos.z, 0.005)
|
||||
|
||||
@property
|
||||
def energy_kev(self) -> float:
|
||||
return self.__energy_pv.value
|
||||
|
||||
@property
|
||||
def ring_current(self) -> float:
|
||||
return self.__ring_current_pv.value
|
||||
|
||||
@property
|
||||
def cryojet_temp(self) -> float:
|
||||
return self.__cryojet_temp.value
|
||||
|
||||
def enable_motors(self):
|
||||
self.aerotech.unlock()
|
||||
self.dtz.refresh() # Why ??
|
||||
|
||||
@@ -1,157 +0,0 @@
|
||||
from enum import Enum
|
||||
from typing import Annotated, Literal, Tuple, List, Optional
|
||||
|
||||
from pydantic import BaseModel, Field
|
||||
|
||||
from aaredaqlib.coordinate import Coordinate
|
||||
from aaredaqlib.sample_geometry import SampleGeometryModel
|
||||
|
||||
|
||||
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 BeamCenterCoeffModel(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 DAQStatusModel(BaseModel):
|
||||
geom: SampleGeometryModel
|
||||
state: BeamlineStateEnum
|
||||
busy: bool
|
||||
light: Annotated[float, Field(ge=0.0, le=100.0)]
|
||||
session: SessionsStateEnum = SessionsStateEnum.Vacant
|
||||
sample: SampleShortInfo | None = None
|
||||
current_pgroup: str | None
|
||||
staff: bool = False
|
||||
|
||||
|
||||
class BeamlineSettingsModel(BaseModel):
|
||||
# Float properties
|
||||
cryojet_park_position: float = 12.0
|
||||
cryojet_measurement_position: float = 5.0
|
||||
dtz_collection: float = 130
|
||||
dtz_park: float = 150.0
|
||||
dtz_wash_sample_distance: float = 150.0
|
||||
dtz_bsz_safety_margin: float = 50.0
|
||||
bsz: float = 25.0
|
||||
|
||||
camera_max_magnification: float = 1.0
|
||||
camera_min_magnification: float = 500.0
|
||||
camera_translation_factor_a: float = 0.00253
|
||||
camera_translation_factor_b: float = 255.0
|
||||
|
||||
cryojet_in_use: bool = True
|
||||
+13
-15
@@ -1,30 +1,27 @@
|
||||
import io
|
||||
from typing import Tuple
|
||||
|
||||
import urllib3
|
||||
from fastapi import HTTPException
|
||||
import logging
|
||||
|
||||
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
|
||||
from aaredaqlib.rotation_scan import RotationScanRequest
|
||||
from aaredaqlib.sample_geometry import SampleGeometryModel
|
||||
from aaredaqlib.screening_scan import ScreeningScanRequest
|
||||
from fastapi import FastAPI, Depends
|
||||
from fastapi import HTTPException
|
||||
from fastapi.security import OAuth2PasswordBearer, OAuth2PasswordRequestForm
|
||||
from starlette.responses import StreamingResponse
|
||||
from urllib3.exceptions import InsecureRequestWarning
|
||||
|
||||
from aaredaq import auth
|
||||
from aaredaq.auth import TokenData
|
||||
from aaredaq.beamline import mx_beamline
|
||||
from aaredaq.config import BeamlineConfig
|
||||
from aaredaq.daq import AareDAQ
|
||||
from aaredaq.models import SampleShortInfo, DAQStatusModel, BeamlineStateEnum, BeamlineSettingsModel, \
|
||||
SampleShortInfoList
|
||||
from aaredaqlib.coordinate import SmargonCoordinate, Coordinate
|
||||
from aaredaqlib.helical_geometry import HelicalScanRequest
|
||||
from aaredaqlib.raster_grid import RasterGridRequest
|
||||
from aaredaqlib.rotation_scan import RotationScanRequest
|
||||
from aaredaqlib.sample_geometry import SampleGeometryModel
|
||||
from aaredaqlib.screening_scan import ScreeningScanRequest
|
||||
|
||||
app = FastAPI()
|
||||
|
||||
@@ -47,8 +44,9 @@ 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 = cfg.session_state(data.session)
|
||||
ret.staff = data.staff
|
||||
ret.session = SessionStatus(current_pgroup = cfg.pgroup,
|
||||
session=cfg.session_state(data.session),
|
||||
staff=data.staff)
|
||||
return ret
|
||||
|
||||
|
||||
|
||||
@@ -7,15 +7,15 @@ from typing import List
|
||||
from urllib.parse import urlparse
|
||||
|
||||
import requests
|
||||
|
||||
from aaredaq.beamline import MXBeamline # noqa: F401
|
||||
from aaredaq.models import (
|
||||
from aaredaqlib.models import (
|
||||
PuckLoadedInfo,
|
||||
SampleShortInfo,
|
||||
DewarAddress,
|
||||
SampleDewarAddress,
|
||||
PuckInfo,
|
||||
)
|
||||
|
||||
from aaredaq.beamline import MXBeamline # noqa: F401
|
||||
from mxlibs3.pshell_client import PShellClient
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
Reference in New Issue
Block a user