Skip to content

Commit

Permalink
Merge pull request #396 from vshekar/mounting-status-indicator
Browse files Browse the repository at this point in the history
Added mounting status indicator with Enum
  • Loading branch information
vshekar authored Oct 30, 2024
2 parents d71d41f + 6ddb04e commit 910c10e
Show file tree
Hide file tree
Showing 5 changed files with 91 additions and 26 deletions.
21 changes: 21 additions & 0 deletions config_params.py
Original file line number Diff line number Diff line change
Expand Up @@ -134,4 +134,25 @@ class OnMountAvailOptions(Enum):
"S": ["V0", "H0"],
"L": ["V1", "H1"]
}


class MountState(Enum):
CURRENTLY_MOUNTING = "cm"
FAILED_MOUNTING = "fm"
MOUNTED = "m"
CURRENTLY_UNMOUNTING = "cu"
FAILED_UNMOUNTING = "fu"

@classmethod
def get_text(cls, enum_value):
text_values = {
cls.CURRENTLY_MOUNTING: "\n(Currently Mounting)",
cls.FAILED_MOUNTING: "\n(Failed Mounting)",
cls.MOUNTED: "\n(Mounted)",
cls.CURRENTLY_UNMOUNTING: "\n(Currently Unmounting)",
cls.FAILED_UNMOUNTING: "\n(Failed Unmounting)"
}
return text_values.get(enum_value, "\n(Unknown State)")

OPHYD_COLLECTIONS = {"amx": False, "fmx": False, "nyx": True}

65 changes: 44 additions & 21 deletions daq_lib.py
Original file line number Diff line number Diff line change
Expand Up @@ -261,19 +261,21 @@ def mountSample(sampID):
if (sampID!=currentMountedSampleID):
puckPos = mountedSampleDict["puckPos"]
pinPos = mountedSampleDict["pinPos"]
# Set status as currently unmounting
set_mounted_pin_data(currentMountedSampleID, mount_state=MountState.CURRENTLY_UNMOUNTING.value)
if robot_lib.unmountRobotSample(gov_robot, puckPos,pinPos,currentMountedSampleID):
db_lib.deleteCompletedRequestsforSample(currentMountedSampleID)
set_field("mounted_pin","")
db_lib.beamlineInfo(daq_utils.beamline, 'mountedSample', info_dict={'puckPos':0,'pinPos':0,'sampleID':""})
(puckPos,pinPos,puckID) = db_lib.getCoordsfromSampleID(daq_utils.beamline,sampID)
if (warmUpNeeded):
gui_message("Warming gripper. Please stand by.")
mountCounter = 0
# About to mount next sample
set_mounted_pin_data(sampID, mount_state=MountState.CURRENTLY_MOUNTING.value, sample_pos={'puckPos':puckPos,'pinPos':pinPos})
mountStat = robot_lib.mountRobotSample(gov_robot, puckPos,pinPos,sampID,init=0,warmup=warmUpNeeded)
if (warmUpNeeded):
destroy_gui_message()
if (mountStat == 1):
set_field("mounted_pin",sampID)
if (mountStat == MOUNT_SUCCESSFUL):
set_mounted_pin_data(sampID, sample_pos={'puckPos':puckPos,'pinPos':pinPos})
detDist = beamline_lib.motorPosFromDescriptor("detectorDist")
if (detDist != saveDetDist):
if (getBlConfig("HePath") == 0):
Expand All @@ -282,36 +284,52 @@ def mountSample(sampID):
# Only run mount options when the robot is online and queue collect is off
daq_macros.run_on_mount_option(sampID)
gov_status = gov_lib.setGovRobot(gov_robot, 'SA')
elif(mountStat == 2):
return 2
elif(mountStat == MOUNT_UNRECOVERABLE_ERROR):
clearMountedSample()
return MOUNT_UNRECOVERABLE_ERROR
else:
return 0
clearMountedSample()
return MOUNT_FAILURE
else:
return 0
set_mounted_pin_data(currentMountedSampleID, mount_state=MountState.FAILED_UNMOUNTING.value)
return UNMOUNT_FAILURE
else: #desired sample is mounted, nothing to do
return 1
return MOUNT_SUCCESSFUL
else: #nothing mounted
(puckPos,pinPos,puckID) = db_lib.getCoordsfromSampleID(daq_utils.beamline,sampID)
set_mounted_pin_data(sampID, mount_state=MountState.CURRENTLY_MOUNTING.value, sample_pos={'puckPos':puckPos,'pinPos':pinPos})
mountStat = robot_lib.mountRobotSample(gov_robot, puckPos,pinPos,sampID,init=1)
if (mountStat == 1):
set_field("mounted_pin",sampID)
if (mountStat == MOUNT_SUCCESSFUL):
set_mounted_pin_data(sampID, sample_pos={'puckPos':puckPos,'pinPos':pinPos})
if getBlConfig('robot_online') and getBlConfig("queueCollect") == 0:
# Only run mount options when the robot is online and queue collect is off
daq_macros.run_on_mount_option(sampID)
gov_status = gov_lib.setGovRobot(gov_robot, 'SA')
elif(mountStat == 2):
return 2
elif(mountStat == MOUNT_UNRECOVERABLE_ERROR):
clearMountedSample()
return MOUNT_UNRECOVERABLE_ERROR
else:
return 0
db_lib.beamlineInfo(daq_utils.beamline, 'mountedSample', info_dict={'puckPos':puckPos,'pinPos':pinPos,'sampleID':sampID})
return 1
clearMountedSample()
return MOUNT_FAILURE
return MOUNT_SUCCESSFUL


