ophyd-async 0.10.0a3__tar.gz → 0.10.0a4__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/PKG-INFO +1 -1
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/pyproject.toml +0 -1
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/src/ophyd_async/_version.py +2 -2
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/src/ophyd_async/core/__init__.py +4 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/src/ophyd_async/core/_derived_signal.py +38 -10
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/src/ophyd_async/core/_detector.py +4 -4
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/src/ophyd_async/core/_signal.py +21 -5
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/src/ophyd_async/core/_signal_backend.py +18 -8
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/src/ophyd_async/core/_utils.py +31 -14
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/src/ophyd_async/epics/adcore/_core_detector.py +2 -2
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/src/ophyd_async/epics/adcore/_core_io.py +3 -3
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/src/ophyd_async/epics/adcore/_utils.py +11 -2
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/src/ophyd_async/epics/adpilatus/_pilatus.py +1 -1
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/src/ophyd_async/epics/adpilatus/_pilatus_controller.py +4 -11
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/src/ophyd_async/epics/core/_aioca.py +2 -2
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/src/ophyd_async/epics/core/_util.py +21 -13
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/src/ophyd_async/epics/eiger/_odin_io.py +12 -13
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/src/ophyd_async/epics/motor.py +3 -2
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/src/ophyd_async/fastcs/eiger/_eiger.py +11 -2
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/src/ophyd_async/fastcs/eiger/_eiger_controller.py +7 -3
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/src/ophyd_async/fastcs/eiger/_eiger_io.py +1 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/src/ophyd_async/sim/_motor.py +2 -2
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/src/ophyd_async/tango/core/_base_device.py +2 -1
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/src/ophyd_async/tango/core/_converters.py +2 -6
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/src/ophyd_async/tango/demo/_tango/_servers.py +0 -1
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/src/ophyd_async.egg-info/PKG-INFO +1 -1
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/tests/core/test_multi_derived_signal.py +5 -2
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/tests/core/test_observe.py +56 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/tests/core/test_single_derived_signal.py +31 -16
- ophyd_async-0.10.0a4/tests/epics/adandor/test_andor.py +37 -0
- ophyd_async-0.10.0a4/tests/epics/adaravis/test_aravis.py +46 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/tests/epics/adpilatus/test_pilatus.py +38 -49
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/tests/epics/conftest.py +1 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/tests/epics/eiger/test_odin_io.py +22 -13
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/tests/epics/signal/test_common.py +39 -1
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/tests/epics/test_motor.py +15 -3
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/tests/fastcs/eiger/test_eiger_controller.py +7 -1
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/tests/fastcs/eiger/test_eiger_detector.py +20 -0
- ophyd_async-0.10.0a3/tests/epics/adandor/test_andor.py +0 -46
- ophyd_async-0.10.0a3/tests/epics/adaravis/test_aravis.py +0 -44
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/.codecov.yml +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/.copier-answers.yml +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/.devcontainer/devcontainer.json +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/.git-blame-ignore-revs +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/.github/CONTRIBUTING.md +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/.github/ISSUE_TEMPLATE/issue.md +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/.github/PULL_REQUEST_TEMPLATE/pull_request_template.md +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/.github/actions/install_requirements/action.yml +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/.github/codeql/codeql-config.yml +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/.github/dependabot.yml +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/.github/pages/index.html +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/.github/pages/make_switcher.py +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/.github/workflows/_check.yml +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/.github/workflows/_codeql.yml +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/.github/workflows/_dist.yml +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/.github/workflows/_docs.yml +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/.github/workflows/_import_with_no_extras.yml +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/.github/workflows/_pypi.yml +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/.github/workflows/_release.yml +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/.github/workflows/_test.yml +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/.github/workflows/_tox.yml +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/.github/workflows/ci.yml +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/.github/workflows/periodic.yml +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/.gitignore +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/.pre-commit-config.yaml +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/Dockerfile +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/LICENSE +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/README.md +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/docs/_static/custom.css +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/docs/conf.py +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/docs/explanations/decisions/0001-record-architecture-decisions.md +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/docs/explanations/decisions/0002-switched-to-python-copier-template.md +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/docs/explanations/decisions/0003-ophyd-async-migration.rst +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/docs/explanations/decisions/0004-repository-structure.rst +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/docs/explanations/decisions/0005-respect-black-line-length.rst +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/docs/explanations/decisions/0006-procedural-device-definitions.rst +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/docs/explanations/decisions/0007-subpackage-structure.md +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/docs/explanations/decisions/0008-signal-types.md +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/docs/explanations/decisions/0009-procedural-vs-declarative-devices.md +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/docs/explanations/decisions/0010-docstring-format.md +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/docs/explanations/decisions/COPYME +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/docs/explanations/decisions.md +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/docs/explanations/declarative-vs-procedural.md +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/docs/explanations/design-goals.md +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/docs/explanations/device-connection-strategies.md +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/docs/explanations/devices-signals-backends.md +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/docs/explanations/flyscanning.md +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/docs/explanations/where-device-logic.md +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/docs/explanations.md +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/docs/genindex.rst +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/docs/how-to/choose-right-baseclass.md +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/docs/how-to/contribute.md +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/docs/how-to/derive-one-signal-from-others.md +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/docs/how-to/implement-ad-detector.md +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/docs/how-to/interact-with-signals.md +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/docs/how-to/put-device-back.md +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/docs/how-to/store-and-retrieve.md +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/docs/how-to.md +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/docs/images/flyscan_collection_windows_and_frames.svg +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/docs/images/ophyd-async-logo.svg +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/docs/images/ophyd-favicon.svg +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/docs/images/set_and_wait_for_other_value.excalidraw.svg +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/docs/index.md +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/docs/reference.md +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/docs/tutorials/implementing-detectors.md +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/docs/tutorials/implementing-devices.md +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/docs/tutorials/installation.md +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/docs/tutorials/using-devices.md +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/docs/tutorials/writing-tests-for-devices.md +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/docs/tutorials.md +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/setup.cfg +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/src/ophyd_async/__init__.py +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/src/ophyd_async/__main__.py +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/src/ophyd_async/_docs_parser.py +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/src/ophyd_async/core/_derived_signal_backend.py +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/src/ophyd_async/core/_device.py +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/src/ophyd_async/core/_device_filler.py +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/src/ophyd_async/core/_flyer.py +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/src/ophyd_async/core/_hdf_dataset.py +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/src/ophyd_async/core/_log.py +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/src/ophyd_async/core/_mock_signal_backend.py +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/src/ophyd_async/core/_protocol.py +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/src/ophyd_async/core/_providers.py +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/src/ophyd_async/core/_readable.py +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/src/ophyd_async/core/_settings.py +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/src/ophyd_async/core/_soft_signal_backend.py +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/src/ophyd_async/core/_status.py +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/src/ophyd_async/core/_table.py +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/src/ophyd_async/core/_yaml_settings.py +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/src/ophyd_async/epics/__init__.py +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/src/ophyd_async/epics/adandor/__init__.py +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/src/ophyd_async/epics/adandor/_andor.py +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/src/ophyd_async/epics/adandor/_andor_controller.py +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/src/ophyd_async/epics/adandor/_andor_io.py +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/src/ophyd_async/epics/adaravis/__init__.py +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/src/ophyd_async/epics/adaravis/_aravis.py +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/src/ophyd_async/epics/adaravis/_aravis_controller.py +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/src/ophyd_async/epics/adaravis/_aravis_io.py +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/src/ophyd_async/epics/adcore/__init__.py +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/src/ophyd_async/epics/adcore/_core_logic.py +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/src/ophyd_async/epics/adcore/_core_writer.py +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/src/ophyd_async/epics/adcore/_hdf_writer.py +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/src/ophyd_async/epics/adcore/_jpeg_writer.py +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/src/ophyd_async/epics/adcore/_single_trigger.py +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/src/ophyd_async/epics/adcore/_tiff_writer.py +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/src/ophyd_async/epics/adkinetix/__init__.py +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/src/ophyd_async/epics/adkinetix/_kinetix.py +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/src/ophyd_async/epics/adkinetix/_kinetix_controller.py +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/src/ophyd_async/epics/adkinetix/_kinetix_io.py +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/src/ophyd_async/epics/adpilatus/__init__.py +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/src/ophyd_async/epics/adpilatus/_pilatus_io.py +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/src/ophyd_async/epics/adsimdetector/__init__.py +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/src/ophyd_async/epics/adsimdetector/_sim.py +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/src/ophyd_async/epics/adsimdetector/_sim_controller.py +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/src/ophyd_async/epics/adsimdetector/_sim_io.py +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/src/ophyd_async/epics/advimba/__init__.py +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/src/ophyd_async/epics/advimba/_vimba.py +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/src/ophyd_async/epics/advimba/_vimba_controller.py +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/src/ophyd_async/epics/advimba/_vimba_io.py +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/src/ophyd_async/epics/core/__init__.py +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/src/ophyd_async/epics/core/_epics_connector.py +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/src/ophyd_async/epics/core/_epics_device.py +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/src/ophyd_async/epics/core/_p4p.py +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/src/ophyd_async/epics/core/_pvi_connector.py +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/src/ophyd_async/epics/core/_signal.py +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/src/ophyd_async/epics/demo/__init__.py +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/src/ophyd_async/epics/demo/__main__.py +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/src/ophyd_async/epics/demo/_ioc.py +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/src/ophyd_async/epics/demo/_motor.py +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/src/ophyd_async/epics/demo/_point_detector.py +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/src/ophyd_async/epics/demo/_point_detector_channel.py +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/src/ophyd_async/epics/demo/_stage.py +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/src/ophyd_async/epics/demo/motor.db +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/src/ophyd_async/epics/demo/point_detector.db +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/src/ophyd_async/epics/demo/point_detector_channel.db +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/src/ophyd_async/epics/eiger/__init__.py +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/src/ophyd_async/epics/signal.py +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/src/ophyd_async/epics/testing/__init__.py +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/src/ophyd_async/epics/testing/_example_ioc.py +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/src/ophyd_async/epics/testing/_utils.py +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/src/ophyd_async/epics/testing/test_records.db +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/src/ophyd_async/epics/testing/test_records_pva.db +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/src/ophyd_async/fastcs/__init__.py +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/src/ophyd_async/fastcs/core.py +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/src/ophyd_async/fastcs/eiger/__init__.py +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/src/ophyd_async/fastcs/odin/__init__.py +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/src/ophyd_async/fastcs/panda/__init__.py +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/src/ophyd_async/fastcs/panda/_block.py +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/src/ophyd_async/fastcs/panda/_control.py +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/src/ophyd_async/fastcs/panda/_hdf_panda.py +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/src/ophyd_async/fastcs/panda/_table.py +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/src/ophyd_async/fastcs/panda/_trigger.py +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/src/ophyd_async/fastcs/panda/_writer.py +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/src/ophyd_async/plan_stubs/__init__.py +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/src/ophyd_async/plan_stubs/_ensure_connected.py +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/src/ophyd_async/plan_stubs/_fly.py +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/src/ophyd_async/plan_stubs/_nd_attributes.py +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/src/ophyd_async/plan_stubs/_panda.py +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/src/ophyd_async/plan_stubs/_settings.py +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/src/ophyd_async/plan_stubs/_utils.py +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/src/ophyd_async/plan_stubs/_wait_for_awaitable.py +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/src/ophyd_async/py.typed +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/src/ophyd_async/sim/__init__.py +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/src/ophyd_async/sim/__main__.py +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/src/ophyd_async/sim/_blob_detector.py +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/src/ophyd_async/sim/_blob_detector_controller.py +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/src/ophyd_async/sim/_blob_detector_writer.py +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/src/ophyd_async/sim/_mirror_horizontal.py +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/src/ophyd_async/sim/_mirror_vertical.py +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/src/ophyd_async/sim/_pattern_generator.py +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/src/ophyd_async/sim/_point_detector.py +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/src/ophyd_async/sim/_stage.py +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/src/ophyd_async/tango/__init__.py +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/src/ophyd_async/tango/core/__init__.py +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/src/ophyd_async/tango/core/_signal.py +8 -8
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/src/ophyd_async/tango/core/_tango_readable.py +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/src/ophyd_async/tango/core/_tango_transport.py +12 -12
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/src/ophyd_async/tango/core/_utils.py +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/src/ophyd_async/tango/demo/__init__.py +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/src/ophyd_async/tango/demo/_counter.py +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/src/ophyd_async/tango/demo/_detector.py +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/src/ophyd_async/tango/demo/_mover.py +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/src/ophyd_async/tango/demo/_tango/__init__.py +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/src/ophyd_async/tango/testing/__init__.py +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/src/ophyd_async/tango/testing/_one_of_everything.py +2 -2
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/src/ophyd_async/testing/__init__.py +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/src/ophyd_async/testing/__pytest_assert_rewrite.py +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/src/ophyd_async/testing/_assert.py +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/src/ophyd_async/testing/_mock_signal_utils.py +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/src/ophyd_async/testing/_one_of_everything.py +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/src/ophyd_async/testing/_single_derived.py +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/src/ophyd_async/testing/_utils.py +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/src/ophyd_async/testing/_wait_for_pending.py +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/src/ophyd_async.egg-info/SOURCES.txt +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/src/ophyd_async.egg-info/dependency_links.txt +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/src/ophyd_async.egg-info/requires.txt +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/src/ophyd_async.egg-info/top_level.txt +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/system_tests/epics/eiger/README.md +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/system_tests/epics/eiger/start_iocs_and_run_tests.sh +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/system_tests/epics/eiger/test_eiger_system.py +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/tests/conftest.py +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/tests/core/test_auto_init_devices.py +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/tests/core/test_detector.py +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/tests/core/test_device.py +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/tests/core/test_flyer.py +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/tests/core/test_log.py +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/tests/core/test_mock_signal_backend.py +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/tests/core/test_protocol.py +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/tests/core/test_providers.py +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/tests/core/test_readable.py +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/tests/core/test_signal.py +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/tests/core/test_soft_signal_backend.py +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/tests/core/test_status.py +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/tests/core/test_subset_enum.py +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/tests/core/test_table.py +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/tests/core/test_utils.py +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/tests/core/test_watchable_async_status.py +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/tests/epics/adcore/test_cont_acq_detector.py +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/tests/epics/adcore/test_detectors.py +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/tests/epics/adcore/test_drivers.py +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/tests/epics/adcore/test_scans.py +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/tests/epics/adcore/test_single_trigger.py +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/tests/epics/adcore/test_writers.py +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/tests/epics/adkinetix/test_kinetix.py +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/tests/epics/adsimdetector/test_sim.py +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/tests/epics/advimba/test_vimba.py +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/tests/epics/demo/test_epics_demo.py +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/tests/epics/pvi/test_pvi.py +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/tests/epics/signal/test_signals.py +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/tests/epics/signal/test_yaml_save_ca.yaml +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/tests/epics/signal/test_yaml_save_pva.yaml +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/tests/epics/test_areadetector_subclass_naming.py +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/tests/fastcs/panda/db/panda.db +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/tests/fastcs/panda/test_hdf_panda.py +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/tests/fastcs/panda/test_panda_connect.py +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/tests/fastcs/panda/test_panda_control.py +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/tests/fastcs/panda/test_panda_utils.py +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/tests/fastcs/panda/test_seq_table.py +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/tests/fastcs/panda/test_trigger.py +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/tests/fastcs/panda/test_writer.py +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/tests/plan_stubs/test_ensure_connected.py +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/tests/plan_stubs/test_fly.py +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/tests/plan_stubs/test_settings.py +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/tests/plan_stubs/test_setup.py +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/tests/sim/__init__.py +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/tests/sim/test_sim_blob_detector.py +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/tests/sim/test_sim_motor.py +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/tests/tango/conftest.py +1 -1
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/tests/tango/context_subprocess.py +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/tests/tango/test_base_device.py +10 -10
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/tests/tango/test_tango_signals.py +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/tests/tango/test_tango_transport.py +9 -9
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/tests/test_cli.py +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/tests/test_data/test_yaml_config_save.yaml +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/tests/test_data/test_yaml_save.yaml +0 -0
- {ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/tests/test_tutorials.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: ophyd-async
|
|
3
|
-
Version: 0.10.
|
|
3
|
+
Version: 0.10.0a4
|
|
4
4
|
Summary: Asynchronous Bluesky hardware abstraction code, compatible with control systems like EPICS and Tango
|
|
5
5
|
Author-email: Tom Cobb <tom.cobb@diamond.ac.uk>
|
|
6
6
|
License: BSD 3-Clause License
|
|
@@ -17,5 +17,5 @@ __version__: str
|
|
|
17
17
|
__version_tuple__: VERSION_TUPLE
|
|
18
18
|
version_tuple: VERSION_TUPLE
|
|
19
19
|
|
|
20
|
-
__version__ = version = '0.10.
|
|
21
|
-
__version_tuple__ = version_tuple = (0, 10, 0, '
|
|
20
|
+
__version__ = version = '0.10.0a4'
|
|
21
|
+
__version_tuple__ = version_tuple = (0, 10, 0, 'a4')
|
|
@@ -75,11 +75,13 @@ from ._utils import (
|
|
|
75
75
|
DEFAULT_TIMEOUT,
|
|
76
76
|
CalculatableTimeout,
|
|
77
77
|
Callback,
|
|
78
|
+
EnumTypes,
|
|
78
79
|
LazyMock,
|
|
79
80
|
NotConnected,
|
|
80
81
|
Reference,
|
|
81
82
|
StrictEnum,
|
|
82
83
|
SubsetEnum,
|
|
84
|
+
SupersetEnum,
|
|
83
85
|
WatcherUpdate,
|
|
84
86
|
gather_dict,
|
|
85
87
|
get_dtype,
|
|
@@ -122,6 +124,8 @@ __all__ = [
|
|
|
122
124
|
"Array1D",
|
|
123
125
|
"StrictEnum",
|
|
124
126
|
"SubsetEnum",
|
|
127
|
+
"SupersetEnum",
|
|
128
|
+
"EnumTypes",
|
|
125
129
|
"Table",
|
|
126
130
|
"SignalMetadata",
|
|
127
131
|
# Soft signal
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
from collections.abc import Awaitable, Callable
|
|
2
|
-
from typing import Any, Generic, get_type_hints, is_typeddict
|
|
2
|
+
from typing import Any, Generic, get_args, get_origin, get_type_hints, is_typeddict
|
|
3
|
+
|
|
4
|
+
from bluesky.protocols import Locatable
|
|
3
5
|
|
|
4
6
|
from ._derived_signal_backend import (
|
|
5
7
|
DerivedSignalBackend,
|
|
@@ -8,7 +10,7 @@ from ._derived_signal_backend import (
|
|
|
8
10
|
TransformT,
|
|
9
11
|
)
|
|
10
12
|
from ._device import Device
|
|
11
|
-
from ._signal import SignalR, SignalRW, SignalT, SignalW
|
|
13
|
+
from ._signal import Signal, SignalR, SignalRW, SignalT, SignalW
|
|
12
14
|
from ._signal_backend import SignalDatatypeT
|
|
13
15
|
|
|
14
16
|
|
|
@@ -35,15 +37,27 @@ class DerivedSignalFactory(Generic[TransformT]):
|
|
|
35
37
|
self._set_derived = set_derived
|
|
36
38
|
# Check the raw and transform devices match the input arguments of the Transform
|
|
37
39
|
if transform_cls is not Transform:
|
|
38
|
-
expected
|
|
39
|
-
|
|
40
|
-
for
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
40
|
+
# Populate expected parameters and types
|
|
41
|
+
expected = {
|
|
42
|
+
**{k: f.annotation for k, f in transform_cls.model_fields.items()},
|
|
43
|
+
**{
|
|
44
|
+
k: v
|
|
45
|
+
for k, v in get_type_hints(transform_cls.raw_to_derived).items()
|
|
46
|
+
if k not in {"self", "return"}
|
|
47
|
+
},
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
# Populate received parameters and types
|
|
51
|
+
# Use Signal datatype, or Locatable datatype, or set type as None
|
|
52
|
+
received = {
|
|
53
|
+
k: v.datatype if isinstance(v, Signal) else get_locatable_type(v)
|
|
54
|
+
for k, v in raw_and_transform_devices.items()
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
if expected != received:
|
|
44
58
|
msg = (
|
|
45
|
-
f"Expected devices to be passed as keyword arguments
|
|
46
|
-
f"got {
|
|
59
|
+
f"Expected devices to be passed as keyword arguments "
|
|
60
|
+
f"{expected}, got {received}"
|
|
47
61
|
)
|
|
48
62
|
raise TypeError(msg)
|
|
49
63
|
self._set_derived_takes_dict = (
|
|
@@ -269,3 +283,17 @@ def derived_signal_w(
|
|
|
269
283
|
units=derived_units,
|
|
270
284
|
precision=derived_precision,
|
|
271
285
|
)
|
|
286
|
+
|
|
287
|
+
|
|
288
|
+
def get_locatable_type(obj: object) -> type | None:
|
|
289
|
+
"""Extract datatype from Locatable parent class.
|
|
290
|
+
|
|
291
|
+
:param obj: Object with possible Locatable inheritance
|
|
292
|
+
:return: Type hint associated with Locatable, or None if not found.
|
|
293
|
+
"""
|
|
294
|
+
for base in getattr(obj.__class__, "__orig_bases__", []):
|
|
295
|
+
if get_origin(base) is Locatable:
|
|
296
|
+
args = get_args(base)
|
|
297
|
+
if args:
|
|
298
|
+
return args[0]
|
|
299
|
+
return None
|
|
@@ -328,10 +328,10 @@ class StandardDetector(
|
|
|
328
328
|
if isinstance(value.number_of_events, list)
|
|
329
329
|
else [value.number_of_events]
|
|
330
330
|
)
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
331
|
+
|
|
332
|
+
await self._controller.prepare(value)
|
|
333
|
+
self._describe = await self._writer.open(self.name, value.exposures_per_event)
|
|
334
|
+
|
|
335
335
|
self._initial_frame = await self._writer.get_indices_written()
|
|
336
336
|
if value.trigger != DetectorTrigger.INTERNAL:
|
|
337
337
|
await self._controller.arm()
|
|
@@ -100,6 +100,11 @@ class Signal(Device, Generic[SignalDatatypeT]):
|
|
|
100
100
|
"""
|
|
101
101
|
return self._connector.backend.source(self.name, read=True)
|
|
102
102
|
|
|
103
|
+
@property
|
|
104
|
+
def datatype(self) -> type[SignalDatatypeT] | None:
|
|
105
|
+
"""Returns the datatype of the signal."""
|
|
106
|
+
return self._connector.backend.datatype
|
|
107
|
+
|
|
103
108
|
|
|
104
109
|
SignalT = TypeVar("SignalT", bound=Signal)
|
|
105
110
|
|
|
@@ -431,8 +436,8 @@ async def observe_signals_value(
|
|
|
431
436
|
Call subscribe_value on all the signals at the start, and clear_sub on
|
|
432
437
|
it at the end.
|
|
433
438
|
:param timeout:
|
|
434
|
-
If given, how long to wait for
|
|
435
|
-
update is not produced in this time then raise asyncio.TimeoutError.
|
|
439
|
+
If given, how long to wait for ANY updated value from shared queue in seconds.
|
|
440
|
+
If an update is not produced in this time then raise asyncio.TimeoutError.
|
|
436
441
|
:param done_status:
|
|
437
442
|
If this status is complete, stop observing and make the iterator return.
|
|
438
443
|
If it raises an exception then this exception will be raised by the
|
|
@@ -454,8 +459,10 @@ async def observe_signals_value(
|
|
|
454
459
|
q: asyncio.Queue[tuple[SignalR[SignalDatatypeT], SignalDatatypeT] | Status] = (
|
|
455
460
|
asyncio.Queue()
|
|
456
461
|
)
|
|
457
|
-
|
|
462
|
+
# dict to store signal subscription to remove it later
|
|
458
463
|
cbs: dict[SignalR, Callback] = {}
|
|
464
|
+
|
|
465
|
+
# subscribe signal to update queue and fill cbs dict
|
|
459
466
|
for signal in signals:
|
|
460
467
|
|
|
461
468
|
def queue_value(value: SignalDatatypeT, signal=signal):
|
|
@@ -468,6 +475,7 @@ async def observe_signals_value(
|
|
|
468
475
|
done_status.add_callback(q.put_nowait)
|
|
469
476
|
overall_deadline = time.monotonic() + done_timeout if done_timeout else None
|
|
470
477
|
try:
|
|
478
|
+
last_item = ()
|
|
471
479
|
while True:
|
|
472
480
|
if overall_deadline and time.monotonic() >= overall_deadline:
|
|
473
481
|
raise asyncio.TimeoutError(
|
|
@@ -476,14 +484,22 @@ async def observe_signals_value(
|
|
|
476
484
|
f"timeout {done_timeout}s"
|
|
477
485
|
)
|
|
478
486
|
iteration_timeout = _get_iteration_timeout(timeout, overall_deadline)
|
|
479
|
-
|
|
487
|
+
try:
|
|
488
|
+
item = await asyncio.wait_for(q.get(), iteration_timeout)
|
|
489
|
+
except asyncio.TimeoutError as exc:
|
|
490
|
+
raise asyncio.TimeoutError(
|
|
491
|
+
f"Timeout Error while waiting {iteration_timeout}s to update "
|
|
492
|
+
f"{[signal.source for signal in signals]}. "
|
|
493
|
+
f"Last observed signal and value were {last_item}"
|
|
494
|
+
) from exc
|
|
480
495
|
if done_status and item is done_status:
|
|
481
496
|
if exc := done_status.exception():
|
|
482
497
|
raise exc
|
|
483
498
|
else:
|
|
484
499
|
break
|
|
485
500
|
else:
|
|
486
|
-
|
|
501
|
+
last_item = cast(tuple[SignalR[SignalDatatypeT], SignalDatatypeT], item)
|
|
502
|
+
yield last_item
|
|
487
503
|
finally:
|
|
488
504
|
for signal, cb in cbs.items():
|
|
489
505
|
signal.clear_sub(cb)
|
|
@@ -6,8 +6,16 @@ import numpy as np
|
|
|
6
6
|
from bluesky.protocols import Reading
|
|
7
7
|
from event_model import DataKey, Dtype, Limits
|
|
8
8
|
|
|
9
|
+
from ophyd_async.core._utils import (
|
|
10
|
+
Callback,
|
|
11
|
+
EnumTypes,
|
|
12
|
+
StrictEnum,
|
|
13
|
+
SubsetEnum,
|
|
14
|
+
SupersetEnum,
|
|
15
|
+
get_enum_cls,
|
|
16
|
+
)
|
|
17
|
+
|
|
9
18
|
from ._table import Table
|
|
10
|
-
from ._utils import Callback, StrictEnum, get_enum_cls
|
|
11
19
|
|
|
12
20
|
DTypeScalar_co = TypeVar("DTypeScalar_co", covariant=True, bound=np.generic)
|
|
13
21
|
"""A numpy dtype like [](#numpy.float64)."""
|
|
@@ -24,7 +32,7 @@ E.g. `Array1D[np.float64]` is a 1D numpy array of 64-bit floats."""
|
|
|
24
32
|
Primitive = bool | int | float | str
|
|
25
33
|
SignalDatatype = (
|
|
26
34
|
Primitive
|
|
27
|
-
|
|
|
35
|
+
| EnumTypes
|
|
28
36
|
| Array1D[np.bool_]
|
|
29
37
|
| Array1D[np.int8]
|
|
30
38
|
| Array1D[np.uint8]
|
|
@@ -39,16 +47,18 @@ SignalDatatype = (
|
|
|
39
47
|
| np.ndarray
|
|
40
48
|
| Sequence[str]
|
|
41
49
|
| Sequence[StrictEnum]
|
|
50
|
+
| Sequence[SubsetEnum]
|
|
51
|
+
| Sequence[SupersetEnum]
|
|
42
52
|
| Table
|
|
43
53
|
)
|
|
44
54
|
"""The supported [](#Signal) datatypes:
|
|
45
55
|
|
|
46
56
|
- A python primitive [](#bool), [](#int), [](#float), [](#str)
|
|
47
|
-
-
|
|
57
|
+
- An [](#EnumTypes) subclass
|
|
48
58
|
- A fixed datatype [](#Array1D) of numpy bool, signed and unsigned integers or float
|
|
49
59
|
- A [](#numpy.ndarray) which can change dimensions and datatype at runtime
|
|
50
60
|
- A sequence of [](#str)
|
|
51
|
-
- A sequence of [](#
|
|
61
|
+
- A sequence of [](#EnumTypes) subclasses
|
|
52
62
|
- A [](#Table) subclass
|
|
53
63
|
"""
|
|
54
64
|
# TODO: These typevars will not be needed when we drop python 3.11
|
|
@@ -58,7 +68,7 @@ PrimitiveT = TypeVar("PrimitiveT", bound=Primitive)
|
|
|
58
68
|
SignalDatatypeT = TypeVar("SignalDatatypeT", bound=SignalDatatype)
|
|
59
69
|
"""A typevar for a [](#SignalDatatype)."""
|
|
60
70
|
SignalDatatypeV = TypeVar("SignalDatatypeV", bound=SignalDatatype)
|
|
61
|
-
EnumT = TypeVar("EnumT", bound=
|
|
71
|
+
EnumT = TypeVar("EnumT", bound=EnumTypes)
|
|
62
72
|
TableT = TypeVar("TableT", bound=Table)
|
|
63
73
|
|
|
64
74
|
|
|
@@ -136,7 +146,7 @@ def _datakey_dtype(datatype: type[SignalDatatype]) -> Dtype:
|
|
|
136
146
|
or issubclass(datatype, Table)
|
|
137
147
|
):
|
|
138
148
|
return "array"
|
|
139
|
-
elif issubclass(datatype,
|
|
149
|
+
elif issubclass(datatype, EnumTypes):
|
|
140
150
|
return "string"
|
|
141
151
|
elif issubclass(datatype, Primitive):
|
|
142
152
|
return _primitive_dtype[datatype]
|
|
@@ -153,7 +163,7 @@ def _datakey_dtype_numpy(
|
|
|
153
163
|
elif (
|
|
154
164
|
get_origin(datatype) is Sequence
|
|
155
165
|
or datatype is str
|
|
156
|
-
or issubclass(datatype,
|
|
166
|
+
or issubclass(datatype, EnumTypes)
|
|
157
167
|
):
|
|
158
168
|
# TODO: use np.dtypes.StringDType when we can use in structured arrays
|
|
159
169
|
# https://github.com/numpy/numpy/issues/25693
|
|
@@ -167,7 +177,7 @@ def _datakey_dtype_numpy(
|
|
|
167
177
|
|
|
168
178
|
|
|
169
179
|
def _datakey_shape(value: SignalDatatype) -> list[int]:
|
|
170
|
-
if type(value) in _primitive_dtype or isinstance(value,
|
|
180
|
+
if type(value) in _primitive_dtype or isinstance(value, EnumTypes):
|
|
171
181
|
return []
|
|
172
182
|
elif isinstance(value, np.ndarray):
|
|
173
183
|
return list(value.shape)
|
|
@@ -5,7 +5,15 @@ import logging
|
|
|
5
5
|
from collections.abc import Awaitable, Callable, Iterable, Mapping, Sequence
|
|
6
6
|
from dataclasses import dataclass
|
|
7
7
|
from enum import Enum, EnumMeta
|
|
8
|
-
from typing import
|
|
8
|
+
from typing import (
|
|
9
|
+
Any,
|
|
10
|
+
Generic,
|
|
11
|
+
Literal,
|
|
12
|
+
ParamSpec,
|
|
13
|
+
TypeVar,
|
|
14
|
+
get_args,
|
|
15
|
+
get_origin,
|
|
16
|
+
)
|
|
9
17
|
from unittest.mock import Mock
|
|
10
18
|
|
|
11
19
|
import numpy as np
|
|
@@ -19,20 +27,16 @@ DEFAULT_TIMEOUT = 10.0
|
|
|
19
27
|
logger = logging.getLogger("ophyd_async")
|
|
20
28
|
|
|
21
29
|
|
|
22
|
-
class
|
|
23
|
-
def __new__(
|
|
24
|
-
ret = super().__new__(
|
|
30
|
+
class UppercaseNameEnumMeta(EnumMeta):
|
|
31
|
+
def __new__(cls, *args, **kwargs):
|
|
32
|
+
ret = super().__new__(cls, *args, **kwargs)
|
|
25
33
|
lowercase_names = [x.name for x in ret if not x.name.isupper()] # type: ignore
|
|
26
34
|
if lowercase_names:
|
|
27
35
|
raise TypeError(f"Names {lowercase_names} should be uppercase")
|
|
28
36
|
return ret
|
|
29
37
|
|
|
30
38
|
|
|
31
|
-
class
|
|
32
|
-
"""All members should exist in the Backend, and there will be no extras."""
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
class SubsetEnumMeta(StrictEnumMeta):
|
|
39
|
+
class AnyStringUppercaseNameEnumMeta(UppercaseNameEnumMeta):
|
|
36
40
|
def __call__(self, value, *args, **kwargs): # type: ignore
|
|
37
41
|
"""Return given value if it is a string and not a member of the enum.
|
|
38
42
|
|
|
@@ -54,10 +58,21 @@ class SubsetEnumMeta(StrictEnumMeta):
|
|
|
54
58
|
return super().__call__(value, *args, **kwargs)
|
|
55
59
|
|
|
56
60
|
|
|
57
|
-
class
|
|
61
|
+
class StrictEnum(str, Enum, metaclass=UppercaseNameEnumMeta):
|
|
62
|
+
"""All members should exist in the Backend, and there will be no extras."""
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
class SubsetEnum(str, Enum, metaclass=AnyStringUppercaseNameEnumMeta):
|
|
58
66
|
"""All members should exist in the Backend, but there may be extras."""
|
|
59
67
|
|
|
60
68
|
|
|
69
|
+
class SupersetEnum(str, Enum, metaclass=UppercaseNameEnumMeta):
|
|
70
|
+
"""Some members should exist in the Backend, and there should be no extras."""
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
EnumTypes = StrictEnum | SubsetEnum | SupersetEnum
|
|
74
|
+
|
|
75
|
+
|
|
61
76
|
CALCULATE_TIMEOUT = "CALCULATE_TIMEOUT"
|
|
62
77
|
"""Sentinel used to implement ``myfunc(timeout=CalculateTimeout)``
|
|
63
78
|
|
|
@@ -207,10 +222,11 @@ def get_dtype(datatype: type) -> np.dtype:
|
|
|
207
222
|
return np.dtype(get_args(get_args(datatype)[1])[0])
|
|
208
223
|
|
|
209
224
|
|
|
210
|
-
def get_enum_cls(datatype: type | None) -> type[
|
|
225
|
+
def get_enum_cls(datatype: type | None) -> type[EnumTypes] | None:
|
|
211
226
|
"""Get the enum class from a datatype.
|
|
212
227
|
|
|
213
|
-
:raises TypeError: if type is not a [](#StrictEnum) or [](#SubsetEnum)
|
|
228
|
+
:raises TypeError: if type is not a [](#StrictEnum) or [](#SubsetEnum)
|
|
229
|
+
or [](#SupersetEnum) subclass
|
|
214
230
|
```python
|
|
215
231
|
>>> from ophyd_async.core import StrictEnum
|
|
216
232
|
>>> from collections.abc import Sequence
|
|
@@ -227,10 +243,11 @@ def get_enum_cls(datatype: type | None) -> type[StrictEnum] | None:
|
|
|
227
243
|
if get_origin(datatype) is Sequence:
|
|
228
244
|
datatype = get_args(datatype)[0]
|
|
229
245
|
if datatype and issubclass(datatype, Enum):
|
|
230
|
-
if not issubclass(datatype,
|
|
246
|
+
if not issubclass(datatype, EnumTypes):
|
|
231
247
|
raise TypeError(
|
|
232
248
|
f"{datatype} should inherit from ophyd_async.core.SubsetEnum "
|
|
233
|
-
"or ophyd_async.core.StrictEnum"
|
|
249
|
+
"or ophyd_async.core.StrictEnum "
|
|
250
|
+
"or ophyd_async.core.SupersetEnum."
|
|
234
251
|
)
|
|
235
252
|
return datatype
|
|
236
253
|
return None
|
{ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/src/ophyd_async/epics/adcore/_core_detector.py
RENAMED
|
@@ -22,8 +22,8 @@ class AreaDetector(StandardDetector[ADBaseControllerT, ADWriter]):
|
|
|
22
22
|
self.fileio = writer.fileio
|
|
23
23
|
|
|
24
24
|
if plugins is not None:
|
|
25
|
-
for
|
|
26
|
-
setattr(self,
|
|
25
|
+
for plugin_name, plugin in plugins.items():
|
|
26
|
+
setattr(self, plugin_name, plugin)
|
|
27
27
|
|
|
28
28
|
super().__init__(
|
|
29
29
|
controller,
|
|
@@ -70,14 +70,14 @@ class NDPluginStatsIO(NDPluginBaseIO):
|
|
|
70
70
|
# Basic statistics
|
|
71
71
|
compute_statistics: A[SignalRW[bool], PvSuffix.rbv("ComputeStatistics")]
|
|
72
72
|
bgd_width: A[SignalRW[int], PvSuffix.rbv("BgdWidth")]
|
|
73
|
-
|
|
73
|
+
total: A[SignalR[float], PvSuffix.rbv("Total")]
|
|
74
74
|
# Centroid statistics
|
|
75
75
|
compute_centroid: A[SignalRW[bool], PvSuffix.rbv("ComputeCentroid")]
|
|
76
76
|
centroid_threshold: A[SignalRW[float], PvSuffix.rbv("CentroidThreshold")]
|
|
77
77
|
# X and Y Profiles
|
|
78
78
|
compute_profiles: A[SignalRW[bool], PvSuffix.rbv("ComputeProfiles")]
|
|
79
|
-
profile_size_x: A[
|
|
80
|
-
profile_size_y: A[
|
|
79
|
+
profile_size_x: A[SignalR[int], PvSuffix.rbv("ProfileSizeX")]
|
|
80
|
+
profile_size_y: A[SignalR[int], PvSuffix.rbv("ProfileSizeY")]
|
|
81
81
|
cursor_x: A[SignalRW[int], PvSuffix.rbv("CursorX")]
|
|
82
82
|
cursor_y: A[SignalRW[int], PvSuffix.rbv("CursorY")]
|
|
83
83
|
# Array Histogram
|
|
@@ -7,11 +7,12 @@ from ophyd_async.core import (
|
|
|
7
7
|
SignalRW,
|
|
8
8
|
StrictEnum,
|
|
9
9
|
SubsetEnum,
|
|
10
|
+
SupersetEnum,
|
|
10
11
|
wait_for_value,
|
|
11
12
|
)
|
|
12
13
|
|
|
13
14
|
|
|
14
|
-
class ADBaseDataType(
|
|
15
|
+
class ADBaseDataType(SupersetEnum):
|
|
15
16
|
INT8 = "Int8"
|
|
16
17
|
UINT8 = "UInt8"
|
|
17
18
|
INT16 = "Int16"
|
|
@@ -22,6 +23,9 @@ class ADBaseDataType(StrictEnum):
|
|
|
22
23
|
UINT64 = "UInt64"
|
|
23
24
|
FLOAT32 = "Float32"
|
|
24
25
|
FLOAT64 = "Float64"
|
|
26
|
+
# Driver database override will blank the enum string if it doesn't
|
|
27
|
+
# support a datatype
|
|
28
|
+
UNDEFINED = ""
|
|
25
29
|
|
|
26
30
|
|
|
27
31
|
def convert_ad_dtype_to_np(ad_dtype: ADBaseDataType) -> str:
|
|
@@ -37,7 +41,12 @@ def convert_ad_dtype_to_np(ad_dtype: ADBaseDataType) -> str:
|
|
|
37
41
|
ADBaseDataType.FLOAT32: "<f4",
|
|
38
42
|
ADBaseDataType.FLOAT64: "<f8",
|
|
39
43
|
}
|
|
40
|
-
|
|
44
|
+
np_type = ad_dtype_to_np_dtype.get(ad_dtype)
|
|
45
|
+
if np_type is None:
|
|
46
|
+
raise ValueError(
|
|
47
|
+
"Areadetector driver has a blank DataType, this is not supported"
|
|
48
|
+
)
|
|
49
|
+
return np_type
|
|
41
50
|
|
|
42
51
|
|
|
43
52
|
def convert_pv_dtype_to_np(datatype: str) -> str:
|
|
@@ -27,7 +27,7 @@ class PilatusDetector(AreaDetector[PilatusController]):
|
|
|
27
27
|
config_sigs: Sequence[SignalR] = (),
|
|
28
28
|
):
|
|
29
29
|
driver = PilatusDriverIO(prefix + drv_suffix)
|
|
30
|
-
controller = PilatusController(driver)
|
|
30
|
+
controller = PilatusController(driver, readout_time=readout_time)
|
|
31
31
|
|
|
32
32
|
writer = writer_cls.with_io(
|
|
33
33
|
prefix,
|
{ophyd_async-0.10.0a3 → ophyd_async-0.10.0a4}/src/ophyd_async/epics/adpilatus/_pilatus_controller.py
RENAMED
|
@@ -29,6 +29,7 @@ class PilatusController(adcore.ADBaseController[PilatusDriverIO]):
|
|
|
29
29
|
DetectorTrigger.INTERNAL: PilatusTriggerMode.INTERNAL,
|
|
30
30
|
DetectorTrigger.CONSTANT_GATE: PilatusTriggerMode.EXT_ENABLE,
|
|
31
31
|
DetectorTrigger.VARIABLE_GATE: PilatusTriggerMode.EXT_ENABLE,
|
|
32
|
+
DetectorTrigger.EDGE_TRIGGER: PilatusTriggerMode.EXT_TRIGGER,
|
|
32
33
|
}
|
|
33
34
|
|
|
34
35
|
def __init__(
|
|
@@ -49,7 +50,9 @@ class PilatusController(adcore.ADBaseController[PilatusDriverIO]):
|
|
|
49
50
|
trigger_info.livetime
|
|
50
51
|
)
|
|
51
52
|
await asyncio.gather(
|
|
52
|
-
self.driver.trigger_mode.set(
|
|
53
|
+
self.driver.trigger_mode.set(
|
|
54
|
+
self._supported_trigger_types[trigger_info.trigger]
|
|
55
|
+
),
|
|
53
56
|
self.driver.num_images.set(
|
|
54
57
|
999_999
|
|
55
58
|
if trigger_info.total_number_of_exposures == 0
|
|
@@ -70,13 +73,3 @@ class PilatusController(adcore.ADBaseController[PilatusDriverIO]):
|
|
|
70
73
|
True,
|
|
71
74
|
timeout=DEFAULT_TIMEOUT,
|
|
72
75
|
)
|
|
73
|
-
|
|
74
|
-
@classmethod
|
|
75
|
-
def _get_trigger_mode(cls, trigger: DetectorTrigger) -> PilatusTriggerMode:
|
|
76
|
-
if trigger not in cls._supported_trigger_types.keys():
|
|
77
|
-
raise ValueError(
|
|
78
|
-
f"{cls.__name__} only supports the following trigger "
|
|
79
|
-
f"types: {cls._supported_trigger_types.keys()} but was asked to "
|
|
80
|
-
f"use {trigger}"
|
|
81
|
-
)
|
|
82
|
-
return cls._supported_trigger_types[trigger]
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import logging
|
|
2
2
|
import sys
|
|
3
3
|
import typing
|
|
4
|
-
from collections.abc import Sequence
|
|
4
|
+
from collections.abc import Mapping, Sequence
|
|
5
5
|
from functools import cache
|
|
6
6
|
from math import isnan, nan
|
|
7
7
|
from typing import Any, Generic, cast
|
|
@@ -146,7 +146,7 @@ class CaBoolConverter(CaConverter[bool]):
|
|
|
146
146
|
|
|
147
147
|
|
|
148
148
|
class CaEnumConverter(CaConverter[str]):
|
|
149
|
-
def __init__(self, supported_values:
|
|
149
|
+
def __init__(self, supported_values: Mapping[str, str]):
|
|
150
150
|
self.supported_values = supported_values
|
|
151
151
|
super().__init__(
|
|
152
152
|
str, dbr.DBR_STRING, metadata=SignalMetadata(choices=list(supported_values))
|
|
@@ -1,16 +1,20 @@
|
|
|
1
|
-
from collections.abc import Sequence
|
|
2
|
-
from typing import Any, get_args, get_origin
|
|
1
|
+
from collections.abc import Mapping, Sequence
|
|
2
|
+
from typing import Any, TypeVar, get_args, get_origin
|
|
3
3
|
|
|
4
4
|
import numpy as np
|
|
5
5
|
|
|
6
6
|
from ophyd_async.core import (
|
|
7
7
|
SignalBackend,
|
|
8
8
|
SignalDatatypeT,
|
|
9
|
+
StrictEnum,
|
|
9
10
|
SubsetEnum,
|
|
11
|
+
SupersetEnum,
|
|
10
12
|
get_dtype,
|
|
11
13
|
get_enum_cls,
|
|
12
14
|
)
|
|
13
15
|
|
|
16
|
+
T = TypeVar("T")
|
|
17
|
+
|
|
14
18
|
|
|
15
19
|
def get_pv_basename_and_field(pv: str) -> tuple[str, str | None]:
|
|
16
20
|
"""Split PV into record name and field."""
|
|
@@ -23,26 +27,30 @@ def get_pv_basename_and_field(pv: str) -> tuple[str, str | None]:
|
|
|
23
27
|
|
|
24
28
|
def get_supported_values(
|
|
25
29
|
pv: str,
|
|
26
|
-
datatype: type,
|
|
30
|
+
datatype: type[T],
|
|
27
31
|
pv_choices: Sequence[str],
|
|
28
|
-
) ->
|
|
32
|
+
) -> Mapping[str, T | str]:
|
|
29
33
|
enum_cls = get_enum_cls(datatype)
|
|
30
34
|
if not enum_cls:
|
|
31
35
|
raise TypeError(f"{datatype} is not an Enum")
|
|
32
36
|
choices = [v.value for v in enum_cls]
|
|
33
37
|
error_msg = f"{pv} has choices {pv_choices}, but {datatype} requested {choices} "
|
|
34
|
-
if issubclass(enum_cls,
|
|
38
|
+
if issubclass(enum_cls, StrictEnum):
|
|
39
|
+
if set(choices) != set(pv_choices):
|
|
40
|
+
raise TypeError(error_msg + "to be strictly equal to them.")
|
|
41
|
+
elif issubclass(enum_cls, SubsetEnum):
|
|
35
42
|
if not set(choices).issubset(pv_choices):
|
|
36
43
|
raise TypeError(error_msg + "to be a subset of them.")
|
|
44
|
+
elif issubclass(enum_cls, SupersetEnum):
|
|
45
|
+
if not set(pv_choices).issubset(choices):
|
|
46
|
+
raise TypeError(error_msg + "to be a superset of them.")
|
|
37
47
|
else:
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
#
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
for v in enum_cls:
|
|
45
|
-
supported_values[v.value] = v
|
|
48
|
+
raise TypeError(f"{datatype} is not a StrictEnum, SubsetEnum, or SupersetEnum")
|
|
49
|
+
# Create a map from the string value to the enum instance
|
|
50
|
+
# For StrictEnum and SupersetEnum, all values here will be enum values
|
|
51
|
+
# For SubsetEnum, only the values in choices will be enum values, the rest will be
|
|
52
|
+
# strings
|
|
53
|
+
supported_values = {x: enum_cls(x) for x in pv_choices}
|
|
46
54
|
return supported_values
|
|
47
55
|
|
|
48
56
|
|
|
@@ -10,9 +10,10 @@ from ophyd_async.core import (
|
|
|
10
10
|
Device,
|
|
11
11
|
DeviceVector,
|
|
12
12
|
PathProvider,
|
|
13
|
+
Reference,
|
|
14
|
+
SignalR,
|
|
13
15
|
StrictEnum,
|
|
14
16
|
observe_value,
|
|
15
|
-
set_and_wait_for_other_value,
|
|
16
17
|
set_and_wait_for_value,
|
|
17
18
|
wait_for_value,
|
|
18
19
|
)
|
|
@@ -51,7 +52,7 @@ class Odin(Device):
|
|
|
51
52
|
|
|
52
53
|
self.capture = epics_signal_rw(Writing, f"{prefix}Capture")
|
|
53
54
|
self.capture_rbv = epics_signal_r(str, prefix + "Capture_RBV")
|
|
54
|
-
self.num_captured = epics_signal_r(int, f"{prefix}
|
|
55
|
+
self.num_captured = epics_signal_r(int, f"{prefix}NumCaptured_RBV")
|
|
55
56
|
self.num_to_capture = epics_signal_rw_rbv(int, f"{prefix}NumCapture")
|
|
56
57
|
|
|
57
58
|
self.start_timeout = epics_signal_rw(str, f"{prefix}StartTimeout")
|
|
@@ -80,9 +81,11 @@ class OdinWriter(DetectorWriter):
|
|
|
80
81
|
self,
|
|
81
82
|
path_provider: PathProvider,
|
|
82
83
|
odin_driver: Odin,
|
|
84
|
+
eiger_bit_depth: SignalR[int],
|
|
83
85
|
) -> None:
|
|
84
86
|
self._drv = odin_driver
|
|
85
87
|
self._path_provider = path_provider
|
|
88
|
+
self._eiger_bit_depth = Reference(eiger_bit_depth)
|
|
86
89
|
super().__init__()
|
|
87
90
|
|
|
88
91
|
async def open(self, name: str, exposures_per_event: int = 1) -> dict[str, DataKey]:
|
|
@@ -92,24 +95,20 @@ class OdinWriter(DetectorWriter):
|
|
|
92
95
|
await asyncio.gather(
|
|
93
96
|
self._drv.file_path.set(str(info.directory_path)),
|
|
94
97
|
self._drv.file_name.set(info.filename),
|
|
95
|
-
self._drv.data_type.set(
|
|
96
|
-
"UInt16"
|
|
97
|
-
), # TODO: Get from eiger https://github.com/bluesky/ophyd-async/issues/529
|
|
98
|
+
self._drv.data_type.set(f"UInt{await self._eiger_bit_depth().get_value()}"),
|
|
98
99
|
self._drv.num_to_capture.set(0),
|
|
99
100
|
)
|
|
100
101
|
|
|
101
102
|
await wait_for_value(self._drv.meta_active, "Active", timeout=DEFAULT_TIMEOUT)
|
|
102
103
|
|
|
103
|
-
await
|
|
104
|
-
|
|
105
|
-
Writing.CAPTURE,
|
|
106
|
-
self._drv.capture_rbv,
|
|
107
|
-
"Capturing",
|
|
108
|
-
set_timeout=None,
|
|
109
|
-
wait_for_set_completion=False,
|
|
104
|
+
await self._drv.capture.set(
|
|
105
|
+
Writing.CAPTURE, wait=False
|
|
110
106
|
) # TODO: Investigate why we do not get a put callback when setting capture pv https://github.com/bluesky/ophyd-async/issues/866
|
|
111
107
|
|
|
112
|
-
await
|
|
108
|
+
await asyncio.gather(
|
|
109
|
+
wait_for_value(self._drv.capture_rbv, "Capturing", timeout=DEFAULT_TIMEOUT),
|
|
110
|
+
wait_for_value(self._drv.meta_writing, "Writing", timeout=DEFAULT_TIMEOUT),
|
|
111
|
+
)
|
|
113
112
|
|
|
114
113
|
return await self._describe()
|
|
115
114
|
|
|
@@ -260,10 +260,11 @@ class Motor(
|
|
|
260
260
|
(await self.acceleration_time.get_value()) * fly_velocity * 0.5
|
|
261
261
|
)
|
|
262
262
|
|
|
263
|
-
|
|
263
|
+
direction = 1 if end_position > start_position else -1
|
|
264
|
+
self._fly_completed_position = end_position + (run_up_distance * direction)
|
|
264
265
|
|
|
265
266
|
# Prepared position not used after prepare, so no need to store in self
|
|
266
|
-
fly_prepared_position = start_position - run_up_distance
|
|
267
|
+
fly_prepared_position = start_position - (run_up_distance * direction)
|
|
267
268
|
|
|
268
269
|
motor_lower_limit, motor_upper_limit, egu = await asyncio.gather(
|
|
269
270
|
self.low_limit_travel.get_value(),
|