Skip to content

Commit 7fee127

Browse files
committed
Implement aperture scatterguard move for reverse direction
1 parent a0f3bd3 commit 7fee127

2 files changed

Lines changed: 54 additions & 27 deletions

File tree

src/dodal/devices/scintillator.py

Lines changed: 15 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -91,27 +91,24 @@ async def _check_beamstop_position(self):
9191
)
9292

9393
async def _set_selected_position(self, position: InOut) -> None:
94+
current_y = await self.y_mm.user_readback.get_value()
95+
current_z = await self.z_mm.user_readback.get_value()
96+
if self._get_selected_position(current_y, current_z) == position:
97+
return
98+
9499
await self._check_beamstop_position()
95-
match position:
96-
case InOut.OUT:
97-
current_y = await self.y_mm.user_readback.get_value()
98-
current_z = await self.z_mm.user_readback.get_value()
99-
if self._get_selected_position(current_y, current_z) == InOut.OUT:
100-
return
101-
102-
async def move_scin_out():
103-
await self.y_mm.set(self._scintillator_out_yz_mm[0])
104-
await self.z_mm.set(self._scintillator_out_yz_mm[1])
105-
106-
await self.do_with_ap_sg_in_safe_pos(move_scin_out)
107-
108-
case InOut.IN:
109-
current_y = await self.y_mm.user_readback.get_value()
110-
current_z = await self.z_mm.user_readback.get_value()
111-
if self._get_selected_position(current_y, current_z) == InOut.IN:
112-
return
100+
101+
async def move_to_new_position():
102+
if position == InOut.OUT:
103+
await self.y_mm.set(self._scintillator_out_yz_mm[0])
104+
await self.z_mm.set(self._scintillator_out_yz_mm[1])
105+
elif position == InOut.IN:
113106
await self.z_mm.set(self._scintillator_in_yz_mm[1])
114107
await self.y_mm.set(self._scintillator_in_yz_mm[0])
108+
109+
match position:
110+
case InOut.OUT | InOut.IN:
111+
await self.do_with_ap_sg_in_safe_pos(move_to_new_position)
115112
case _:
116113
raise ValueError(f"Cannot set scintillator to position {position}")
117114

tests/devices/test_scintillator.py

Lines changed: 39 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,8 @@ async def test_when_set_to_unknown_position_then_error_raised(
9494
scintillator_and_ap_sg: tuple[Scintillator, ApertureScatterguard],
9595
):
9696
scintillator, _ = scintillator_and_ap_sg
97+
await scintillator.y_mm.set(100.855)
98+
await scintillator.z_mm.set(101.5115)
9799
with pytest.raises(ValueError):
98100
await scintillator.selected_pos.set(InOut.UNKNOWN)
99101

@@ -131,11 +133,17 @@ async def test_given_aperture_scatterguard_parked_when_set_to_in_position_then_r
131133
)
132134
async def test_given_scintillator_already_out_when_moved_in_or_out_then_does_nothing(
133135
scintillator_and_ap_sg: tuple[Scintillator, ApertureScatterguard],
136+
beamstop: Beamstop,
134137
expected_position,
135138
y,
136139
z,
137140
):
138141
scintillator, ap_sg = scintillator_and_ap_sg
142+
ap_sg.get_scin_move_position.return_value = {
143+
ap_sg.aperture.x: -1.0,
144+
ap_sg.scatterguard.x: -1.5,
145+
}
146+
beamstop.selected_pos.get_value.return_value = BeamstopPositions.UNKNOWN
139147
await scintillator.y_mm.set(y)
140148
await scintillator.z_mm.set(z)
141149

@@ -147,6 +155,8 @@ async def test_given_scintillator_already_out_when_moved_in_or_out_then_does_not
147155

148156
get_mock_put(scintillator.y_mm.user_setpoint).assert_not_called()
149157
get_mock_put(scintillator.z_mm.user_setpoint).assert_not_called()
158+
get_mock_put(ap_sg.aperture.x.user_setpoint).assert_not_called()
159+
get_mock_put(ap_sg.scatterguard.x.user_setpoint).assert_not_called()
150160

151161

152162
@pytest.mark.parametrize(
@@ -176,14 +186,29 @@ async def test_beamstop_check_in_known_good_position(
176186
await scintillator.selected_pos.set(InOut.OUT)
177187

178188

179-
async def test_move_scintillator_out_moves_ap_sg_to_scin_move_and_back(
189+
@pytest.mark.parametrize(
190+
"initial_y, initial_z, final_y, final_z, swap_order, final_position",
191+
[
192+
[100.855, 101.5115, -0.02, 0.1, False, InOut.OUT],
193+
[-0.02, 0.1, 100.855, 101.5115, True, InOut.IN],
194+
],
195+
)
196+
async def test_move_scintillator_moves_ap_sg_to_scin_move_and_back(
180197
scintillator_and_ap_sg: tuple[Scintillator, ApertureScatterguard],
198+
initial_y: float,
199+
initial_z: float,
200+
final_y: float,
201+
final_z: float,
202+
swap_order: bool,
203+
final_position: InOut,
181204
):
182205
scintillator, ap_sg = scintillator_and_ap_sg
183206
ap_sg.get_scin_move_position.return_value = {
184207
ap_sg.aperture.x: -1.0,
185208
ap_sg.scatterguard.x: -1.5,
186209
}
210+
set_mock_value(scintillator.y_mm.user_readback, initial_y)
211+
set_mock_value(scintillator.z_mm.user_readback, initial_z)
187212

188213
parent = MagicMock()
189214
parent.aperture.attach_mock(get_mock_put(ap_sg.aperture.x.user_setpoint), "x")
@@ -201,15 +226,20 @@ async def test_move_scintillator_out_moves_ap_sg_to_scin_move_and_back(
201226
parent.scintillator.attach_mock(
202227
get_mock_put(scintillator.z_mm.user_setpoint), "z_mm"
203228
)
204-
await scintillator.selected_pos.set(InOut.OUT)
205-
206-
parent.assert_has_calls(
207-
[
208-
call.aperture.x(-1.0, wait=True),
209-
call.scatterguard.x(-1.5, wait=True),
210-
call.scintillator.y_mm(-0.02, wait=True),
211-
call.scintillator.z_mm(0.1, wait=True),
229+
await scintillator.selected_pos.set(final_position)
230+
231+
expected_scintillator_move = [
232+
call.scintillator.y_mm(final_y, wait=True),
233+
call.scintillator.z_mm(final_z, wait=True),
234+
]
235+
if swap_order:
236+
expected_scintillator_move = expected_scintillator_move[::-1]
237+
expected_calls = (
238+
[call.aperture.x(-1.0, wait=True), call.scatterguard.x(-1.5, wait=True)]
239+
+ expected_scintillator_move
240+
+ [
212241
call.aperture.x(1.0, wait=True),
213242
call.scatterguard.x(2.0, wait=True),
214243
]
215244
)
245+
parent.assert_has_calls(expected_calls)

0 commit comments

Comments
 (0)