DAQ: updated raster COM calculation to send crystal size, b_factor and res estimate to daq status and to do COM on both y and x scans
This commit is contained in:
+78
-20
@@ -593,23 +593,65 @@ class AareDAQ:
|
||||
print("COM by low res spots")
|
||||
result_array = self.create_quality_filtered_array(images, 'spots_low_res', min_spots=None,
|
||||
min_efficiency=1.0, min_background=None)
|
||||
if r.n_x == 1:
|
||||
print('vertical scan')
|
||||
max_image = max(images, key=lambda img: img.spots_low_res)
|
||||
new_y = max_image.ny
|
||||
com = (0, new_y)
|
||||
else:
|
||||
print('horizontal scan')
|
||||
com = ndimage.center_of_mass(result_array)
|
||||
|
||||
print('horizontal scan')
|
||||
com = ndimage.center_of_mass(result_array)
|
||||
|
||||
print(f"Center of mass: {com}")
|
||||
|
||||
try:
|
||||
labeled_array, num_objects = ndimage.label(result_array)
|
||||
areas = ndimage.sum(np.ones_like(result_array, dtype=np.int32), labeled_array,
|
||||
index=range(1, num_objects + 1))
|
||||
largest_idx = int(np.argmax(areas)) + 1 # +1 because labels start at 1
|
||||
largest_area = int(areas[largest_idx - 1])
|
||||
print(f"Largest object label: {largest_idx}, area (px): {largest_area}")
|
||||
|
||||
# Optional: get bounding box of largest object
|
||||
object_mask = labeled_array == largest_idx
|
||||
rows = np.any(object_mask, axis=1)
|
||||
cols = np.any(object_mask, axis=0)
|
||||
row_min, row_max = np.where(rows)[0][[0, -1]]
|
||||
col_min, col_max = np.where(cols)[0][[0, -1]]
|
||||
print(f"Largest bbox: width={col_max - col_min}, height={row_max - row_min}")
|
||||
print(
|
||||
f"Largest bbox: width={(col_max - col_min) * r.grid_size_mm.x}, y={(row_max - row_min) * r.grid_size_mm.y}")
|
||||
|
||||
if r.n_x == 1:
|
||||
|
||||
if self.crystal_size is None:
|
||||
self.crystal_size = CrystalSize(x=0,y=0,z=0)
|
||||
|
||||
crystal_size = self.crystal_size
|
||||
|
||||
crystal_size = CrystalSize(x=crystal_size.x, y=crystal_size.y,
|
||||
z=(col_max - col_min) * r.grid_size_mm.y * 1000)
|
||||
|
||||
else:
|
||||
crystal_size = CrystalSize(x=(row_max - row_min) * r.grid_size_mm.x * 1000,
|
||||
y=(col_max - col_min) * r.grid_size_mm.y * 1000,
|
||||
z=0)
|
||||
except Exception as e:
|
||||
crystal_size = CrystalSize(x=0, y=0, z=0)
|
||||
|
||||
|
||||
self.crystal_size = crystal_size
|
||||
|
||||
if r.n_x == 1 and (np.isnan(com[1]) or np.isnan(com[0])):
|
||||
print('vertical scan')
|
||||
try:
|
||||
max_image = max(images, key=lambda img: img.spots_low_res)
|
||||
com = (0, max_image.ny)
|
||||
except:
|
||||
print("no spots")
|
||||
|
||||
if np.isnan(com[1]) or np.isnan(com[0]):
|
||||
print("Center of mass is nan")
|
||||
com = None
|
||||
grid_mm_x = None
|
||||
grid_mm_y = None
|
||||
best_res = None
|
||||
best_b_factor = None
|
||||
|
||||
else:
|
||||
grid_mm_x = com[0] * r.grid_size_mm.x
|
||||
@@ -620,29 +662,45 @@ class AareDAQ:
|
||||
cx, cy = com[::-1] # com=(y, x) -> (x, y), rounded once
|
||||
start_x, end_x = round(cx - 1), round(cx + 1)
|
||||
start_y, end_y = round(cy - 1), round(cy + 1)
|
||||
|
||||
print(f"range x {start_x} {end_x}, y {start_y} {end_y}")
|
||||
# Collect images in the 3x3 neighborhood around the center
|
||||
res_list = [img for img in images
|
||||
if start_x <= img.nx <= end_x and start_y <= img.ny <= end_y]
|
||||
|
||||
print(res_list)
|
||||
# Best by res, skipping None
|
||||
best_res = max((img for img in res_list if img.res is not None),
|
||||
key=lambda img: img.res,
|
||||
default=None)
|
||||
print(f"Best res: {best_res}")
|
||||
best_b_factor = min((img for img in res_list if img.b is not None),
|
||||
key=lambda img: img.b,
|
||||
default=None)
|
||||
print(f"Best b: {best_b_factor}")
|
||||
|
||||
for image in images:
|
||||
if image.nx == round(com[0]) and image.ny == round(com[1]):
|
||||
print(f"com found for image: {image.number}")
|
||||
|
||||
try:
|
||||
if best_res is not None and best_res.res is not None:
|
||||
# store the numeric resolution on the config/session so it appears in status
|
||||
self.__cfg.last_best_res = float(best_res.res)
|
||||
else:
|
||||
self.__cfg.last_best_res = None
|
||||
except Exception as e:
|
||||
# Don't break the flow if best_res cannot be published
|
||||
self.__cfg.last_best_res = None
|
||||
try:
|
||||
if best_res is not None and best_res.res is not None:
|
||||
# store the numeric resolution on the config/session so it appears in status
|
||||
print(f"best res: {best_res.res}")
|
||||
self.last_best_res = float(best_res.res)
|
||||
else:
|
||||
print(f'res is None')
|
||||
self.last_best_res = None
|
||||
except Exception as e:
|
||||
print(f'error with last_best_res {e}')
|
||||
self.last_best_res = None
|
||||
try:
|
||||
if best_b_factor is not None and best_b_factor.b is not None:
|
||||
print(f"best res: {best_res.b}")
|
||||
self.last_best_b_factor = float(best_b_factor.b)
|
||||
else:
|
||||
print(f'last_best_b_factor is None')
|
||||
self.last_best_b_factor = None
|
||||
except Exception as e:
|
||||
print(f'error with last_best_b_factor {e}')
|
||||
self.last_best_b_factor = None
|
||||
|
||||
if com is not None and grid_mm_x is not None and grid_mm_y is not None:
|
||||
new_delta_mm = self.sample_geometry.smargon_nudge(Coordinate(x=grid_mm_x, y=grid_mm_y))
|
||||
|
||||
Reference in New Issue
Block a user