-
Notifications
You must be signed in to change notification settings - Fork 11
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Document when to make a Device class extend Movable #1031
Comments
@DominicOram @Relm-Arrowny, @callumforrester says this is something you're interested in. |
Definitely think we should document it, possibly upstream in ophyd-async, paging @coretl |
I will gladly accept docs. My opinion is that we should only add a Agree with @DiamondJoseph's position on using primitives rather than dataclass for the set method wherever possible. |
for a 4d Movable like this: class TablePosition(BaseModel):
x: float
y: float
z: float | None = None
theta: float | None = None then how to set the mock correctly? @pytest.fixture
async def table() -> Table:
"""Fixture to set up a mock Table device using DeviceCollector."""
async with DeviceCollector(mock=True):
table = Table(prefix="MIRROR:")
def propagate_status(value: float, *args, **kwargs):
set_mock_value(table.x.user_readback, value.x)
set_mock_value(table.y.user_readback, value.y)
set_mock_value(table.z.user_readback, value.z)
set_mock_value(table.theta.user_readback, value.theta)
callback_on_mock_put(table.x.user_readback, propagate_status)
callback_on_mock_put(table, propagate_status)
callback_on_mock_put(table, propagate_status)
callback_on_mock_put(table, propagate_status)
return table not obvious how to proceed here |
I don't think the backlight is an example of this. What we're trying to solve there is that it's a universal requirement that when you move the backlight out you should turn it off and when you move it in you should turn it on. To the point where if we didn't have this we would inevitably have the first question from the scientist be "I did I think therefore that the usecase for
I actually think the |
I guess abs_set(SR570, SR570GainToCurrentTable.SEN_1) does look crazy and it may work but the intention is for user to do this |
To me this is included in the "limited set of valid positions" sensible set method- there are 2 actually valid positions: (In, On) and (Out, Off). I think for the CurrentAmp we just need to add type hints to the set method so it's clear what's going on: mapping from an allowed set of float |
Taking (what I think is) my summary of this thread in #1030, the docs should say the following:
Anyone has anything else/disagrees with anything let me know! |
using set when a device is a clear vector in physical space - for a composite motor also has an obvious meaning |
Yes, although we are not settled on whether the input in this case should be a TypedDict or dataclass: |
re: is this the right link? it only mentions it twice? from typing import Generic, TypedDict, TypeVar, get_args
class TransformArgument(TypedDict, Generic[SignalDatatypeT]):
pass what aspect is the concern? performance, DX? |
That is correct. Concerns are how nicely it plays with typed and untyped usage. This is on hold at the moment but I thought I would mention it as it seemed relevant. |
Increasingly our new devices are becoming
StandardReadable
s with a structure of signals underneath them- this is good, easy to understand and a vote in favour of the Standardness of StandardReadable.Sometimes, these devices have a few settable fields, and it is tempting to define a set method on the type to allow setting them in one step.
e.g. Backlight, CurrentAmp, BimorphMirror
I think it is useful to document when defining a set method is a value add, and when it is added boilerplate that makes using the device or writing plans for the device more complex without benefit.
I think in the cases where the set method is constructing a dict or dataclass mapping directly to the underlying signals, using this set method requires constructing that dict or dataclass in the plan. If this does not lead to a speedup of the set (e.g. the previously believed behaviour of the Bimorph, that all signals can be set, then the move triggered for an (N-1)fold speedup for N signals), I do not see the value of the set method, but the method must be documented, tested and maintained.
If there is a limited set of valid positions (e.g. captured as an Enum, or a float range) that require several axes in co-ordination, then the set method is useful.
As we move towards using ScanSpec to describe trajectory scans, and those specs are defined in terms of
Movable[float]
s, having plans that are used to accessingabs_set(device.field, 5)
rather thanabs_set(device, {"field": 5})
may make understanding plan flow better?Acceptance Criteria
The text was updated successfully, but these errors were encountered: