diff --git a/docs/source/upcoming_release_notes/1216-Fixing_Tpr_Bug_For_MultiDerivedSignals.rst b/docs/source/upcoming_release_notes/1216-Fixing_Tpr_Bug_For_MultiDerivedSignals.rst new file mode 100644 index 00000000000..10137bf0744 --- /dev/null +++ b/docs/source/upcoming_release_notes/1216-Fixing_Tpr_Bug_For_MultiDerivedSignals.rst @@ -0,0 +1,33 @@ +1216 Fixing_Tpr_Bug_For_MultiDerivedSignals +################# + +API Breaks +---------- +- N/A + +Features +-------- +- N/A + +Device Updates +-------------- +- N/A + +New Devices +----------- +- N/A + +Bugfixes +-------- +- Previously, calculate_on_get/put functions used in MultiDerivedSignals in tpr classes were not accessing + their attrs correctly and would throw KeyErrors when called +- Specifically, the name of the attr was being used as the key for items dictionary instead of the actual signal object +- Also added unit tests for these MultiDerivedSignals + +Maintenance +----------- +- N/A + +Contributors +------------ +- KaushikMalapati diff --git a/pcdsdevices/tests/test_tpr.py b/pcdsdevices/tests/test_tpr.py index 4d87931cc3d..fd655bda99d 100644 --- a/pcdsdevices/tests/test_tpr.py +++ b/pcdsdevices/tests/test_tpr.py @@ -1,7 +1,7 @@ import pytest from ophyd.sim import make_fake_device -from ..tpr import TimingMode, TprTrigger +from ..tpr import TPR_TAP_NS, TPR_TICK_NS, TimingMode, TprTrigger @pytest.fixture(scope='function') @@ -22,3 +22,32 @@ def test_enable(fake_trigger): @pytest.mark.timeout(5) def test_disconnected_trigger(): TprTrigger('TST', channel=1, timing_mode=TimingMode.LCLS1, name='test') + + +def put_equals_setpoint(mds, setpoint, ns_time): + status = mds.put(ns_time) + status.wait() + return setpoint.get() == ns_time + + +def mds_get(mds, tick_signal, tap_signal, num_ticks, num_taps): + tick_signal.put(num_ticks) + tap_signal.put(num_taps) + return mds.get() == (TPR_TICK_NS * num_ticks + TPR_TAP_NS * num_taps) + + +@pytest.mark.timeout(5) +def test_ns_delay(fake_trigger): + assert put_equals_setpoint(fake_trigger.ns_delay, fake_trigger.delay_setpoint, 100) + assert mds_get(fake_trigger.ns_delay, fake_trigger.delay_ticks, fake_trigger.delay_taps, 0, 7) + + +@pytest.mark.timeout(5) +def test_width(fake_trigger): + assert put_equals_setpoint(fake_trigger.width, fake_trigger.width_setpoint, 100) + assert fake_trigger.width.get() == fake_trigger.width_ticks.get() * TPR_TICK_NS + + +def test_motor(fake_trigger): + assert mds_get(fake_trigger.ns_delay_scan.readback, fake_trigger.ns_delay_scan.delay_ticks, + fake_trigger.ns_delay_scan.delay_taps, 3, 3) diff --git a/pcdsdevices/tpr.py b/pcdsdevices/tpr.py index 9caa5e2c6ea..326ee911326 100644 --- a/pcdsdevices/tpr.py +++ b/pcdsdevices/tpr.py @@ -21,17 +21,17 @@ class TimingMode(Enum): def _get_delay(mds: MultiDerivedSignal, items: SignalToValue) -> float: """Calculates delay in ns from ticks and taps""" - return items[mds.attrs[0]] * TPR_TICK_NS + items[mds.attrs[1] * TPR_TAP_NS] + return items[mds.signals[0]] * TPR_TICK_NS + items[mds.signals[1]] * TPR_TAP_NS def _get_width(mds: MultiDerivedSignal, items: SignalToValue) -> float: """Calculates width in ns from ticks""" - return items[mds.attrs[0]] * TPR_TICK_NS + return items[mds.signals[0]] * TPR_TICK_NS def _put_last(mds: MultiDerivedSignal, value: float) -> SignalToValue: """Only writes value to last attr""" - return {mds.attrs[-1]: value} + return {mds.signals[-1]: value} class TprMotor(PVPositionerIsClose):