Tidy up ROM action and add a lock

This commit is contained in:
Julian Stirling 2025-10-16 15:13:44 +01:00
parent ee76a46882
commit f1730ff2c0

View file

@ -16,6 +16,7 @@ this is 10% of the expected motion is the measured axis.
from typing import Literal, Any, Optional from typing import Literal, Any, Optional
import time import time
from dataclasses import dataclass from dataclasses import dataclass
from threading import Lock
from scipy.optimize import curve_fit from scipy.optimize import curve_fit
from PIL import Image from PIL import Image
@ -64,6 +65,11 @@ class RomDataTracker:
self.stage_coords.append(current_pos) self.stage_coords.append(current_pos)
self.cor_lat_steps.append(cor) self.cor_lat_steps.append(cor)
@property
def final_position(self) -> dict[str, int]:
"""The last stage coordinate recorded."""
return self.stage_coords[-1].copy()
@dataclass @dataclass
class RomDeps: class RomDeps:
@ -368,8 +374,13 @@ class RangeofMotionThing(lt.Thing):
initial_value=None, model=Optional[list[int, int]], readonly=True initial_value=None, model=Optional[list[int, int]], readonly=True
) )
def __init__(self) -> None:
"""Initalise and create the lock."""
super().__init__()
self._lock = Lock()
@lt.thing_action @lt.thing_action
def rom_main( def perform_rom_test(
self, self,
autofocus: AutofocusDep, autofocus: AutofocusDep,
stage: StageDep, stage: StageDep,
@ -386,6 +397,10 @@ class RangeofMotionThing(lt.Thing):
:param logger: A raw_thing_client depeendency for the logger. :param logger: A raw_thing_client depeendency for the logger.
:return: Results dictionary separated into keys of each axis and direction. :return: Results dictionary separated into keys of each axis and direction.
""" """
got_lock = self._lock.acquire(blocking=False)
if not got_lock:
raise RuntimeError("Trying to run ROM test when a test is already running.")
rom_deps = RomDeps( rom_deps = RomDeps(
autofocus=autofocus, stage=stage, csm=csm, cam=cam, logger=logger autofocus=autofocus, stage=stage, csm=csm, cam=cam, logger=logger
) )
@ -394,32 +409,24 @@ class RangeofMotionThing(lt.Thing):
"Please ensure you are using a big enough sample." "Please ensure you are using a big enough sample."
) )
start_time = time.time() start_time = time.time()
rom_json = {}
# Loop through all axes and directions. # The total range for the two axes under test
for axis_dir in [["x", 1], ["x", -1], ["y", 1], ["y", -1]]: step_range = []
axis_dir_results = self._rom_axis(
axis=axis_dir[0], for axis in ["x", "y"]:
direction=axis_dir[1], # The final position of the axis under test in the given direction
rom_deps=rom_deps, axis_limits = []
) for axis_dir in [1, -1]:
# Save results from single axis and direction axis_data = self._rom_axis(
rom_json[ axis=axis, direction=axis_dir, rom_deps=rom_deps
f"{'positive' if axis_dir[1] == 1 else 'negative'} {axis_dir[0]}" )
] = axis_dir_results # Append final position
axis_limits.append(axis_data.final_position[axis])
# Calculate step range.
step_range.append(abs(axis_limits[0] - axis_limits[1]))
end_time = time.time() end_time = time.time()
total_time = (end_time - start_time) / 60 total_time = end_time - start_time
x_range = abs(
rom_json["positive x"]["final_position"]["x"]
- rom_json["negative x"]["final_position"]["x"]
)
y_range = abs(
rom_json["positive y"]["final_position"]["y"]
- rom_json["negative y"]["final_position"]["y"]
)
step_range = [x_range, y_range]
logger.info(f"Range of motion is {step_range[0]} x {step_range[1]} steps") logger.info(f"Range of motion is {step_range[0]} x {step_range[1]} steps")
@ -450,7 +457,6 @@ class RangeofMotionThing(lt.Thing):
starting_position = list(rom_deps.stage.position.values()) starting_position = list(rom_deps.stage.position.values())
rom_data = RomDataTracker() # initialise data tracking object rom_data = RomDataTracker() # initialise data tracking object
axis_results = {}
try: try:
dir_str = "positive" if direction == 1 else "negative" dir_str = "positive" if direction == 1 else "negative"
@ -520,15 +526,7 @@ class RangeofMotionThing(lt.Thing):
rom_deps=rom_deps, rom_deps=rom_deps,
) )
rom_data.stage_coords[np.shape(np.array(rom_data.stage_coords))[0] - 1] = ( rom_data.stage_coords[-1] = final_pos
final_pos
)
axis_results = {
"correlation_lateral_steps": rom_data.cor_lat_steps.copy(),
"stage_positions": rom_data.stage_coords.copy(),
"final_position": final_pos,
}
finally: finally:
rom_deps.stage.move_absolute( rom_deps.stage.move_absolute(
@ -538,4 +536,4 @@ class RangeofMotionThing(lt.Thing):
block_cancellation=True, block_cancellation=True,
) )
return axis_results return rom_data