Skip to content
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

Fmx setenergy UI changes and cleanup #369

Merged
merged 19 commits into from
Apr 29, 2024
Merged
Show file tree
Hide file tree
Changes from 15 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions config_params.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
# GUI default configuration
BEAM_CHECK = "beamCheck"
UNMOUNT_COLD_CHECK = "unmountColdCheck"
SET_ENERGY_CHECK = "setEnergyCheck"


# raster request status updates
Expand Down
9 changes: 9 additions & 0 deletions daq_macros.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
import bluesky.plans as bp
from bluesky.preprocessors import finalize_wrapper
from fmx_annealer import govStatusGet, govStateSet, fmxAnnealer, amxAnnealer # for using annealer specific to FMX and AMX
from setenergy_lsdc import setELsdc

try:
import ispybLib
Expand Down Expand Up @@ -85,6 +86,14 @@ def abortBS():
RE.abort()
except super_state_machine.errors.TransitionError:
logger.error("caught BS")

def set_energy(energy):
try:
daq_lib.set_field("program_state","Setting Energy")
RE(setELsdc(energy))
except Exception as e:
logger.error(f"Exception while running set_energy: {e}")
daq_lib.set_field("program_state","Program Ready")

def move_omega(omega, relative=True):
"""Moves omega by a certain amount"""
Expand Down
39 changes: 32 additions & 7 deletions gui/control_main.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
RASTER_GUI_XREC_FILL_DELAY,
SAMPLE_TIMER_DELAY,
SERVER_CHECK_DELAY,
SET_ENERGY_CHECK,
VALID_DET_DIST,
VALID_EXP_TIMES,
VALID_TOTAL_EXP_TIMES,
Expand All @@ -47,6 +48,7 @@
PuckDialog,
RasterExploreDialog,
ScreenDefaultsDialog,
SetEnergyDialog,
SnapCommentDialog,
StaffScreenDialog,
UserScreenDialog,
Expand Down Expand Up @@ -561,13 +563,20 @@ def createSampleTab(self):
)
self.energy_ledit = self.energyMoveLedit.getEntry()
self.energy_ledit.setValidator(QtGui.QDoubleValidator())
self.energy_ledit.returnPressed.connect(self.moveEnergyCB)
self.energy_ledit.returnPressed.connect(self.moveEnergy10eVCB)
moveEnergyButton = QtWidgets.QPushButton("Move Energy")
moveEnergyButton.clicked.connect(self.moveEnergyCB)
hBoxColParams3.addWidget(colEnergyLabel)
hBoxColParams3.addWidget(self.energyReadback)
hBoxColParams3.addWidget(energySPLabel)
hBoxColParams3.addWidget(self.energy_ledit)
if daq_utils.beamline == "fmx":
if getBlConfig(SET_ENERGY_CHECK):
hBoxColParams3.addWidget(moveEnergyButton)
else:
hBoxColParams3.addWidget(self.energy_ledit)
else:
hBoxColParams3.addWidget(self.energy_ledit)

hBoxColParams22.addWidget(colTransmissionLabel)
hBoxColParams22.addWidget(self.transmissionReadback_ledit)
hBoxColParams22.addWidget(transmisionSPLabel)
Expand Down Expand Up @@ -2693,13 +2702,24 @@ def moveOmegaCB(self):
{"relative": False}
)

def moveEnergyCB(self):
def moveEnergy10eVCB(self):
JunAishima marked this conversation as resolved.
Show resolved Hide resolved
energyRequest = float(str(self.energy_ledit.text()))
if abs(energyRequest - self.energy_pv.get()) > 10.0:
self.popupServerMessage("Energy change must be less than 10 ev")
return
if self.controlEnabled():
if abs(energyRequest - self.energy_pv.get()) > 10.0:
self.popupServerMessage("Energy change must be less than 10 ev")
JunAishima marked this conversation as resolved.
Show resolved Hide resolved
return
else:
self.send_to_server("mvaDescriptor", ["energy", float(self.energy_ledit.text())])
comm_s = 'mvaDescriptor("energy",' + str(self.energy_ledit.text()) + ")"
JunAishima marked this conversation as resolved.
Show resolved Hide resolved
logger.info(comm_s)
else:
self.send_to_server("mvaDescriptor", ["energy", float(self.energy_ledit.text())])
self.popupServerMessage("You don't have control")

def moveEnergyCB(self):
if self.controlEnabled():
set_energy = SetEnergyDialog(parent=self)
else:
self.popupServerMessage("You don't have control")

