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

Search for objects by PV name fragment #21

Open
prjemian opened this issue Feb 13, 2025 · 2 comments
Open

Search for objects by PV name fragment #21

prjemian opened this issue Feb 13, 2025 · 2 comments
Labels
enhancement New feature or request

Comments

@prjemian
Copy link
Contributor

Searching is enabled for labels and names. Can it be expanded to search by PV (or prefix) fragment?

Example: I have IOC55:m55 motor and I want to figure out what this is called in bluesky, if it is implemented.

Or, what objects are connected to IOC prefix ABC:?

@canismarko canismarko added the enhancement New feature or request label Feb 14, 2025
@canismarko
Copy link
Contributor

I can see this being useful.

PVs

Doing this for a specific PV seems straight-forward.

How would you want to interact with this feature? I'm thinking:

m1 = Motor(name="m1", prefix="255idVME:m1")
registry.register(m1)
assert registry["ca://255idVME:m1.RBV"] is m1.user_readback

The "ca://" part is how ophyd-async keeps track of whether it's a PV or something else. I could probably include a check that matches the source designation so that "255idVME:m1.RBV" is equivalent to "*://255idVME:m1.RBV" for convenience.

Prefixes

Prefixes will take more thought, especially since threaded ophyd and ophyd-async work differently.

I don't know of a way to reliably determine what the IOC prefix is for every device, or if it even has one, or has multiple.

Threaded ophyd: The Device class has a prefix argument, but the FormattedComponent means that this prefix doesn't necessarily relate to the device's children. Here's an example inspired by a device at 25-ID:

class EnergyPositioner(Device):
    mono = FCpt(Monochromator, "{mono_prefix}")
    undulator = FCpt(Undulator, "{id_prefix}")

    def __init__(self, prefix: str= "" , *, mono_prefix: str, id_prefix: str, ...):
        assert prefix == "", "Specify *mono_prefix* and *id_prefix*"
        self.mono_prefix = mono_prefix
        self.id_prefix = id_prefix

energy = EnergyPositioner(mono_prefix="255idbUP:", id_prefix="US:25ID:")
registry.register(energy)

registry.findall(source="25idbUP:")  # <- what should this return?

That last line could return energy.mono, but not energy. Probably fine, though.

Ophyd-async: Doesn't treat prefixes as special, and prefix is not even an argument to the base Device class. It's up to the subclasses to include this argument if needed, and it's typically not kept around once the device is initalized (at least not in standardized way). If the device is a Signal(), then it will have the source attribute that we can use.

Back to the original motor example:

registry.findall(source="ca://255idVME:m1", allow_none=True)

could return either:

  1. The empty set, because no signal matches this source exactly
  2. The set of all the motor's children (but not the motor itself), because every signal's source is a partial match

Seems like the option 2 is the only one that meets your original use case. Would this be too much noise to be useful?

@canismarko
Copy link
Contributor

canismarko commented Feb 26, 2025

registry.find(pv="25idcVME:m1") => eliminiates descendents just like name=""
registry.findall(pv="25idcVME:m1") => return motor and all descendent signals
registry.find(pv="25idcVME:") => raises exception
registry.findall(pv="25idcVME:") => giant list of things (on you to figure it out)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants