ophyd-registry


Nameophyd-registry JSON
Version 1.0.0 PyPI version JSON
download
home_pageNone
SummaryA registry to keep track of, and retrieve, Ophyd objects.
upload_time2024-03-24 15:55:46
maintainerNone
docs_urlNone
authorNone
requires_python>=3.7
licenseNone
keywords synchrotron xray bluesky
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # Ophyd Registry

[![Python Tests](https://github.com/spc-group/ophyd-registry/actions/workflows/ci.yml/badge.svg)](https://github.com/spc-group/ophyd-registry/actions/workflows/ci.yml)

A registry to keep track of, and retrieve, Ophyd objects.

The **Ophyd registry** provides a way to keep track of the devices
(including components, motors, signals, etc.) that have been defined
across a project. In order for the registry to know of a device, that
device must first be registered, though there are ways to do this
automatically.

This allows for a simple way to keep track of the Ophyd devices that were
created in your project.

```python

import ophyd
from ophydregistry import OphydRegistry

# Register the devices when they're created
registry = OphydRegistry()
registry.register(ophyd.sim.motor)

# Then elsewhere in your project, use them...
registry['motor'].set(15.3)

```

Installation
============

The easiest way to install the ophyd registry is with pip from PyPI:

```bash
python -m pip install ophyd-registry
```

To create a **developer installation**:

```bash
git clone https://github.com/spc-group/ophyd-registry.git
python -m pip install "ophyd_registry[dev]"
```

Usage
=====

Registering Devices
-------------------

There are three ways to have an instrument registry know about a
device.

1. Implicitly capture all Ophyd objects
2. Register a device class
3. Register individual objects

By default, a new instrument registry will alert itself to all future
devices:

```python
from ophydregistry import Registry
registry = Registry()

the_device = MyDevice("255id:Dev:", name="my_device")

assert registry.find("my_device") is the_device
```

This greedy behavior can be suppressed with the *auto_register*
parameter. If *auto_register* is false, then a device class can be
decorated to allow the registry to find it:

```python
from ophyd import Device
from ophydregistry import Registry

registry = Registry(auto_register=False)

@registry.register
class MyDevice(Device):
    ...

the_device = MyDevice("255id:Dev:", name="my_device")

assert registry.find("my_device") is the_device
```

Lastly, individual instantions of a device can be explicitly
registered.

```python
from ophyd import Device
from ophydregistry import Registry

registry = Registry(auto_register=False)

class MyDevice(Device):
    ...

the_device = MyDevice("255id:Dev:", name="my_device")
registry.register(the_device)

assert registry.find("my_device") is the_device
```

Looking Up Registered Devices/Components
----------------------------------------

Registered objects can be found by *name*, *label*, or both. The
easist way is to treat the registry like a dictionary:
``registry['motor1']``. This will look for an individual device first
by *name* then by *label*. It will raise an exception if the number of
devices is not 1.

For more sophisticated queries, the *Registry.find()* method will
return a single result, while *Registry.findall()* returns more than
one. By default, *findall()* will raise an exception if no objects
match the criteria, but this can be overridden with the *allow_none*
keyword argument.

The registry uses the built-in concept of device labels in Ophyd. The
registry's ``find()`` and ``findall()`` methods allows devices to be
looked up by label or device name. For example, assuming four devices
exist with the label "ion_chambers", then these devices can be
retrieved using the registry:

```python
ion_chambers = registry.findall(label="ion_chambers")
assert len(ion_chambers) == 4
```

Devices can also be found by name:

```python
ion_chambers = registry.find(name="I0")
assert len(ion_chambers) == 4
```

A set of the **root devices**, those without a parent, can be
retrieved at ``Registry.root_devices``.

Looking Up Sub-Components by Dot-Notation
-----------------------------------------

For simple devices, the full name of the sub-component should be
enough to retrieve the device. For example, to find the signal
*preset_time* on the device named "vortex_me4", the following may work
fine:

```python
preset_time = haven.registry.find("vortex_me4_preset_time")
```

However, **if the component is lazy** and has not been accessed prior
to being registered, then **it will not be available in the
registry**. Sub-components can instead be accessed by dot
notation. Unlike the full device name, dot-notation names only resolve
when the component is requested from the registry, at which point the
lazy components can be accessed.

For example, area detectors use many lazy components. If ``sim_det``
is an area detector with a camera component ``sim_det.cam``, then the
name of the gain channel is "sim_det_cam_gain", however this is a lazy
component so is not available. Instead, retrieving the device by
``haven.registry.find("sim_det.cam.gain")`` will first find the area
detector ("sim_det"), then access the *cam* attribute, and then cam's
*gain* attribute. This has the side-effect of instantiating the lazy
components.


Removing Devices
----------------

The ``OphydRegistry`` class behaves similarly to a python dictionary.

To **remove all devices** from the registry, use the ``clear()``
method:

```python

registry.clear()
```

To **remove individual objects**, use either the *del* keyword, or the
``pop()`` method. These approaches work with either the
``OphydObject`` instance itself, or the instance's name:

```python

# Just delete the item and move on
# (by name)
del registry["motor1"]
del registry[motor]

# Remove the item and use it
# (return ``None`` if motor1 is not in the registry)
registry.pop("motor1", None)

```

Integrating with Typhos
-----------------------

Typhos includes a PyDM plugin that can directly interact with ophyd
devices. It requires ophyd objects to be registered in order to find
them. **ophyd_registry** can automatically register devices with
Typhos by simply passing the *use_typhos* argument when creating the
registry:

.. code:: python
    
    from ophydregistry import Registry
    registry = Registry(use_typos=True)

or setting the *use_typhos* attribute on an existing registry:

.. code:: python
    
    from ophydregistry import Registry
    registry = Registry()
    registry.use_typhos = True

If using the typhos registry, calling the *clear()* method on the
ophyd registry will also clear the Typhos registry.

            

Raw data

            {
    "_id": null,
    "home_page": null,
    "name": "ophyd-registry",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.7",
    "maintainer_email": null,
    "keywords": "synchrotron, xray, bluesky",
    "author": null,
    "author_email": "Mark Wolfman <wolfman@anl.gov>",
    "download_url": "https://files.pythonhosted.org/packages/c8/9f/972a87d4b8eb7eb3af151c8c063c5a6b0f126cf6d7eb664f77d189221f03/ophyd-registry-1.0.0.tar.gz",
    "platform": null,
    "description": "# Ophyd Registry\n\n[![Python Tests](https://github.com/spc-group/ophyd-registry/actions/workflows/ci.yml/badge.svg)](https://github.com/spc-group/ophyd-registry/actions/workflows/ci.yml)\n\nA registry to keep track of, and retrieve, Ophyd objects.\n\nThe **Ophyd registry** provides a way to keep track of the devices\n(including components, motors, signals, etc.) that have been defined\nacross a project. In order for the registry to know of a device, that\ndevice must first be registered, though there are ways to do this\nautomatically.\n\nThis allows for a simple way to keep track of the Ophyd devices that were\ncreated in your project.\n\n```python\n\nimport ophyd\nfrom ophydregistry import OphydRegistry\n\n# Register the devices when they're created\nregistry = OphydRegistry()\nregistry.register(ophyd.sim.motor)\n\n# Then elsewhere in your project, use them...\nregistry['motor'].set(15.3)\n\n```\n\nInstallation\n============\n\nThe easiest way to install the ophyd registry is with pip from PyPI:\n\n```bash\npython -m pip install ophyd-registry\n```\n\nTo create a **developer installation**:\n\n```bash\ngit clone https://github.com/spc-group/ophyd-registry.git\npython -m pip install \"ophyd_registry[dev]\"\n```\n\nUsage\n=====\n\nRegistering Devices\n-------------------\n\nThere are three ways to have an instrument registry know about a\ndevice.\n\n1. Implicitly capture all Ophyd objects\n2. Register a device class\n3. Register individual objects\n\nBy default, a new instrument registry will alert itself to all future\ndevices:\n\n```python\nfrom ophydregistry import Registry\nregistry = Registry()\n\nthe_device = MyDevice(\"255id:Dev:\", name=\"my_device\")\n\nassert registry.find(\"my_device\") is the_device\n```\n\nThis greedy behavior can be suppressed with the *auto_register*\nparameter. If *auto_register* is false, then a device class can be\ndecorated to allow the registry to find it:\n\n```python\nfrom ophyd import Device\nfrom ophydregistry import Registry\n\nregistry = Registry(auto_register=False)\n\n@registry.register\nclass MyDevice(Device):\n    ...\n\nthe_device = MyDevice(\"255id:Dev:\", name=\"my_device\")\n\nassert registry.find(\"my_device\") is the_device\n```\n\nLastly, individual instantions of a device can be explicitly\nregistered.\n\n```python\nfrom ophyd import Device\nfrom ophydregistry import Registry\n\nregistry = Registry(auto_register=False)\n\nclass MyDevice(Device):\n    ...\n\nthe_device = MyDevice(\"255id:Dev:\", name=\"my_device\")\nregistry.register(the_device)\n\nassert registry.find(\"my_device\") is the_device\n```\n\nLooking Up Registered Devices/Components\n----------------------------------------\n\nRegistered objects can be found by *name*, *label*, or both. The\neasist way is to treat the registry like a dictionary:\n``registry['motor1']``. This will look for an individual device first\nby *name* then by *label*. It will raise an exception if the number of\ndevices is not 1.\n\nFor more sophisticated queries, the *Registry.find()* method will\nreturn a single result, while *Registry.findall()* returns more than\none. By default, *findall()* will raise an exception if no objects\nmatch the criteria, but this can be overridden with the *allow_none*\nkeyword argument.\n\nThe registry uses the built-in concept of device labels in Ophyd. The\nregistry's ``find()`` and ``findall()`` methods allows devices to be\nlooked up by label or device name. For example, assuming four devices\nexist with the label \"ion_chambers\", then these devices can be\nretrieved using the registry:\n\n```python\nion_chambers = registry.findall(label=\"ion_chambers\")\nassert len(ion_chambers) == 4\n```\n\nDevices can also be found by name:\n\n```python\nion_chambers = registry.find(name=\"I0\")\nassert len(ion_chambers) == 4\n```\n\nA set of the **root devices**, those without a parent, can be\nretrieved at ``Registry.root_devices``.\n\nLooking Up Sub-Components by Dot-Notation\n-----------------------------------------\n\nFor simple devices, the full name of the sub-component should be\nenough to retrieve the device. For example, to find the signal\n*preset_time* on the device named \"vortex_me4\", the following may work\nfine:\n\n```python\npreset_time = haven.registry.find(\"vortex_me4_preset_time\")\n```\n\nHowever, **if the component is lazy** and has not been accessed prior\nto being registered, then **it will not be available in the\nregistry**. Sub-components can instead be accessed by dot\nnotation. Unlike the full device name, dot-notation names only resolve\nwhen the component is requested from the registry, at which point the\nlazy components can be accessed.\n\nFor example, area detectors use many lazy components. If ``sim_det``\nis an area detector with a camera component ``sim_det.cam``, then the\nname of the gain channel is \"sim_det_cam_gain\", however this is a lazy\ncomponent so is not available. Instead, retrieving the device by\n``haven.registry.find(\"sim_det.cam.gain\")`` will first find the area\ndetector (\"sim_det\"), then access the *cam* attribute, and then cam's\n*gain* attribute. This has the side-effect of instantiating the lazy\ncomponents.\n\n\nRemoving Devices\n----------------\n\nThe ``OphydRegistry`` class behaves similarly to a python dictionary.\n\nTo **remove all devices** from the registry, use the ``clear()``\nmethod:\n\n```python\n\nregistry.clear()\n```\n\nTo **remove individual objects**, use either the *del* keyword, or the\n``pop()`` method. These approaches work with either the\n``OphydObject`` instance itself, or the instance's name:\n\n```python\n\n# Just delete the item and move on\n# (by name)\ndel registry[\"motor1\"]\ndel registry[motor]\n\n# Remove the item and use it\n# (return ``None`` if motor1 is not in the registry)\nregistry.pop(\"motor1\", None)\n\n```\n\nIntegrating with Typhos\n-----------------------\n\nTyphos includes a PyDM plugin that can directly interact with ophyd\ndevices. It requires ophyd objects to be registered in order to find\nthem. **ophyd_registry** can automatically register devices with\nTyphos by simply passing the *use_typhos* argument when creating the\nregistry:\n\n.. code:: python\n    \n    from ophydregistry import Registry\n    registry = Registry(use_typos=True)\n\nor setting the *use_typhos* attribute on an existing registry:\n\n.. code:: python\n    \n    from ophydregistry import Registry\n    registry = Registry()\n    registry.use_typhos = True\n\nIf using the typhos registry, calling the *clear()* method on the\nophyd registry will also clear the Typhos registry.\n",
    "bugtrack_url": null,
    "license": null,
    "summary": "A registry to keep track of, and retrieve, Ophyd objects.",
    "version": "1.0.0",
    "project_urls": {
        "Bug Tracker": "https://github.com/spc-group/ophyd-registry/issues",
        "Homepage": "https://github.com/spc-group/ophyd-registry"
    },
    "split_keywords": [
        "synchrotron",
        " xray",
        " bluesky"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "3ee45d6d20891f4e8adc455949d1b5ac1a7a3917e353e85b8a6b2c2135745f59",
                "md5": "2a7464e5b3ad2273552c42db50b036b9",
                "sha256": "bec59563ea3d0862376b8bd038bad183ac0e94fa36e70eed0548696c4a10360d"
            },
            "downloads": -1,
            "filename": "ophyd_registry-1.0.0-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "2a7464e5b3ad2273552c42db50b036b9",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.7",
            "size": 11188,
            "upload_time": "2024-03-24T15:55:43",
            "upload_time_iso_8601": "2024-03-24T15:55:43.033297Z",
            "url": "https://files.pythonhosted.org/packages/3e/e4/5d6d20891f4e8adc455949d1b5ac1a7a3917e353e85b8a6b2c2135745f59/ophyd_registry-1.0.0-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "c89f972a87d4b8eb7eb3af151c8c063c5a6b0f126cf6d7eb664f77d189221f03",
                "md5": "a9dcbb847c64f9408dd15e832e0510b1",
                "sha256": "1fa87e16871e156263f6980cd500da2c1f9eb0b773fba4c2036b50b4c9906e4a"
            },
            "downloads": -1,
            "filename": "ophyd-registry-1.0.0.tar.gz",
            "has_sig": false,
            "md5_digest": "a9dcbb847c64f9408dd15e832e0510b1",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.7",
            "size": 10339,
            "upload_time": "2024-03-24T15:55:46",
            "upload_time_iso_8601": "2024-03-24T15:55:46.910095Z",
            "url": "https://files.pythonhosted.org/packages/c8/9f/972a87d4b8eb7eb3af151c8c063c5a6b0f126cf6d7eb664f77d189221f03/ophyd-registry-1.0.0.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2024-03-24 15:55:46",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "spc-group",
    "github_project": "ophyd-registry",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": true,
    "lcname": "ophyd-registry"
}
        
Elapsed time: 0.20749s