You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: doc/plans/reflectometry/autoalign.md
+18-8Lines changed: 18 additions & 8 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -2,13 +2,19 @@
2
2
3
3
For reflectometers, we provide a few generic plans which can be used as helpers for automated beamline alignment.
4
4
5
-
The {py:obj}`~ibex_bluesky_core.plans.reflectometry.optimise_axis_against_intensity` plan is designed to scan over a movable against beam intensity, and given which fitting parameter is chosen to be optimised and the fitting method, it will aim to find an optimum value. See[standard fits](/callbacks/fitting/standard_fits.md)for the fitting parameters for each fitting model you can use. At this stage it will check if the value is 'sensible' - there are some default checks, but the user is encouraged to provide their own checks. If found to be sensible, the motor will be moved to this value, otherwise it will optionally run a callback that can be provided, and then ask the user if they want to rescan or continue to move the movable.
5
+
The {py:obj}`~ibex_bluesky_core.plans.reflectometry.optimise_axis_against_intensity` plan is designed to scan a {py:obj}`~bluesky.protocols.Movable` against beam intensity, and given a fitting routine, will aim to find an optimum value. Many[standard fits](/callbacks/fitting/standard_fits.md)have been implemented and can be used easily.
6
6
7
-
The idea for how we expect the main auto-alignment plan to be used is that at the top / instrument level, you will move all other movables to some position ready to align, yield from this plan and then re-zero the motor.
8
-
The following is how you would do this for a reflectometry parameter as your movable:
7
+
Once a fit has been performed, {py:obj}`~ibex_bluesky_core.plans.reflectometry.optimise_axis_against_intensity` will check that the fit parameters are 'sensible' - there are some default checks, but the user is encouraged to provide their own checks. If the checks pass, the motor will be moved to the fit value, otherwise it will run a user-provided callback, and then ask the user if they want to rescan or move anyway.
9
8
10
-
```python
9
+
Reflectometer auto-alignment routines will generally be structured as a series of calls which:
10
+
- Put the beamline into a suitable state for the alignment
11
+
- Call {py:obj}`~ibex_bluesky_core.plans.reflectometry.optimise_axis_against_intensity` to optimise the axis. This will leave the axis parked at its optimal position.
12
+
- Redefine that position as zero (note: this is fully optional, but common on reflectometers)
13
+
- Repeat the above steps for subsequent axes
14
+
15
+
For example, using a reflectometry parameter as your {py:obj}`~bluesky.protocols.Movable`:
As mentioned prior, it is recommended that for each movable you want to align, you should provide a checking function, to make sure that for the value you receive for the chosen fitting paramater e.g centre of a gaussian, is sensible. If the optimised value is not found to be sensible then you will have the option to either type 1 and restart the alignment for this movable, or press 2 and continue with moving the movable to the found value. The following is how you would make a check function with the right signature and pass it to {py:obj}`ibex_bluesky_core.plans.reflectometry.optimise_axis_against_intensity`:
55
+
As mentioned prior, it is recommended that for each {py:obj}`~bluesky.protocols.Movable` to be aligned, you should provide a checking function, to make sure that for the value you receive for the chosen fitting paramater e.g centre of a gaussian, is physically reasonable. If the optimised value fails the check, then you will have the option to either restart the alignment for this axis, or continue moving this axis to the located value despite the failing check.
56
+
57
+
The following is how you would define a check function with the right signature and pass it to {py:obj}`~ibex_bluesky_core.plans.reflectometry.optimise_axis_against_intensity`:
51
58
52
59
```python
60
+
from lmfit.model import ModelResult
61
+
from math import isclose
62
+
53
63
54
64
defs1vg_checks(result: ModelResult, alignment_param_value: float) -> str|None: # Must take a ModelResult and a float
55
65
"""Check for optimised S1VG value. Returns True if sensible."""
0 commit comments