refactor: tidy up for gridscan analysis switching
CI / lint (push) Skipped
CI / test (3.11) (push) Skipped
CI / test (3.12) (push) Skipped
CI / test (3.13) (push) Skipped
CI / lint (pull_request) Successful in 25s
CI / test (3.11) (pull_request) Successful in 1m24s
CI / test (3.12) (pull_request) Successful in 1m40s
CI / test (3.13) (pull_request) Successful in 1m44s
CI / lint (push) Skipped
CI / test (3.11) (push) Skipped
CI / test (3.12) (push) Skipped
CI / test (3.13) (push) Skipped
CI / lint (pull_request) Successful in 25s
CI / test (3.11) (pull_request) Successful in 1m24s
CI / test (3.12) (pull_request) Successful in 1m40s
CI / test (3.13) (pull_request) Successful in 1m44s
This commit is contained in:
@@ -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:
|
||||
|
||||
@@ -51,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"]
|
||||
|
||||
Reference in New Issue
Block a user