feat(csaxs): invert option for BPM and SignalForwarder, enabled for BPM XBox2
CI for csaxs_bec / test (push) Successful in 4m17s
CI for csaxs_bec / test (push) Successful in 4m17s
The XBox2 BPM amplifier outputs a negative current, so more beam showed as more negative blade values. invert: true in the device config negates the input signals; the BPM position/diagonal ratios are unchanged and the intensity becomes positive. Enabled for bpm_xbox2_slowrb. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017NrH3poJsYBCTVq2Y9fuHZ
This commit is contained in:
1 parent
c4a23cc5b6
commit
e9a1b83bc6
4 files changed
+45
-7
No files matched your search
@@ -1163,6 +1163,7 @@ bpm_xbox2_slowrb:
|
||||
right_top_ref: galilrioesxbox.analog_in.ch1
|
||||
right_bot_ref: galilrioesxbox.analog_in.ch2
|
||||
left_bot_ref: galilrioesxbox.analog_in.ch3
|
||||
invert: true # amplifier output is negative; positive values = more beam
|
||||
enabled: true
|
||||
readoutPriority: monitored
|
||||
onFailure: retry
|
||||
|
||||
@@ -7,7 +7,12 @@ from ophyd_devices.utils.bec_processed_signal import BECProcessedSignal
|
||||
|
||||
|
||||
class BPM(PSIPseudoDeviceBase):
|
||||
"""BPM positioner pseudo device."""
|
||||
"""BPM positioner pseudo device.
|
||||
|
||||
invert=True negates the four blade signals, e.g. for an amplifier whose
|
||||
output current is negative. pos_x, pos_y and diagonal are ratios and do
|
||||
not change; intensity changes sign.
|
||||
"""
|
||||
|
||||
# Blade signals, a,b,c,d
|
||||
left_top = Cpt(
|
||||
@@ -76,11 +81,13 @@ class BPM(PSIPseudoDeviceBase):
|
||||
right_top_ref: str,
|
||||
right_bot_ref: str,
|
||||
left_bot_ref: str,
|
||||
invert: bool = False,
|
||||
device_manager=None,
|
||||
scan_info=None,
|
||||
**kwargs,
|
||||
):
|
||||
super().__init__(name=name, device_manager=device_manager, scan_info=scan_info, **kwargs)
|
||||
self._sign = -1 if invert else 1
|
||||
# Get all blade signal objects from utility method
|
||||
signal_t = self.left_top.get_device_object_from_bec(
|
||||
object_name=left_top_ref, signal_name=self.name, device_manager=device_manager
|
||||
@@ -131,7 +138,7 @@ class BPM(PSIPseudoDeviceBase):
|
||||
)
|
||||
|
||||
def _compute_blade_signal(self, signal: Signal) -> float:
|
||||
return signal.get()
|
||||
return self._sign * signal.get()
|
||||
|
||||
def _compute_intensity(
|
||||
self, left_top: Signal, right_top: Signal, right_bot: Signal, left_bot: Signal
|
||||
|
||||
@@ -9,7 +9,7 @@ from ophyd_devices.utils.bec_processed_signal import BECProcessedSignal
|
||||
|
||||
|
||||
class SignalForwarder(PSIPseudoDeviceBase):
|
||||
"""Forward one signal unchanged."""
|
||||
"""Forward one signal unchanged, or negated with invert=True."""
|
||||
|
||||
signal = Cpt(
|
||||
BECProcessedSignal,
|
||||
@@ -20,8 +20,17 @@ class SignalForwarder(PSIPseudoDeviceBase):
|
||||
doc="Forwarded signal",
|
||||
)
|
||||
|
||||
def __init__(self, name, signal_ref: str, device_manager=None, scan_info=None, **kwargs):
|
||||
def __init__(
|
||||
self,
|
||||
name,
|
||||
signal_ref: str,
|
||||
invert: bool = False,
|
||||
device_manager=None,
|
||||
scan_info=None,
|
||||
**kwargs,
|
||||
):
|
||||
super().__init__(name=name, device_manager=device_manager, scan_info=scan_info, **kwargs)
|
||||
self._sign = -1 if invert else 1
|
||||
|
||||
src = self.signal.get_device_object_from_bec(
|
||||
object_name=signal_ref, signal_name=self.name, device_manager=device_manager
|
||||
@@ -30,4 +39,4 @@ class SignalForwarder(PSIPseudoDeviceBase):
|
||||
self.signal.set_compute_method(self._compute_signal, signal=src)
|
||||
|
||||
def _compute_signal(self, signal: Signal) -> float:
|
||||
return signal.get()
|
||||
return self._sign * signal.get()
|
||||
@@ -141,8 +141,9 @@ def patched_dm_bpm(dm_with_devices):
|
||||
return dm
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def bpm(patched_dm_bpm):
|
||||
@pytest.fixture(params=[False])
|
||||
def bpm(request, patched_dm_bpm):
|
||||
invert = request.param
|
||||
name = "bpm"
|
||||
bpm_config = Device(
|
||||
name=name,
|
||||
@@ -165,6 +166,7 @@ def bpm(patched_dm_bpm):
|
||||
right_top_ref="right_top",
|
||||
right_bot_ref="right_bot",
|
||||
left_bot_ref="left_bot",
|
||||
invert=invert,
|
||||
device_manager=patched_dm_bpm,
|
||||
)
|
||||
patched_dm_bpm.devices._add_device(bpm.name, bpm)
|
||||
@@ -239,3 +241,22 @@ def test_bpm_positions(bpm):
|
||||
assert bpm.pos_x.get() == 0
|
||||
assert bpm.pos_y.get() == 0
|
||||
assert bpm.diagonal.get() == 1
|
||||
|
||||
|
||||
@pytest.mark.parametrize("bpm", [True], indirect=True)
|
||||
def test_bpm_invert_negates_blades_keeps_positions(bpm):
|
||||
"""invert=True: negative amplifier currents read as positive blade
|
||||
signals and intensity; the ratio-based positions are unchanged."""
|
||||
devices = bpm.device_manager.devices
|
||||
devices["left_top"].put(-1)
|
||||
devices["right_top"].put(-3)
|
||||
devices["right_bot"].put(-2)
|
||||
devices["left_bot"].put(-2)
|
||||
|
||||
assert bpm.left_top.get() == 1
|
||||
assert bpm.right_top.get() == 3
|
||||
assert bpm.intensity.get() == 8
|
||||
# same ratios as the non-inverted signals would give
|
||||
assert bpm.pos_x.get() == 0.25
|
||||
assert bpm.pos_y.get() == 0
|
||||
assert bpm.diagonal.get() == 0.25
|
||||
Reference in new issue
Block a user