DAQ: change exposure and gain based of off zoom. Interpolates gain and exposure if zoom value is not in redis.
This commit is contained in:
@@ -108,8 +108,7 @@ class LoopCenteringZoomModelElem(BaseModel):
|
||||
|
||||
|
||||
class LoopCenteringZoomModel(BaseModel):
|
||||
z: List[LoopCenteringZoomModelElem]
|
||||
|
||||
z: List[LoopCenteringZoomModelElem]
|
||||
|
||||
# zoom gain exp (X06DA)
|
||||
# 1 50 0.05
|
||||
@@ -124,7 +123,7 @@ def def_loop_centering_zoom() -> LoopCenteringZoomModel:
|
||||
return LoopCenteringZoomModel(
|
||||
z=[
|
||||
LoopCenteringZoomModelElem(
|
||||
zoom_value=280, sam_cam_gain=50.0, sam_cam_exp=0.10
|
||||
zoom_value=280, sam_cam_gain=100.0, sam_cam_exp=0.05
|
||||
)
|
||||
]
|
||||
)
|
||||
@@ -152,6 +151,60 @@ class SampleCameraSettings(BaseModel):
|
||||
gain: float
|
||||
exposure: float
|
||||
|
||||
|
||||
class ZoomModel(BaseModel):
|
||||
z:dict[float, SampleCameraSettings]
|
||||
|
||||
def get_camera_settings(self, zoom_value: float) -> SampleCameraSettings | tuple[float, float]:
|
||||
if not self.z:
|
||||
raise ValueError("No zoom data available")
|
||||
|
||||
if zoom_value in self.z:
|
||||
elem = self.z[zoom_value]
|
||||
return SampleCameraSettings(gain=elem.gain, exposure=elem.exposure)
|
||||
|
||||
sorted_zooms = sorted(self.z.keys())
|
||||
|
||||
if zoom_value <= sorted_zooms[0]:
|
||||
elem = self.z[sorted_zooms[0]]
|
||||
return SampleCameraSettings(gain=elem.gain, exposure=elem.exposure)
|
||||
|
||||
if zoom_value >= sorted_zooms[-1]:
|
||||
elem = self.z[sorted_zooms[-1]]
|
||||
return SampleCameraSettings(gain=elem.gain, exposure=elem.exposure)
|
||||
|
||||
for i in range(len(sorted_zooms) - 1):
|
||||
if sorted_zooms[i] <= zoom_value <= sorted_zooms[i + 1]:
|
||||
lower_zoom = sorted_zooms[i]
|
||||
upper_zoom = sorted_zooms[i + 1]
|
||||
|
||||
lower_elem = self.z[lower_zoom]
|
||||
upper_elem = self.z[upper_zoom]
|
||||
|
||||
t = (zoom_value - lower_zoom) / (upper_zoom - lower_zoom)
|
||||
|
||||
interpolated_gain = lower_elem.gain + t * (upper_elem.gain - lower_elem.gain)
|
||||
interpolated_exp = lower_elem.exposure + t * (upper_elem.exposure - lower_elem.exposure)
|
||||
|
||||
return SampleCameraSettings(gain=interpolated_gain, exposure=interpolated_exp)
|
||||
|
||||
closest = min(self.z.keys(), key=lambda x: abs(x - zoom_value))
|
||||
elem = self.z[closest]
|
||||
return SampleCameraSettings(gain=elem.gain, exposure=elem.exposure)
|
||||
|
||||
def def_zoom() -> ZoomModel:
|
||||
return ZoomModel(
|
||||
z={
|
||||
1: SampleCameraSettings(gain=50.0, exposure=0.05),
|
||||
280: SampleCameraSettings(gain=100.0, exposure=0.05),
|
||||
500: SampleCameraSettings(gain=100.0, exposure=0.05),
|
||||
700: SampleCameraSettings(gain=150.0, exposure=0.05),
|
||||
800: SampleCameraSettings(gain=100.0, exposure=0.10),
|
||||
1000: SampleCameraSettings(gain=200.0, exposure=0.10)
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
class AutofocusSettings(BaseModel):
|
||||
center_x_pxl: float
|
||||
center_y_pxl: float
|
||||
|
||||
@@ -14,7 +14,7 @@ from aaredaqlib.models import (
|
||||
def_loop_centering_zoom,
|
||||
SampleShortInfo,
|
||||
SessionStatus,
|
||||
BeamlineStateEnum, SessionsStateEnum, SampleShortInfoList, CryojetSettingsModel,
|
||||
BeamlineStateEnum, SessionsStateEnum, SampleShortInfoList, CryojetSettingsModel, ZoomModel, def_zoom,
|
||||
)
|
||||
|
||||
from aaredaqlib.beamline import MXBeamline
|
||||
@@ -352,6 +352,18 @@ class BeamlineConfig:
|
||||
def alc_zoom_settings(self, data: LoopCenteringZoomModel):
|
||||
self.__client.set(f"{self.__bl}:alc_zoom_settings", data.model_dump_json())
|
||||
|
||||
@property
|
||||
def zoom_settings(self) -> ZoomModel:
|
||||
tmp = self.__client.get(f"{self.__bl}:zoom_settings")
|
||||
if tmp is None:
|
||||
return def_zoom()
|
||||
data_dict = json.loads(tmp)
|
||||
return ZoomModel(**data_dict)
|
||||
|
||||
@zoom_settings.setter
|
||||
def zoom_settings(self, data: ZoomModel):
|
||||
self.__client.set(f"{self.__bl}:zoom_settings", data.model_dump_json())
|
||||
|
||||
@property
|
||||
def abr_meas_pos(self) -> Coordinate:
|
||||
tmp = self.__client.get(f"{self.__bl}:abr_meas_pos")
|
||||
|
||||
@@ -97,6 +97,8 @@ class AareDAQ:
|
||||
def zoom(self, val: float):
|
||||
self.__saved_box = None
|
||||
self.__devs.zoom = val
|
||||
self.samcam_settings = self.__cfg.zoom_settings.get_camera_settings(val)
|
||||
#elf.__cfg.state_busy = False
|
||||
|
||||
@property
|
||||
def light(self) -> float:
|
||||
@@ -226,7 +228,7 @@ class AareDAQ:
|
||||
self.__cfg.current_sample = None
|
||||
else:
|
||||
# reset zoom
|
||||
self.__devs.zoom = 280
|
||||
self.zoom = 280
|
||||
# mount sample
|
||||
self.__aare.sample_unmounted(curr_sample)
|
||||
self.__devs.tell.mount(
|
||||
@@ -414,7 +416,7 @@ class AareDAQ:
|
||||
|
||||
for s in self.__cfg.alc_zoom_settings.z:
|
||||
self.__devs.samcam_settings = SampleCameraSettings(exposure=s.sam_cam_exp, gain=s.sam_cam_gain)
|
||||
self.__devs.zoom = s.zoom_value
|
||||
self.zoom = s.zoom_value
|
||||
time.sleep(5.0) # Wait for settings to stabilize
|
||||
|
||||
image = self.__devs.sample_cam.get_image(gray=False)
|
||||
|
||||
Reference in New Issue
Block a user