-
Notifications
You must be signed in to change notification settings - Fork 62
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
SmarAct UI overhaul #1320
SmarAct UI overhaul #1320
Conversation
…ick behavior from TyphosPositionerRow
…ude optional picoscale
I know this is a really large PR due to the size of the pyqt scripts/uis, so feel free to break it up (perhaps I should've submitted 2 different PRs, honestly) |
pcdsdevices/ui/SmarAct.detailed.py
Outdated
def __init__(self, parent=None, **kwargs): | ||
super().__init__(parent=parent) | ||
|
||
self.ui = typing.cast(_SmarActDetailedUI, uic.loadUi(self.ui_template, self)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm a little surprised you'd need to invoke the uic loader manually here. Naively I'd expect PyDM to do this for you in the super call:
https://github.com/slaclab/pydm/blob/ba4125d479a2e6adb033e9ab1a05ab2bab2fdf84/pydm/display.py#L315-L316
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Perhaps this is why your macros aren't being expanded?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Definitely why the macro isn't being expanded, but also I can't omit this line or else self.ui
never populates. Not sure why the super()
call doesn't proc it
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay figured out why pydm.Display
wasn't loading the UI correctly. Got that remedied, but now I can't quite grab my object names. Might need to fenagle a bit more of the code to fix that
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This sadly isn't why the macro isn't being expanded. Got the super call to work with:
class SmarActDetailedWidget(Display, utils.TyphosBase):
"""
Custom widget for managing the SmarAct detailed screen
"""
ui: _SmarActDetailedUI
ui_template = path.join(path.dirname(path.realpath(__file__)), 'SmarAct.detailed.ui')
def __init__(self, parent=None, ui_filename=ui_template, **kwargs):
super().__init__(parent=parent, ui_filename=ui_filename)
but still get greeted with the complaints when the expert screen opens:
[2025-01-30 16:17:39] - INFO - Loading Tools ...
[2025-01-30 16:17:39] - INFO - Adding devices ...
[2025-01-30 16:17:42] - INFO - Launching application ...
[2025-01-30 16:17:45] - INFO - Loading Tools ...
[2025-01-30 16:17:45] - INFO - Adding devices ...
[2025-01-30 16:17:45] - ERROR - Unable to find signal for <PyDMChannel (sig://${name}_motor_egu)> in signal registry.Use typhos.plugins.register_signal()
[2025-01-30 16:17:45] - ERROR - Unable to find signal for <PyDMChannel (sig://${name}_description)> in signal registry.Use typhos.plugins.register_signal()
:sadge:
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is pretty cool. Some of this Typhos stuff is a bit beyond me, but reading through this, things generally make sense. I'd be interested to understand if this is a good template to base other, similar screens off of. I imagine there's a lot of nice things that we could do with many of our devices if we put in a little time.
class _SmarActDetailedUI(QtWidgets.QWidget): | ||
"""Annotations helper for SmarAct.detailed.ui. Do not instantiate.""" | ||
# Status bar | ||
calibrated_bool: pydm.widgets.byte.PyDMByteIndicator |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Generally we don't add the type to the signal name; is there a reason you're doing that here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you make a stub class with annotations and apply it like this, you get really good autocomplete/api lookup help in e.g. vscode because it knows that self.ui.calibrated_bool
is a PyDMByteIndicator
|
||
def add_device(self, device): | ||
"""Typhos hook for adding a new device.""" | ||
super().add_device(device) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this occur after the check for None
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think that will always kill the screen, because I have to wait for typhos to grab add_device
and link the ophyd.device back to the display. Let me try it out at the very least!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I checked a bit and I think the ordering doesn't matter (based on the code for TyphosBase
)
|
||
def add_device(self, device): | ||
"""Typhos hook for adding a new device.""" | ||
super().add_device(device) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same comment as above.
To my quick-ish readthrough of the python file everything looks kosher, I can go again later with a more critical eye if you'd like to make sure there aren't any potential smaller issues. The results look good! I can try to nitpick ui layout stuff too (resize behavior, whitespace) if that's desirable. |
I think some of the As long as the method hooks the typhos magic and you get the |
…n checks for TipTilt
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So far looks good! Albeit that it has been a while since I have had to work with typhos/pydm and never got this far. Two questions/comments.
- when released, will the *.ui and *.py "screens" join to be just *.ui like the rest?

- what command did you use to open the detailed screen with the pico scale check? I tried running
typhos "pcdsdevices.epics_motor.SmarAct[{'prefix':'LAS:FTL:MCS:01:m1', 'name':'LAS:FTL:MCS:01:m1'}]"
but it never shows the pico scale tab and has the EGU/description error
Both the
That's expected! A The egu and description signal error seems to be tied to how the |
I might consider refactoring these screens given the ease of pcdshub/typhos#627. I think I'd still need to do something janky to get the ordering the way I want for the tabs, but it does cut down on a lot of hard coding since I can just add things like:
To the |
I wonder if this is worth a typhos patch itself, or if there are cases where one might want to avoid the py file. |
… as a byte indicator
… epics_motor device
These screenshots look really great! |
This does look amazing. I will mention that this seems to have a merge conflict, hopefully that's not too painful |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Mostly nitpicks! Can ignore if you like!
I think this is pretty great.
def __init__(self, *args, **kwargs): | ||
super().__init__(*args, **kwargs) | ||
# Long name shenanigans | ||
self.step_voltage.long_name = 'Step Voltage' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
side note: the long_name ophyd PR churned a little bit recently (rebase?) so these are pretty safe for the future.
pcdsdevices/ui/SmarAct.detailed.py
Outdated
def __init__(self, parent=None, ui_filename=ui_template, **kwargs): | ||
super().__init__(parent=parent, ui_filename=ui_filename) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nitpick: this might be redundant now, unless you intend to block the kwargs pass-through
def __init__(self, parent=None, ui_filename=ui_template, **kwargs): | |
super().__init__(parent=parent, ui_filename=ui_filename) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It breaks if I change it 🤷
I think if I just manually call out the template anyway it's superfluous, but I deleted that and went the super().__init__
route. I remember it only being able to catch my template if I did it this way (still doesn't expand my macros) but let me tinker
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah I don't really gain or lose anything by blocking the **kwargs
or not, least as far as I can tell. Still need to super().__init__
though. Maintainer's choice on whether or not I should pass the **kwargs
🤷
pcdsdevices/ui/SmarAct.detailed.py
Outdated
""" | ||
ui: _SmarActDetailedUI | ||
# Seems confusing, but really just cleans up the call to pydm for setting self.ui | ||
ui_template = path.join(path.dirname(path.realpath(__file__)), 'SmarAct.detailed.ui') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Question: In the past I was able to just give e.g. SmarAct.detailed.ui
without any path handling and pydm knew to check the same dir. Does it behave differently here? (same for the embedded widget)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You're absolutely right! This is probably a relic of previous fenagling I was doing. I can update this across the .py
files
|
||
def add_device(self, device): | ||
"""Typhos hook for adding a new device.""" | ||
super().add_device(device) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I checked a bit and I think the ordering doesn't matter (based on the code for TyphosBase
)
def fix_pvs(self): | ||
""" | ||
Fix all the channel access and signal linking to various pydm objects in the screen, | ||
since the macros aren't expanded when the UI is initialized. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: it'd be nice to figure out and clean the root cause here but it's not strictly required
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah the lack of macro expansion is very annoying considering the tedium of adding it in designer
in the first place, but c'est la vie. I can't figure out why pydm
isn't expanding the ui
before opening the .py
screen.
A little hacky for me to just handle the egu
and desc
signals this way, but it got rid of the terminal spam on start-up complaining about how the sig//${name}_egu
etc. didn't exist
pcdsdevices/ui/SmarAct.detailed.py
Outdated
self.maybe_add_pico() | ||
self.add_tool_tips() | ||
# Only start this timer if PicoScale exists | ||
if hasattr(self.device, 'pico_exists'): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nitpick: possibly this belongs in maybe_add_pico
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh! Good point, I'll move this there, not sense in having it out here if the check is already done in maybe_add_pico
Co-authored-by: Zachary Lentz <[email protected]>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Still happy, still on-board
Description
Adding new SmarAct screens to help with day-to-day ops:
I made the bulk of the UI in designer and (mostly) manually labeled the signals 🤮. Noticed in #430 that the discussion for naming signals with human-readable text has come up a few times. I think Ken had a good point that I should probably put the
dotted_name
signals back in as a tooltip for hutch-python friendlinessMotivation and Context
While fixing #1275 we realized it was time to update the SmarAct screens to improve user readability.
How Has This Been Tested?
I've tested this on some live devices for linear & tip-tilt (open-loop) in the LRL as well as the picoscale devices in the FTL (with permission). Everything appears to work as intended with the live devices.
One small hang-up is that launching the
SmarAct.detailed.py
screen from typhos using CLI triggers some complaints:Since the
ui
file isn't having the macros expanded before it opens. I have to wait untiladd_device
processes for the macros to be expanded, so none of the other signals appear to trigger it.Both the
EGU
andDESC
fields read/write regardless of this complaint.Now I could fix this by emptying out all the channel slots on all the elements in the
ui
file then just slot the signals in the.py
but it would be super annoying and messy, I think. Also, theui
works by itself for any non-picoscale related system, so I'd hate to break it.Where Has This Been Documented?
This PR
Screenshots (if appropriate):
Some vids showing off the GUI
smaract_embedded_tip_tilt.mp4
smaract_picoscale_screen.mp4
Pre-merge checklist