feat: add software autofocus support to MDAWidget#553
Conversation
|
thanks for opening this @gcharvin! Great feature, definitely needed. (I think there's an issue discussing it somewhere in one of the repos, but not immediately finding it). One high level thought I'm having here is that this feels similar in spirit to pymmcore-plus/pymmcore-plus#439 (pixel calibration routine to find the camera affine transform): basically, they are both "extended routines" that operate on a core. They both take in some config, and produce a result. So, I've been thinking that we need some sort of a class SoftwareAutofocus:
"""Scan Z, score focus, return best position."""
class Events(SignalGroup):
step_scored = Signal(float, float)
attempt_started = Signal(int, int)
finished = Signal(SoftwareAutofocusResult)
failed = Signal(str)
events = Events()
def run(
self,
core: CMMCorePlus,
config: SoftwareAutofocusConfig, # some dataclass with config
) -> SoftwareAutofocusResult: # some dataclass with result
...I've struggled to decide where these sorts of things belong.
Does anyone have thoughts A) on the general concept of a "routines" pattern? B) on where it should live (low programmatic level with separation of concerns, or don't try... just put it in a higher level lib) |
|
Thanks Talley, I agree that this feels more like a “routine” than something that should live directly in the widget/MDA layer. I’d be happy to refactor the software autofocus in that direction: move the core logic into a GUI-free SoftwareAutofocus object, with a config object, a result object, and maybe a few progress events like step scored / finished / failed. Then the widget would just collect the config and display progress, and the MDA engine would just call the same routine. I also agree that pymmcore_plus.routines is probably the cleanest home conceptually. Maybe a reasonable first step would be to prototype it as a GUI-free module in pymmcore-widgets, and then move it down to pymmcore-plus once the shape feels stable? |
that sounds great to me! want to use this PR to play with the pattern? A couple additional thoughts on the implementation here: My main thought is about the general pattern of subclassing But, those are just side thoughts: the key next step should be architectural. Let's try to break up the programmatic and GUI portions into two clear modules, where the routine has a |
Summary
Draft feature PR for design feedback. This adds software autofocus support to the MDA widget path.
It includes:
Background
This was developed and field-tested during TiEclipse timelapse work where hardware PFS-like behavior was needed from software autofocus inside MDA execution. I do not have a screenshot or formal bug report saved, so this PR is documented from commit history and the behavior implemented here.
Notes for reviewers
This is intentionally a draft. I would like feedback on API shape, metadata schema, and whether the engine integration belongs here or should be refactored before merge. Hardware coverage is limited to the TiEclipse workflow so far.
Validation