def clearMountedSample():
set_field("mounted_pin","")
db_lib.beamlineInfo(daq_utils.beamline, 'mountedSample', info_dict={'puckPos':0,'pinPos':0,'sampleID':""})


def set_mounted_pin_data(sample_id, mount_state=MountState.MOUNTED.value, sample_pos=None):
current_pin_data = f"{sample_id},{mount_state}"
logger.info(f"current pin data = {current_pin_data}")
set_field("mounted_pin", current_pin_data)

if sample_pos:
info_dict = { 'puckPos' : sample_pos["puckPos"],
'pinPos' : sample_pos["pinPos"],
'sampleID': sample_id }
db_lib.beamlineInfo(daq_utils.beamline, 'mountedSample', info_dict=info_dict)

def unmountSample():
global mountCounter

Expand All @@ -322,13 +340,15 @@ def unmountSample():
if (currentMountedSampleID != ""):
puckPos = mountedSampleDict["puckPos"]
pinPos = mountedSampleDict["pinPos"]
# Set status as currently unmounting
set_mounted_pin_data(currentMountedSampleID, mount_state=MountState.CURRENTLY_UNMOUNTING.value)
if robot_lib.unmountRobotSample(gov_robot, puckPos,pinPos,currentMountedSampleID):
db_lib.deleteCompletedRequestsforSample(currentMountedSampleID)
robot_lib.finish()
set_field("mounted_pin","")
db_lib.beamlineInfo(daq_utils.beamline, 'mountedSample', info_dict={'puckPos':0,'pinPos':0,'sampleID':""})
clearMountedSample()
return 1
else:
set_mounted_pin_data(currentMountedSampleID, mount_state=MountState.FAILED_UNMOUNTING.value)
return 0

def unmountCold():
Expand All @@ -337,14 +357,17 @@ def unmountCold():
if (currentMountedSampleID != ""):
puckPos = mountedSampleDict["puckPos"]
pinPos = mountedSampleDict["pinPos"]
# Set status as currently unmounting
set_mounted_pin_data(currentMountedSampleID, mount_state=MountState.CURRENTLY_UNMOUNTING.value)
if robot_lib.unmountRobotSample(gov_robot, puckPos,pinPos,currentMountedSampleID):
db_lib.deleteCompletedRequestsforSample(currentMountedSampleID)
robot_lib.parkGripper()
set_field("mounted_pin","")
db_lib.beamlineInfo(daq_utils.beamline, 'mountedSample', info_dict={'puckPos':0,'pinPos':0,'sampleID':""})
if getBlConfig("robot_online"):
robot_lib.parkGripper()
clearMountedSample()
setPvDesc("robotGovActive",1)
return 1
else:
set_mounted_pin_data(currentMountedSampleID, mount_state=MountState.FAILED_UNMOUNTING.value)
return 0

