Skip to content

Commit 824588d

Browse files
authored
fix: connect core roiSet signal to MDAWidget _core_grid and _core_position (#406)
* add mmc.events.roiSet connection * add test * update + test
1 parent 4b0e7fc commit 824588d

3 files changed

Lines changed: 92 additions & 1 deletion

File tree

src/pymmcore_widgets/mda/_core_grid.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ def __init__(
4545

4646
self._mmc.events.systemConfigurationLoaded.connect(self._update_fov_size)
4747
self._mmc.events.pixelSizeChanged.connect(self._update_fov_size)
48+
self._mmc.events.roiSet.connect(self._update_fov_size)
4849
self._update_fov_size()
4950

5051
def _update_fov_size(self) -> None:

src/pymmcore_widgets/mda/_core_positions.py

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
QWizard,
1818
)
1919
from superqt.utils import signals_blocked
20-
from useq import WellPlatePlan
20+
from useq import MDASequence, WellPlatePlan
2121

2222
from pymmcore_widgets import HCSWizard
2323
from pymmcore_widgets.useq_widgets import PositionTable
@@ -112,6 +112,8 @@ def __init__(
112112
# connect
113113
self._mmc.events.systemConfigurationLoaded.connect(self._on_sys_config_loaded)
114114
self._mmc.events.propertyChanged.connect(self._on_property_changed)
115+
self._mmc.events.roiSet.connect(self._update_fov_size)
116+
self._mmc.events.pixelSizeChanged.connect(self._update_fov_size)
115117

116118
self.destroyed.connect(self._disconnect)
117119

@@ -455,3 +457,30 @@ def _disconnect(self) -> None:
455457
self._on_sys_config_loaded
456458
)
457459
self._mmc.events.propertyChanged.disconnect(self._on_property_changed)
460+
461+
def _update_fov_size(self) -> None:
462+
"""Update the FOV size of any grid plan subsequence."""
463+
if not (pos_list := self.value()):
464+
return
465+
466+
# get updated FOV size
467+
px = self._mmc.getPixelSizeUm()
468+
fov_w = self._mmc.getImageWidth() * px
469+
fov_h = self._mmc.getImageHeight() * px
470+
471+
new_pos_list = []
472+
for pos in pos_list:
473+
# skip if there is not a subsequence
474+
if pos.sequence is None:
475+
new_pos_list.append(pos)
476+
continue
477+
# skip if there is not a grid plan
478+
if (gp := pos.sequence.grid_plan) is None:
479+
new_pos_list.append(pos)
480+
continue
481+
# update the FOV size
482+
new_gp = gp.model_copy(update={"fov_width": fov_w, "fov_height": fov_h})
483+
new_pos = pos.model_copy(update={"sequence": MDASequence(grid_plan=new_gp)})
484+
new_pos_list.append(new_pos)
485+
# update the table
486+
self.setValue(new_pos_list)

tests/test_useq_core_widgets.py

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -983,3 +983,64 @@ def _qmsgbox(*args, **kwargs):
983983
# AF column should be hidden
984984
assert pos_table.table().isColumnHidden(af_col)
985985
assert pos_table.table().isColumnHidden(af_btn_col)
986+
987+
988+
def test_grid_plan_fov_update(qtbot: QtBot, global_mmcore: CMMCorePlus) -> None:
989+
mmc = global_mmcore
990+
wdg = MDAWidget()
991+
qtbot.addWidget(wdg)
992+
wdg.show()
993+
994+
wdg.tab_wdg.setChecked(wdg.grid_plan, True)
995+
grid_plan = useq.GridRowsColumns(rows=2, columns=1)
996+
wdg.grid_plan.setValue(grid_plan)
997+
998+
assert wdg.value().grid_plan.fov_height == 512
999+
assert wdg.value().grid_plan.fov_width == 512
1000+
1001+
with qtbot.waitSignal(mmc.events.roiSet):
1002+
mmc.setROI(0, 0, 100, 150)
1003+
assert wdg.value().grid_plan.fov_width == 100
1004+
assert wdg.value().grid_plan.fov_height == 150
1005+
1006+
with qtbot.waitSignal(mmc.events.pixelSizeChanged):
1007+
mmc.setPixelSizeConfig("Res20x")
1008+
assert wdg.value().grid_plan.fov_width == 50
1009+
assert wdg.value().grid_plan.fov_height == 75
1010+
1011+
1012+
def test_grid_plan_subsequence_fov_update(
1013+
qtbot: QtBot, global_mmcore: CMMCorePlus
1014+
) -> None:
1015+
mmc = global_mmcore
1016+
wdg = MDAWidget()
1017+
qtbot.addWidget(wdg)
1018+
wdg.show()
1019+
1020+
pos = useq.AbsolutePosition(
1021+
x=0.0,
1022+
y=0.0,
1023+
z=0.0,
1024+
sequence=useq.MDASequence(
1025+
grid_plan=useq.GridRowsColumns(
1026+
fov_width=512.0, fov_height=512.0, rows=3, columns=1
1027+
)
1028+
),
1029+
)
1030+
wdg.tab_wdg.setChecked(wdg.stage_positions, True)
1031+
wdg.stage_positions.setValue([pos])
1032+
1033+
sp = wdg.stage_positions
1034+
assert sp.value()[0].sequence.grid_plan.fov_width == 512
1035+
assert sp.value()[0].sequence.grid_plan.fov_height == 512
1036+
1037+
with qtbot.waitSignal(mmc.events.roiSet):
1038+
mmc.setROI(0, 0, 100, 150)
1039+
1040+
assert sp.value()[0].sequence.grid_plan.fov_width == 100
1041+
assert sp.value()[0].sequence.grid_plan.fov_height == 150
1042+
1043+
with qtbot.waitSignal(mmc.events.pixelSizeChanged):
1044+
mmc.setPixelSizeConfig("Res20x")
1045+
assert sp.value()[0].sequence.grid_plan.fov_width == 50
1046+
assert sp.value()[0].sequence.grid_plan.fov_height == 75

0 commit comments

Comments
 (0)