from .. import StandardImagingFC2
from ..core.geometry import Point
from ..metrics.image import SizedDiskLocator
[docs]
class QuasarLightRadScaling(StandardImagingFC2):
"""A light/rad and also scaling analysis for the Quasar phantom. The user
also uses custom edge blocks with offset BBs to detect the light corners.
It's a mix of scaling validation and light/rad."""
common_name = "Quasar Light/Rad Scaling"
bb_sampling_box_size_mm = 10
bb_size_mm = 5
field_strip_width_mm = 20
light_rad_bb_offset_mm = 11
scaling_centers: list[Point]
[docs]
def analyze(
self, invert: bool = False, fwxm: int = 50, bb_edge_threshold_mm: float = 10
) -> None:
"""Analyze the image for the light/rad and scaling"""
super().analyze(
invert=invert, fwxm=fwxm, bb_edge_threshold_mm=bb_edge_threshold_mm
)
self.scaling_centers = self._detect_scaling_centers()
def _determine_bb_set(self, fwxm: int) -> dict:
"""We determine the BB set to use for the CAX (the light/rad part is separate).
We do this by first finding the field edges and then offsetting inward by 10 mm.
"""
fs_y = self.field_width_y / 2
fs_x = self.field_width_x / 2
positions_offsets = {
"TL": (
-fs_x + self.light_rad_bb_offset_mm,
-fs_y + self.light_rad_bb_offset_mm,
),
"BL": (
-fs_x + self.light_rad_bb_offset_mm,
fs_y - self.light_rad_bb_offset_mm,
),
"TR": (
fs_x - self.light_rad_bb_offset_mm,
fs_y - self.light_rad_bb_offset_mm,
),
"BR": (
fs_x - self.light_rad_bb_offset_mm,
-fs_y + self.light_rad_bb_offset_mm,
),
}
return positions_offsets
def _detect_scaling_centers(self) -> list[Point]:
"""Sample a 10x10mm square about each BB to detect it. Adjustable using self.bb_sampling_box_size_mm"""
scaling_centers = self.image.compute(
SizedDiskLocator.from_center_physical(
expected_position_mm=Point(0, 0),
search_window_mm=(35, 35),
radius_mm=self.bb_size_mm / 2,
radius_tolerance_mm=self.bb_size_mm / 2,
min_number=5,
max_number=5,
min_separation_mm=4,
)
)
return scaling_centers