ophyd-async 0.5.0__tar.gz → 0.5.2__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.5.0 → ophyd_async-0.5.2}/.github/workflows/_release.yml +1 -1
- {ophyd_async-0.5.0 → ophyd_async-0.5.2}/PKG-INFO +4 -2
- {ophyd_async-0.5.0 → ophyd_async-0.5.2}/docs/examples/foo_detector.py +1 -1
- {ophyd_async-0.5.0 → ophyd_async-0.5.2}/docs/how-to/make-a-simple-device.rst +1 -1
- {ophyd_async-0.5.0 → ophyd_async-0.5.2}/docs/how-to/make-a-standard-detector.rst +2 -2
- {ophyd_async-0.5.0 → ophyd_async-0.5.2}/pyproject.toml +10 -2
- {ophyd_async-0.5.0 → ophyd_async-0.5.2}/src/ophyd_async/_version.py +2 -2
- {ophyd_async-0.5.0 → ophyd_async-0.5.2}/src/ophyd_async/core/__init__.py +6 -3
- {ophyd_async-0.5.0 → ophyd_async-0.5.2}/src/ophyd_async/core/_detector.py +38 -28
- {ophyd_async-0.5.0 → ophyd_async-0.5.2}/src/ophyd_async/core/_hdf_dataset.py +1 -5
- {ophyd_async-0.5.0 → ophyd_async-0.5.2}/src/ophyd_async/core/_mock_signal_utils.py +4 -3
- {ophyd_async-0.5.0 → ophyd_async-0.5.2}/src/ophyd_async/core/_providers.py +30 -39
- {ophyd_async-0.5.0 → ophyd_async-0.5.2}/src/ophyd_async/core/_signal.py +73 -28
- {ophyd_async-0.5.0 → ophyd_async-0.5.2}/src/ophyd_async/core/_status.py +17 -1
- {ophyd_async-0.5.0 → ophyd_async-0.5.2}/src/ophyd_async/epics/adaravis/_aravis.py +1 -1
- {ophyd_async-0.5.0 → ophyd_async-0.5.2}/src/ophyd_async/epics/adcore/__init__.py +16 -5
- {ophyd_async-0.5.0 → ophyd_async-0.5.2}/src/ophyd_async/epics/adcore/_core_io.py +29 -5
- {ophyd_async-0.5.0 → ophyd_async-0.5.2}/src/ophyd_async/epics/adcore/_core_logic.py +7 -4
- {ophyd_async-0.5.0 → ophyd_async-0.5.2}/src/ophyd_async/epics/adcore/_hdf_writer.py +51 -33
- ophyd_async-0.5.2/src/ophyd_async/epics/adcore/_utils.py +132 -0
- {ophyd_async-0.5.0 → ophyd_async-0.5.2}/src/ophyd_async/epics/adkinetix/_kinetix.py +1 -1
- {ophyd_async-0.5.0 → ophyd_async-0.5.2}/src/ophyd_async/epics/adkinetix/_kinetix_io.py +4 -1
- {ophyd_async-0.5.0 → ophyd_async-0.5.2}/src/ophyd_async/epics/adpilatus/_pilatus.py +1 -1
- {ophyd_async-0.5.0 → ophyd_async-0.5.2}/src/ophyd_async/epics/adpilatus/_pilatus_controller.py +1 -1
- {ophyd_async-0.5.0 → ophyd_async-0.5.2}/src/ophyd_async/epics/adpilatus/_pilatus_io.py +1 -1
- {ophyd_async-0.5.0 → ophyd_async-0.5.2}/src/ophyd_async/epics/adsimdetector/_sim.py +1 -1
- {ophyd_async-0.5.0 → ophyd_async-0.5.2}/src/ophyd_async/epics/advimba/_vimba.py +1 -1
- {ophyd_async-0.5.0 → ophyd_async-0.5.2}/src/ophyd_async/epics/advimba/_vimba_controller.py +3 -3
- {ophyd_async-0.5.0 → ophyd_async-0.5.2}/src/ophyd_async/epics/advimba/_vimba_io.py +6 -4
- ophyd_async-0.5.2/src/ophyd_async/epics/eiger/__init__.py +5 -0
- ophyd_async-0.5.2/src/ophyd_async/epics/eiger/_eiger.py +43 -0
- ophyd_async-0.5.2/src/ophyd_async/epics/eiger/_eiger_controller.py +66 -0
- ophyd_async-0.5.2/src/ophyd_async/epics/eiger/_eiger_io.py +42 -0
- ophyd_async-0.5.2/src/ophyd_async/epics/eiger/_odin_io.py +125 -0
- {ophyd_async-0.5.0 → ophyd_async-0.5.2}/src/ophyd_async/epics/motor.py +16 -3
- {ophyd_async-0.5.0 → ophyd_async-0.5.2}/src/ophyd_async/epics/signal/_aioca.py +12 -5
- {ophyd_async-0.5.0 → ophyd_async-0.5.2}/src/ophyd_async/epics/signal/_common.py +1 -1
- {ophyd_async-0.5.0 → ophyd_async-0.5.2}/src/ophyd_async/epics/signal/_p4p.py +14 -11
- {ophyd_async-0.5.0 → ophyd_async-0.5.2}/src/ophyd_async/fastcs/panda/__init__.py +3 -3
- ophyd_async-0.5.0/src/ophyd_async/fastcs/panda/_common_blocks.py → ophyd_async-0.5.2/src/ophyd_async/fastcs/panda/_block.py +2 -0
- ophyd_async-0.5.0/src/ophyd_async/fastcs/panda/_panda_controller.py → ophyd_async-0.5.2/src/ophyd_async/fastcs/panda/_control.py +1 -1
- {ophyd_async-0.5.0 → ophyd_async-0.5.2}/src/ophyd_async/fastcs/panda/_hdf_panda.py +4 -4
- {ophyd_async-0.5.0 → ophyd_async-0.5.2}/src/ophyd_async/fastcs/panda/_trigger.py +1 -1
- ophyd_async-0.5.0/src/ophyd_async/fastcs/panda/_hdf_writer.py → ophyd_async-0.5.2/src/ophyd_async/fastcs/panda/_writer.py +29 -22
- {ophyd_async-0.5.0 → ophyd_async-0.5.2}/src/ophyd_async/plan_stubs/__init__.py +3 -0
- ophyd_async-0.5.2/src/ophyd_async/plan_stubs/_nd_attributes.py +63 -0
- {ophyd_async-0.5.0 → ophyd_async-0.5.2}/src/ophyd_async/sim/demo/_pattern_detector/_pattern_detector_controller.py +5 -2
- {ophyd_async-0.5.0 → ophyd_async-0.5.2}/src/ophyd_async/sim/demo/_pattern_detector/_pattern_generator.py +1 -3
- {ophyd_async-0.5.0 → ophyd_async-0.5.2}/src/ophyd_async.egg-info/PKG-INFO +4 -2
- {ophyd_async-0.5.0 → ophyd_async-0.5.2}/src/ophyd_async.egg-info/SOURCES.txt +17 -5
- {ophyd_async-0.5.0 → ophyd_async-0.5.2}/src/ophyd_async.egg-info/requires.txt +4 -1
- ophyd_async-0.5.2/system_tests/epics/eiger/README.md +8 -0
- ophyd_async-0.5.2/system_tests/epics/eiger/start_iocs_and_run_tests.sh +25 -0
- ophyd_async-0.5.2/system_tests/epics/eiger/test_eiger_system.py +92 -0
- {ophyd_async-0.5.0 → ophyd_async-0.5.2}/tests/conftest.py +13 -0
- {ophyd_async-0.5.0 → ophyd_async-0.5.2}/tests/core/test_log.py +2 -2
- {ophyd_async-0.5.0 → ophyd_async-0.5.2}/tests/core/test_providers.py +4 -4
- {ophyd_async-0.5.0 → ophyd_async-0.5.2}/tests/core/test_signal.py +60 -34
- {ophyd_async-0.5.0 → ophyd_async-0.5.2}/tests/core/test_status.py +7 -1
- {ophyd_async-0.5.0 → ophyd_async-0.5.2}/tests/core/test_subset_enum.py +1 -1
- {ophyd_async-0.5.0 → ophyd_async-0.5.2}/tests/core/test_utils.py +4 -1
- {ophyd_async-0.5.0 → ophyd_async-0.5.2}/tests/epics/adaravis/test_aravis.py +13 -4
- {ophyd_async-0.5.0 → ophyd_async-0.5.2}/tests/epics/adcore/test_scans.py +2 -2
- ophyd_async-0.5.2/tests/epics/adcore/test_writers.py +221 -0
- {ophyd_async-0.5.0 → ophyd_async-0.5.2}/tests/epics/adkinetix/test_kinetix.py +12 -4
- {ophyd_async-0.5.0 → ophyd_async-0.5.2}/tests/epics/adpilatus/test_pilatus.py +6 -2
- {ophyd_async-0.5.0 → ophyd_async-0.5.2}/tests/epics/adpilatus/test_pilatus_controller.py +1 -1
- {ophyd_async-0.5.0 → ophyd_async-0.5.2}/tests/epics/adsimdetector/test_sim.py +61 -17
- {ophyd_async-0.5.0 → ophyd_async-0.5.2}/tests/epics/advimba/test_vimba.py +26 -16
- ophyd_async-0.5.2/tests/epics/eiger/test_eiger_controller.py +114 -0
- ophyd_async-0.5.2/tests/epics/eiger/test_eiger_detector.py +38 -0
- ophyd_async-0.5.2/tests/epics/eiger/test_odin_io.py +75 -0
- {ophyd_async-0.5.0 → ophyd_async-0.5.2}/tests/epics/signal/test_common.py +8 -2
- {ophyd_async-0.5.0 → ophyd_async-0.5.2}/tests/epics/signal/test_records.db +14 -0
- {ophyd_async-0.5.0 → ophyd_async-0.5.2}/tests/epics/signal/test_signals.py +31 -3
- ophyd_async-0.5.2/tests/epics/test_areadetector_subclass_naming.py +32 -0
- {ophyd_async-0.5.0 → ophyd_async-0.5.2}/tests/epics/test_motor.py +26 -3
- {ophyd_async-0.5.0 → ophyd_async-0.5.2}/tests/fastcs/panda/test_hdf_panda.py +7 -0
- {ophyd_async-0.5.0 → ophyd_async-0.5.2}/tests/fastcs/panda/test_panda_connect.py +1 -1
- ophyd_async-0.5.0/tests/fastcs/panda/test_panda_controller.py → ophyd_async-0.5.2/tests/fastcs/panda/test_panda_control.py +2 -6
- {ophyd_async-0.5.0 → ophyd_async-0.5.2}/tests/fastcs/panda/test_panda_utils.py +1 -0
- {ophyd_async-0.5.0 → ophyd_async-0.5.2}/tests/fastcs/panda/test_writer.py +44 -15
- ophyd_async-0.5.0/src/ophyd_async/epics/adcore/_utils.py +0 -133
- ophyd_async-0.5.0/tests/epics/adcore/test_utils_adcore.py +0 -19
- ophyd_async-0.5.0/tests/epics/adcore/test_writers.py +0 -59
- {ophyd_async-0.5.0 → ophyd_async-0.5.2}/.codecov.yml +0 -0
- {ophyd_async-0.5.0 → ophyd_async-0.5.2}/.copier-answers.yml +0 -0
- {ophyd_async-0.5.0 → ophyd_async-0.5.2}/.devcontainer/devcontainer.json +0 -0
- {ophyd_async-0.5.0 → ophyd_async-0.5.2}/.git-blame-ignore-revs +0 -0
- {ophyd_async-0.5.0 → ophyd_async-0.5.2}/.github/CONTRIBUTING.md +0 -0
- {ophyd_async-0.5.0 → ophyd_async-0.5.2}/.github/actions/install_requirements/action.yml +0 -0
- {ophyd_async-0.5.0 → ophyd_async-0.5.2}/.github/dependabot.yml +0 -0
- {ophyd_async-0.5.0 → ophyd_async-0.5.2}/.github/pages/index.html +0 -0
- {ophyd_async-0.5.0 → ophyd_async-0.5.2}/.github/pages/make_switcher.py +0 -0
- {ophyd_async-0.5.0 → ophyd_async-0.5.2}/.github/workflows/_check.yml +0 -0
- {ophyd_async-0.5.0 → ophyd_async-0.5.2}/.github/workflows/_dist.yml +0 -0
- {ophyd_async-0.5.0 → ophyd_async-0.5.2}/.github/workflows/_docs.yml +0 -0
- {ophyd_async-0.5.0 → ophyd_async-0.5.2}/.github/workflows/_pypi.yml +0 -0
- {ophyd_async-0.5.0 → ophyd_async-0.5.2}/.github/workflows/_test.yml +0 -0
- {ophyd_async-0.5.0 → ophyd_async-0.5.2}/.github/workflows/_tox.yml +0 -0
- {ophyd_async-0.5.0 → ophyd_async-0.5.2}/.github/workflows/ci.yml +0 -0
- {ophyd_async-0.5.0 → ophyd_async-0.5.2}/.github/workflows/periodic.yml +0 -0
- {ophyd_async-0.5.0 → ophyd_async-0.5.2}/.gitignore +0 -0
- {ophyd_async-0.5.0 → ophyd_async-0.5.2}/.mailmap +0 -0
- {ophyd_async-0.5.0 → ophyd_async-0.5.2}/.pre-commit-config.yaml +0 -0
- {ophyd_async-0.5.0 → ophyd_async-0.5.2}/Dockerfile +0 -0
- {ophyd_async-0.5.0 → ophyd_async-0.5.2}/LICENSE +0 -0
- {ophyd_async-0.5.0 → ophyd_async-0.5.2}/README.md +0 -0
- {ophyd_async-0.5.0 → ophyd_async-0.5.2}/docs/_templates/README +0 -0
- {ophyd_async-0.5.0 → ophyd_async-0.5.2}/docs/_templates/custom-class-template.rst +0 -0
- {ophyd_async-0.5.0 → ophyd_async-0.5.2}/docs/_templates/custom-module-template.rst +0 -0
- {ophyd_async-0.5.0 → ophyd_async-0.5.2}/docs/conf.py +0 -0
- {ophyd_async-0.5.0 → ophyd_async-0.5.2}/docs/examples/epics_demo.py +0 -0
- {ophyd_async-0.5.0 → ophyd_async-0.5.2}/docs/explanations/decisions/0001-record-architecture-decisions.md +0 -0
- {ophyd_async-0.5.0 → ophyd_async-0.5.2}/docs/explanations/decisions/0002-switched-to-python-copier-template.md +0 -0
- {ophyd_async-0.5.0 → ophyd_async-0.5.2}/docs/explanations/decisions/0003-ophyd-async-migration.rst +0 -0
- {ophyd_async-0.5.0 → ophyd_async-0.5.2}/docs/explanations/decisions/0004-repository-structure.rst +0 -0
- {ophyd_async-0.5.0 → ophyd_async-0.5.2}/docs/explanations/decisions/0005-respect-black-line-length.rst +0 -0
- {ophyd_async-0.5.0 → ophyd_async-0.5.2}/docs/explanations/decisions/0006-procedural-device-definitions.rst +0 -0
- {ophyd_async-0.5.0 → ophyd_async-0.5.2}/docs/explanations/decisions/0007-subpackage-structure.md +0 -0
- {ophyd_async-0.5.0 → ophyd_async-0.5.2}/docs/explanations/decisions/COPYME +0 -0
- {ophyd_async-0.5.0 → ophyd_async-0.5.2}/docs/explanations/decisions.md +0 -0
- {ophyd_async-0.5.0 → ophyd_async-0.5.2}/docs/explanations/design-goals.rst +0 -0
- {ophyd_async-0.5.0 → ophyd_async-0.5.2}/docs/explanations/event-loop-choice.rst +0 -0
- {ophyd_async-0.5.0 → ophyd_async-0.5.2}/docs/explanations/flyscanning.rst +0 -0
- {ophyd_async-0.5.0 → ophyd_async-0.5.2}/docs/explanations.md +0 -0
- {ophyd_async-0.5.0 → ophyd_async-0.5.2}/docs/genindex.rst +0 -0
- {ophyd_async-0.5.0 → ophyd_async-0.5.2}/docs/how-to/choose-interfaces-for-devices.md +0 -0
- {ophyd_async-0.5.0 → ophyd_async-0.5.2}/docs/how-to/compound-devices.rst +0 -0
- {ophyd_async-0.5.0 → ophyd_async-0.5.2}/docs/how-to/contribute.md +0 -0
- {ophyd_async-0.5.0 → ophyd_async-0.5.2}/docs/how-to/write-tests-for-devices.rst +0 -0
- {ophyd_async-0.5.0 → ophyd_async-0.5.2}/docs/how-to.md +0 -0
- {ophyd_async-0.5.0 → ophyd_async-0.5.2}/docs/images/bluesky_ophyd_epics_devices_logo.svg +0 -0
- {ophyd_async-0.5.0 → ophyd_async-0.5.2}/docs/images/bluesky_ophyd_logo.svg +0 -0
- {ophyd_async-0.5.0 → ophyd_async-0.5.2}/docs/images/ophyd_favicon.svg +0 -0
- {ophyd_async-0.5.0 → ophyd_async-0.5.2}/docs/index.md +0 -0
- {ophyd_async-0.5.0 → ophyd_async-0.5.2}/docs/reference/api.rst +0 -0
- {ophyd_async-0.5.0 → ophyd_async-0.5.2}/docs/reference.md +0 -0
- {ophyd_async-0.5.0 → ophyd_async-0.5.2}/docs/tutorials/installation.md +0 -0
- {ophyd_async-0.5.0 → ophyd_async-0.5.2}/docs/tutorials/using-existing-devices.rst +0 -0
- {ophyd_async-0.5.0 → ophyd_async-0.5.2}/docs/tutorials.md +0 -0
- {ophyd_async-0.5.0 → ophyd_async-0.5.2}/setup.cfg +0 -0
- {ophyd_async-0.5.0 → ophyd_async-0.5.2}/src/ophyd_async/__init__.py +0 -0
- {ophyd_async-0.5.0 → ophyd_async-0.5.2}/src/ophyd_async/__main__.py +0 -0
- {ophyd_async-0.5.0 → ophyd_async-0.5.2}/src/ophyd_async/core/_device.py +0 -0
- {ophyd_async-0.5.0 → ophyd_async-0.5.2}/src/ophyd_async/core/_device_save_loader.py +0 -0
- {ophyd_async-0.5.0 → ophyd_async-0.5.2}/src/ophyd_async/core/_flyer.py +0 -0
- {ophyd_async-0.5.0 → ophyd_async-0.5.2}/src/ophyd_async/core/_log.py +0 -0
- {ophyd_async-0.5.0 → ophyd_async-0.5.2}/src/ophyd_async/core/_mock_signal_backend.py +0 -0
- {ophyd_async-0.5.0 → ophyd_async-0.5.2}/src/ophyd_async/core/_protocol.py +0 -0
- {ophyd_async-0.5.0 → ophyd_async-0.5.2}/src/ophyd_async/core/_readable.py +0 -0
- {ophyd_async-0.5.0 → ophyd_async-0.5.2}/src/ophyd_async/core/_signal_backend.py +0 -0
- {ophyd_async-0.5.0 → ophyd_async-0.5.2}/src/ophyd_async/core/_soft_signal_backend.py +0 -0
- {ophyd_async-0.5.0 → ophyd_async-0.5.2}/src/ophyd_async/core/_utils.py +0 -0
- {ophyd_async-0.5.0 → ophyd_async-0.5.2}/src/ophyd_async/epics/__init__.py +0 -0
- {ophyd_async-0.5.0 → ophyd_async-0.5.2}/src/ophyd_async/epics/adaravis/__init__.py +0 -0
- {ophyd_async-0.5.0 → ophyd_async-0.5.2}/src/ophyd_async/epics/adaravis/_aravis_controller.py +0 -0
- {ophyd_async-0.5.0 → ophyd_async-0.5.2}/src/ophyd_async/epics/adaravis/_aravis_io.py +0 -0
- {ophyd_async-0.5.0 → ophyd_async-0.5.2}/src/ophyd_async/epics/adcore/_single_trigger.py +0 -0
- {ophyd_async-0.5.0 → ophyd_async-0.5.2}/src/ophyd_async/epics/adkinetix/__init__.py +0 -0
- {ophyd_async-0.5.0 → ophyd_async-0.5.2}/src/ophyd_async/epics/adkinetix/_kinetix_controller.py +0 -0
- {ophyd_async-0.5.0 → ophyd_async-0.5.2}/src/ophyd_async/epics/adpilatus/__init__.py +0 -0
- {ophyd_async-0.5.0 → ophyd_async-0.5.2}/src/ophyd_async/epics/adsimdetector/__init__.py +0 -0
- {ophyd_async-0.5.0 → ophyd_async-0.5.2}/src/ophyd_async/epics/adsimdetector/_sim_controller.py +0 -0
- {ophyd_async-0.5.0 → ophyd_async-0.5.2}/src/ophyd_async/epics/advimba/__init__.py +0 -0
- {ophyd_async-0.5.0 → ophyd_async-0.5.2}/src/ophyd_async/epics/demo/__init__.py +0 -0
- {ophyd_async-0.5.0 → ophyd_async-0.5.2}/src/ophyd_async/epics/demo/_mover.py +0 -0
- {ophyd_async-0.5.0 → ophyd_async-0.5.2}/src/ophyd_async/epics/demo/_sensor.py +0 -0
- {ophyd_async-0.5.0 → ophyd_async-0.5.2}/src/ophyd_async/epics/demo/mover.db +0 -0
- {ophyd_async-0.5.0 → ophyd_async-0.5.2}/src/ophyd_async/epics/demo/sensor.db +0 -0
- {ophyd_async-0.5.0 → ophyd_async-0.5.2}/src/ophyd_async/epics/pvi/__init__.py +0 -0
- {ophyd_async-0.5.0 → ophyd_async-0.5.2}/src/ophyd_async/epics/pvi/_pvi.py +0 -0
- {ophyd_async-0.5.0 → ophyd_async-0.5.2}/src/ophyd_async/epics/signal/__init__.py +0 -0
- {ophyd_async-0.5.0 → ophyd_async-0.5.2}/src/ophyd_async/epics/signal/_epics_transport.py +0 -0
- {ophyd_async-0.5.0 → ophyd_async-0.5.2}/src/ophyd_async/epics/signal/_signal.py +0 -0
- {ophyd_async-0.5.0 → ophyd_async-0.5.2}/src/ophyd_async/fastcs/__init__.py +0 -0
- {ophyd_async-0.5.0 → ophyd_async-0.5.2}/src/ophyd_async/fastcs/odin/__init__.py +0 -0
- {ophyd_async-0.5.0 → ophyd_async-0.5.2}/src/ophyd_async/fastcs/panda/_table.py +0 -0
- {ophyd_async-0.5.0 → ophyd_async-0.5.2}/src/ophyd_async/fastcs/panda/_utils.py +0 -0
- {ophyd_async-0.5.0 → ophyd_async-0.5.2}/src/ophyd_async/plan_stubs/_ensure_connected.py +0 -0
- {ophyd_async-0.5.0 → ophyd_async-0.5.2}/src/ophyd_async/plan_stubs/_fly.py +0 -0
- {ophyd_async-0.5.0 → ophyd_async-0.5.2}/src/ophyd_async/sim/__init__.py +0 -0
- {ophyd_async-0.5.0 → ophyd_async-0.5.2}/src/ophyd_async/sim/demo/__init__.py +0 -0
- {ophyd_async-0.5.0 → ophyd_async-0.5.2}/src/ophyd_async/sim/demo/_pattern_detector/__init__.py +0 -0
- {ophyd_async-0.5.0 → ophyd_async-0.5.2}/src/ophyd_async/sim/demo/_pattern_detector/_pattern_detector.py +0 -0
- {ophyd_async-0.5.0 → ophyd_async-0.5.2}/src/ophyd_async/sim/demo/_pattern_detector/_pattern_detector_writer.py +0 -0
- {ophyd_async-0.5.0 → ophyd_async-0.5.2}/src/ophyd_async/sim/demo/_sim_motor.py +0 -0
- {ophyd_async-0.5.0 → ophyd_async-0.5.2}/src/ophyd_async/sim/testing/__init__.py +0 -0
- {ophyd_async-0.5.0 → ophyd_async-0.5.2}/src/ophyd_async/tango/__init__.py +0 -0
- {ophyd_async-0.5.0 → ophyd_async-0.5.2}/src/ophyd_async.egg-info/dependency_links.txt +0 -0
- {ophyd_async-0.5.0 → ophyd_async-0.5.2}/src/ophyd_async.egg-info/entry_points.txt +0 -0
- {ophyd_async-0.5.0 → ophyd_async-0.5.2}/src/ophyd_async.egg-info/top_level.txt +0 -0
- {ophyd_async-0.5.0 → ophyd_async-0.5.2}/tests/core/test_device.py +0 -0
- {ophyd_async-0.5.0 → ophyd_async-0.5.2}/tests/core/test_device_collector.py +0 -0
- {ophyd_async-0.5.0 → ophyd_async-0.5.2}/tests/core/test_device_save_loader.py +0 -0
- {ophyd_async-0.5.0 → ophyd_async-0.5.2}/tests/core/test_flyer.py +0 -0
- {ophyd_async-0.5.0 → ophyd_async-0.5.2}/tests/core/test_mock_signal_backend.py +0 -0
- {ophyd_async-0.5.0 → ophyd_async-0.5.2}/tests/core/test_protocol.py +0 -0
- {ophyd_async-0.5.0 → ophyd_async-0.5.2}/tests/core/test_readable.py +0 -0
- {ophyd_async-0.5.0 → ophyd_async-0.5.2}/tests/core/test_soft_signal_backend.py +0 -0
- {ophyd_async-0.5.0 → ophyd_async-0.5.2}/tests/core/test_watchable_async_status.py +0 -0
- {ophyd_async-0.5.0 → ophyd_async-0.5.2}/tests/epics/adcore/test_drivers.py +0 -0
- {ophyd_async-0.5.0 → ophyd_async-0.5.2}/tests/epics/adcore/test_single_trigger.py +0 -0
- {ophyd_async-0.5.0 → ophyd_async-0.5.2}/tests/epics/adsimdetector/test_adsim_controller.py +0 -0
- {ophyd_async-0.5.0 → ophyd_async-0.5.2}/tests/epics/demo/test_demo.py +0 -0
- {ophyd_async-0.5.0 → ophyd_async-0.5.2}/tests/epics/pvi/test_pvi.py +0 -0
- {ophyd_async-0.5.0 → ophyd_async-0.5.2}/tests/fastcs/panda/db/panda.db +0 -0
- {ophyd_async-0.5.0 → ophyd_async-0.5.2}/tests/fastcs/panda/test_table.py +0 -0
- {ophyd_async-0.5.0 → ophyd_async-0.5.2}/tests/fastcs/panda/test_trigger.py +0 -0
- {ophyd_async-0.5.0 → ophyd_async-0.5.2}/tests/plan_stubs/test_ensure_connected.py +0 -0
- {ophyd_async-0.5.0 → ophyd_async-0.5.2}/tests/plan_stubs/test_fly.py +0 -0
- {ophyd_async-0.5.0 → ophyd_async-0.5.2}/tests/sim/__init__.py +0 -0
- {ophyd_async-0.5.0 → ophyd_async-0.5.2}/tests/sim/conftest.py +0 -0
- {ophyd_async-0.5.0 → ophyd_async-0.5.2}/tests/sim/demo/__init__.py +0 -0
- {ophyd_async-0.5.0 → ophyd_async-0.5.2}/tests/sim/demo/test_sim_motor.py +0 -0
- {ophyd_async-0.5.0 → ophyd_async-0.5.2}/tests/sim/test_pattern_generator.py +0 -0
- {ophyd_async-0.5.0 → ophyd_async-0.5.2}/tests/sim/test_sim_detector.py +0 -0
- {ophyd_async-0.5.0 → ophyd_async-0.5.2}/tests/sim/test_sim_writer.py +0 -0
- {ophyd_async-0.5.0 → ophyd_async-0.5.2}/tests/sim/test_streaming_plan.py +0 -0
- {ophyd_async-0.5.0 → ophyd_async-0.5.2}/tests/test_cli.py +0 -0
- {ophyd_async-0.5.0 → ophyd_async-0.5.2}/tests/test_data/test_yaml_save.yml +0 -0
|
@@ -23,7 +23,7 @@ jobs:
|
|
|
23
23
|
- name: Create GitHub Release
|
|
24
24
|
# We pin to the SHA, not the tag, for security reasons.
|
|
25
25
|
# https://docs.github.com/en/actions/learn-github-actions/security-hardening-for-github-actions#using-third-party-actions
|
|
26
|
-
uses: softprops/action-gh-release@
|
|
26
|
+
uses: softprops/action-gh-release@c062e08bd532815e2082a85e87e3ef29c3e6d191 # v2.0.8
|
|
27
27
|
with:
|
|
28
28
|
prerelease: ${{ contains(github.ref_name, 'a') || contains(github.ref_name, 'b') || contains(github.ref_name, 'rc') }}
|
|
29
29
|
files: "*"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: ophyd-async
|
|
3
|
-
Version: 0.5.
|
|
3
|
+
Version: 0.5.2
|
|
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
|
|
@@ -55,14 +55,16 @@ Provides-Extra: ca
|
|
|
55
55
|
Requires-Dist: aioca>=1.6; extra == "ca"
|
|
56
56
|
Provides-Extra: pva
|
|
57
57
|
Requires-Dist: p4p; extra == "pva"
|
|
58
|
+
Provides-Extra: sim
|
|
59
|
+
Requires-Dist: h5py; extra == "sim"
|
|
58
60
|
Provides-Extra: dev
|
|
59
61
|
Requires-Dist: ophyd_async[pva]; extra == "dev"
|
|
62
|
+
Requires-Dist: ophyd_async[sim]; extra == "dev"
|
|
60
63
|
Requires-Dist: ophyd_async[ca]; extra == "dev"
|
|
61
64
|
Requires-Dist: black; extra == "dev"
|
|
62
65
|
Requires-Dist: flake8; extra == "dev"
|
|
63
66
|
Requires-Dist: flake8-isort; extra == "dev"
|
|
64
67
|
Requires-Dist: Flake8-pyproject; extra == "dev"
|
|
65
|
-
Requires-Dist: h5py; extra == "dev"
|
|
66
68
|
Requires-Dist: inflection; extra == "dev"
|
|
67
69
|
Requires-Dist: ipython; extra == "dev"
|
|
68
70
|
Requires-Dist: ipywidgets; extra == "dev"
|
|
@@ -29,7 +29,7 @@ First some Signals are constructed and stored on the Device. Each one is passed
|
|
|
29
29
|
its Python type, which could be:
|
|
30
30
|
|
|
31
31
|
- A primitive (`str`, `int`, `float`)
|
|
32
|
-
- An array (`numpy.typing.NDArray` or ``Sequence[str]``)
|
|
32
|
+
- An array (`numpy.typing.NDArray` ie. ``numpy.typing.NDArray[numpy.uint16]`` or ``Sequence[str]``)
|
|
33
33
|
- An enum (`enum.Enum`) which **must** also extend `str`
|
|
34
34
|
- `str` and ``EnumClass(str, Enum)`` are the only valid ``datatype`` for an enumerated signal.
|
|
35
35
|
|
|
@@ -50,12 +50,12 @@ Writing a non-AreaDetector StandardDetector
|
|
|
50
50
|
A non-AreaDetector `StandardDetector` should implement `DetectorControl` and `DetectorWriter` directly.
|
|
51
51
|
Here we construct a `DetectorControl` that co-ordinates signals on a PandA PositionCapture block - a child device "pcap" of the `StandardDetector` implementation, analogous to the :py:class:`FooDriver`.
|
|
52
52
|
|
|
53
|
-
.. literalinclude:: ../../src/ophyd_async/fastcs/panda/
|
|
53
|
+
.. literalinclude:: ../../src/ophyd_async/fastcs/panda/_control.py
|
|
54
54
|
:pyobject: PandaPcapController
|
|
55
55
|
|
|
56
56
|
The PandA may write a number of fields, and the :py:class:`PandaHDFWriter` co-ordinates those, configures the filewriter and describes the data for the RunEngine.
|
|
57
57
|
|
|
58
|
-
.. literalinclude:: ../../src/ophyd_async/fastcs/panda/
|
|
58
|
+
.. literalinclude:: ../../src/ophyd_async/fastcs/panda/_writer.py
|
|
59
59
|
:pyobject: PandaHDFWriter
|
|
60
60
|
|
|
61
61
|
The PandA StandardDetector implementation simply ties the component parts and its child devices together.
|
|
@@ -32,14 +32,15 @@ requires-python = ">=3.10"
|
|
|
32
32
|
[project.optional-dependencies]
|
|
33
33
|
ca = ["aioca>=1.6"]
|
|
34
34
|
pva = ["p4p"]
|
|
35
|
+
sim = ["h5py"]
|
|
35
36
|
dev = [
|
|
36
37
|
"ophyd_async[pva]",
|
|
38
|
+
"ophyd_async[sim]",
|
|
37
39
|
"ophyd_async[ca]",
|
|
38
40
|
"black",
|
|
39
41
|
"flake8",
|
|
40
42
|
"flake8-isort",
|
|
41
43
|
"Flake8-pyproject",
|
|
42
|
-
"h5py",
|
|
43
44
|
"inflection",
|
|
44
45
|
"ipython",
|
|
45
46
|
"ipywidgets",
|
|
@@ -138,7 +139,7 @@ commands =
|
|
|
138
139
|
|
|
139
140
|
|
|
140
141
|
[tool.ruff]
|
|
141
|
-
src = ["src", "tests"]
|
|
142
|
+
src = ["src", "tests", "system_tests"]
|
|
142
143
|
line-length = 88
|
|
143
144
|
lint.select = [
|
|
144
145
|
"C4", # flake8-comprehensions - https://beta.ruff.rs/docs/rules/#flake8-comprehensions-c4
|
|
@@ -146,4 +147,11 @@ lint.select = [
|
|
|
146
147
|
"F", # pyflakes rules - https://beta.ruff.rs/docs/rules/#pyflakes-f
|
|
147
148
|
"W", # pycodestyle warnings - https://beta.ruff.rs/docs/rules/#warning-w
|
|
148
149
|
"I001", # isort
|
|
150
|
+
"SLF", # self - https://docs.astral.sh/ruff/settings/#lintflake8-self
|
|
149
151
|
]
|
|
152
|
+
|
|
153
|
+
[tool.ruff.lint.per-file-ignores]
|
|
154
|
+
# By default, private member access is allowed in tests
|
|
155
|
+
# See https://github.com/DiamondLightSource/python-copier-template/issues/154
|
|
156
|
+
# Remove this line to forbid private member access in tests
|
|
157
|
+
"tests/**/*" = ["SLF001"]
|
|
@@ -33,11 +33,11 @@ from ._protocol import AsyncConfigurable, AsyncReadable, AsyncStageable
|
|
|
33
33
|
from ._providers import (
|
|
34
34
|
AutoIncrementFilenameProvider,
|
|
35
35
|
AutoIncrementingPathProvider,
|
|
36
|
+
DatasetDescriber,
|
|
36
37
|
FilenameProvider,
|
|
37
38
|
NameProvider,
|
|
38
39
|
PathInfo,
|
|
39
40
|
PathProvider,
|
|
40
|
-
ShapeProvider,
|
|
41
41
|
StaticFilenameProvider,
|
|
42
42
|
StaticPathProvider,
|
|
43
43
|
UUIDFilenameProvider,
|
|
@@ -55,6 +55,7 @@ from ._signal import (
|
|
|
55
55
|
assert_reading,
|
|
56
56
|
assert_value,
|
|
57
57
|
observe_value,
|
|
58
|
+
set_and_wait_for_other_value,
|
|
58
59
|
set_and_wait_for_value,
|
|
59
60
|
soft_signal_r_and_setter,
|
|
60
61
|
soft_signal_rw,
|
|
@@ -62,7 +63,7 @@ from ._signal import (
|
|
|
62
63
|
)
|
|
63
64
|
from ._signal_backend import RuntimeSubsetEnum, SignalBackend, SubsetEnum
|
|
64
65
|
from ._soft_signal_backend import SignalMetadata, SoftSignalBackend
|
|
65
|
-
from ._status import AsyncStatus, WatchableAsyncStatus
|
|
66
|
+
from ._status import AsyncStatus, WatchableAsyncStatus, completed_status
|
|
66
67
|
from ._utils import (
|
|
67
68
|
DEFAULT_TIMEOUT,
|
|
68
69
|
CalculatableTimeout,
|
|
@@ -116,7 +117,7 @@ __all__ = [
|
|
|
116
117
|
"NameProvider",
|
|
117
118
|
"PathInfo",
|
|
118
119
|
"PathProvider",
|
|
119
|
-
"
|
|
120
|
+
"DatasetDescriber",
|
|
120
121
|
"StaticFilenameProvider",
|
|
121
122
|
"StaticPathProvider",
|
|
122
123
|
"UUIDFilenameProvider",
|
|
@@ -135,6 +136,7 @@ __all__ = [
|
|
|
135
136
|
"assert_value",
|
|
136
137
|
"observe_value",
|
|
137
138
|
"set_and_wait_for_value",
|
|
139
|
+
"set_and_wait_for_other_value",
|
|
138
140
|
"soft_signal_r_and_setter",
|
|
139
141
|
"soft_signal_rw",
|
|
140
142
|
"wait_for_value",
|
|
@@ -156,4 +158,5 @@ __all__ = [
|
|
|
156
158
|
"get_unique",
|
|
157
159
|
"in_micros",
|
|
158
160
|
"wait_for_connection",
|
|
161
|
+
"completed_status",
|
|
159
162
|
]
|
|
@@ -55,11 +55,16 @@ class TriggerInfo(BaseModel):
|
|
|
55
55
|
#: Sort of triggers that will be sent
|
|
56
56
|
trigger: DetectorTrigger = Field()
|
|
57
57
|
#: What is the minimum deadtime between triggers
|
|
58
|
-
deadtime: float = Field(ge=0)
|
|
58
|
+
deadtime: float | None = Field(ge=0)
|
|
59
59
|
#: What is the maximum high time of the triggers
|
|
60
|
-
livetime: float = Field(ge=0)
|
|
60
|
+
livetime: float | None = Field(ge=0)
|
|
61
61
|
#: What is the maximum timeout on waiting for a frame
|
|
62
62
|
frame_timeout: float | None = Field(None, gt=0)
|
|
63
|
+
#: How many triggers make up a single StreamDatum index, to allow multiple frames
|
|
64
|
+
#: from a faster detector to be zipped with a single frame from a slow detector
|
|
65
|
+
#: e.g. if num=10 and multiplier=5 then the detector will take 10 frames,
|
|
66
|
+
#: but publish 2 indices, and describe() will show a shape of (5, h, w)
|
|
67
|
+
multiplier: int = 1
|
|
63
68
|
|
|
64
69
|
|
|
65
70
|
class DetectorControl(ABC):
|
|
@@ -69,7 +74,7 @@ class DetectorControl(ABC):
|
|
|
69
74
|
"""
|
|
70
75
|
|
|
71
76
|
@abstractmethod
|
|
72
|
-
def get_deadtime(self, exposure: float) -> float:
|
|
77
|
+
def get_deadtime(self, exposure: float | None) -> float:
|
|
73
78
|
"""For a given exposure, how long should the time between exposures be"""
|
|
74
79
|
|
|
75
80
|
@abstractmethod
|
|
@@ -196,10 +201,10 @@ class StandardDetector(
|
|
|
196
201
|
|
|
197
202
|
@AsyncStatus.wrap
|
|
198
203
|
async def stage(self) -> None:
|
|
199
|
-
# Disarm the detector, stop filewriting
|
|
204
|
+
# Disarm the detector, stop filewriting.
|
|
200
205
|
await self._check_config_sigs()
|
|
201
206
|
await asyncio.gather(self.writer.close(), self.controller.disarm())
|
|
202
|
-
self.
|
|
207
|
+
self._trigger_info = None
|
|
203
208
|
|
|
204
209
|
async def _check_config_sigs(self):
|
|
205
210
|
"""Checks configuration signals are named and connected."""
|
|
@@ -212,7 +217,7 @@ class StandardDetector(
|
|
|
212
217
|
await signal.get_value()
|
|
213
218
|
except NotImplementedError:
|
|
214
219
|
raise Exception(
|
|
215
|
-
f"config signal {signal.
|
|
220
|
+
f"config signal {signal.name} must be connected before it is "
|
|
216
221
|
+ "passed to the detector"
|
|
217
222
|
)
|
|
218
223
|
|
|
@@ -236,10 +241,15 @@ class StandardDetector(
|
|
|
236
241
|
|
|
237
242
|
@AsyncStatus.wrap
|
|
238
243
|
async def trigger(self) -> None:
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
244
|
+
if self._trigger_info is None:
|
|
245
|
+
await self.prepare(
|
|
246
|
+
TriggerInfo(
|
|
247
|
+
number=1,
|
|
248
|
+
trigger=DetectorTrigger.internal,
|
|
249
|
+
deadtime=None,
|
|
250
|
+
livetime=None,
|
|
251
|
+
)
|
|
252
|
+
)
|
|
243
253
|
# Arm the detector and wait for it to finish.
|
|
244
254
|
indices_written = await self.writer.get_indices_written()
|
|
245
255
|
written_status = await self.controller.arm(
|
|
@@ -250,19 +260,15 @@ class StandardDetector(
|
|
|
250
260
|
end_observation = indices_written + 1
|
|
251
261
|
|
|
252
262
|
async for index in self.writer.observe_indices_written(
|
|
253
|
-
DEFAULT_TIMEOUT
|
|
263
|
+
DEFAULT_TIMEOUT
|
|
264
|
+
+ (self._trigger_info.livetime or 0)
|
|
265
|
+
+ (self._trigger_info.deadtime or 0)
|
|
254
266
|
):
|
|
255
267
|
if index >= end_observation:
|
|
256
268
|
break
|
|
257
269
|
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
value: T,
|
|
261
|
-
) -> AsyncStatus:
|
|
262
|
-
# Just arm detector for the time being
|
|
263
|
-
return AsyncStatus(self._prepare(value))
|
|
264
|
-
|
|
265
|
-
async def _prepare(self, value: T) -> None:
|
|
270
|
+
@AsyncStatus.wrap
|
|
271
|
+
async def prepare(self, value: TriggerInfo) -> None:
|
|
266
272
|
"""
|
|
267
273
|
Arm detector.
|
|
268
274
|
|
|
@@ -277,22 +283,26 @@ class StandardDetector(
|
|
|
277
283
|
Args:
|
|
278
284
|
value: TriggerInfo describing how to trigger the detector
|
|
279
285
|
"""
|
|
280
|
-
assert type(value) is TriggerInfo
|
|
281
286
|
self._trigger_info = value
|
|
287
|
+
if value.trigger != DetectorTrigger.internal:
|
|
288
|
+
assert (
|
|
289
|
+
value.deadtime
|
|
290
|
+
), "Deadtime must be supplied when in externally triggered mode"
|
|
291
|
+
if value.deadtime:
|
|
292
|
+
required = self.controller.get_deadtime(self._trigger_info.livetime)
|
|
293
|
+
assert required <= value.deadtime, (
|
|
294
|
+
f"Detector {self.controller} needs at least {required}s deadtime, "
|
|
295
|
+
f"but trigger logic provides only {value.deadtime}s"
|
|
296
|
+
)
|
|
282
297
|
self._initial_frame = await self.writer.get_indices_written()
|
|
283
298
|
self._last_frame = self._initial_frame + self._trigger_info.number
|
|
284
|
-
|
|
285
|
-
required = self.controller.get_deadtime(self._trigger_info.livetime)
|
|
286
|
-
assert required <= self._trigger_info.deadtime, (
|
|
287
|
-
f"Detector {self.controller} needs at least {required}s deadtime, "
|
|
288
|
-
f"but trigger logic provides only {self._trigger_info.deadtime}s"
|
|
289
|
-
)
|
|
290
299
|
self._arm_status = await self.controller.arm(
|
|
291
300
|
num=self._trigger_info.number,
|
|
292
301
|
trigger=self._trigger_info.trigger,
|
|
293
302
|
exposure=self._trigger_info.livetime,
|
|
294
303
|
)
|
|
295
304
|
self._fly_start = time.monotonic()
|
|
305
|
+
self._describe = await self.writer.open(value.multiplier)
|
|
296
306
|
|
|
297
307
|
@AsyncStatus.wrap
|
|
298
308
|
async def kickoff(self):
|
|
@@ -307,8 +317,8 @@ class StandardDetector(
|
|
|
307
317
|
self._trigger_info.frame_timeout
|
|
308
318
|
or (
|
|
309
319
|
DEFAULT_TIMEOUT
|
|
310
|
-
+ self._trigger_info.livetime
|
|
311
|
-
+ self._trigger_info.deadtime
|
|
320
|
+
+ (self._trigger_info.livetime or 0)
|
|
321
|
+
+ (self._trigger_info.deadtime or 0)
|
|
312
322
|
)
|
|
313
323
|
):
|
|
314
324
|
yield WatcherUpdate(
|
|
@@ -10,8 +10,6 @@ from event_model import (
|
|
|
10
10
|
StreamResource,
|
|
11
11
|
)
|
|
12
12
|
|
|
13
|
-
from ._providers import PathInfo
|
|
14
|
-
|
|
15
13
|
|
|
16
14
|
@dataclass
|
|
17
15
|
class HDFDataset:
|
|
@@ -28,14 +26,12 @@ SLICE_NAME = "AD_HDF5_SWMR_SLICE"
|
|
|
28
26
|
|
|
29
27
|
class HDFFile:
|
|
30
28
|
"""
|
|
31
|
-
:param directory_info: Contains information about how to construct a StreamResource
|
|
32
29
|
:param full_file_name: Absolute path to the file to be written
|
|
33
30
|
:param datasets: Datasets to write into the file
|
|
34
31
|
"""
|
|
35
32
|
|
|
36
33
|
def __init__(
|
|
37
34
|
self,
|
|
38
|
-
path_info: PathInfo,
|
|
39
35
|
full_file_name: Path,
|
|
40
36
|
datasets: List[HDFDataset],
|
|
41
37
|
hostname: str = "localhost",
|
|
@@ -53,7 +49,7 @@ class HDFFile:
|
|
|
53
49
|
(
|
|
54
50
|
"file",
|
|
55
51
|
self._hostname,
|
|
56
|
-
str(
|
|
52
|
+
str(full_file_name.absolute()),
|
|
57
53
|
"",
|
|
58
54
|
"",
|
|
59
55
|
None,
|
|
@@ -8,11 +8,12 @@ from ._utils import T
|
|
|
8
8
|
|
|
9
9
|
|
|
10
10
|
def _get_mock_signal_backend(signal: Signal) -> MockSignalBackend:
|
|
11
|
-
|
|
11
|
+
backend = signal._backend # noqa:SLF001
|
|
12
|
+
assert isinstance(backend, MockSignalBackend), (
|
|
12
13
|
"Expected to receive a `MockSignalBackend`, instead "
|
|
13
|
-
f" received {type(
|
|
14
|
+
f" received {type(backend)}. "
|
|
14
15
|
)
|
|
15
|
-
return
|
|
16
|
+
return backend
|
|
16
17
|
|
|
17
18
|
|
|
18
19
|
def set_mock_value(signal: Signal[T], value: T):
|
|
@@ -13,34 +13,24 @@ class PathInfo:
|
|
|
13
13
|
"""
|
|
14
14
|
Information about where and how to write a file.
|
|
15
15
|
|
|
16
|
-
|
|
17
|
-
different applications mounting filesystems at different mount points.
|
|
18
|
-
The portion of this path which is relevant only for the writer is the 'root',
|
|
19
|
-
while the path from an agreed upon mutual mounting is the resource_path.
|
|
20
|
-
The resource_dir is used with the filename to construct the resource_path.
|
|
21
|
-
|
|
22
|
-
:param root: Path of a root directory, relevant only for the file writer
|
|
23
|
-
:param resource_dir: Directory into which files should be written, relative to root
|
|
16
|
+
:param directory_path: Directory into which files should be written
|
|
24
17
|
:param filename: Base filename to use generated by FilenameProvider, w/o extension
|
|
25
18
|
:param create_dir_depth: Optional depth of directories to create if they do not
|
|
26
19
|
exist
|
|
27
20
|
"""
|
|
28
21
|
|
|
29
|
-
|
|
30
|
-
resource_dir: Path
|
|
22
|
+
directory_path: Path
|
|
31
23
|
filename: str
|
|
32
24
|
create_dir_depth: int = 0
|
|
33
25
|
|
|
34
26
|
|
|
35
27
|
class FilenameProvider(Protocol):
|
|
36
28
|
@abstractmethod
|
|
37
|
-
def __call__(self) -> str:
|
|
29
|
+
def __call__(self, device_name: Optional[str] = None) -> str:
|
|
38
30
|
"""Get a filename to use for output data, w/o extension"""
|
|
39
31
|
|
|
40
32
|
|
|
41
33
|
class PathProvider(Protocol):
|
|
42
|
-
_filename_provider: FilenameProvider
|
|
43
|
-
|
|
44
34
|
@abstractmethod
|
|
45
35
|
def __call__(self, device_name: Optional[str] = None) -> PathInfo:
|
|
46
36
|
"""Get the current directory to write files into"""
|
|
@@ -50,7 +40,7 @@ class StaticFilenameProvider(FilenameProvider):
|
|
|
50
40
|
def __init__(self, filename: str):
|
|
51
41
|
self._static_filename = filename
|
|
52
42
|
|
|
53
|
-
def __call__(self) -> str:
|
|
43
|
+
def __call__(self, device_name: Optional[str] = None) -> str:
|
|
54
44
|
return self._static_filename
|
|
55
45
|
|
|
56
46
|
|
|
@@ -63,7 +53,7 @@ class UUIDFilenameProvider(FilenameProvider):
|
|
|
63
53
|
self._uuid_call_func = uuid_call_func
|
|
64
54
|
self._uuid_call_args = uuid_call_args or []
|
|
65
55
|
|
|
66
|
-
def __call__(self) -> str:
|
|
56
|
+
def __call__(self, device_name: Optional[str] = None) -> str:
|
|
67
57
|
if (
|
|
68
58
|
self._uuid_call_func in [uuid.uuid3, uuid.uuid5]
|
|
69
59
|
and len(self._uuid_call_args) < 2
|
|
@@ -92,7 +82,7 @@ class AutoIncrementFilenameProvider(FilenameProvider):
|
|
|
92
82
|
self._increment = increment
|
|
93
83
|
self._inc_delimeter = inc_delimeter
|
|
94
84
|
|
|
95
|
-
def __call__(self):
|
|
85
|
+
def __call__(self, device_name: Optional[str] = None) -> str:
|
|
96
86
|
if len(str(self._current_value)) > self._max_digits:
|
|
97
87
|
raise ValueError(
|
|
98
88
|
f"Auto incrementing filename counter \
|
|
@@ -112,20 +102,17 @@ class StaticPathProvider(PathProvider):
|
|
|
112
102
|
self,
|
|
113
103
|
filename_provider: FilenameProvider,
|
|
114
104
|
directory_path: Path,
|
|
115
|
-
resource_dir: Path = Path("."),
|
|
116
105
|
create_dir_depth: int = 0,
|
|
117
106
|
) -> None:
|
|
118
107
|
self._filename_provider = filename_provider
|
|
119
108
|
self._directory_path = directory_path
|
|
120
|
-
self._resource_dir = resource_dir
|
|
121
109
|
self._create_dir_depth = create_dir_depth
|
|
122
110
|
|
|
123
111
|
def __call__(self, device_name: Optional[str] = None) -> PathInfo:
|
|
124
|
-
filename = self._filename_provider()
|
|
112
|
+
filename = self._filename_provider(device_name)
|
|
125
113
|
|
|
126
114
|
return PathInfo(
|
|
127
|
-
|
|
128
|
-
resource_dir=self._resource_dir,
|
|
115
|
+
directory_path=self._directory_path,
|
|
129
116
|
filename=filename,
|
|
130
117
|
create_dir_depth=self._create_dir_depth,
|
|
131
118
|
)
|
|
@@ -135,7 +122,7 @@ class AutoIncrementingPathProvider(PathProvider):
|
|
|
135
122
|
def __init__(
|
|
136
123
|
self,
|
|
137
124
|
filename_provider: FilenameProvider,
|
|
138
|
-
|
|
125
|
+
base_directory_path: Path,
|
|
139
126
|
create_dir_depth: int = 0,
|
|
140
127
|
max_digits: int = 5,
|
|
141
128
|
starting_value: int = 0,
|
|
@@ -145,7 +132,7 @@ class AutoIncrementingPathProvider(PathProvider):
|
|
|
145
132
|
base_name: str = None,
|
|
146
133
|
) -> None:
|
|
147
134
|
self._filename_provider = filename_provider
|
|
148
|
-
self.
|
|
135
|
+
self._base_directory_path = base_directory_path
|
|
149
136
|
self._create_dir_depth = create_dir_depth
|
|
150
137
|
self._base_name = base_name
|
|
151
138
|
self._starting_value = starting_value
|
|
@@ -157,15 +144,17 @@ class AutoIncrementingPathProvider(PathProvider):
|
|
|
157
144
|
self._inc_delimeter = inc_delimeter
|
|
158
145
|
|
|
159
146
|
def __call__(self, device_name: Optional[str] = None) -> PathInfo:
|
|
160
|
-
filename = self._filename_provider()
|
|
147
|
+
filename = self._filename_provider(device_name)
|
|
161
148
|
|
|
162
149
|
padded_counter = f"{self._current_value:0{self._max_digits}}"
|
|
163
150
|
|
|
164
|
-
|
|
151
|
+
auto_inc_dir_name = str(padded_counter)
|
|
165
152
|
if self._base_name is not None:
|
|
166
|
-
|
|
153
|
+
auto_inc_dir_name = (
|
|
154
|
+
f"{self._base_name}{self._inc_delimeter}{padded_counter}"
|
|
155
|
+
)
|
|
167
156
|
elif device_name is not None:
|
|
168
|
-
|
|
157
|
+
auto_inc_dir_name = f"{device_name}{self._inc_delimeter}{padded_counter}"
|
|
169
158
|
|
|
170
159
|
self._inc_counter += 1
|
|
171
160
|
if self._inc_counter == self._num_calls_per_inc:
|
|
@@ -173,8 +162,7 @@ class AutoIncrementingPathProvider(PathProvider):
|
|
|
173
162
|
self._current_value += self._increment
|
|
174
163
|
|
|
175
164
|
return PathInfo(
|
|
176
|
-
|
|
177
|
-
resource_dir=resource_dir,
|
|
165
|
+
directory_path=self._base_directory_path / auto_inc_dir_name,
|
|
178
166
|
filename=filename,
|
|
179
167
|
create_dir_depth=self._create_dir_depth,
|
|
180
168
|
)
|
|
@@ -184,12 +172,12 @@ class YMDPathProvider(PathProvider):
|
|
|
184
172
|
def __init__(
|
|
185
173
|
self,
|
|
186
174
|
filename_provider: FilenameProvider,
|
|
187
|
-
|
|
175
|
+
base_directory_path: Path,
|
|
188
176
|
create_dir_depth: int = -3, # Default to -3 to create YMD dirs
|
|
189
177
|
device_name_as_base_dir: bool = False,
|
|
190
178
|
) -> None:
|
|
191
179
|
self._filename_provider = filename_provider
|
|
192
|
-
self.
|
|
180
|
+
self._base_directory_path = Path(base_directory_path)
|
|
193
181
|
self._create_dir_depth = create_dir_depth
|
|
194
182
|
self._device_name_as_base_dir = device_name_as_base_dir
|
|
195
183
|
|
|
@@ -197,22 +185,21 @@ class YMDPathProvider(PathProvider):
|
|
|
197
185
|
sep = os.path.sep
|
|
198
186
|
current_date = date.today().strftime(f"%Y{sep}%m{sep}%d")
|
|
199
187
|
if device_name is None:
|
|
200
|
-
|
|
188
|
+
ymd_dir_path = current_date
|
|
201
189
|
elif self._device_name_as_base_dir:
|
|
202
|
-
|
|
190
|
+
ymd_dir_path = os.path.join(
|
|
203
191
|
current_date,
|
|
204
192
|
device_name,
|
|
205
193
|
)
|
|
206
194
|
else:
|
|
207
|
-
|
|
195
|
+
ymd_dir_path = os.path.join(
|
|
208
196
|
device_name,
|
|
209
197
|
current_date,
|
|
210
198
|
)
|
|
211
199
|
|
|
212
|
-
filename = self._filename_provider()
|
|
200
|
+
filename = self._filename_provider(device_name)
|
|
213
201
|
return PathInfo(
|
|
214
|
-
|
|
215
|
-
resource_dir=resource_dir,
|
|
202
|
+
directory_path=self._base_directory_path / ymd_dir_path,
|
|
216
203
|
filename=filename,
|
|
217
204
|
create_dir_depth=self._create_dir_depth,
|
|
218
205
|
)
|
|
@@ -224,7 +211,11 @@ class NameProvider(Protocol):
|
|
|
224
211
|
"""Get the name to be used as a data_key in the descriptor document"""
|
|
225
212
|
|
|
226
213
|
|
|
227
|
-
class
|
|
214
|
+
class DatasetDescriber(Protocol):
|
|
215
|
+
@abstractmethod
|
|
216
|
+
async def np_datatype(self) -> str:
|
|
217
|
+
"""Represents the numpy datatype"""
|
|
218
|
+
|
|
228
219
|
@abstractmethod
|
|
229
|
-
async def
|
|
220
|
+
async def shape(self) -> tuple[int, ...]:
|
|
230
221
|
"""Get the shape of the data collection"""
|