fix typing in find xtal and exclude meitian's new analysis from QA #30

Merged
perl_d merged 2 commits from fix/exclude_bad_file into main 2026-09-03 12:52:15 +02:00
2 changed files with 28 additions and 28 deletions
+20 -11
View File
@@ -318,29 +318,38 @@ def raster_centre_of_mass(result_array, images) -> CenterOfMassModel | None:
return _to_com_model(com, images, "Center of mass")
def raster_highest_score(images, min_low_res_spots: float = 10.0) -> CenterOfMassModel | None:
def center_of_grid(n_x: int, n_y: int) -> CenterOfMassModel:
# get_com_mm maps index i -> (i+0.5)*step, so index (N-1)/2 is the true
# geometric centre of the grid for both odd and even N (and N==1).
y_pos = (n_y - 1) / 2.0
x_pos = (n_x - 1) / 2.0
return CenterOfMassModel(n_x=x_pos, n_y=y_pos, max_image=int(y_pos * n_x + x_pos))
def raster_highest_score(images, min_low_res_spots: float = 10.0) -> CenterOfMassModel:
"""Target the grid cell with the highest crystal score.
If the whole grid is too weak to hold a crystal — max spots_low_res below
min_low_res_spots — target the geometric centre of the grid instead of
collecting at a noisy cell, so a 'nothing here' result is centred and
deliberate rather than random noise.
"""
score_array = compute_crystal_score_array(images)
max_low_res = max((getattr(img, "spots_low_res", 0) or 0 for img in images), default=0)
if max_low_res < min_low_res_spots:
n_nx, n_ny = score_array.shape
logger.info(
f"No crystal in loop (max spots_low_res={max_low_res} < {min_low_res_spots}); "
f"targeting grid centre of {n_nx}x{n_ny} grid"
f"No crystal in loop (max spots_low_res={max_low_res} < {min_low_res_spots}); targeting grid centre"
)
# get_com_mm maps index i -> (i+0.5)*step, so index (N-1)/2 is the true
# geometric centre of the grid for both odd and even N (and N==1).
y_pos = (n_ny - 1) / 2.0
x_pos = (n_nx - 1) / 2.0
return CenterOfMassModel(n_x=x_pos, n_y=y_pos, max_image=int(y_pos * n_nx + x_pos))
return _to_com_model(_max_cell(score_array), images, "Highest score")
return center_of_grid(*score_array.shape)
com = _to_com_model(_max_cell(score_array), images, "Highest score")
if com is None:
logger.error(
"Error in computing centre of mass for gridscan result, images contained invalid data. Returning center image of grid."
)
return center_of_grid(*score_array.shape)
else:
return com
def has_sufficient_low_res_spots(result_array: np.ndarray, min_spots_low_res: float) -> bool:
+8 -17
View File
@@ -1,3 +1,5 @@
# ruff: noqa
# noqa
"""Grid-scan decision from a Jungfraujoch ``scan_result``.
Turns the per-image spot statistics of a grid scan into the position to collect
@@ -49,24 +51,13 @@ from pydantic import BaseModel, Field
# The structures this exchanges with AareDAQ and Jungfraujoch. Verified against
# jfjoch-client 1.0.0-rc.165. The fallbacks let the module import and its self-test
# run outside AareDAQ; inside it the real classes are always the ones used.
try:
from jfjoch_client.models.grid_scan import GridScan
from jfjoch_client.models.scan_result import ScanResult
from jfjoch_client.models.scan_result_images_inner import ScanResultImagesInner
from jfjoch_client.models.unit_cell import UnitCell
except ImportError: # pragma: no cover
GridScan = ScanResult = ScanResultImagesInner = UnitCell = Any
from jfjoch_client.models.grid_scan import GridScan
from jfjoch_client.models.scan_result import ScanResult
from jfjoch_client.models.scan_result_images_inner import ScanResultImagesInner
from jfjoch_client.models.unit_cell import UnitCell
try:
from aarecommon.math.coordinate import Coordinate
from aarecommon.math.sample_geometry import SampleGeometryModel
except ImportError: # pragma: no cover
SampleGeometryModel = Any
class Coordinate(BaseModel): # same shape as aarecommon's
x: float = 0.0
y: float = 0.0
z: float = 0.0
from aarecommon.math.coordinate import Coordinate
from aarecommon.math.sample_geometry import SampleGeometryModel
__all__ = ["Centre", "Counts", "GridScanResult", "Size", "Thresholds", "analyse"]