ophyd-async 0.13.6__tar.gz → 0.13.7__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.13.6 → ophyd_async-0.13.7}/.devcontainer/devcontainer.json +18 -2
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/.github/workflows/_test.yml +1 -13
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/.github/workflows/ci.yml +2 -7
- ophyd_async-0.13.7/Dockerfile +25 -0
- {ophyd_async-0.13.6/src/ophyd_async.egg-info → ophyd_async-0.13.7}/PKG-INFO +1 -1
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/docs/conf.py +0 -1
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/src/ophyd_async/_version.py +3 -3
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/src/ophyd_async/core/_signal.py +2 -1
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/src/ophyd_async/epics/motor.py +18 -3
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/src/ophyd_async/epics/pmac/_pmac_io.py +10 -13
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/src/ophyd_async/epics/pmac/_pmac_trajectory.py +9 -10
- ophyd_async-0.13.7/src/ophyd_async/epics/pmac/_utils.py +210 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/src/ophyd_async/tango/core/__init__.py +0 -2
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/src/ophyd_async/tango/core/_base_device.py +4 -1
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/src/ophyd_async/tango/demo/_counter.py +10 -3
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/src/ophyd_async/tango/demo/_mover.py +4 -3
- {ophyd_async-0.13.6 → ophyd_async-0.13.7/src/ophyd_async.egg-info}/PKG-INFO +1 -1
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/src/ophyd_async.egg-info/SOURCES.txt +2 -3
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/tests/conftest.py +160 -0
- ophyd_async-0.13.7/tests/system_tests/conftest.py +11 -0
- ophyd_async-0.13.7/tests/system_tests/epics/adsim/external_dependencies.sh +32 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/tests/system_tests/epics/adsim/test_adsim_system.py +20 -4
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/tests/system_tests/tango/test_base_device.py +5 -4
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/tests/system_tests/tango/test_tango_signals.py +1 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/tests/unit_tests/core/test_signal.py +31 -0
- ophyd_async-0.13.7/tests/unit_tests/epics/pmac/conftest.py +93 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/tests/unit_tests/epics/pmac/test_pmac_trajectory.py +1 -1
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/tests/unit_tests/epics/pmac/test_pmac_utils.py +39 -4
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/tests/unit_tests/epics/test_motor.py +6 -2
- ophyd_async-0.13.6/Dockerfile +0 -10
- ophyd_async-0.13.6/src/ophyd_async/epics/pmac/_utils.py +0 -167
- ophyd_async-0.13.6/src/ophyd_async/tango/core/_tango_readable.py +0 -15
- ophyd_async-0.13.6/tests/system_tests/epics/adsim/start_iocs.sh +0 -14
- ophyd_async-0.13.6/tests/system_tests/epics/adsim/stop_iocs.sh +0 -14
- ophyd_async-0.13.6/tests/unit_tests/epics/pmac/conftest.py +0 -34
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/.codecov.yml +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/.copier-answers.yml +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/.git-blame-ignore-revs +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/.github/CONTRIBUTING.md +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/.github/ISSUE_TEMPLATE/issue.md +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/.github/PULL_REQUEST_TEMPLATE/pull_request_template.md +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/.github/codeql/codeql-config.yml +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/.github/pages/index.html +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/.github/pages/make_switcher.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/.github/renovate.json +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/.github/workflows/_codeql.yml +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/.github/workflows/_dist.yml +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/.github/workflows/_docs.yml +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/.github/workflows/_pypi.yml +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/.github/workflows/_release.yml +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/.github/workflows/_tox.yml +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/.github/workflows/periodic.yml +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/.gitignore +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/.gitleaks.toml +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/.gitmodules +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/.pre-commit-config.yaml +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/.python-version +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/LICENSE +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/README.md +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/docs/_static/custom.css +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/docs/explanations/decisions/0001-record-architecture-decisions.md +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/docs/explanations/decisions/0002-switched-to-python-copier-template.md +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/docs/explanations/decisions/0003-ophyd-async-migration.rst +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/docs/explanations/decisions/0004-repository-structure.rst +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/docs/explanations/decisions/0005-respect-black-line-length.rst +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/docs/explanations/decisions/0006-procedural-device-definitions.rst +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/docs/explanations/decisions/0007-subpackage-structure.md +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/docs/explanations/decisions/0008-signal-types.md +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/docs/explanations/decisions/0009-procedural-vs-declarative-devices.md +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/docs/explanations/decisions/0010-docstring-format.md +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/docs/explanations/decisions/0011-buffer-updates-camonitor.md +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/docs/explanations/decisions/COPYME +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/docs/explanations/decisions.md +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/docs/explanations/declarative-vs-procedural.md +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/docs/explanations/design-goals.md +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/docs/explanations/device-connection-strategies.md +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/docs/explanations/devices-signals-backends.md +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/docs/explanations/fly-scanning.md +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/docs/explanations/plan-stubs.md +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/docs/explanations/when-to-extend-movable.md +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/docs/explanations/where-device-logic.md +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/docs/explanations.md +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/docs/genindex.rst +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/docs/how-to/choose-right-baseclass.md +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/docs/how-to/contribute.md +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/docs/how-to/derive-one-signal-from-others.md +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/docs/how-to/implement-ad-detector.md +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/docs/how-to/interact-with-signals.md +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/docs/how-to/put-device-back.md +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/docs/how-to/store-and-retrieve.md +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/docs/how-to.md +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/docs/images/fly_scan_collection_windows_and_frames.svg +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/docs/images/ophyd-async-logo.svg +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/docs/images/ophyd-favicon.svg +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/docs/images/set_and_wait_for_other_value.excalidraw.svg +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/docs/index.md +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/docs/reference.md +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/docs/tutorials/implementing-detectors.md +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/docs/tutorials/implementing-devices.md +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/docs/tutorials/installation.md +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/docs/tutorials/using-devices.md +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/docs/tutorials/writing-tests-for-devices.md +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/docs/tutorials.md +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/pyproject.toml +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/setup.cfg +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/src/ophyd_async/__init__.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/src/ophyd_async/__main__.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/src/ophyd_async/_docs_parser.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/src/ophyd_async/core/__init__.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/src/ophyd_async/core/_derived_signal.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/src/ophyd_async/core/_derived_signal_backend.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/src/ophyd_async/core/_detector.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/src/ophyd_async/core/_device.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/src/ophyd_async/core/_device_filler.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/src/ophyd_async/core/_enums.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/src/ophyd_async/core/_flyer.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/src/ophyd_async/core/_hdf_dataset.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/src/ophyd_async/core/_log.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/src/ophyd_async/core/_mock_signal_backend.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/src/ophyd_async/core/_protocol.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/src/ophyd_async/core/_providers.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/src/ophyd_async/core/_readable.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/src/ophyd_async/core/_settings.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/src/ophyd_async/core/_signal_backend.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/src/ophyd_async/core/_soft_signal_backend.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/src/ophyd_async/core/_status.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/src/ophyd_async/core/_table.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/src/ophyd_async/core/_utils.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/src/ophyd_async/core/_yaml_settings.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/src/ophyd_async/epics/__init__.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/src/ophyd_async/epics/adandor/__init__.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/src/ophyd_async/epics/adandor/_andor.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/src/ophyd_async/epics/adandor/_andor_controller.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/src/ophyd_async/epics/adandor/_andor_io.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/src/ophyd_async/epics/adaravis/__init__.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/src/ophyd_async/epics/adaravis/_aravis.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/src/ophyd_async/epics/adaravis/_aravis_controller.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/src/ophyd_async/epics/adaravis/_aravis_io.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/src/ophyd_async/epics/adcore/__init__.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/src/ophyd_async/epics/adcore/_core_detector.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/src/ophyd_async/epics/adcore/_core_io.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/src/ophyd_async/epics/adcore/_core_logic.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/src/ophyd_async/epics/adcore/_core_writer.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/src/ophyd_async/epics/adcore/_hdf_writer.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/src/ophyd_async/epics/adcore/_jpeg_writer.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/src/ophyd_async/epics/adcore/_single_trigger.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/src/ophyd_async/epics/adcore/_tiff_writer.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/src/ophyd_async/epics/adcore/_utils.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/src/ophyd_async/epics/adkinetix/__init__.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/src/ophyd_async/epics/adkinetix/_kinetix.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/src/ophyd_async/epics/adkinetix/_kinetix_controller.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/src/ophyd_async/epics/adkinetix/_kinetix_io.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/src/ophyd_async/epics/adpilatus/__init__.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/src/ophyd_async/epics/adpilatus/_pilatus.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/src/ophyd_async/epics/adpilatus/_pilatus_controller.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/src/ophyd_async/epics/adpilatus/_pilatus_io.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/src/ophyd_async/epics/adsimdetector/__init__.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/src/ophyd_async/epics/adsimdetector/_sim.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/src/ophyd_async/epics/adsimdetector/_sim_controller.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/src/ophyd_async/epics/adsimdetector/_sim_io.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/src/ophyd_async/epics/advimba/__init__.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/src/ophyd_async/epics/advimba/_vimba.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/src/ophyd_async/epics/advimba/_vimba_controller.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/src/ophyd_async/epics/advimba/_vimba_io.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/src/ophyd_async/epics/core/__init__.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/src/ophyd_async/epics/core/_aioca.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/src/ophyd_async/epics/core/_epics_connector.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/src/ophyd_async/epics/core/_epics_device.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/src/ophyd_async/epics/core/_p4p.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/src/ophyd_async/epics/core/_pvi_connector.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/src/ophyd_async/epics/core/_signal.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/src/ophyd_async/epics/core/_util.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/src/ophyd_async/epics/demo/__init__.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/src/ophyd_async/epics/demo/__main__.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/src/ophyd_async/epics/demo/_ioc.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/src/ophyd_async/epics/demo/_motor.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/src/ophyd_async/epics/demo/_point_detector.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/src/ophyd_async/epics/demo/_point_detector_channel.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/src/ophyd_async/epics/demo/_stage.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/src/ophyd_async/epics/demo/motor.db +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/src/ophyd_async/epics/demo/point_detector.db +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/src/ophyd_async/epics/demo/point_detector_channel.db +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/src/ophyd_async/epics/odin/__init__.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/src/ophyd_async/epics/odin/_odin_io.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/src/ophyd_async/epics/pmac/__init__.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/src/ophyd_async/epics/pmac/_pmac_trajectory_generation.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/src/ophyd_async/epics/signal.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/src/ophyd_async/epics/testing/__init__.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/src/ophyd_async/epics/testing/_example_ioc.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/src/ophyd_async/epics/testing/_utils.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/src/ophyd_async/epics/testing/test_records.db +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/src/ophyd_async/epics/testing/test_records_pva.db +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/src/ophyd_async/fastcs/__init__.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/src/ophyd_async/fastcs/core.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/src/ophyd_async/fastcs/eiger/__init__.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/src/ophyd_async/fastcs/eiger/_eiger.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/src/ophyd_async/fastcs/eiger/_eiger_controller.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/src/ophyd_async/fastcs/eiger/_eiger_io.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/src/ophyd_async/fastcs/jungfrau/__init__.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/src/ophyd_async/fastcs/jungfrau/_controller.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/src/ophyd_async/fastcs/jungfrau/_jungfrau.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/src/ophyd_async/fastcs/jungfrau/_signals.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/src/ophyd_async/fastcs/jungfrau/_utils.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/src/ophyd_async/fastcs/odin/__init__.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/src/ophyd_async/fastcs/panda/__init__.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/src/ophyd_async/fastcs/panda/_block.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/src/ophyd_async/fastcs/panda/_control.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/src/ophyd_async/fastcs/panda/_hdf_panda.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/src/ophyd_async/fastcs/panda/_table.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/src/ophyd_async/fastcs/panda/_trigger.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/src/ophyd_async/fastcs/panda/_writer.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/src/ophyd_async/plan_stubs/__init__.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/src/ophyd_async/plan_stubs/_ensure_connected.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/src/ophyd_async/plan_stubs/_fly.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/src/ophyd_async/plan_stubs/_nd_attributes.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/src/ophyd_async/plan_stubs/_panda.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/src/ophyd_async/plan_stubs/_settings.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/src/ophyd_async/plan_stubs/_utils.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/src/ophyd_async/plan_stubs/_wait_for_awaitable.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/src/ophyd_async/py.typed +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/src/ophyd_async/sim/__init__.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/src/ophyd_async/sim/__main__.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/src/ophyd_async/sim/_blob_detector.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/src/ophyd_async/sim/_blob_detector_controller.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/src/ophyd_async/sim/_blob_detector_writer.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/src/ophyd_async/sim/_mirror_horizontal.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/src/ophyd_async/sim/_mirror_vertical.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/src/ophyd_async/sim/_motor.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/src/ophyd_async/sim/_pattern_generator.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/src/ophyd_async/sim/_point_detector.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/src/ophyd_async/sim/_stage.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/src/ophyd_async/tango/__init__.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/src/ophyd_async/tango/core/_converters.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/src/ophyd_async/tango/core/_signal.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/src/ophyd_async/tango/core/_tango_transport.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/src/ophyd_async/tango/core/_utils.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/src/ophyd_async/tango/demo/__init__.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/src/ophyd_async/tango/demo/_detector.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/src/ophyd_async/tango/demo/_tango/__init__.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/src/ophyd_async/tango/demo/_tango/_servers.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/src/ophyd_async/tango/testing/__init__.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/src/ophyd_async/tango/testing/_one_of_everything.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/src/ophyd_async/tango/testing/_test_config.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/src/ophyd_async/testing/__init__.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/src/ophyd_async/testing/__pytest_assert_rewrite.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/src/ophyd_async/testing/_assert.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/src/ophyd_async/testing/_mock_signal_utils.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/src/ophyd_async/testing/_one_of_everything.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/src/ophyd_async/testing/_single_derived.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/src/ophyd_async/testing/_utils.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/src/ophyd_async/testing/_wait_for_pending.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/src/ophyd_async.egg-info/dependency_links.txt +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/src/ophyd_async.egg-info/requires.txt +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/src/ophyd_async.egg-info/top_level.txt +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/tests/README.md +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/tests/system_tests/epics/adsim/baseline.yaml +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/tests/system_tests/epics/eiger/README.md +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/tests/system_tests/epics/eiger/start_iocs_and_run_tests.sh +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/tests/system_tests/epics/eiger/test_eiger_system.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/tests/system_tests/epics/signal/test_signals.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/tests/system_tests/epics/signal/test_yaml_save_ca.yaml +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/tests/system_tests/epics/signal/test_yaml_save_pva.yaml +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/tests/system_tests/fastcs/panda/test_panda_connect.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/tests/system_tests/tango/conftest.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/tests/system_tests/tango/context_subprocess.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/tests/system_tests/tango/test_tango_transport.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/tests/system_tests/test_tutorials.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/tests/unit_tests/core/test_auto_init_devices.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/tests/unit_tests/core/test_detector.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/tests/unit_tests/core/test_device.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/tests/unit_tests/core/test_flyer.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/tests/unit_tests/core/test_log.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/tests/unit_tests/core/test_mock_signal_backend.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/tests/unit_tests/core/test_multi_derived_signal.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/tests/unit_tests/core/test_observe.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/tests/unit_tests/core/test_protocol.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/tests/unit_tests/core/test_providers.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/tests/unit_tests/core/test_readable.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/tests/unit_tests/core/test_single_derived_signal.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/tests/unit_tests/core/test_soft_signal_backend.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/tests/unit_tests/core/test_status.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/tests/unit_tests/core/test_subset_enum.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/tests/unit_tests/core/test_table.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/tests/unit_tests/core/test_utils.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/tests/unit_tests/core/test_watchable_async_status.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/tests/unit_tests/epics/adandor/test_andor.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/tests/unit_tests/epics/adaravis/test_aravis.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/tests/unit_tests/epics/adcore/test_cont_acq_detector.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/tests/unit_tests/epics/adcore/test_detectors.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/tests/unit_tests/epics/adcore/test_drivers.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/tests/unit_tests/epics/adcore/test_plugins.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/tests/unit_tests/epics/adcore/test_scans.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/tests/unit_tests/epics/adcore/test_single_trigger.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/tests/unit_tests/epics/adcore/test_writers.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/tests/unit_tests/epics/adkinetix/test_kinetix.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/tests/unit_tests/epics/adpilatus/test_pilatus.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/tests/unit_tests/epics/adsimdetector/test_sim.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/tests/unit_tests/epics/advimba/test_vimba.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/tests/unit_tests/epics/conftest.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/tests/unit_tests/epics/demo/test_epics_demo.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/tests/unit_tests/epics/eiger/test_odin_io.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/tests/unit_tests/epics/pmac/test_pmac_io.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/tests/unit_tests/epics/pmac/test_pmac_trajectory_generation.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/tests/unit_tests/epics/pvi/test_pvi.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/tests/unit_tests/epics/signal/test_common.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/tests/unit_tests/epics/test_areadetector_subclass_naming.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/tests/unit_tests/fastcs/eiger/test_eiger_controller.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/tests/unit_tests/fastcs/eiger/test_eiger_detector.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/tests/unit_tests/fastcs/jungfrau/__init__.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/tests/unit_tests/fastcs/jungfrau/test_controller.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/tests/unit_tests/fastcs/jungfrau/test_utils.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/tests/unit_tests/fastcs/panda/db/panda.db +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/tests/unit_tests/fastcs/panda/test_hdf_panda.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/tests/unit_tests/fastcs/panda/test_panda_connect_mock.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/tests/unit_tests/fastcs/panda/test_panda_control.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/tests/unit_tests/fastcs/panda/test_panda_utils.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/tests/unit_tests/fastcs/panda/test_seq_table.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/tests/unit_tests/fastcs/panda/test_trigger.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/tests/unit_tests/fastcs/panda/test_writer.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/tests/unit_tests/plan_stubs/test_ensure_connected.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/tests/unit_tests/plan_stubs/test_fly.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/tests/unit_tests/plan_stubs/test_settings.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/tests/unit_tests/plan_stubs/test_setup.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/tests/unit_tests/sim/__init__.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/tests/unit_tests/sim/test_sim_blob_detector.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/tests/unit_tests/sim/test_sim_motor.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/tests/unit_tests/test_branching.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/tests/unit_tests/test_cli.py +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/tests/unit_tests/test_data/test_yaml_config_save.yaml +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/tests/unit_tests/test_data/test_yaml_save.yaml +0 -0
- {ophyd_async-0.13.6 → ophyd_async-0.13.7}/uv.lock +0 -0
|
@@ -16,7 +16,9 @@
|
|
|
16
16
|
"UV_PROJECT_ENVIRONMENT": "/cache/venv-for${localWorkspaceFolder}",
|
|
17
17
|
// Do the equivalent of "activate" the venv so we don't have to "uv run" everything
|
|
18
18
|
"VIRTUAL_ENV": "/cache/venv-for${localWorkspaceFolder}",
|
|
19
|
-
"PATH": "/cache/venv-for${localWorkspaceFolder}/bin:${containerEnv:PATH}"
|
|
19
|
+
"PATH": "/cache/venv-for${localWorkspaceFolder}/bin:${containerEnv:PATH}",
|
|
20
|
+
// Help external service fixtures match docker compose working directory with the host
|
|
21
|
+
"EXAMPLE_SERVICES_PATH": "${localWorkspaceFolder}/example-services"
|
|
20
22
|
},
|
|
21
23
|
"customizations": {
|
|
22
24
|
"vscode": {
|
|
@@ -58,7 +60,9 @@
|
|
|
58
60
|
// Allow the container to access the host X11 display and EPICS CA
|
|
59
61
|
"--net=host",
|
|
60
62
|
// Make sure SELinux does not disable with access to host filesystems like tmp
|
|
61
|
-
"--security-opt=label=disable"
|
|
63
|
+
"--security-opt=label=disable",
|
|
64
|
+
// add the docker socket environment variable to the container
|
|
65
|
+
"-e=DOCKER_HOST=${localEnv:DOCKER_HOST}"
|
|
62
66
|
],
|
|
63
67
|
"mounts": [
|
|
64
68
|
// Mount in the user terminal config folder so it can be edited
|
|
@@ -72,6 +76,18 @@
|
|
|
72
76
|
"source": "devcontainer-shared-cache",
|
|
73
77
|
"target": "/cache",
|
|
74
78
|
"type": "volume"
|
|
79
|
+
},
|
|
80
|
+
// Match host external services file paths (internal docker starts them on the host)
|
|
81
|
+
{
|
|
82
|
+
"source": "${localWorkspaceFolder}/example-services",
|
|
83
|
+
"target": "${localWorkspaceFolder}/example-services",
|
|
84
|
+
"type": "bind"
|
|
85
|
+
},
|
|
86
|
+
// Mount the user sockets folder
|
|
87
|
+
{
|
|
88
|
+
"source": "${localEnv:XDG_RUNTIME_DIR}",
|
|
89
|
+
"target": "${localEnv:XDG_RUNTIME_DIR}",
|
|
90
|
+
"type": "bind"
|
|
75
91
|
}
|
|
76
92
|
],
|
|
77
93
|
// Mount the parent as /workspaces so we can pip install peers as editable
|
|
@@ -13,10 +13,6 @@ on:
|
|
|
13
13
|
type: string
|
|
14
14
|
description: The path to look for tests
|
|
15
15
|
required: true
|
|
16
|
-
needs-services:
|
|
17
|
-
type: boolean
|
|
18
|
-
description: Whether to start external services
|
|
19
|
-
required: true
|
|
20
16
|
secrets:
|
|
21
17
|
CODECOV_TOKEN:
|
|
22
18
|
required: true
|
|
@@ -32,6 +28,7 @@ jobs:
|
|
|
32
28
|
|
|
33
29
|
env:
|
|
34
30
|
COVERAGE_PROCESS_START: .coveragerc
|
|
31
|
+
EXAMPLE_SERVICES_PATH: ./example-services
|
|
35
32
|
|
|
36
33
|
steps:
|
|
37
34
|
- name: Checkout repository (with submodules)
|
|
@@ -49,15 +46,6 @@ jobs:
|
|
|
49
46
|
- name: Install uv
|
|
50
47
|
uses: astral-sh/setup-uv@v7
|
|
51
48
|
|
|
52
|
-
- if: inputs.needs-services && inputs.runs-on != 'windows-latest'
|
|
53
|
-
name: Run docker compose
|
|
54
|
-
uses: hoverkraft-tech/compose-action@v2.4.1
|
|
55
|
-
with:
|
|
56
|
-
compose-file: "./example-services/compose.yaml"
|
|
57
|
-
services: |
|
|
58
|
-
bl01t-di-cam-01
|
|
59
|
-
ca-gateway
|
|
60
|
-
|
|
61
49
|
- name: Run tests win
|
|
62
50
|
if: inputs.runs-on == 'windows-latest'
|
|
63
51
|
run: uv run --locked tox -e tests -- --timeout=10 ${{ inputs.tests-path}}
|
|
@@ -19,18 +19,13 @@ jobs:
|
|
|
19
19
|
matrix:
|
|
20
20
|
runs-on: ["ubuntu-latest", "windows-latest"] # can add macos-latest
|
|
21
21
|
python-version: ["3.11", "3.12", "3.13"]
|
|
22
|
-
|
|
23
|
-
- tests-path: "tests/unit_tests"
|
|
24
|
-
needs-services: false
|
|
25
|
-
- tests-path: "tests/system_tests"
|
|
26
|
-
needs-services: true
|
|
22
|
+
tests-path: ["", "tests/system_tests"]
|
|
27
23
|
fail-fast: false
|
|
28
24
|
uses: ./.github/workflows/_test.yml
|
|
29
25
|
with:
|
|
30
26
|
runs-on: ${{ matrix.runs-on }}
|
|
31
27
|
python-version: ${{ matrix.python-version }}
|
|
32
|
-
tests-path: ${{ matrix.
|
|
33
|
-
needs-services: ${{ matrix.test-config.needs-services }}
|
|
28
|
+
tests-path: ${{ matrix.tests-path }}
|
|
34
29
|
secrets:
|
|
35
30
|
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
|
|
36
31
|
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# The devcontainer should use the developer target and run as root with podman
|
|
2
|
+
# or docker with user namespaces.
|
|
3
|
+
FROM ghcr.io/diamondlightsource/ubuntu-devcontainer:noble AS developer
|
|
4
|
+
|
|
5
|
+
ENV DOCKER=docker-28.5.1
|
|
6
|
+
ENV DOCKER_COMPOSE_RELEASE_TAG=v2.40.3
|
|
7
|
+
|
|
8
|
+
# Add any system dependencies for the developer/build environment here
|
|
9
|
+
RUN apt-get update -y && apt-get install -y --no-install-recommends \
|
|
10
|
+
graphviz \
|
|
11
|
+
libxcb-cursor0 \
|
|
12
|
+
qt6-base-dev \
|
|
13
|
+
curl \
|
|
14
|
+
&& apt-get dist-clean
|
|
15
|
+
|
|
16
|
+
# install the docker ce cli binary
|
|
17
|
+
RUN curl -O https://download.docker.com/linux/static/stable/x86_64/${DOCKER}.tgz && \
|
|
18
|
+
tar xvf ${DOCKER}.tgz && \
|
|
19
|
+
cp docker/docker /usr/bin && \
|
|
20
|
+
rm -r ${DOCKER}.tgz docker
|
|
21
|
+
|
|
22
|
+
# install docker-compose plugin
|
|
23
|
+
RUN mkdir -p /usr/libexec/docker/cli-plugins/ && \
|
|
24
|
+
curl -SL https://github.com/docker/compose/releases/download/${DOCKER_COMPOSE_RELEASE_TAG}/docker-compose-linux-x86_64 -o /usr/libexec/docker/cli-plugins/docker-compose && \
|
|
25
|
+
chmod +x /usr/libexec/docker/cli-plugins/docker-compose
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: ophyd-async
|
|
3
|
-
Version: 0.13.
|
|
3
|
+
Version: 0.13.7
|
|
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
|
|
@@ -206,7 +206,6 @@ intersphinx_mapping = {
|
|
|
206
206
|
"bluesky": ("https://blueskyproject.io/bluesky/main", None),
|
|
207
207
|
"scanspec": ("https://blueskyproject.io/scanspec/main", None),
|
|
208
208
|
"numpy": ("https://numpy.org/devdocs/", None),
|
|
209
|
-
"databroker": ("https://blueskyproject.io/databroker/", None),
|
|
210
209
|
"event-model": ("https://blueskyproject.io/event-model/main", None),
|
|
211
210
|
"pytest": ("https://docs.pytest.org/en/stable/", None),
|
|
212
211
|
}
|
|
@@ -28,7 +28,7 @@ version_tuple: VERSION_TUPLE
|
|
|
28
28
|
commit_id: COMMIT_ID
|
|
29
29
|
__commit_id__: COMMIT_ID
|
|
30
30
|
|
|
31
|
-
__version__ = version = '0.13.
|
|
32
|
-
__version_tuple__ = version_tuple = (0, 13,
|
|
31
|
+
__version__ = version = '0.13.7'
|
|
32
|
+
__version_tuple__ = version_tuple = (0, 13, 7)
|
|
33
33
|
|
|
34
|
-
__commit_id__ = commit_id = '
|
|
34
|
+
__commit_id__ = commit_id = 'g80ae4488a'
|
|
@@ -639,9 +639,10 @@ async def set_and_wait_for_other_value(
|
|
|
639
639
|
if wait_for_set_completion:
|
|
640
640
|
await status
|
|
641
641
|
except TimeoutError as exc:
|
|
642
|
+
matcher_name = getattr(matcher, "__name__", f"<{type(matcher).__name__}>")
|
|
642
643
|
raise TimeoutError(
|
|
643
644
|
f"{match_signal.name} value didn't match value from"
|
|
644
|
-
f" {
|
|
645
|
+
f" {matcher_name}() in {timeout}s"
|
|
645
646
|
) from exc
|
|
646
647
|
|
|
647
648
|
return status
|
|
@@ -98,9 +98,12 @@ class Motor(
|
|
|
98
98
|
self.motor_done_move = epics_signal_r(int, prefix + ".DMOV")
|
|
99
99
|
self.low_limit_travel = epics_signal_rw(float, prefix + ".LLM")
|
|
100
100
|
self.high_limit_travel = epics_signal_rw(float, prefix + ".HLM")
|
|
101
|
+
self.dial_low_limit_travel = epics_signal_rw(float, prefix + ".DLLM")
|
|
102
|
+
self.dial_high_limit_travel = epics_signal_rw(float, prefix + ".DHLM")
|
|
101
103
|
self.offset_freeze_switch = epics_signal_rw(OffsetMode, prefix + ".FOFF")
|
|
102
104
|
self.high_limit_switch = epics_signal_r(int, prefix + ".HLS")
|
|
103
105
|
self.low_limit_switch = epics_signal_r(int, prefix + ".LLS")
|
|
106
|
+
self.output_link = epics_signal_r(str, prefix + ".OUT")
|
|
104
107
|
self.set_use_switch = epics_signal_rw(UseSetMode, prefix + ".SET")
|
|
105
108
|
|
|
106
109
|
# Note:cannot use epics_signal_x here, as the motor record specifies that
|
|
@@ -131,16 +134,26 @@ class Motor(
|
|
|
131
134
|
Will raise a MotorLimitsException if the given absolute positions will be
|
|
132
135
|
outside the motor soft limits.
|
|
133
136
|
"""
|
|
134
|
-
|
|
137
|
+
(
|
|
138
|
+
motor_lower_limit,
|
|
139
|
+
motor_upper_limit,
|
|
140
|
+
egu,
|
|
141
|
+
dial_lower_limit,
|
|
142
|
+
dial_upper_limit,
|
|
143
|
+
) = await asyncio.gather(
|
|
135
144
|
self.low_limit_travel.get_value(),
|
|
136
145
|
self.high_limit_travel.get_value(),
|
|
137
146
|
self.motor_egu.get_value(),
|
|
147
|
+
self.dial_low_limit_travel.get_value(),
|
|
148
|
+
self.dial_high_limit_travel.get_value(),
|
|
138
149
|
)
|
|
139
150
|
|
|
140
|
-
# EPICS motor record treats limits of 0, 0 as no limit
|
|
141
|
-
|
|
151
|
+
# EPICS motor record treats dial limits of 0, 0 as no limit
|
|
152
|
+
# Use DLLM and DHLM to check
|
|
153
|
+
if dial_lower_limit == 0 and dial_upper_limit == 0:
|
|
142
154
|
return
|
|
143
155
|
|
|
156
|
+
# Use real motor limit(i.e. HLM and LLM) to check if the move is permissible
|
|
144
157
|
if (
|
|
145
158
|
not motor_upper_limit >= abs_start_pos >= motor_lower_limit
|
|
146
159
|
or not motor_upper_limit >= abs_end_pos >= motor_lower_limit
|
|
@@ -150,6 +163,8 @@ class Motor(
|
|
|
150
163
|
f"{abs_start_pos}{egu} to "
|
|
151
164
|
f"{abs_end_pos}{egu} but motor limits are "
|
|
152
165
|
f"{motor_lower_limit}{egu} <= x <= {motor_upper_limit}{egu} "
|
|
166
|
+
f"dial limits are "
|
|
167
|
+
f"{dial_lower_limit}{egu} <= x <= {dial_upper_limit}"
|
|
153
168
|
)
|
|
154
169
|
|
|
155
170
|
@AsyncStatus.wrap
|
|
@@ -6,7 +6,8 @@ from ophyd_async.core import Array1D, Device, DeviceVector, StandardReadable
|
|
|
6
6
|
from ophyd_async.epics import motor
|
|
7
7
|
from ophyd_async.epics.core import epics_signal_r, epics_signal_rw, epics_signal_x
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
# Map the CS axis letters to their index (1 indexed)
|
|
10
|
+
CS_INDEX = {letter: index + 1 for index, letter in enumerate("ABCUVWXYZ")}
|
|
10
11
|
|
|
11
12
|
|
|
12
13
|
class PmacTrajectoryIO(StandardReadable):
|
|
@@ -20,24 +21,20 @@ class PmacTrajectoryIO(StandardReadable):
|
|
|
20
21
|
# 1 indexed CS axes so we can index into them from the compound motor input link
|
|
21
22
|
self.positions = DeviceVector(
|
|
22
23
|
{
|
|
23
|
-
i
|
|
24
|
-
|
|
25
|
-
)
|
|
26
|
-
for i, letter in enumerate(CS_LETTERS)
|
|
24
|
+
i: epics_signal_rw(Array1D[np.float64], f"{prefix}{letter}:Positions")
|
|
25
|
+
for letter, i in CS_INDEX.items()
|
|
27
26
|
}
|
|
28
27
|
)
|
|
29
28
|
self.use_axis = DeviceVector(
|
|
30
29
|
{
|
|
31
|
-
i
|
|
32
|
-
for
|
|
30
|
+
i: epics_signal_rw(bool, f"{prefix}{letter}:UseAxis")
|
|
31
|
+
for letter, i in CS_INDEX.items()
|
|
33
32
|
}
|
|
34
33
|
)
|
|
35
34
|
self.velocities = DeviceVector(
|
|
36
35
|
{
|
|
37
|
-
i
|
|
38
|
-
|
|
39
|
-
)
|
|
40
|
-
for i, letter in enumerate(CS_LETTERS)
|
|
36
|
+
i: epics_signal_rw(Array1D[np.float64], f"{prefix}{letter}:Velocities")
|
|
37
|
+
for letter, i in CS_INDEX.items()
|
|
41
38
|
}
|
|
42
39
|
)
|
|
43
40
|
self.total_points = epics_signal_r(int, f"{prefix}TotalPoints_RBV")
|
|
@@ -76,8 +73,8 @@ class PmacCoordIO(Device):
|
|
|
76
73
|
self.cs_port = epics_signal_r(str, f"{prefix}Port")
|
|
77
74
|
self.cs_axis_setpoint = DeviceVector(
|
|
78
75
|
{
|
|
79
|
-
i
|
|
80
|
-
for i in
|
|
76
|
+
i: epics_signal_rw(float, f"{prefix}M{i}:DirectDemand")
|
|
77
|
+
for i in CS_INDEX.values()
|
|
81
78
|
}
|
|
82
79
|
)
|
|
83
80
|
super().__init__(name=name)
|
|
@@ -15,10 +15,10 @@ from ophyd_async.core import (
|
|
|
15
15
|
wait_for_value,
|
|
16
16
|
)
|
|
17
17
|
from ophyd_async.epics.motor import Motor
|
|
18
|
-
|
|
19
|
-
from
|
|
20
|
-
from
|
|
21
|
-
from
|
|
18
|
+
|
|
19
|
+
from ._pmac_io import CS_INDEX, PmacIO
|
|
20
|
+
from ._pmac_trajectory_generation import PVT, Trajectory
|
|
21
|
+
from ._utils import (
|
|
22
22
|
_PmacMotorInfo,
|
|
23
23
|
calculate_ramp_position_and_duration,
|
|
24
24
|
)
|
|
@@ -131,8 +131,7 @@ class PmacTrajectoryTriggerLogic(FlyerController):
|
|
|
131
131
|
slice, path_length, motor_info, ramp_up_time
|
|
132
132
|
)
|
|
133
133
|
use_axis = {
|
|
134
|
-
|
|
135
|
-
for axis in range(len(CS_LETTERS))
|
|
134
|
+
i: (i in motor_info.motor_cs_index.values()) for i in CS_INDEX.values()
|
|
136
135
|
}
|
|
137
136
|
|
|
138
137
|
coros = [
|
|
@@ -177,14 +176,14 @@ class PmacTrajectoryTriggerLogic(FlyerController):
|
|
|
177
176
|
self, trajectory: Trajectory, motor_info: _PmacMotorInfo
|
|
178
177
|
):
|
|
179
178
|
coros = []
|
|
180
|
-
for motor,
|
|
179
|
+
for motor, cs_index in motor_info.motor_cs_index.items():
|
|
181
180
|
coros.append(
|
|
182
|
-
self.pmac.trajectory.positions[
|
|
181
|
+
self.pmac.trajectory.positions[cs_index].set(
|
|
183
182
|
trajectory.positions[motor]
|
|
184
183
|
)
|
|
185
184
|
)
|
|
186
185
|
coros.append(
|
|
187
|
-
self.pmac.trajectory.velocities[
|
|
186
|
+
self.pmac.trajectory.velocities[cs_index].set(
|
|
188
187
|
trajectory.velocities[motor]
|
|
189
188
|
)
|
|
190
189
|
)
|
|
@@ -206,7 +205,7 @@ class PmacTrajectoryTriggerLogic(FlyerController):
|
|
|
206
205
|
for motor, position in ramp_up_position.items():
|
|
207
206
|
coros.append(
|
|
208
207
|
set_and_wait_for_value(
|
|
209
|
-
coord.cs_axis_setpoint[motor_info.motor_cs_index[motor]
|
|
208
|
+
coord.cs_axis_setpoint[motor_info.motor_cs_index[motor]],
|
|
210
209
|
position,
|
|
211
210
|
set_timeout=10,
|
|
212
211
|
wait_for_set_completion=False,
|
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import asyncio
|
|
4
|
+
import re
|
|
5
|
+
from collections.abc import Sequence
|
|
6
|
+
from dataclasses import dataclass
|
|
7
|
+
|
|
8
|
+
import numpy as np
|
|
9
|
+
from scanspec.core import Slice
|
|
10
|
+
|
|
11
|
+
from ophyd_async.core import gather_dict
|
|
12
|
+
from ophyd_async.epics.motor import Motor
|
|
13
|
+
|
|
14
|
+
from ._pmac_io import CS_INDEX, PmacIO
|
|
15
|
+
|
|
16
|
+
# PMAC durations are in milliseconds
|
|
17
|
+
# We must convert from scanspec durations (seconds) to milliseconds
|
|
18
|
+
# PMAC motion program multiples durations by 0.001
|
|
19
|
+
# (see https://github.com/DiamondLightSource/pmac/blob/afe81f8bb9179c3a20eff351f30bc6cfd1539ad9/pmacApp/pmc/trajectory_scan_code_ppmac.pmc#L241)
|
|
20
|
+
# Therefore, we must divide scanspec durations by 10e-6
|
|
21
|
+
TICK_S = 0.000001
|
|
22
|
+
MIN_TURNAROUND = 0.002
|
|
23
|
+
MIN_INTERVAL = 0.002
|
|
24
|
+
|
|
25
|
+
# Regex to parse outlink strings of the form "@asyn(PMAC1CS2, 7)"
|
|
26
|
+
# returning PMAC1CS2 and 7
|
|
27
|
+
# https://regex101.com/r/Mu9XpO/1
|
|
28
|
+
OUTLINK_REGEX = re.compile(r"^\@asyn\(([^,]+),\s*(\d+)\)$")
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
@dataclass
|
|
32
|
+
class _PmacMotorInfo:
|
|
33
|
+
cs_port: str
|
|
34
|
+
cs_number: int
|
|
35
|
+
motor_cs_index: dict[Motor, int]
|
|
36
|
+
motor_acceleration_rate: dict[Motor, float]
|
|
37
|
+
motor_max_velocity: dict[Motor, float]
|
|
38
|
+
|
|
39
|
+
@classmethod
|
|
40
|
+
async def from_motors(cls, pmac: PmacIO, motors: Sequence[Motor]) -> _PmacMotorInfo:
|
|
41
|
+
"""Creates a _PmacMotorInfo instance based on a controller and list of motors.
|
|
42
|
+
|
|
43
|
+
:param pmac: The PMAC device
|
|
44
|
+
:param motors: Sequence of motors involved in trajectory
|
|
45
|
+
:raises RuntimeError:
|
|
46
|
+
if motors do not share common CS port or CS number, or if
|
|
47
|
+
motors do not have unique CS index assignments
|
|
48
|
+
:returns:
|
|
49
|
+
_PmacMotorInfo instance with motor's common CS port and CS number, and
|
|
50
|
+
dictionaries of motor's to their unique CS index and accelerate rate
|
|
51
|
+
|
|
52
|
+
"""
|
|
53
|
+
is_raw_motor = [motor in pmac.motor_assignment_index for motor in motors]
|
|
54
|
+
if all(is_raw_motor):
|
|
55
|
+
# Get the CS port, number and axis letter from the PVs for the raw motor
|
|
56
|
+
assignments = {
|
|
57
|
+
motor: pmac.assignment[pmac.motor_assignment_index[motor]]
|
|
58
|
+
for motor in motors
|
|
59
|
+
}
|
|
60
|
+
cs_ports, cs_numbers, cs_axis_letters = await asyncio.gather(
|
|
61
|
+
gather_dict(
|
|
62
|
+
{motor: assignments[motor].cs_port.get_value() for motor in motors}
|
|
63
|
+
),
|
|
64
|
+
gather_dict(
|
|
65
|
+
{
|
|
66
|
+
motor: assignments[motor].cs_number.get_value()
|
|
67
|
+
for motor in motors
|
|
68
|
+
}
|
|
69
|
+
),
|
|
70
|
+
gather_dict(
|
|
71
|
+
{
|
|
72
|
+
motor: assignments[motor].cs_axis_letter.get_value()
|
|
73
|
+
for motor in motors
|
|
74
|
+
}
|
|
75
|
+
),
|
|
76
|
+
)
|
|
77
|
+
# Translate axis letters to cs_index and check for duplicates
|
|
78
|
+
motor_cs_index: dict[Motor, int] = {}
|
|
79
|
+
for motor, cs_axis_letter in cs_axis_letters.items():
|
|
80
|
+
if not cs_axis_letter:
|
|
81
|
+
raise ValueError(
|
|
82
|
+
f"Motor {motor.name} does not have an axis assignment."
|
|
83
|
+
)
|
|
84
|
+
try:
|
|
85
|
+
# 1 indexed to match coord
|
|
86
|
+
index = CS_INDEX[cs_axis_letter]
|
|
87
|
+
except KeyError as err:
|
|
88
|
+
raise ValueError(
|
|
89
|
+
f"Motor {motor.name} assigned to '{cs_axis_letter}' "
|
|
90
|
+
f"but must be assigned to one of '{','.join(CS_INDEX)}'"
|
|
91
|
+
) from err
|
|
92
|
+
if index in motor_cs_index.values():
|
|
93
|
+
raise ValueError(
|
|
94
|
+
f"Motor {motor.name} assigned to '{cs_axis_letter}' "
|
|
95
|
+
"but another motor is already assigned to this axis."
|
|
96
|
+
)
|
|
97
|
+
motor_cs_index[motor] = index
|
|
98
|
+
elif not any(is_raw_motor):
|
|
99
|
+
# Get CS numbers from all the cs ports and output links for the CS motors
|
|
100
|
+
output_links, cs_lookup = await asyncio.gather(
|
|
101
|
+
gather_dict({motor: motor.output_link.get_value() for motor in motors}),
|
|
102
|
+
gather_dict(
|
|
103
|
+
{
|
|
104
|
+
cs_number: cs.cs_port.get_value()
|
|
105
|
+
for cs_number, cs in pmac.coord.items()
|
|
106
|
+
}
|
|
107
|
+
),
|
|
108
|
+
)
|
|
109
|
+
# Create a reverse lookup from cs_port to cs_number
|
|
110
|
+
cs_reverse_lookup = {
|
|
111
|
+
cs_port: cs_number for cs_number, cs_port in cs_lookup.items()
|
|
112
|
+
}
|
|
113
|
+
cs_ports: dict[Motor, str] = {}
|
|
114
|
+
cs_numbers: dict[Motor, int] = {}
|
|
115
|
+
motor_cs_index: dict[Motor, int] = {}
|
|
116
|
+
# Populate the cs_ports, cs_numbers and motor_cs_index dicts from outlinks
|
|
117
|
+
for motor, output_link in output_links.items():
|
|
118
|
+
match = OUTLINK_REGEX.match(output_link)
|
|
119
|
+
if not match:
|
|
120
|
+
raise ValueError(
|
|
121
|
+
f"Motor {motor.name} has invalid output link '{output_link}'"
|
|
122
|
+
)
|
|
123
|
+
cs_port, cs_index = match.groups()
|
|
124
|
+
cs_ports[motor] = cs_port
|
|
125
|
+
cs_numbers[motor] = cs_reverse_lookup[cs_port]
|
|
126
|
+
motor_cs_index[motor] = int(cs_index)
|
|
127
|
+
else:
|
|
128
|
+
raise ValueError("Unable to use raw motors and CS motors in the same scan")
|
|
129
|
+
|
|
130
|
+
# check if the values in cs_port and cs_number are the same
|
|
131
|
+
cs_ports_set = set(cs_ports.values())
|
|
132
|
+
if len(cs_ports_set) != 1:
|
|
133
|
+
raise RuntimeError(
|
|
134
|
+
"Failed to fetch common CS port."
|
|
135
|
+
"Motors passed are assigned to multiple CS ports:"
|
|
136
|
+
f"{list(cs_ports_set)}"
|
|
137
|
+
)
|
|
138
|
+
cs_numbers_set = set(cs_numbers.values())
|
|
139
|
+
if len(cs_numbers_set) != 1:
|
|
140
|
+
raise RuntimeError(
|
|
141
|
+
"Failed to fetch common CS number."
|
|
142
|
+
"Motors passed are assigned to multiple CS numbers:"
|
|
143
|
+
f"{list(cs_numbers_set)}"
|
|
144
|
+
)
|
|
145
|
+
|
|
146
|
+
# Get the velocities and acceleration rates for each motor
|
|
147
|
+
max_velocity, acceleration_time = await asyncio.gather(
|
|
148
|
+
gather_dict({motor: motor.max_velocity.get_value() for motor in motors}),
|
|
149
|
+
gather_dict(
|
|
150
|
+
{motor: motor.acceleration_time.get_value() for motor in motors}
|
|
151
|
+
),
|
|
152
|
+
)
|
|
153
|
+
motor_acceleration_rate = {
|
|
154
|
+
motor: max_velocity[motor] / acceleration_time[motor] for motor in motors
|
|
155
|
+
}
|
|
156
|
+
return _PmacMotorInfo(
|
|
157
|
+
cs_port=cs_ports_set.pop(),
|
|
158
|
+
cs_number=cs_numbers_set.pop(),
|
|
159
|
+
motor_cs_index=motor_cs_index,
|
|
160
|
+
motor_acceleration_rate=motor_acceleration_rate,
|
|
161
|
+
motor_max_velocity=max_velocity,
|
|
162
|
+
)
|
|
163
|
+
|
|
164
|
+
|
|
165
|
+
def calculate_ramp_position_and_duration(
|
|
166
|
+
slice: Slice[Motor], motor_info: _PmacMotorInfo, is_up: bool
|
|
167
|
+
) -> tuple[dict[Motor, np.float64], float]:
|
|
168
|
+
"""Calculate the the required ramp position and duration of a trajectory.
|
|
169
|
+
|
|
170
|
+
This function will:
|
|
171
|
+
- Calculate the ramp time required to achieve each motor's
|
|
172
|
+
initial entry velocity into the first frame of a slice
|
|
173
|
+
or final exit velocity out of the last frame of a slice
|
|
174
|
+
- Use the longest ramp time to calculate all motor's
|
|
175
|
+
ramp up positions.
|
|
176
|
+
|
|
177
|
+
:param slice: Information about a series of scan frames along a number of axes
|
|
178
|
+
:param motor_info: Instance of _PmacMotorInfo
|
|
179
|
+
:param is_up: Boolean representing ramping up into a frame or down out of a frame
|
|
180
|
+
:returns tuple: A tuple containing:
|
|
181
|
+
dict: Motor to ramp positions
|
|
182
|
+
float: Ramp time required for all motors
|
|
183
|
+
"""
|
|
184
|
+
if slice.duration is None:
|
|
185
|
+
raise ValueError("Slice must have a duration")
|
|
186
|
+
|
|
187
|
+
scan_axes = slice.axes()
|
|
188
|
+
idx = 0 if is_up else -1
|
|
189
|
+
|
|
190
|
+
velocities: dict[Motor, float] = {}
|
|
191
|
+
ramp_times: list[float] = []
|
|
192
|
+
for axis in scan_axes:
|
|
193
|
+
velocity = (slice.upper[axis][idx] - slice.lower[axis][idx]) / slice.duration[
|
|
194
|
+
idx
|
|
195
|
+
]
|
|
196
|
+
velocities[axis] = velocity
|
|
197
|
+
ramp_times.append(abs(velocity) / motor_info.motor_acceleration_rate[axis])
|
|
198
|
+
ramp_times.append(
|
|
199
|
+
MIN_TURNAROUND
|
|
200
|
+
) # Adding a 2ms ramp time as a min tournaround time
|
|
201
|
+
max_ramp_time = max(ramp_times)
|
|
202
|
+
|
|
203
|
+
motor_to_ramp_position = {}
|
|
204
|
+
sign = -1 if is_up else 1
|
|
205
|
+
for axis, v in velocities.items():
|
|
206
|
+
ref_pos = slice.lower[axis][0] if is_up else slice.upper[axis][-1]
|
|
207
|
+
displacement = 0.5 * v * max_ramp_time
|
|
208
|
+
motor_to_ramp_position[axis] = ref_pos + sign * displacement
|
|
209
|
+
|
|
210
|
+
return (motor_to_ramp_position, max_ramp_time)
|
|
@@ -8,7 +8,6 @@ from ._signal import (
|
|
|
8
8
|
tango_signal_w,
|
|
9
9
|
tango_signal_x,
|
|
10
10
|
)
|
|
11
|
-
from ._tango_readable import TangoReadable
|
|
12
11
|
from ._tango_transport import (
|
|
13
12
|
AttributeProxy,
|
|
14
13
|
CommandProxy,
|
|
@@ -50,7 +49,6 @@ __all__ = [
|
|
|
50
49
|
"tango_signal_w",
|
|
51
50
|
"tango_signal_x",
|
|
52
51
|
"TangoDevice",
|
|
53
|
-
"TangoReadable",
|
|
54
52
|
"TangoPolling",
|
|
55
53
|
"TangoDeviceConnector",
|
|
56
54
|
"TangoLongStringTable",
|
|
@@ -29,7 +29,7 @@ class TangoDevice(Device):
|
|
|
29
29
|
|
|
30
30
|
def __init__(
|
|
31
31
|
self,
|
|
32
|
-
trl: str
|
|
32
|
+
trl: str = "",
|
|
33
33
|
support_events: bool = False,
|
|
34
34
|
name: str = "",
|
|
35
35
|
auto_fill_signals: bool = True,
|
|
@@ -80,6 +80,9 @@ class TangoDeviceConnector(DeviceConnector):
|
|
|
80
80
|
self._support_events = support_events
|
|
81
81
|
self._auto_fill_signals = auto_fill_signals
|
|
82
82
|
|
|
83
|
+
def set_trl(self, trl: str):
|
|
84
|
+
self.trl = trl
|
|
85
|
+
|
|
83
86
|
def create_children_from_annotations(self, device: Device):
|
|
84
87
|
if not hasattr(self, "filler"):
|
|
85
88
|
self.filler = DeviceFiller(
|
|
@@ -1,11 +1,18 @@
|
|
|
1
1
|
from typing import Annotated as A
|
|
2
2
|
|
|
3
|
-
from ophyd_async.core import
|
|
3
|
+
from ophyd_async.core import (
|
|
4
|
+
DEFAULT_TIMEOUT,
|
|
5
|
+
AsyncStatus,
|
|
6
|
+
SignalR,
|
|
7
|
+
SignalRW,
|
|
8
|
+
SignalX,
|
|
9
|
+
StandardReadable,
|
|
10
|
+
)
|
|
4
11
|
from ophyd_async.core import StandardReadableFormat as Format
|
|
5
|
-
from ophyd_async.tango.core import
|
|
12
|
+
from ophyd_async.tango.core import TangoDevice, TangoPolling
|
|
6
13
|
|
|
7
14
|
|
|
8
|
-
class TangoCounter(
|
|
15
|
+
class TangoCounter(TangoDevice, StandardReadable):
|
|
9
16
|
"""Tango counting device."""
|
|
10
17
|
|
|
11
18
|
# Enter the name and type of the signals you want to use
|
|
@@ -11,16 +11,17 @@ from ophyd_async.core import (
|
|
|
11
11
|
SignalR,
|
|
12
12
|
SignalRW,
|
|
13
13
|
SignalX,
|
|
14
|
+
StandardReadable,
|
|
14
15
|
WatchableAsyncStatus,
|
|
15
16
|
WatcherUpdate,
|
|
16
17
|
observe_value,
|
|
17
18
|
wait_for_value,
|
|
18
19
|
)
|
|
19
20
|
from ophyd_async.core import StandardReadableFormat as Format
|
|
20
|
-
from ophyd_async.tango.core import DevStateEnum,
|
|
21
|
+
from ophyd_async.tango.core import DevStateEnum, TangoDevice, TangoPolling
|
|
21
22
|
|
|
22
23
|
|
|
23
|
-
class TangoMover(
|
|
24
|
+
class TangoMover(TangoDevice, StandardReadable, Movable, Stoppable):
|
|
24
25
|
"""Tango moving device."""
|
|
25
26
|
|
|
26
27
|
# Enter the name and type of the signals you want to use
|
|
@@ -32,7 +33,7 @@ class TangoMover(TangoReadable, Movable, Stoppable):
|
|
|
32
33
|
# If a tango name clashes with a bluesky verb, add a trailing underscore
|
|
33
34
|
stop_: SignalX
|
|
34
35
|
|
|
35
|
-
def __init__(self, trl: str
|
|
36
|
+
def __init__(self, trl: str = "", name=""):
|
|
36
37
|
super().__init__(trl, name=name)
|
|
37
38
|
self.add_readables([self.position], Format.HINTED_SIGNAL)
|
|
38
39
|
self.add_readables([self.velocity], Format.CONFIG_SIGNAL)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: ophyd-async
|
|
3
|
-
Version: 0.13.
|
|
3
|
+
Version: 0.13.7
|
|
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
|
|
@@ -216,7 +216,6 @@ src/ophyd_async/tango/core/__init__.py
|
|
|
216
216
|
src/ophyd_async/tango/core/_base_device.py
|
|
217
217
|
src/ophyd_async/tango/core/_converters.py
|
|
218
218
|
src/ophyd_async/tango/core/_signal.py
|
|
219
|
-
src/ophyd_async/tango/core/_tango_readable.py
|
|
220
219
|
src/ophyd_async/tango/core/_tango_transport.py
|
|
221
220
|
src/ophyd_async/tango/core/_utils.py
|
|
222
221
|
src/ophyd_async/tango/demo/__init__.py
|
|
@@ -238,10 +237,10 @@ src/ophyd_async/testing/_utils.py
|
|
|
238
237
|
src/ophyd_async/testing/_wait_for_pending.py
|
|
239
238
|
tests/README.md
|
|
240
239
|
tests/conftest.py
|
|
240
|
+
tests/system_tests/conftest.py
|
|
241
241
|
tests/system_tests/test_tutorials.py
|
|
242
242
|
tests/system_tests/epics/adsim/baseline.yaml
|
|
243
|
-
tests/system_tests/epics/adsim/
|
|
244
|
-
tests/system_tests/epics/adsim/stop_iocs.sh
|
|
243
|
+
tests/system_tests/epics/adsim/external_dependencies.sh
|
|
245
244
|
tests/system_tests/epics/adsim/test_adsim_system.py
|
|
246
245
|
tests/system_tests/epics/eiger/README.md
|
|
247
246
|
tests/system_tests/epics/eiger/start_iocs_and_run_tests.sh
|