ophyd-async 0.10.0a4__tar.gz → 0.10.1__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.0a4 → ophyd_async-0.10.1}/PKG-INFO +2 -2
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/pyproject.toml +1 -1
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/src/ophyd_async/_version.py +2 -2
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/src/ophyd_async/core/_derived_signal.py +1 -1
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/src/ophyd_async/core/_derived_signal_backend.py +7 -5
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/src/ophyd_async/core/_hdf_dataset.py +1 -1
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/src/ophyd_async/core/_providers.py +1 -1
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/src/ophyd_async/core/_signal.py +6 -1
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/src/ophyd_async/core/_signal_backend.py +1 -1
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/src/ophyd_async/epics/adcore/_core_logic.py +34 -10
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/src/ophyd_async/epics/adcore/_hdf_writer.py +15 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/src/ophyd_async.egg-info/PKG-INFO +2 -2
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/src/ophyd_async.egg-info/requires.txt +1 -1
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/tests/core/test_multi_derived_signal.py +56 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/tests/core/test_signal.py +6 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/tests/core/test_single_derived_signal.py +108 -6
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/tests/epics/adcore/test_drivers.py +54 -2
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/tests/epics/adcore/test_writers.py +16 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/.codecov.yml +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/.copier-answers.yml +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/.devcontainer/devcontainer.json +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/.git-blame-ignore-revs +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/.github/CONTRIBUTING.md +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/.github/ISSUE_TEMPLATE/issue.md +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/.github/PULL_REQUEST_TEMPLATE/pull_request_template.md +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/.github/actions/install_requirements/action.yml +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/.github/codeql/codeql-config.yml +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/.github/dependabot.yml +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/.github/pages/index.html +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/.github/pages/make_switcher.py +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/.github/workflows/_check.yml +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/.github/workflows/_codeql.yml +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/.github/workflows/_dist.yml +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/.github/workflows/_docs.yml +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/.github/workflows/_import_with_no_extras.yml +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/.github/workflows/_pypi.yml +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/.github/workflows/_release.yml +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/.github/workflows/_test.yml +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/.github/workflows/_tox.yml +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/.github/workflows/ci.yml +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/.github/workflows/periodic.yml +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/.gitignore +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/.pre-commit-config.yaml +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/Dockerfile +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/LICENSE +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/README.md +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/docs/_static/custom.css +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/docs/conf.py +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/docs/explanations/decisions/0001-record-architecture-decisions.md +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/docs/explanations/decisions/0002-switched-to-python-copier-template.md +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/docs/explanations/decisions/0003-ophyd-async-migration.rst +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/docs/explanations/decisions/0004-repository-structure.rst +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/docs/explanations/decisions/0005-respect-black-line-length.rst +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/docs/explanations/decisions/0006-procedural-device-definitions.rst +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/docs/explanations/decisions/0007-subpackage-structure.md +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/docs/explanations/decisions/0008-signal-types.md +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/docs/explanations/decisions/0009-procedural-vs-declarative-devices.md +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/docs/explanations/decisions/0010-docstring-format.md +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/docs/explanations/decisions/COPYME +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/docs/explanations/decisions.md +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/docs/explanations/declarative-vs-procedural.md +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/docs/explanations/design-goals.md +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/docs/explanations/device-connection-strategies.md +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/docs/explanations/devices-signals-backends.md +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/docs/explanations/flyscanning.md +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/docs/explanations/where-device-logic.md +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/docs/explanations.md +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/docs/genindex.rst +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/docs/how-to/choose-right-baseclass.md +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/docs/how-to/contribute.md +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/docs/how-to/derive-one-signal-from-others.md +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/docs/how-to/implement-ad-detector.md +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/docs/how-to/interact-with-signals.md +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/docs/how-to/put-device-back.md +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/docs/how-to/store-and-retrieve.md +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/docs/how-to.md +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/docs/images/flyscan_collection_windows_and_frames.svg +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/docs/images/ophyd-async-logo.svg +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/docs/images/ophyd-favicon.svg +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/docs/images/set_and_wait_for_other_value.excalidraw.svg +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/docs/index.md +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/docs/reference.md +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/docs/tutorials/implementing-detectors.md +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/docs/tutorials/implementing-devices.md +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/docs/tutorials/installation.md +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/docs/tutorials/using-devices.md +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/docs/tutorials/writing-tests-for-devices.md +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/docs/tutorials.md +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/setup.cfg +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/src/ophyd_async/__init__.py +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/src/ophyd_async/__main__.py +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/src/ophyd_async/_docs_parser.py +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/src/ophyd_async/core/__init__.py +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/src/ophyd_async/core/_detector.py +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/src/ophyd_async/core/_device.py +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/src/ophyd_async/core/_device_filler.py +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/src/ophyd_async/core/_flyer.py +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/src/ophyd_async/core/_log.py +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/src/ophyd_async/core/_mock_signal_backend.py +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/src/ophyd_async/core/_protocol.py +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/src/ophyd_async/core/_readable.py +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/src/ophyd_async/core/_settings.py +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/src/ophyd_async/core/_soft_signal_backend.py +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/src/ophyd_async/core/_status.py +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/src/ophyd_async/core/_table.py +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/src/ophyd_async/core/_utils.py +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/src/ophyd_async/core/_yaml_settings.py +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/src/ophyd_async/epics/__init__.py +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/src/ophyd_async/epics/adandor/__init__.py +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/src/ophyd_async/epics/adandor/_andor.py +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/src/ophyd_async/epics/adandor/_andor_controller.py +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/src/ophyd_async/epics/adandor/_andor_io.py +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/src/ophyd_async/epics/adaravis/__init__.py +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/src/ophyd_async/epics/adaravis/_aravis.py +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/src/ophyd_async/epics/adaravis/_aravis_controller.py +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/src/ophyd_async/epics/adaravis/_aravis_io.py +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/src/ophyd_async/epics/adcore/__init__.py +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/src/ophyd_async/epics/adcore/_core_detector.py +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/src/ophyd_async/epics/adcore/_core_io.py +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/src/ophyd_async/epics/adcore/_core_writer.py +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/src/ophyd_async/epics/adcore/_jpeg_writer.py +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/src/ophyd_async/epics/adcore/_single_trigger.py +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/src/ophyd_async/epics/adcore/_tiff_writer.py +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/src/ophyd_async/epics/adcore/_utils.py +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/src/ophyd_async/epics/adkinetix/__init__.py +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/src/ophyd_async/epics/adkinetix/_kinetix.py +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/src/ophyd_async/epics/adkinetix/_kinetix_controller.py +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/src/ophyd_async/epics/adkinetix/_kinetix_io.py +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/src/ophyd_async/epics/adpilatus/__init__.py +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/src/ophyd_async/epics/adpilatus/_pilatus.py +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/src/ophyd_async/epics/adpilatus/_pilatus_controller.py +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/src/ophyd_async/epics/adpilatus/_pilatus_io.py +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/src/ophyd_async/epics/adsimdetector/__init__.py +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/src/ophyd_async/epics/adsimdetector/_sim.py +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/src/ophyd_async/epics/adsimdetector/_sim_controller.py +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/src/ophyd_async/epics/adsimdetector/_sim_io.py +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/src/ophyd_async/epics/advimba/__init__.py +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/src/ophyd_async/epics/advimba/_vimba.py +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/src/ophyd_async/epics/advimba/_vimba_controller.py +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/src/ophyd_async/epics/advimba/_vimba_io.py +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/src/ophyd_async/epics/core/__init__.py +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/src/ophyd_async/epics/core/_aioca.py +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/src/ophyd_async/epics/core/_epics_connector.py +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/src/ophyd_async/epics/core/_epics_device.py +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/src/ophyd_async/epics/core/_p4p.py +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/src/ophyd_async/epics/core/_pvi_connector.py +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/src/ophyd_async/epics/core/_signal.py +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/src/ophyd_async/epics/core/_util.py +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/src/ophyd_async/epics/demo/__init__.py +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/src/ophyd_async/epics/demo/__main__.py +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/src/ophyd_async/epics/demo/_ioc.py +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/src/ophyd_async/epics/demo/_motor.py +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/src/ophyd_async/epics/demo/_point_detector.py +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/src/ophyd_async/epics/demo/_point_detector_channel.py +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/src/ophyd_async/epics/demo/_stage.py +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/src/ophyd_async/epics/demo/motor.db +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/src/ophyd_async/epics/demo/point_detector.db +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/src/ophyd_async/epics/demo/point_detector_channel.db +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/src/ophyd_async/epics/eiger/__init__.py +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/src/ophyd_async/epics/eiger/_odin_io.py +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/src/ophyd_async/epics/motor.py +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/src/ophyd_async/epics/signal.py +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/src/ophyd_async/epics/testing/__init__.py +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/src/ophyd_async/epics/testing/_example_ioc.py +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/src/ophyd_async/epics/testing/_utils.py +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/src/ophyd_async/epics/testing/test_records.db +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/src/ophyd_async/epics/testing/test_records_pva.db +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/src/ophyd_async/fastcs/__init__.py +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/src/ophyd_async/fastcs/core.py +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/src/ophyd_async/fastcs/eiger/__init__.py +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/src/ophyd_async/fastcs/eiger/_eiger.py +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/src/ophyd_async/fastcs/eiger/_eiger_controller.py +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/src/ophyd_async/fastcs/eiger/_eiger_io.py +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/src/ophyd_async/fastcs/odin/__init__.py +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/src/ophyd_async/fastcs/panda/__init__.py +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/src/ophyd_async/fastcs/panda/_block.py +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/src/ophyd_async/fastcs/panda/_control.py +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/src/ophyd_async/fastcs/panda/_hdf_panda.py +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/src/ophyd_async/fastcs/panda/_table.py +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/src/ophyd_async/fastcs/panda/_trigger.py +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/src/ophyd_async/fastcs/panda/_writer.py +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/src/ophyd_async/plan_stubs/__init__.py +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/src/ophyd_async/plan_stubs/_ensure_connected.py +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/src/ophyd_async/plan_stubs/_fly.py +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/src/ophyd_async/plan_stubs/_nd_attributes.py +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/src/ophyd_async/plan_stubs/_panda.py +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/src/ophyd_async/plan_stubs/_settings.py +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/src/ophyd_async/plan_stubs/_utils.py +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/src/ophyd_async/plan_stubs/_wait_for_awaitable.py +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/src/ophyd_async/py.typed +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/src/ophyd_async/sim/__init__.py +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/src/ophyd_async/sim/__main__.py +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/src/ophyd_async/sim/_blob_detector.py +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/src/ophyd_async/sim/_blob_detector_controller.py +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/src/ophyd_async/sim/_blob_detector_writer.py +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/src/ophyd_async/sim/_mirror_horizontal.py +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/src/ophyd_async/sim/_mirror_vertical.py +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/src/ophyd_async/sim/_motor.py +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/src/ophyd_async/sim/_pattern_generator.py +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/src/ophyd_async/sim/_point_detector.py +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/src/ophyd_async/sim/_stage.py +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/src/ophyd_async/tango/__init__.py +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/src/ophyd_async/tango/core/__init__.py +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/src/ophyd_async/tango/core/_base_device.py +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/src/ophyd_async/tango/core/_converters.py +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/src/ophyd_async/tango/core/_signal.py +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/src/ophyd_async/tango/core/_tango_readable.py +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/src/ophyd_async/tango/core/_tango_transport.py +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/src/ophyd_async/tango/core/_utils.py +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/src/ophyd_async/tango/demo/__init__.py +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/src/ophyd_async/tango/demo/_counter.py +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/src/ophyd_async/tango/demo/_detector.py +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/src/ophyd_async/tango/demo/_mover.py +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/src/ophyd_async/tango/demo/_tango/__init__.py +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/src/ophyd_async/tango/demo/_tango/_servers.py +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/src/ophyd_async/tango/testing/__init__.py +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/src/ophyd_async/tango/testing/_one_of_everything.py +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/src/ophyd_async/testing/__init__.py +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/src/ophyd_async/testing/__pytest_assert_rewrite.py +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/src/ophyd_async/testing/_assert.py +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/src/ophyd_async/testing/_mock_signal_utils.py +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/src/ophyd_async/testing/_one_of_everything.py +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/src/ophyd_async/testing/_single_derived.py +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/src/ophyd_async/testing/_utils.py +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/src/ophyd_async/testing/_wait_for_pending.py +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/src/ophyd_async.egg-info/SOURCES.txt +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/src/ophyd_async.egg-info/dependency_links.txt +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/src/ophyd_async.egg-info/top_level.txt +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/system_tests/epics/eiger/README.md +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/system_tests/epics/eiger/start_iocs_and_run_tests.sh +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/system_tests/epics/eiger/test_eiger_system.py +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/tests/conftest.py +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/tests/core/test_auto_init_devices.py +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/tests/core/test_detector.py +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/tests/core/test_device.py +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/tests/core/test_flyer.py +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/tests/core/test_log.py +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/tests/core/test_mock_signal_backend.py +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/tests/core/test_observe.py +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/tests/core/test_protocol.py +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/tests/core/test_providers.py +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/tests/core/test_readable.py +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/tests/core/test_soft_signal_backend.py +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/tests/core/test_status.py +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/tests/core/test_subset_enum.py +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/tests/core/test_table.py +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/tests/core/test_utils.py +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/tests/core/test_watchable_async_status.py +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/tests/epics/adandor/test_andor.py +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/tests/epics/adaravis/test_aravis.py +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/tests/epics/adcore/test_cont_acq_detector.py +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/tests/epics/adcore/test_detectors.py +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/tests/epics/adcore/test_scans.py +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/tests/epics/adcore/test_single_trigger.py +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/tests/epics/adkinetix/test_kinetix.py +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/tests/epics/adpilatus/test_pilatus.py +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/tests/epics/adsimdetector/test_sim.py +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/tests/epics/advimba/test_vimba.py +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/tests/epics/conftest.py +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/tests/epics/demo/test_epics_demo.py +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/tests/epics/eiger/test_odin_io.py +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/tests/epics/pvi/test_pvi.py +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/tests/epics/signal/test_common.py +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/tests/epics/signal/test_signals.py +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/tests/epics/signal/test_yaml_save_ca.yaml +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/tests/epics/signal/test_yaml_save_pva.yaml +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/tests/epics/test_areadetector_subclass_naming.py +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/tests/epics/test_motor.py +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/tests/fastcs/eiger/test_eiger_controller.py +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/tests/fastcs/eiger/test_eiger_detector.py +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/tests/fastcs/panda/db/panda.db +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/tests/fastcs/panda/test_hdf_panda.py +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/tests/fastcs/panda/test_panda_connect.py +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/tests/fastcs/panda/test_panda_control.py +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/tests/fastcs/panda/test_panda_utils.py +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/tests/fastcs/panda/test_seq_table.py +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/tests/fastcs/panda/test_trigger.py +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/tests/fastcs/panda/test_writer.py +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/tests/plan_stubs/test_ensure_connected.py +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/tests/plan_stubs/test_fly.py +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/tests/plan_stubs/test_settings.py +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/tests/plan_stubs/test_setup.py +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/tests/sim/__init__.py +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/tests/sim/test_sim_blob_detector.py +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/tests/sim/test_sim_motor.py +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/tests/tango/conftest.py +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/tests/tango/context_subprocess.py +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/tests/tango/test_base_device.py +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/tests/tango/test_tango_signals.py +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/tests/tango/test_tango_transport.py +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/tests/test_cli.py +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/tests/test_data/test_yaml_config_save.yaml +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/tests/test_data/test_yaml_save.yaml +0 -0
- {ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/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.1
|
|
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
|
|
@@ -43,7 +43,7 @@ Description-Content-Type: text/markdown
|
|
|
43
43
|
License-File: LICENSE
|
|
44
44
|
Requires-Dist: numpy
|
|
45
45
|
Requires-Dist: bluesky>=1.13.1rc2
|
|
46
|
-
Requires-Dist: event-model>=1.
|
|
46
|
+
Requires-Dist: event-model>=1.23
|
|
47
47
|
Requires-Dist: pyyaml
|
|
48
48
|
Requires-Dist: colorlog
|
|
49
49
|
Requires-Dist: pydantic>=2.0
|
|
@@ -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,
|
|
20
|
+
__version__ = version = '0.10.1'
|
|
21
|
+
__version_tuple__ = version_tuple = (0, 10, 1)
|
|
@@ -248,7 +248,7 @@ def derived_signal_rw(
|
|
|
248
248
|
if raw_to_derived_datatype != set_derived_datatype:
|
|
249
249
|
msg = (
|
|
250
250
|
f"{raw_to_derived} has datatype {raw_to_derived_datatype} "
|
|
251
|
-
f"!= {set_derived_datatype}
|
|
251
|
+
f"!= {set_derived_datatype} datatype {set_derived_datatype}"
|
|
252
252
|
)
|
|
253
253
|
raise TypeError(msg)
|
|
254
254
|
|
|
@@ -61,7 +61,7 @@ class Transform(BaseModel, Generic[RawT, DerivedT]):
|
|
|
61
61
|
TransformT = TypeVar("TransformT", bound=Transform)
|
|
62
62
|
|
|
63
63
|
|
|
64
|
-
def
|
|
64
|
+
def validate_by_type(raw_devices: Mapping[str, Any], type_: type[T]) -> dict[str, T]:
|
|
65
65
|
filtered_devices: dict[str, T] = {}
|
|
66
66
|
for name, device in raw_devices.items():
|
|
67
67
|
if not isinstance(device, type_):
|
|
@@ -91,21 +91,23 @@ class SignalTransformer(Generic[TransformT]):
|
|
|
91
91
|
|
|
92
92
|
@cached_property
|
|
93
93
|
def raw_locatables(self) -> dict[str, AsyncLocatable]:
|
|
94
|
-
return
|
|
94
|
+
return validate_by_type(self._raw_devices, AsyncLocatable)
|
|
95
95
|
|
|
96
96
|
@cached_property
|
|
97
97
|
def transform_readables(self) -> dict[str, AsyncReadable]:
|
|
98
|
-
return
|
|
98
|
+
return validate_by_type(self._transform_devices, AsyncReadable)
|
|
99
99
|
|
|
100
100
|
@cached_property
|
|
101
101
|
def raw_and_transform_readables(self) -> dict[str, AsyncReadable]:
|
|
102
|
-
return
|
|
102
|
+
return validate_by_type(
|
|
103
103
|
self._raw_devices | self._transform_devices, AsyncReadable
|
|
104
104
|
)
|
|
105
105
|
|
|
106
106
|
@cached_property
|
|
107
107
|
def raw_and_transform_subscribables(self) -> dict[str, Subscribable]:
|
|
108
|
-
return
|
|
108
|
+
return validate_by_type(
|
|
109
|
+
self._raw_devices | self._transform_devices, Subscribable
|
|
110
|
+
)
|
|
109
111
|
|
|
110
112
|
def _complete_cached_reading(self) -> dict[str, Reading] | None:
|
|
111
113
|
if self._cached_readings and len(self._cached_readings) == len(
|
|
@@ -23,7 +23,7 @@ class HDFDatasetDescription(BaseModel):
|
|
|
23
23
|
"""The dataset name within the HDF file,
|
|
24
24
|
e.g. /entry/data/data or /entry/instrument/NDAttributes/sum"""
|
|
25
25
|
|
|
26
|
-
shape: tuple[int, ...] = Field(default_factory=tuple)
|
|
26
|
+
shape: tuple[int | None, ...] = Field(default_factory=tuple)
|
|
27
27
|
"""The shape of a single event's data in the HDF file,
|
|
28
28
|
e.g. (1, 768, 1024) for arrays or () for scalars"""
|
|
29
29
|
|
|
@@ -163,7 +163,12 @@ class _SignalCache(Generic[SignalDatatypeT]):
|
|
|
163
163
|
self._notify(function, want_value)
|
|
164
164
|
|
|
165
165
|
def unsubscribe(self, function: Callback) -> bool:
|
|
166
|
-
self._listeners.pop(function)
|
|
166
|
+
_listener = self._listeners.pop(function, None)
|
|
167
|
+
if not _listener:
|
|
168
|
+
self._signal.log.warning(
|
|
169
|
+
f"Unsubscribe failed: subscriber {function} was not found "
|
|
170
|
+
f" in listeners list: {list(self._listeners)}"
|
|
171
|
+
)
|
|
167
172
|
return self._staged or bool(self._listeners)
|
|
168
173
|
|
|
169
174
|
def set_staged(self, staged: bool) -> bool:
|
|
@@ -176,7 +176,7 @@ def _datakey_dtype_numpy(
|
|
|
176
176
|
raise TypeError(f"Can't make dtype_numpy for {datatype}")
|
|
177
177
|
|
|
178
178
|
|
|
179
|
-
def _datakey_shape(value: SignalDatatype) -> list[int]:
|
|
179
|
+
def _datakey_shape(value: SignalDatatype) -> list[int | None]:
|
|
180
180
|
if type(value) in _primitive_dtype or isinstance(value, EnumTypes):
|
|
181
181
|
return []
|
|
182
182
|
elif isinstance(value, np.ndarray):
|
|
@@ -7,6 +7,7 @@ from ophyd_async.core import (
|
|
|
7
7
|
DetectorController,
|
|
8
8
|
DetectorTrigger,
|
|
9
9
|
TriggerInfo,
|
|
10
|
+
observe_value,
|
|
10
11
|
set_and_wait_for_value,
|
|
11
12
|
)
|
|
12
13
|
|
|
@@ -89,34 +90,57 @@ class ADBaseController(DetectorController, Generic[ADBaseIOT]):
|
|
|
89
90
|
self.driver.acquire_period.set(full_frame_time, timeout=timeout),
|
|
90
91
|
)
|
|
91
92
|
|
|
92
|
-
async def start_acquiring_driver_and_ensure_status(
|
|
93
|
+
async def start_acquiring_driver_and_ensure_status(
|
|
94
|
+
self,
|
|
95
|
+
start_timeout: float = DEFAULT_TIMEOUT,
|
|
96
|
+
state_timeout: float = DEFAULT_TIMEOUT,
|
|
97
|
+
) -> AsyncStatus:
|
|
93
98
|
"""Start acquiring driver, raising ValueError if the detector is in a bad state.
|
|
94
99
|
|
|
95
100
|
This sets driver.acquire to True, and waits for it to be True up to a timeout.
|
|
96
101
|
Then, it checks that the DetectorState PV is in DEFAULT_GOOD_STATES,
|
|
97
102
|
and otherwise raises a ValueError.
|
|
98
103
|
|
|
104
|
+
|
|
105
|
+
:param start_timeout:
|
|
106
|
+
Timeout used for waiting for the driver to start
|
|
107
|
+
acquiring.
|
|
108
|
+
:param state_timeout:
|
|
109
|
+
Timeout used for waiting for the detector to be in a good
|
|
110
|
+
state after it stops acquiring.
|
|
99
111
|
:returns AsyncStatus:
|
|
100
112
|
An AsyncStatus that can be awaited to set driver.acquire to True and perform
|
|
101
113
|
subsequent raising (if applicable) due to detector state.
|
|
114
|
+
|
|
102
115
|
"""
|
|
103
116
|
status = await set_and_wait_for_value(
|
|
104
117
|
self.driver.acquire,
|
|
105
118
|
True,
|
|
106
|
-
timeout=
|
|
119
|
+
timeout=start_timeout,
|
|
107
120
|
wait_for_set_completion=False,
|
|
108
121
|
)
|
|
109
122
|
|
|
110
123
|
async def complete_acquisition() -> None:
|
|
111
|
-
# NOTE: possible race condition here between the callback from
|
|
112
|
-
# set_and_wait_for_value and the detector state updating.
|
|
113
124
|
await status
|
|
114
|
-
state =
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
125
|
+
state = None
|
|
126
|
+
try:
|
|
127
|
+
async for state in observe_value(
|
|
128
|
+
self.driver.detector_state, done_timeout=state_timeout
|
|
129
|
+
):
|
|
130
|
+
if state in self.good_states:
|
|
131
|
+
return
|
|
132
|
+
except asyncio.TimeoutError as exc:
|
|
133
|
+
if state is not None:
|
|
134
|
+
raise ValueError(
|
|
135
|
+
f"Final detector state {state.value} not in valid end "
|
|
136
|
+
f"states: {self.good_states}"
|
|
137
|
+
) from exc
|
|
138
|
+
else:
|
|
139
|
+
# No updates from the detector, something else is wrong
|
|
140
|
+
raise asyncio.TimeoutError(
|
|
141
|
+
"Could not monitor detector state: "
|
|
142
|
+
+ self.driver.detector_state.source
|
|
143
|
+
) from exc
|
|
120
144
|
|
|
121
145
|
return AsyncStatus(complete_acquisition())
|
|
122
146
|
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import asyncio
|
|
2
2
|
from collections.abc import AsyncIterator
|
|
3
3
|
from pathlib import Path
|
|
4
|
+
from typing import TypeGuard
|
|
4
5
|
from xml.etree import ElementTree as ET
|
|
5
6
|
|
|
6
7
|
from bluesky.protocols import StreamAsset
|
|
@@ -22,6 +23,10 @@ from ._utils import (
|
|
|
22
23
|
)
|
|
23
24
|
|
|
24
25
|
|
|
26
|
+
def _is_fully_described(shape: tuple[int | None, ...]) -> TypeGuard[tuple[int, ...]]:
|
|
27
|
+
return None not in shape
|
|
28
|
+
|
|
29
|
+
|
|
25
30
|
class ADHDFWriter(ADWriter[NDFileHDFIO]):
|
|
26
31
|
"""Allow `NDFileHDFIO` to be used within `StandardDetector`."""
|
|
27
32
|
|
|
@@ -75,6 +80,16 @@ class ADHDFWriter(ADWriter[NDFileHDFIO]):
|
|
|
75
80
|
# Determine number of frames that will be saved per HDF chunk
|
|
76
81
|
frames_per_chunk = await self.fileio.num_frames_chunks.get_value()
|
|
77
82
|
|
|
83
|
+
if not _is_fully_described(detector_shape):
|
|
84
|
+
# Questions:
|
|
85
|
+
# - Can AreaDetector support this?
|
|
86
|
+
# - How to deal with chunking?
|
|
87
|
+
# Don't support for now - leave option open to support it later
|
|
88
|
+
raise ValueError(
|
|
89
|
+
"Datasets with partially unknown dimensionality "
|
|
90
|
+
"are not currently supported by ADHDFWriter."
|
|
91
|
+
)
|
|
92
|
+
|
|
78
93
|
# Add the main data
|
|
79
94
|
self._datasets = [
|
|
80
95
|
HDFDatasetDescription(
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: ophyd-async
|
|
3
|
-
Version: 0.10.
|
|
3
|
+
Version: 0.10.1
|
|
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
|
|
@@ -43,7 +43,7 @@ Description-Content-Type: text/markdown
|
|
|
43
43
|
License-File: LICENSE
|
|
44
44
|
Requires-Dist: numpy
|
|
45
45
|
Requires-Dist: bluesky>=1.13.1rc2
|
|
46
|
-
Requires-Dist: event-model>=1.
|
|
46
|
+
Requires-Dist: event-model>=1.23
|
|
47
47
|
Requires-Dist: pyyaml
|
|
48
48
|
Requires-Dist: colorlog
|
|
49
49
|
Requires-Dist: pydantic>=2.0
|
|
@@ -8,6 +8,9 @@ from bluesky.protocols import Reading
|
|
|
8
8
|
|
|
9
9
|
from ophyd_async.core import (
|
|
10
10
|
DerivedSignalFactory,
|
|
11
|
+
SignalRW,
|
|
12
|
+
Table,
|
|
13
|
+
derived_signal_rw,
|
|
11
14
|
soft_signal_rw,
|
|
12
15
|
)
|
|
13
16
|
from ophyd_async.sim import (
|
|
@@ -22,6 +25,7 @@ from ophyd_async.testing import (
|
|
|
22
25
|
assert_reading,
|
|
23
26
|
assert_value,
|
|
24
27
|
get_mock,
|
|
28
|
+
set_mock_value,
|
|
25
29
|
)
|
|
26
30
|
|
|
27
31
|
|
|
@@ -131,3 +135,55 @@ def test_mismatching_args():
|
|
|
131
135
|
jack22=soft_signal_rw(float),
|
|
132
136
|
distance=soft_signal_rw(float),
|
|
133
137
|
)
|
|
138
|
+
|
|
139
|
+
|
|
140
|
+
@pytest.fixture
|
|
141
|
+
def derived_signal() -> SignalRW[float]:
|
|
142
|
+
signal_r = soft_signal_rw(int, initial_value=4)
|
|
143
|
+
|
|
144
|
+
def _get(ts: int) -> float:
|
|
145
|
+
return ts
|
|
146
|
+
|
|
147
|
+
async def _put(value: float) -> None:
|
|
148
|
+
pass
|
|
149
|
+
|
|
150
|
+
return derived_signal_rw(_get, _put, ts=signal_r)
|
|
151
|
+
|
|
152
|
+
|
|
153
|
+
async def test_derived_signal_backend_connect_pass(
|
|
154
|
+
derived_signal: SignalRW,
|
|
155
|
+
):
|
|
156
|
+
result = await derived_signal.connect()
|
|
157
|
+
assert result is None
|
|
158
|
+
|
|
159
|
+
|
|
160
|
+
async def test_derived_signal_backend_set_value(
|
|
161
|
+
derived_signal: SignalRW,
|
|
162
|
+
) -> None:
|
|
163
|
+
await derived_signal.connect(mock=True)
|
|
164
|
+
with pytest.raises(RuntimeError):
|
|
165
|
+
set_mock_value(derived_signal, 1.0)
|
|
166
|
+
|
|
167
|
+
|
|
168
|
+
async def test_derived_signal_backend_put_wait_fails(
|
|
169
|
+
derived_signal: SignalRW,
|
|
170
|
+
) -> None:
|
|
171
|
+
with pytest.raises(RuntimeError):
|
|
172
|
+
await derived_signal.set(value=None, wait=False)
|
|
173
|
+
with pytest.raises(RuntimeError):
|
|
174
|
+
await derived_signal.set(value=None, wait=True)
|
|
175
|
+
|
|
176
|
+
|
|
177
|
+
def test_make_rw_signal_type_mismatch():
|
|
178
|
+
factory = DerivedSignalFactory(
|
|
179
|
+
TwoJackTransform,
|
|
180
|
+
set_derived=None,
|
|
181
|
+
distance=soft_signal_rw(float),
|
|
182
|
+
jack1=soft_signal_rw(float),
|
|
183
|
+
jack2=soft_signal_rw(float),
|
|
184
|
+
)
|
|
185
|
+
with pytest.raises(
|
|
186
|
+
ValueError,
|
|
187
|
+
match=re.escape("Must define a set_derived method to support derived"),
|
|
188
|
+
):
|
|
189
|
+
factory.derived_signal_rw(datatype=Table, name="")
|
|
@@ -1013,3 +1013,9 @@ async def test_notify_runtime_error(signal_cache: _SignalCache[Any]) -> None:
|
|
|
1013
1013
|
def test_signal_backend_throws_type_error() -> None:
|
|
1014
1014
|
with pytest.raises(TypeError, match="Unsupported protocol: XYZ"):
|
|
1015
1015
|
get_signal_backend_type("XYZ") # type: ignore
|
|
1016
|
+
|
|
1017
|
+
|
|
1018
|
+
def test_remove_non_existing_listener():
|
|
1019
|
+
signal_rw = soft_signal_rw(int, initial_value=4)
|
|
1020
|
+
cbs = []
|
|
1021
|
+
assert signal_rw.clear_sub(cbs.append) is None
|
|
@@ -1,12 +1,18 @@
|
|
|
1
1
|
import asyncio
|
|
2
2
|
import re
|
|
3
|
-
from unittest.mock import call
|
|
3
|
+
from unittest.mock import MagicMock, call, patch
|
|
4
4
|
|
|
5
5
|
import pytest
|
|
6
|
+
from bluesky.protocols import Reading, Subscribable
|
|
6
7
|
|
|
7
8
|
from ophyd_async.core import (
|
|
9
|
+
Callback,
|
|
10
|
+
Signal,
|
|
11
|
+
SignalBackend,
|
|
12
|
+
SignalDatatype,
|
|
8
13
|
derived_signal_r,
|
|
9
14
|
derived_signal_rw,
|
|
15
|
+
derived_signal_w,
|
|
10
16
|
soft_signal_r_and_setter,
|
|
11
17
|
soft_signal_rw,
|
|
12
18
|
)
|
|
@@ -22,6 +28,16 @@ from ophyd_async.testing import (
|
|
|
22
28
|
)
|
|
23
29
|
|
|
24
30
|
|
|
31
|
+
@pytest.fixture
|
|
32
|
+
def movable_beamstop() -> MovableBeamstop:
|
|
33
|
+
return MovableBeamstop("device")
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
@pytest.fixture
|
|
37
|
+
def readonly_beamstop() -> ReadOnlyBeamstop:
|
|
38
|
+
return ReadOnlyBeamstop("device")
|
|
39
|
+
|
|
40
|
+
|
|
25
41
|
def _get_position(foo: float, bar: float) -> BeamstopPosition:
|
|
26
42
|
if abs(foo) < 1 and abs(bar) < 2:
|
|
27
43
|
return BeamstopPosition.IN_POSITION
|
|
@@ -137,14 +153,100 @@ def test_mismatching_args_and_types(func, expected_msg, args):
|
|
|
137
153
|
derived_signal_r(func, **args)
|
|
138
154
|
|
|
139
155
|
|
|
156
|
+
def _get(ts: int) -> float:
|
|
157
|
+
return ts
|
|
158
|
+
|
|
159
|
+
|
|
160
|
+
async def _put(value: float) -> None:
|
|
161
|
+
pass
|
|
162
|
+
|
|
163
|
+
|
|
164
|
+
@pytest.fixture
|
|
165
|
+
def derived_signal_backend() -> SignalBackend[SignalDatatype]:
|
|
166
|
+
signal_rw = soft_signal_rw(int, initial_value=4)
|
|
167
|
+
derived = derived_signal_rw(_get, _put, ts=signal_rw)
|
|
168
|
+
return derived._connector.backend
|
|
169
|
+
|
|
170
|
+
|
|
140
171
|
async def test_derived_signal_rw_works_with_signal_r():
|
|
141
172
|
signal_r, _ = soft_signal_r_and_setter(int, initial_value=4)
|
|
173
|
+
derived = derived_signal_rw(_get, _put, ts=signal_r)
|
|
174
|
+
assert await derived.get_value() == 4
|
|
175
|
+
|
|
142
176
|
|
|
143
|
-
|
|
177
|
+
async def test_validate_by_type(derived_signal_backend: SignalBackend):
|
|
178
|
+
def float_get(ts: float) -> float:
|
|
144
179
|
return ts
|
|
145
180
|
|
|
146
|
-
|
|
147
|
-
|
|
181
|
+
with pytest.raises(TypeError, match=re.escape(" is not an instance of")):
|
|
182
|
+
derived_signal_rw(float_get, _put, ts=Signal(derived_signal_backend))
|
|
148
183
|
|
|
149
|
-
|
|
150
|
-
|
|
184
|
+
|
|
185
|
+
async def test_set_derived_not_initialized():
|
|
186
|
+
sig = derived_signal_r(_get, ts=soft_signal_rw(int, initial_value=4))
|
|
187
|
+
with pytest.raises(
|
|
188
|
+
RuntimeError,
|
|
189
|
+
match="Cannot put as no set_derived method given",
|
|
190
|
+
):
|
|
191
|
+
await sig._connector.backend.put(1.0, True)
|
|
192
|
+
|
|
193
|
+
|
|
194
|
+
async def test_derived_update_cached_reading_not_initialized(
|
|
195
|
+
derived_signal_backend: SignalBackend,
|
|
196
|
+
):
|
|
197
|
+
class test_cls(Subscribable):
|
|
198
|
+
def subscribe(self, function: Callback) -> None:
|
|
199
|
+
pass
|
|
200
|
+
|
|
201
|
+
def clear_sub(self, function: Callback) -> None:
|
|
202
|
+
function("")
|
|
203
|
+
|
|
204
|
+
@property
|
|
205
|
+
def name(self) -> str:
|
|
206
|
+
return ""
|
|
207
|
+
|
|
208
|
+
with patch.object(
|
|
209
|
+
derived_signal_backend.transformer, # type: ignore
|
|
210
|
+
"raw_and_transform_subscribables",
|
|
211
|
+
{"raw_device": test_cls()},
|
|
212
|
+
):
|
|
213
|
+
with pytest.raises(
|
|
214
|
+
RuntimeError,
|
|
215
|
+
match=re.escape(
|
|
216
|
+
"Cannot update cached reading as it has not been initialised"
|
|
217
|
+
),
|
|
218
|
+
): # noqa: E501
|
|
219
|
+
derived_signal_backend.set_callback(None)
|
|
220
|
+
|
|
221
|
+
|
|
222
|
+
async def test_set_derived_callback_already_set(derived_signal_backend: SignalBackend):
|
|
223
|
+
mock_callback = MagicMock(Callback[Reading])
|
|
224
|
+
derived_signal_backend.set_callback(mock_callback)
|
|
225
|
+
with pytest.raises(RuntimeError, match=re.escape("Callback already set for")):
|
|
226
|
+
derived_signal_backend.set_callback(mock_callback)
|
|
227
|
+
|
|
228
|
+
|
|
229
|
+
@patch("ophyd_async.core._derived_signal.get_type_hints", return_value={})
|
|
230
|
+
def test_get_return_datatype_no_type(movable_beamstop: MovableBeamstop):
|
|
231
|
+
with pytest.raises(
|
|
232
|
+
TypeError, match=re.escape("does not have a type hint for it's return value")
|
|
233
|
+
):
|
|
234
|
+
derived_signal_r(movable_beamstop._get_position)
|
|
235
|
+
|
|
236
|
+
|
|
237
|
+
@patch("ophyd_async.core._derived_signal.get_type_hints", return_value={})
|
|
238
|
+
def test_get_first_arg_datatype_no_type(movable_beamstop: MovableBeamstop):
|
|
239
|
+
with pytest.raises(
|
|
240
|
+
TypeError, match=re.escape("does not have a type hinted argument")
|
|
241
|
+
):
|
|
242
|
+
derived_signal_w(movable_beamstop._set_from_position)
|
|
243
|
+
|
|
244
|
+
|
|
245
|
+
def test_derived_signal_rw_type_error(movable_beamstop: MovableBeamstop):
|
|
246
|
+
with patch.object(
|
|
247
|
+
movable_beamstop, "_set_from_position", movable_beamstop._get_position
|
|
248
|
+
): # noqa: E501
|
|
249
|
+
with pytest.raises(TypeError):
|
|
250
|
+
derived_signal_rw(
|
|
251
|
+
movable_beamstop._get_position, movable_beamstop._set_from_position
|
|
252
|
+
) # noqa: E501
|
|
@@ -68,7 +68,6 @@ async def test_start_acquiring_driver_and_ensure_status_flags_immediate_failure(
|
|
|
68
68
|
await acquiring
|
|
69
69
|
|
|
70
70
|
|
|
71
|
-
@patch("ophyd_async.core._detector.DEFAULT_TIMEOUT", 0.2)
|
|
72
71
|
async def test_start_acquiring_driver_and_ensure_status_fails_after_some_time(
|
|
73
72
|
controller: adsimdetector.SimController,
|
|
74
73
|
):
|
|
@@ -87,9 +86,62 @@ async def test_start_acquiring_driver_and_ensure_status_fails_after_some_time(
|
|
|
87
86
|
|
|
88
87
|
controller.frame_timeout = 0.1
|
|
89
88
|
|
|
90
|
-
acquiring = await controller.start_acquiring_driver_and_ensure_status(
|
|
89
|
+
acquiring = await controller.start_acquiring_driver_and_ensure_status(
|
|
90
|
+
start_timeout=0.2, state_timeout=0.2
|
|
91
|
+
)
|
|
91
92
|
|
|
92
93
|
with pytest.raises(
|
|
93
94
|
ValueError, match="Final detector state Disconnected not in valid end states:"
|
|
94
95
|
):
|
|
95
96
|
await acquiring
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
async def test_start_acquiring_driver_and_ensure_status_timing(
|
|
100
|
+
controller: adsimdetector.SimController,
|
|
101
|
+
):
|
|
102
|
+
"""This test ensures the camera has time to return to a good state.
|
|
103
|
+
|
|
104
|
+
Real world application; there is race condition wherein the
|
|
105
|
+
detector has been asked to complete acquisition, but has not yet
|
|
106
|
+
returned to a known good state before the status check.
|
|
107
|
+
|
|
108
|
+
"""
|
|
109
|
+
set_mock_value(controller.driver.detector_state, adcore.ADState.ACQUIRE)
|
|
110
|
+
|
|
111
|
+
acquiring = await controller.start_acquiring_driver_and_ensure_status(
|
|
112
|
+
start_timeout=0.2, state_timeout=0.2
|
|
113
|
+
)
|
|
114
|
+
|
|
115
|
+
async def complete_acquire():
|
|
116
|
+
"""Return to idle state, but pretend the detector is slow."""
|
|
117
|
+
await asyncio.sleep(0.05)
|
|
118
|
+
set_mock_value(controller.driver.detector_state, adcore.ADState.IDLE)
|
|
119
|
+
|
|
120
|
+
await asyncio.gather(acquiring, complete_acquire())
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
async def bad_observe_value(*args, **kwargs):
|
|
124
|
+
"Stub to simulate a disconnected ``observe_value()``."
|
|
125
|
+
if True:
|
|
126
|
+
raise asyncio.TimeoutError()
|
|
127
|
+
yield None # Make it a generator
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
@patch("ophyd_async.epics.adcore._core_logic.observe_value", bad_observe_value)
|
|
131
|
+
async def test_start_acquiring_driver_and_ensure_status_disconnected(
|
|
132
|
+
controller: adsimdetector.SimController,
|
|
133
|
+
):
|
|
134
|
+
"""This test ensures the function behaves gracefully if no detector
|
|
135
|
+
states are available.
|
|
136
|
+
|
|
137
|
+
"""
|
|
138
|
+
acquiring = await controller.start_acquiring_driver_and_ensure_status(
|
|
139
|
+
start_timeout=0.2, state_timeout=0.2
|
|
140
|
+
)
|
|
141
|
+
|
|
142
|
+
with pytest.raises(asyncio.TimeoutError) as exc:
|
|
143
|
+
await acquiring
|
|
144
|
+
assert (
|
|
145
|
+
str(exc.value)
|
|
146
|
+
== "Could not monitor detector state: mock+ca://DRV:DetectorState_RBV"
|
|
147
|
+
)
|
|
@@ -296,3 +296,19 @@ async def test_nd_attributes_plan_stub_gives_correct_error(RE, detectors):
|
|
|
296
296
|
== f"Invalid type for ndattributes: {type(invalidObjects[0])}. "
|
|
297
297
|
+ "Expected NDAttributePv or NDAttributeParam."
|
|
298
298
|
)
|
|
299
|
+
|
|
300
|
+
|
|
301
|
+
async def test_hdf_writer_descriptor_shape_contains_none(
|
|
302
|
+
hdf_writer: adcore.ADHDFWriter,
|
|
303
|
+
):
|
|
304
|
+
async def shape_containing_none():
|
|
305
|
+
return 10, None, 10
|
|
306
|
+
|
|
307
|
+
hdf_writer._dataset_describer.shape = shape_containing_none
|
|
308
|
+
|
|
309
|
+
with pytest.raises(
|
|
310
|
+
ValueError,
|
|
311
|
+
match=r"Datasets with partially unknown dimensionality "
|
|
312
|
+
r"are not currently supported by ADHDFWriter.",
|
|
313
|
+
):
|
|
314
|
+
await hdf_writer.open(DETECTOR_NAME)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{ophyd_async-0.10.0a4 → ophyd_async-0.10.1}/.github/PULL_REQUEST_TEMPLATE/pull_request_template.md
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|