Skip to content

Commit b121c68

Browse files
committed
initial commit
1 parent 5e20cef commit b121c68

File tree

3 files changed

+59
-63
lines changed

3 files changed

+59
-63
lines changed

src/ibex_bluesky_core/plans/reflectometry/_autoalign.py

+9-8
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
logger = logging.getLogger(__name__)
1818

1919

20-
def _print_and_log(msg):
20+
def _print_and_log(msg: str) -> None:
2121
logger.info(msg)
2222
print(msg)
2323

@@ -96,8 +96,9 @@ def _optimise_axis_over_range( # noqa: PLR0913 PLR0917
9696
A callback for what to do if the optimised value is not found to be sensible.
9797
9898
Returns:
99-
Tuple of [ISISCallbacks, success (bool)]. The ISISCallbacks are a reference to a set of standard callbacks,
100-
including the fit. The success flag indicates whether the optimization was successful.
99+
Tuple of [ISISCallbacks, success (bool)]. The ISISCallbacks are a reference to a set of
100+
standard callbacks, including the fit.
101+
The success flag indicates whether the optimization was successful.
101102
102103
"""
103104
_print_and_log(
@@ -158,7 +159,7 @@ def _optimise_axis_over_range( # noqa: PLR0913 PLR0917
158159
return icc, True
159160

160161

161-
def optimise_axis_against_intensity(
162+
def optimise_axis_against_intensity( # noqa: PLR0913
162163
dae: SimpleDae,
163164
alignment_param: NamedMovable[float],
164165
fit_method: FitMethod,
@@ -205,9 +206,9 @@ def optimise_axis_against_intensity(
205206
Instance of :obj:`ibex_bluesky_core.callbacks.ISISCallbacks`.
206207
207208
"""
208-
problem_found_plan = problem_found_plan or (lambda: bps.null())
209+
problem_found_plan = problem_found_plan or bps.null
209210

210-
logging.info(
211+
logger.info(
211212
"Starting optimise_axis_against_intensity with param=%s, ranges=%s",
212213
alignment_param.name,
213214
rel_scan_ranges,
@@ -232,11 +233,11 @@ def optimise_axis_against_intensity(
232233
)
233234

234235
if not all_ok:
235-
logging.info("Problem found during _optimise_axis_over_range, restarting scan loop")
236+
logger.info("Problem found during _optimise_axis_over_range, restarting scan loop")
236237
break
237238

238239
if all_ok:
239-
logging.info(
240+
logger.info(
240241
"Finished optimise_axis_against_intensity with param=%s, ranges=%s",
241242
alignment_param.name,
242243
rel_scan_ranges,

tests/plans/test_reflectometry.py

+40-55
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
)
2020
from ibex_bluesky_core.plans.reflectometry._autoalign import (
2121
_check_parameter,
22+
_optimise_axis_over_range,
2223
)
2324

2425

@@ -104,10 +105,6 @@ def plan(mock) -> Generator[Msg, None, None]:
104105

105106
mock = MagicMock()
106107

107-
def _mock_optimise_axis_over_range(*args, **kwargs):
108-
yield from bps.null()
109-
return None, True
110-
111108
with (
112109
patch("ibex_bluesky_core.devices.reflectometry.get_pv_prefix", return_value=prefix),
113110
patch("ibex_bluesky_core.plans.reflectometry._autoalign.scan", return_value=_fake_scan()),
@@ -120,10 +117,6 @@ def _mock_optimise_axis_over_range(*args, **kwargs):
120117
"ibex_bluesky_core.plans.reflectometry._autoalign._check_parameter",
121118
side_effect=["Test!", None],
122119
),
123-
patch(
124-
"ibex_bluesky_core.plans.reflectometry._autoalign._optimise_axis_over_range",
125-
new=_mock_optimise_axis_over_range,
126-
),
127120
):
128121
param = ReflParameter(prefix=prefix, name="S1VG", changing_timeout_s=60)
129122

@@ -143,10 +136,10 @@ def _mock_optimise_axis_over_range(*args, **kwargs):
143136

144137

145138
@pytest.mark.parametrize(
146-
"param_value, problem_str",
139+
("param_value", "problem_str"),
147140
[
148-
(-5, "Optimised value found to be to be outside, to the right, of scan range"),
149-
(5, "Optimised value found to be to be outside, to the left, of scan range"),
141+
(-5, "Optimised value found to be to be outside, to the left, of scan range"),
142+
(5, "Optimised value found to be to be outside, to the right, of scan range"),
150143
(0, None),
151144
],
152145
)
@@ -155,11 +148,9 @@ def test_alignment_param_value_outside_of_scan_range_returns_problem(param_value
155148
with (
156149
patch("lmfit.model.ModelResult") as mr,
157150
):
158-
mr.values = {"x0": param_value}
159-
160151
assert (
161152
_check_parameter(
162-
alignment_param_value=0.0,
153+
alignment_param_value=param_value,
163154
result=mr,
164155
init_mot_pos=0.0,
165156
rel_scan_range=1.0,
@@ -182,31 +173,26 @@ def my_check(model: ModelResult, param_val: float) -> str | None:
182173
with patch("lmfit.model.ModelResult") as mr:
183174
mr.values = {"x0": 0.0}
184175

185-
if problem:
186-
with pytest.raises(ValueError):
187-
_check_parameter(
188-
alignment_param_value=0.0,
189-
result=mr,
190-
init_mot_pos=0.0,
191-
rel_scan_range=1.0,
192-
is_good_fit=my_check,
193-
)
194-
195-
else: # Check that does not raise
196-
_check_parameter(
197-
alignment_param_value=0.0,
198-
result=mr,
199-
init_mot_pos=0.0,
200-
rel_scan_range=1.0,
201-
is_good_fit=my_check,
202-
)
176+
assert ("problem" if problem else None) == _check_parameter(
177+
alignment_param_value=0.0,
178+
result=mr,
179+
init_mot_pos=0.0,
180+
rel_scan_range=1.0,
181+
is_good_fit=my_check,
182+
)
203183

204184

205-
def test_that_if_no_problem_found_then_motor_is_moved_and_rezeroed(RE, prefix, simpledae):
185+
def test_that_if_no_problem_found_then_motor_is_moved(RE, prefix, simpledae):
206186
"""Test that if no problems are found with the optimised
207-
value then move the motor to it and redefine this as 0
187+
value then move the motor to it
208188
"""
209-
sp = 5.0
189+
190+
icc = MagicMock(spec=ISISCallbacks)
191+
icc.live_fit.fit_result.params[""] = 0.0
192+
193+
def mock_scan(*a, **k):
194+
yield from bps.null()
195+
return icc
210196

211197
with (
212198
patch("ibex_bluesky_core.devices.reflectometry.get_pv_prefix", return_value=prefix),
@@ -223,19 +209,24 @@ def test_that_if_no_problem_found_then_motor_is_moved_and_rezeroed(RE, prefix, s
223209
return_value=_plan_return_0(),
224210
),
225211
patch(
226-
"ibex_bluesky_core.plans.reflectometry._autoalign._optimise_axis_over_range",
227-
return_value=sp,
212+
"ibex_bluesky_core.plans.reflectometry._autoalign.scan",
213+
new=mock_scan,
228214
),
229215
):
230216
param = ReflParameter(prefix=prefix, name="S1VG", changing_timeout_s=60)
231217

232218
RE(
233-
optimise_axis_against_intensity(
219+
_optimise_axis_over_range(
234220
simpledae,
235221
alignment_param=param,
236-
rel_scan_ranges=[0.0],
222+
rel_scan_range=0.0,
237223
fit_method=SlitScan().fit(),
238224
fit_param="",
225+
num_points=10,
226+
periods=True,
227+
save_run=True,
228+
is_good_fit=lambda *a, **k: None,
229+
problem_found_plan=bps.null,
239230
)
240231
)
241232

@@ -247,11 +238,13 @@ def test_that_if_problem_found_and_type_1_then_re_scan(RE, prefix, simpledae, mo
247238
"""Test that if a problem is found, and the user types 1, then rescan.
248239
Then if they type 2, moves to value.
249240
"""
241+
call_count = 0
250242

251243
def counter(str: str):
252-
counter.call_count += 1 # type: ignore
244+
nonlocal call_count
245+
call_count += 1 # type: ignore
253246

254-
if counter.call_count == 1: # type: ignore
247+
if call_count == 1: # type: ignore
255248
return "1"
256249
else:
257250
return "2"
@@ -271,13 +264,8 @@ def counter(str: str):
271264
"ibex_bluesky_core.plans.reflectometry._autoalign.bps.rd",
272265
return_value=_plan_return_0(),
273266
),
274-
patch(
275-
"ibex_bluesky_core.plans.reflectometry._autoalign._optimise_axis_over_range",
276-
return_value=0,
277-
),
278267
):
279268
param = ReflParameter(prefix=prefix, name="S1VG", changing_timeout_s=60)
280-
counter.call_count = 0 # type: ignore
281269

282270
monkeypatch.setattr("builtins.input", counter)
283271
RE(
@@ -297,13 +285,15 @@ def test_that_if_problem_found_and_type_random_then_re_ask(RE, prefix, simpledae
297285
"""Test that if a problem is found, and the user types gibberish, then ask again.
298286
Then if they type 1, it rescans. If they type 2, it moves to value.
299287
"""
288+
call_count = 0
300289

301290
def counter(str: str):
302-
counter.call_count += 1 # type: ignore
291+
nonlocal call_count
292+
call_count += 1
303293

304-
if counter.call_count == 1: # type: ignore
294+
if call_count == 1: # type: ignore
305295
return "platypus"
306-
elif counter.call_count == 2: # type: ignore
296+
elif call_count == 2: # type: ignore
307297
return "1"
308298
else:
309299
return "2"
@@ -323,20 +313,15 @@ def counter(str: str):
323313
"ibex_bluesky_core.plans.reflectometry._autoalign.bps.rd",
324314
return_value=_plan_return_0(),
325315
),
326-
patch(
327-
"ibex_bluesky_core.plans.reflectometry._autoalign._optimise_axis_over_range",
328-
return_value=0,
329-
),
330316
):
331317
param = ReflParameter(prefix=prefix, name="S1VG", changing_timeout_s=60)
332-
counter.call_count = 0 # type: ignore
333318

334319
monkeypatch.setattr("builtins.input", counter)
335320
RE(
336321
optimise_axis_against_intensity(
337322
simpledae,
338323
alignment_param=param,
339-
rel_scan_ranges=[0.0],
324+
rel_scan_ranges=[10.0],
340325
fit_method=SlitScan().fit(),
341326
fit_param="",
342327
)

tests/test_plan_stubs.py

+10
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
CALL_QT_AWARE_MSG_KEY,
1212
call_qt_aware,
1313
call_sync,
14+
prompt_user_for_choice,
1415
)
1516
from ibex_bluesky_core.run_engine._msg_handlers import call_sync_handler
1617

@@ -123,3 +124,12 @@ def plan():
123124
RE(plan())
124125

125126
mock.assert_not_called()
127+
128+
129+
def test_get_user_input(RE):
130+
with patch("ibex_bluesky_core.plan_stubs.input") as mock_input:
131+
mock_input.__name__ = "mock"
132+
mock_input.side_effect = ["foo", "bar", "baz"]
133+
134+
result = RE(prompt_user_for_choice(prompt="choice?", choices=["bar", "baz"]))
135+
assert result.plan_result == "bar"

0 commit comments

Comments
 (0)