Skip to content

Commit

Permalink
Merge pull request #323 from spc-group/dark_current_shutter
Browse files Browse the repository at this point in the history
Added back the shutter selector to the voltmeters display.
  • Loading branch information
canismarko authored Dec 20, 2024
2 parents 389c4d5 + 15d1e89 commit d40fc30
Show file tree
Hide file tree
Showing 4 changed files with 124 additions and 9 deletions.
2 changes: 1 addition & 1 deletion environment.yml
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ dependencies:
- aioca
- aiokafka
- asynctest
- apsbss
- apsbss < 2.0
- time-machine
- rich
- autoapi
Expand Down
74 changes: 71 additions & 3 deletions src/firefly/tests/test_voltmeters.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
import asyncio

import pytest
from bluesky_queueserver_api import BPlan
from ophyd_async.core import Device
from pydm import widgets as PyDMWidgets
from pydm.widgets.analog_indicator import PyDMAnalogIndicator
from qtpy import QtWidgets
Expand Down Expand Up @@ -28,6 +31,19 @@ async def ion_chambers(sim_registry):
return devices


@pytest.fixture()
async def shutters(sim_registry):
front_end_shutter = Device(name="front_end_shutter")
front_end_shutter.allow_close = False
endstation_shutter = Device(name="endstation_shutter")
shutters = [front_end_shutter, endstation_shutter]
await asyncio.gather(*[d.connect(mock=True) for d in shutters])
for shutter in shutters:
shutter._ophyd_labels_ = {"shutters"}
sim_registry.register(shutter)
return shutters


@pytest.fixture()
async def voltmeters_display(qtbot, ion_chambers, sim_registry):
vms_display = VoltmetersDisplay()
Expand Down Expand Up @@ -151,14 +167,66 @@ def check_item(item):
display.ui.auto_gain_button.click()


async def test_shutters_checkbox_no_shutters(voltmeters_display, sim_registry):
display = voltmeters_display
combobox = display.ui.shutter_combobox
checkbox = display.ui.shutter_checkbox
checkbox.setChecked(True)
# Update the state of the UI with no shutters
await display.update_devices(sim_registry)
# Ensure checkbox has been disabled
assert not checkbox.isEnabled()
assert not checkbox.checkState()
assert not display.ui.shutter_checkbox.setChecked(True)
combobox_items = [combobox.itemText(idx) for idx in range(combobox.count())]
assert len(combobox_items) == 0


async def test_shutters_checkbox_with_shutters(
voltmeters_display,
sim_registry,
shutters,
):
display = voltmeters_display
checkbox = display.ui.shutter_checkbox
combobox = display.ui.shutter_combobox
# Update the state of the UI with no shutters
await display.update_devices(sim_registry)
# Ensure checkbox has been enabled
assert checkbox.isEnabled()
# Check that shutters were added to the combobox
combobox_items = [combobox.itemText(idx) for idx in range(combobox.count())]
assert "front_end_shutter" not in combobox_items
assert "endstation_shutter" in combobox_items


@pytest.mark.asyncio
async def test_read_dark_current_plan(voltmeters_display, qtbot):
display = voltmeters_display
display.ui.shutter_checkbox.setChecked(False)
# Check that the correct plan was sent
expected_item = BPlan("record_dark_current", ["I0", "It"])

def check_item(item):
return item.to_dict() == expected_item.to_dict()

# Click the run button and see if the plan is queued
with qtbot.waitSignal(
display.queue_item_submitted, timeout=1000, check_params_cb=check_item
):
# Simulate clicking on the dark_current button
# display.ui.dark_current_button.click()
display.ui.record_dark_current()


@pytest.mark.asyncio
async def test_read_dark_current_plan_with_shutters(voltmeters_display, qtbot):
display = voltmeters_display
display.ui.shutter_checkbox.setChecked(True)
display.ui.shutter_combobox.setCurrentIndex(1)
# Check that the correct plan was sent
expected_item = BPlan(
"record_dark_current", ["I0", "It"], shutters=["experiment_shutter"]
)
shutter_name = display.ui.shutter_combobox.itemText(1)
expected_item = BPlan("record_dark_current", ["I0", "It"], shutters=[shutter_name])

def check_item(item):
return item.to_dict() == expected_item.to_dict()
Expand Down
29 changes: 26 additions & 3 deletions src/firefly/voltmeters.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,28 @@ async def update_devices(self, registry):
# Connect the details button signal
details_slot = partial(self.details_window_requested.emit, ic.name)
row.details_button.clicked.connect(details_slot)
# Remove old shutters from the combobox
for idx in range(self.ui.shutter_combobox.count()):
self.ui.shutter_combobox.removeItem(idx)

# Decide which shutters we should show (only those that can be opened/closed)
def is_controllable(shtr):
can_open = getattr(shtr, "allow_open", True)
can_close = getattr(shtr, "allow_close", True)
return can_open and can_close

shutters = registry.findall("shutters", allow_none=True)
shutters = [shtr for shtr in shutters if is_controllable(shtr)]
has_shutters = bool(len(shutters))
# Add the shutters to the shutter combobox
if has_shutters:
self.ui.shutter_checkbox.setEnabled(True)
for shutter in shutters:
self.ui.shutter_combobox.addItem(shutter.name)
else:
log.warning("No shutters found, disabling checkbox.")
self.ui.shutter_checkbox.setEnabled(False)
self.ui.shutter_checkbox.setCheckState(False)

def update_queue_status(self, status):
super().update_queue_status(status)
Expand Down Expand Up @@ -104,12 +126,13 @@ def record_dark_current(self):
"""
# Determine which shutters to close
shutters = []
kwargs = {}
if self.ui.shutter_checkbox.isChecked():
shutters.append("experiment_shutter")
shutter_name = self.ui.shutter_combobox.currentText()
kwargs["shutters"] = [shutter_name]
# Construct the plan
ic_names = [ic.name for ic in self.ion_chambers]
item = BPlan("record_dark_current", ic_names, shutters=shutters)
item = BPlan("record_dark_current", ic_names, **kwargs)
# Send it to the queue server
self.queue_item_submitted.emit(item)

Expand Down
28 changes: 26 additions & 2 deletions src/firefly/voltmeters.ui
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@
<item>
<widget class="QCheckBox" name="shutter_checkbox">
<property name="enabled">
<bool>false</bool>
<bool>true</bool>
</property>
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Close the experimental experimental hutch shutter prior to recording dark current. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;This feature is disabled pending availability of shutter controls.&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
Expand All @@ -103,6 +103,13 @@
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="shutter_combobox">
<property name="enabled">
<bool>false</bool>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
Expand Down Expand Up @@ -224,5 +231,22 @@
</customwidget>
</customwidgets>
<resources/>
<connections/>
<connections>
<connection>
<sender>shutter_checkbox</sender>
<signal>toggled(bool)</signal>
<receiver>shutter_combobox</receiver>
<slot>setEnabled(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>157</x>
<y>53</y>
</hint>
<hint type="destinationlabel">
<x>249</x>
<y>53</y>
</hint>
</hints>
</connection>
</connections>
</ui>

0 comments on commit d40fc30

Please sign in to comment.