refactor: extract common code from aaredaq
This commit is contained in:
@@ -0,0 +1,87 @@
|
||||
import math
|
||||
from typing import Annotated, Tuple
|
||||
|
||||
from pydantic import BaseModel, Field
|
||||
|
||||
|
||||
class DiffractionGeometry(BaseModel):
|
||||
energy_keV: Annotated[float, Field(gt=1.0, lt=100.0)]
|
||||
dtz_mm: Annotated[float, Field(gt=10.0, lt=5000.0)]
|
||||
pixel_size_mm: Annotated[float, Field(ge=0.05, le=0.5)]
|
||||
beam_center_pxl: Tuple[float, float]
|
||||
detector_size_pxl: Tuple[int, int]
|
||||
detector_description: str
|
||||
detector_serial_number: str
|
||||
poni_rot1_rad: float
|
||||
poni_rot2_rad: float
|
||||
|
||||
@property
|
||||
def detector_max_radius_pxl(self):
|
||||
x0 = self.detector_size_pxl[0] - self.beam_center_pxl[0]
|
||||
x1 = self.beam_center_pxl[0]
|
||||
y0 = self.detector_size_pxl[1] - self.beam_center_pxl[1]
|
||||
y1 = self.beam_center_pxl[1]
|
||||
return max(abs(x0), abs(x1), abs(y0), abs(y1))
|
||||
|
||||
@property
|
||||
def detector_radius_mm(self):
|
||||
return self.detector_max_radius_pxl * self.pixel_size_mm
|
||||
|
||||
@property
|
||||
def wavelength_angstrom(self):
|
||||
return 12.398 / self.energy_keV
|
||||
|
||||
@property
|
||||
def max_resolution_angstrom(self):
|
||||
return self.resolution_angstrom(self.dtz_mm)
|
||||
|
||||
def resolution_angstrom(self, exp_dtz_mm: float) -> float:
|
||||
if exp_dtz_mm <= 0:
|
||||
raise ValueError(f"Detector distance must be positive {exp_dtz_mm}")
|
||||
|
||||
theta = math.atan(self.detector_radius_mm / exp_dtz_mm) * 0.5
|
||||
return self.wavelength_angstrom / (2 * math.sin(theta))
|
||||
|
||||
def calc_dtz_mm(self, exp_resolution_angstrom: float) -> float:
|
||||
if exp_resolution_angstrom <= 0:
|
||||
raise ValueError("Resolution must be positive")
|
||||
x = self.wavelength_angstrom / (2 * exp_resolution_angstrom)
|
||||
if x >= 1.0 or x <= -1.0:
|
||||
return 0.0
|
||||
theta = math.asin(x)
|
||||
return self.detector_radius_mm / math.tan(2 * theta)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
from aare.daq.config import BeamlineConfig
|
||||
from aare.devices.jfjoch import JFJochWrapper
|
||||
from aarecommon.config.beamline import mx_beamline
|
||||
|
||||
bl = mx_beamline()
|
||||
client = JFJochWrapper(bl)
|
||||
cfg = BeamlineConfig(bl)
|
||||
print(cfg)
|
||||
det_cfg = client.detector()
|
||||
print(det_cfg)
|
||||
print(f"pixel_size: {det_cfg.pixel_size_mm:.4f} mm")
|
||||
print(f"Detector height: {det_cfg.height:.2f} pixel")
|
||||
print(f"Detector width: {det_cfg.width:.2f} pixel")
|
||||
print(f"beam centre = ({cfg.beam_center[0]:.2f}, {cfg.beam_center[1]:.2f})")
|
||||
geom = DiffractionGeometry(
|
||||
energy_keV=12.4,
|
||||
dtz_mm=200.0,
|
||||
pixel_size_mm=det_cfg.pixel_size_mm,
|
||||
beam_center_pxl=(det_cfg.width / 2, det_cfg.height / 2),
|
||||
detector_size_pxl=(det_cfg.width, det_cfg.height),
|
||||
detector_description=det_cfg.description,
|
||||
detector_serial_number=det_cfg.serial_number,
|
||||
poni_rot1_rad=-0.001396263,
|
||||
poni_rot2_rad=-0.003839724,
|
||||
)
|
||||
print(f"geom.max_resolution_angstrom: {geom.max_resolution_angstrom:.2f} Angstrom")
|
||||
print(f"geom.calc_dtz_mm(3.9): {geom.calc_dtz_mm(3.9):.2f} mm")
|
||||
|
||||
print(
|
||||
f"geom.resolution_angstrom(1244.42): {geom.resolution_angstrom(1244.42):.2f} Angstrom"
|
||||
)
|
||||
print(f"geom.detector_radius_mm: {geom.detector_radius_mm:.2f} mm")
|
||||
Reference in New Issue
Block a user