-
Notifications
You must be signed in to change notification settings - Fork 12
Create beamsize devices #1704
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
base: main
Are you sure you want to change the base?
Create beamsize devices #1704
Conversation
a645d65 to
76f53b0
Compare
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #1704 +/- ##
========================================
Coverage 99.07% 99.08%
========================================
Files 271 278 +7
Lines 9971 10140 +169
========================================
+ Hits 9879 10047 +168
- Misses 92 93 +1 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
src/dodal/devices/i03/beamsize.py
Outdated
|
|
||
|
|
||
| class Beamsize(BeamsizeBase): | ||
| def __init__(self, aperture_scatterguard: ApertureScatterguard, name="beamsize"): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it better to add a name when you instantiate the device and leave this as name=""?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I think leave it as "" default
9b06c0e to
28f718c
Compare
28f718c to
2a57c7b
Compare
DominicOram
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great, thanks. This works (mostly) but I wonder if we could make something more generic where the Beamsize takes a list of signals/constants and just finds the minimum e.g. something like:
class Beamsize(BeamsizeBase):
def __init__(
self,
x_signals:list[SignalR|float],
y_signals:list[SignalR|float],
):
super().__init__(name=name)
self.x_um = derived_signal_r(
self._get_beamsize_x,
x_signals=x_signals,
derived_units="µm",
)
self.y_um = derived_signal_r(
self._get_beamsize_y,
y_signals=y_signals,
derived_units="µm",
)
def _get_beamsize_x(
self,
x_signals: list[float],
) -> float:
return min(*x_signals)
def _get_beamsize_y(
self,
y_signals: list[float],
) -> float:
return min(*y_signals)This won't work exactly like that because derived_signal won't play nice with lists of signals, especially where one of those things might not be a signal but a constant. We could maybe get round the constant thing by making a dummy soft signal that just has the constant value though. I think it's worth playing with this though and if it isn't obvious maybe asking in #ophy-async how it would be done
src/dodal/beamlines/i03.py
Outdated
|
|
||
| @device_factory() | ||
| def beamsize() -> Beamsize: | ||
| """Get the i03 beamstop device, instantiate it if it hasn't already been. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should:
| """Get the i03 beamstop device, instantiate it if it hasn't already been. | |
| """Get the i03 beamsize device, instantiate it if it hasn't already been. |
These comments are kind of rubbish anyway but let's make them correct rubbish
src/dodal/beamlines/i04.py
Outdated
|
|
||
| @device_factory() | ||
| def beamsize() -> Beamsize: | ||
| """Get the i03 beamstop device, instantiate it if it hasn't already been. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should: As above
| """Get the i03 beamstop device, instantiate it if it hasn't already been. | |
| """Get the i03 beamsize device, instantiate it if it hasn't already been. |
src/dodal/beamlines/i04.py
Outdated
|
|
||
| @device_factory() | ||
| def beamsize() -> Beamsize: | ||
| """Get the i04 beamstop device, instantiate it if it hasn't already been. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should: As above
| """Get the i04 beamstop device, instantiate it if it hasn't already been. | |
| """Get the i04 beamsize device, instantiate it if it hasn't already been. |
src/dodal/devices/i03/beamsize.py
Outdated
|
|
||
|
|
||
| class Beamsize(BeamsizeBase): | ||
| def __init__(self, aperture_scatterguard: ApertureScatterguard, name="beamsize"): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I think leave it as "" default
| def __init__(self, name="beamsize"): | ||
| super().__init__(name=name) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could: I think we can just remove the constructor all together and it will pass the value through.
|
|
||
| self.x_um = derived_signal_r( | ||
| self._get_beamsize_x, | ||
| aperture_radius=self._aperture_scatterguard_ref().radius, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's only in reading this that I've realised that this isn't the radius at all, it's the diameter. Would you be able to write an issue to fix it in the ApertureScattergaurd and downstream?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah that completely went over my head too lol
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| (ApertureValue.PARKED, (0, 0, 0), (0.0, 0.0)), | ||
| ], | ||
| ) | ||
| async def test_beamsize_gives_min_of_aperture_and_beam_width_and_height( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should: I think this is testing more of the internal logic of the aperture than you need. You should be able to just do set_mock_value(aperture.radius, 10) then test that value is used. Tests that selecting specific apertures changes the radius should already exist in other places. If you can't do this because you can't do set_mock_value on a derived signal then we should make an ophyd_async issue and instead do ap_sg.aperture._get_current_radius = MagicMock(return_value=10)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah I tried that initially but it doesn't work with derived signals. I'll raise an issue and mock _get_current_radius for now.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| (ApertureValue.PARKED, (0, 0, 0), (120.0, 120.0), (0.0, 0.0)), | ||
| ], | ||
| ) | ||
| async def test_beamsize_gives_min_of_aperture_and_transfocator_width_and_height( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should: As on the other test re internal device logic
tests/devices/i03/test_beamsize.py
Outdated
| (ApertureValue.OUT_OF_BEAM, (0, 0, 0), (0.0, 0.0)), | ||
| (ApertureValue.PARKED, (0, 0, 0), (0.0, 0.0)), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Must: I think the logic here is actually wrong. When we're out of the beam there is no aperture so the beamsize should be the default value. I think a good solution to this is to change the aperture device so that it's radius at these positions is infinite
| x_um: SignalR[float] | ||
| y_um: SignalR[float] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should: These should be hinted as Format.HINTED_SIGNAL. This will mean that they will get read when you read the whole device.
https://blueskyproject.io/ophyd-async/main/how-to/derive-one-signal-from-others.html#multi-derived-signal might let you do it. Needs some investigation |
0146f69 to
a58c05d
Compare
Fixes DiamondLightSource/mx-bluesky#1424
Required by DiamondLightSource/mx-bluesky#1445
Adds
beamsizedevices for i03 and i04 so that the beamsize be read correctly in both cases, using thetransfocatorfor i04 and theaperturefor i03.Instructions to reviewer on how to test:
Checks for reviewer
dodal connect ${BEAMLINE}