def setLifetimeCB(self, lifetime):
if hasattr(self, "sampleLifetimeReadback_ledit"):
Expand Down Expand Up @@ -5152,6 +5172,11 @@ def printServerMessage(self, message_s):
print(message_s)

def colorProgramState(self, programState_s):
if programState_s == "Setting Energy":
self.setEnabled(False)
else:
self.setEnabled(True)

if programState_s.find("Ready") == -1:
self.statusLabel.setColor("yellow")
else:
Expand Down
1 change: 1 addition & 0 deletions gui/dialog/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@
from .puck_dialog import PuckDialog
from .dewar import DewarDialog
from .screen_defaults import ScreenDefaultsDialog
from .set_energy import SetEnergyDialog
138 changes: 138 additions & 0 deletions gui/dialog/set_energy.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
import logging
import typing

from ophyd import Component as Cpt
from ophyd import Device, EpicsMotor
from qtpy import QtCore, QtGui, QtWidgets
from qtpy.QtCore import Qt

import daq_utils
import db_lib

if typing.TYPE_CHECKING:
from lsdcGui import ControlMain

logger = logging.getLogger()


class DCM(Device):
JunAishima marked this conversation as resolved.
Show resolved Hide resolved
b = Cpt(EpicsMotor, "-Ax:B}Mtr", labels=["fmx"])
g = Cpt(EpicsMotor, "-Ax:G}Mtr", labels=["fmx"])
p = Cpt(EpicsMotor, "-Ax:P}Mtr", labels=["fmx"])
r = Cpt(EpicsMotor, "-Ax:R}Mtr", labels=["fmx"])
e = Cpt(EpicsMotor, "-Ax:E}Mtr", labels=["fmx"])


class SetEnergyDialog(QtWidgets.QDialog):
energy_changed_signal = QtCore.Signal(object)

def __init__(self, parent: "ControlMain"):
self.hdcm = DCM("XF:17IDA-OP:FMX{Mono:DCM", name="hdcm")
super().__init__(parent)
self._parent = parent
self.initUI()

def initUI(self):
layout = QtWidgets.QGridLayout()
self.current_energy_label = QtWidgets.QLabel("Current Energy: ")
self.current_energy_value_label = QtWidgets.QLabel(
f"{self.hdcm.e.user_readback.get():.2f} eV"
)
layout.addWidget(self.current_energy_label, 0, 0)
layout.addWidget(self.current_energy_value_label, 0, 1)

self.setpoint_label = QtWidgets.QLabel("Energy setpoint: ")
validator = QtGui.QDoubleValidator()
validator.setBottom(5000)
validator.setTop(15000)
self.setpoint_edit = QtWidgets.QLineEdit()
self.setpoint_edit.setValidator(validator)
self.setpoint_edit.returnPressed.connect(self.check_value)
layout.addWidget(self.setpoint_label, 1, 0)
layout.addWidget(self.setpoint_edit, 1, 1)

self.message = QtWidgets.QLabel("")
layout.addWidget(self.message, 2, 0, 1, 2)

self.monochromator_button = QtWidgets.QPushButton("Monochromator")
self.monochromator_button.setAutoDefault(False)
self.monochromator_button.clicked.connect(self.set_monochromator_energy)

self.full_alignment_button = QtWidgets.QPushButton("Full Alignment")
self.full_alignment_button.setAutoDefault(False)
self.full_alignment_button.clicked.connect(self.set_full_alignment_energy)

self.close_button = QtWidgets.QPushButton("Close")
self.close_button.clicked.connect(self.close)
self.close_button.setAutoDefault(False)

layout.addWidget(self.monochromator_button, 3, 0)
layout.addWidget(self.full_alignment_button, 3, 1)
layout.addWidget(self.close_button, 4, 0, 1, 2)

self.hdcm.e.user_readback.subscribe(self.update_energy, run=True)

self.energy_changed_signal.connect(
lambda value: self.current_energy_value_label.setText(f"{value:.2f}")
)

self.setLayout(layout)
self.setModal(True)
self.show()

def update_energy(self, value, old_value, **kwargs):
self.energy_changed_signal.emit(value)

def check_value(self):
if abs(float(self.setpoint_edit.text()) - self.hdcm.e.user_readback.get()) > 10:
self.message.setText(
"Energy change is greater than 10 eV.\nMonochromator cannot be used for alignment"
)
self.monochromator_button.setDisabled(True)
else:
self.message.setText("Energy change less than 10 eV")
self.monochromator_button.setDisabled(False)