def waitBeam():
Expand Down
4 changes: 2 additions & 2 deletions gui/control_main.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@
from gui.vector import VectorMarker, VectorWidget
from QPeriodicTable import QPeriodicTable
from threads import RaddoseThread, ServerCheckThread, VideoThread
from utils import validation
from utils import validation, custom_pv

logger = logging.getLogger()

Expand Down Expand Up @@ -5243,7 +5243,7 @@ def initCallbacks(self):
self.treeChanged_pv = PV(daq_utils.beamlineComm + "live_q_change_flag")
self.refreshTreeSignal.connect(self.dewarTree.refreshTree)
self.treeChanged_pv.add_callback(self.treeChangedCB)
self.mountedPin_pv = PV(daq_utils.beamlineComm + "mounted_pin")
self.mountedPin_pv = custom_pv.MountedPinPV(daq_utils.beamlineComm + "mounted_pin")
self.mountedPinSignal.connect(self.processMountedPin)
self.mountedPin_pv.add_callback(self.mountedPinChangedCB)
det_stop_pv = daq_utils.pvLookupDict["stopEiger"]
Expand Down
13 changes: 10 additions & 3 deletions gui/dewar_tree.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
IS_STAFF,
PUCKS_PER_DEWAR_SECTOR,
SAMPLE_TIMER_DELAY,
MountState
)

if typing.TYPE_CHECKING:
Expand Down Expand Up @@ -136,14 +137,20 @@ def keyPressEvent(self, event):
def refreshTree(self):
self.parent.dewarViewToggleCheckCB()

def set_mounted_sample(self, item):
def set_mounted_sample(self, item, sample_name=None):
# Formats the text of the item that is passed in as the mounted sample
item.setForeground(QtGui.QColor("red"))
font = QtGui.QFont()
font.setUnderline(True)
font.setItalic(True)
font.setOverline(True)
item.setFont(font)
if self.parent.mountedPin_pv.get_pin_state() is not None:
state = self.parent.mountedPin_pv.get_pin_state()
mount_state = MountState(state)
if sample_name is None:
sample_name = item.text()
item.setText(sample_name + MountState.get_text(mount_state))

def refreshTreeDewarView(self, get_latest_pucks=False):
puck = ""
Expand Down Expand Up @@ -230,8 +237,9 @@ def add_samples_to_puck_tree(
item.setData(sample_id, 32)
item.setData("sample", 33)
if sample_id == self.parent.mountedPin_pv.get():
self.set_mounted_sample(item)
self.set_mounted_sample(item, position_s)
parentItem.appendRow(item)

if sample_id == self.parent.mountedPin_pv.get():
mountedIndex = self.model.indexFromItem(item)
# looking for the selected item
Expand Down Expand Up @@ -261,7 +269,6 @@ def add_samples_to_puck_tree(
elif mountedIndex:
current_index = mountedIndex
item = self.model.itemFromIndex(mountedIndex)
self.set_mounted_sample(item)
elif selectedIndex:
current_index = selectedIndex
elif collectionRunning and mountedIndex:
Expand Down
14 changes: 14 additions & 0 deletions utils/custom_pv.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
from epics import PV


class MountedPinPV(PV):

def get(self, *args, **kwargs):
value = str(super().get(*args, **kwargs))
return value.split(",")[0]

def get_pin_state(self):
value = str(super().get()).split(",")
if len(value) == 2:
return value[1]
return None

0 comments on commit 910c10e

Please sign in to comment.