if float(self.setpoint_edit.text()) <= 10000:
self.message.setText(
f"{self.message.text()} \n Beam shape not automatically optimized \nfor energies between 5 keV and 10 keV"
)

def unmount_cold_dialog(self):
msg_box = QtWidgets.QMessageBox()
msg_box.setText("A sample is mounted. Unmount cold?")
msg_box.setStandardButtons(QtWidgets.QMessageBox.StandardButton.Ok | QtWidgets.QMessageBox.StandardButton.Cancel) # type: ignore
msg_box.setDefaultButton(QtWidgets.QMessageBox.StandardButton.Ok)
return msg_box

def set_full_alignment_energy(self):
if self._parent.mountedPin_pv.get():
# If sample is mounted, ask user to unmount cold
response = self.unmount_cold_dialog().exec_()

if response == QtWidgets.QMessageBox.Ok:
self._parent.send_to_server("unmountCold")
else:
return

if self._parent.governorMessage.getEntry().text() not in [
"state SE",
JunAishima marked this conversation as resolved.
Show resolved Hide resolved
"state BA",
"state BL",
"state XF",
"state SA",
]:
self.message.setText("Governor not in a valid state, call staff!")
return
else:
self._parent.send_to_server("setGovState", ['SA'])

self._parent.send_to_server(f"set_energy", [float(self.setpoint_edit.text())])
JunAishima marked this conversation as resolved.
Show resolved Hide resolved

def set_monochromator_energy(self):
if abs(float(self.setpoint_edit.text()) - self.hdcm.e.user_readback.get()) > 10:
self.message.setText(
"Energy change is greater than 10 eV.\nMonochromator cannot be used for alignment"
)
else:
self._parent.send_to_server("mvaDescriptor", ["energy", float(self.setpoint_edit.text())])
32 changes: 30 additions & 2 deletions gui/dialog/staff_screen.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,14 @@
from qtpy import QtCore, QtWidgets
from qtpy.QtWidgets import QCheckBox

from config_params import BEAM_CHECK, TOP_VIEW_CHECK, UNMOUNT_COLD_CHECK
from config_params import (
BEAM_CHECK,
SET_ENERGY_CHECK,
TOP_VIEW_CHECK,
UNMOUNT_COLD_CHECK,
)
from daq_utils import getBlConfig, setBlConfig
import db_lib
import daq_utils

if typing.TYPE_CHECKING:
from lsdcGui import ControlMain
Expand Down Expand Up @@ -65,6 +70,17 @@ def __init__(self, parent: "ControlMain", **kwargs):
self.gripperUnmountColdCheckBox.setEnabled(False)
self.gripperUnmountColdCheckBox.setChecked(False)

# Set energy checkbox
if daq_utils.beamline == "fmx":
self.set_energy_checkbox = QCheckBox("Set Energy")
hBoxColParams1.addWidget(self.set_energy_checkbox)
if getBlConfig(SET_ENERGY_CHECK) == 1:
self.set_energy_checkbox.setChecked(True)
else:
self.set_energy_checkbox.setChecked(False)
self.set_energy_checkbox.stateChanged.connect(self.set_energy_check_cb)


self.queueCollectOnCheckBox = QCheckBox("Queue Collect")
hBoxColParams1.addWidget(self.queueCollectOnCheckBox)
self.checkQueueCollect()
Expand Down Expand Up @@ -297,6 +313,18 @@ def beamCheckOnCheckCB(self, state):
setBlConfig(BEAM_CHECK, 0)
logger.debug(f"{BEAM_CHECK} off")

def set_energy_check_cb(self, state):
if state == QtCore.Qt.Checked:
setBlConfig(SET_ENERGY_CHECK, 1)
logger.debug(f"{SET_ENERGY_CHECK} on")
else:
setBlConfig(SET_ENERGY_CHECK, 0)
logger.debug(f"{SET_ENERGY_CHECK} off")
msg_box = QtWidgets.QMessageBox()
msg_box.setText("Set Energy state changed, please restart the GUI to access feature")
msg_box.setStandardButtons(QtWidgets.QMessageBox.StandardButton.Ok) # type: ignore
msg_box.setDefaultButton(QtWidgets.QMessageBox.StandardButton.Ok)

def unmountColdCheckCB(self, state):
if state == QtCore.Qt.Checked:
logger.info("unmountColdCheckCB On")
Expand Down
Loading