From c14061c0f7927611baf90642e27f8032557fbf63 Mon Sep 17 00:00:00 2001 From: "Ware, Joseph (DLSLtd,RAL,LSCI)" Date: Tue, 17 Sep 2024 15:39:15 +0100 Subject: [PATCH] Remove dependency on dls_bluesky_core --- dev-requirements.txt | 17 ----- docs/explanations/lifecycle.md | 2 +- helm/blueapi/values.yaml | 4 -- pyproject.toml | 3 +- src/blueapi/config.py | 2 - src/blueapi/core/bluesky_types.py | 2 +- src/blueapi/startup/example_plans.py | 77 +++++++++++++++++------ tests/unit_tests/core/fake_plan_module.py | 2 +- 8 files changed, 61 insertions(+), 48 deletions(-) diff --git a/dev-requirements.txt b/dev-requirements.txt index 68b3ecac7..18bd82ab0 100644 --- a/dev-requirements.txt +++ b/dev-requirements.txt @@ -20,7 +20,6 @@ bluesky-kafka==0.10.0 bluesky-live==0.0.8 bluesky-stomp==0.1.2 boltons==24.0.0 -bump-pydantic==0.8.0 cachetools==5.5.0 caproto==1.1.1 certifi==2024.8.30 @@ -43,21 +42,18 @@ dataclasses-json==0.6.7 decorator==5.1.1 deepmerge==2.0 distlib==0.3.8 -dls-bluesky-core==0.0.4 dls-dodal==1.31.1 dnspython==2.6.1 docopt==0.6.2 doct==1.1.0 docutils==0.21.2 dunamai==1.22.0 -email_validator==2.2.0 entrypoints==0.4 epicscorelibs==7.0.7.99.0.2 event-model==1.21.0 exceptiongroup==1.2.2 executing==2.1.0 fastapi==0.114.2 -fastapi-cli==0.0.5 fasteners==0.19 filelock==3.16.0 flexcache==0.3 @@ -74,7 +70,6 @@ h5py==3.11.0 HeapDict==1.0.1 historydict==1.2.6 httpcore==1.0.5 -httptools==0.6.1 httpx==0.27.2 humanize==4.10.0 identify==2.6.1 @@ -87,7 +82,6 @@ iniconfig==2.0.0 intake==0.6.4 ipython==8.18.0 ipywidgets==8.1.5 -itsdangerous==2.2.0 jedi==0.19.1 Jinja2==3.1.4 jinja2-ansible-filters==1.3.2 @@ -96,8 +90,6 @@ jsonschema-specifications==2023.12.1 jupyterlab_widgets==3.0.13 kiwisolver==1.4.7 ldap3==2.9.1 -libcst==1.4.0 -livereload==2.7.0 locket==1.0.0 lz4==4.3.3 markdown-it-py==3.0.0 @@ -155,7 +147,6 @@ py==1.11.0 pyasn1==0.6.1 pycryptodome==3.20.0 pydantic==2.9.1 -pydantic-extra-types==2.9.0 pydantic-settings==2.5.2 pydantic_core==2.23.3 pydantic_numpy==5.0.2 @@ -170,17 +161,14 @@ pytest-asyncio==0.24.0 pytest-cov==5.0.0 python-dateutil==2.9.0.post0 python-dotenv==1.0.1 -python-multipart==0.0.9 pytz==2024.2 PyYAML==6.0.2 -pyyaml-include==2.1 questionary==2.0.1 redis==5.0.8 redis-json-dict==0.2.0 referencing==0.35.1 requests==2.32.3 responses==0.25.3 -rich==13.7.1 rpds-py==0.20.0 ruamel.yaml==0.18.6 ruamel.yaml.clib==0.2.8 @@ -188,7 +176,6 @@ ruff==0.6.5 scanspec==0.7.2 semver==3.0.2 setuptools-dso==2.11 -shellingham==1.5.4 six==1.16.0 slicerator==1.1.0 smmap==5.0.1 @@ -219,12 +206,10 @@ super-state-machine==2.0.2 tifffile==2024.8.30 tomli==2.0.1 toolz==0.12.1 -tornado==6.4.1 tox==3.28.0 tox-direct==0.4 tqdm==4.66.5 traitlets==5.14.3 -typer==0.12.4 types-mock==5.1.0.20240425 types-PyYAML==6.0.12.20240917 types-requests==2.32.0.20240914 @@ -233,10 +218,8 @@ typing-inspect==0.9.0 typing_extensions==4.12.2 tzdata==2024.1 tzlocal==5.2 -ujson==5.10.0 urllib3==2.2.3 uvicorn==0.30.6 -uvloop==0.19.0 virtualenv==20.26.4 watchfiles==0.24.0 wcwidth==0.2.13 diff --git a/docs/explanations/lifecycle.md b/docs/explanations/lifecycle.md index 862f3a754..98bd23af5 100644 --- a/docs/explanations/lifecycle.md +++ b/docs/explanations/lifecycle.md @@ -7,7 +7,7 @@ of being written, loaded and run. Take the following plan. import bluesky.plans as bp from blueapi.core import MsgGenerator - from dls_bluesky_core.core import inject + from dodal.common import inject from bluesky.protocols import Readable diff --git a/helm/blueapi/values.yaml b/helm/blueapi/values.yaml index d32e9f1eb..a38c3eb39 100644 --- a/helm/blueapi/values.yaml +++ b/helm/blueapi/values.yaml @@ -94,10 +94,6 @@ worker: module: blueapi.startup.example_devices - kind: planFunctions module: blueapi.startup.example_plans - - kind: planFunctions - module: dls_bluesky_core.plans - - kind: planFunctions - module: dls_bluesky_core.stubs stomp: auth: username: guest diff --git a/pyproject.toml b/pyproject.toml index ea16df3a0..75cf808b6 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -27,7 +27,6 @@ dependencies = [ "fastapi>=0.112.0", "uvicorn", "requests", - "dls-bluesky-core", #requires ophyd-async "dls-dodal>=1.31.0", "super-state-machine", # See GH issue 553 "GitPython", @@ -144,5 +143,5 @@ extend-immutable-calls = [ "fastapi.Depends", "fastapi.Body", "fastapi.Task", - "dls_bluesky_core.core.inject", + "dodal.common.inject", ] diff --git a/src/blueapi/config.py b/src/blueapi/config.py index 3502590ba..a6345f71f 100644 --- a/src/blueapi/config.py +++ b/src/blueapi/config.py @@ -51,8 +51,6 @@ class EnvironmentConfig(BlueapiBaseModel): kind=SourceKind.DEVICE_FUNCTIONS, module="blueapi.startup.example_devices" ), Source(kind=SourceKind.PLAN_FUNCTIONS, module="blueapi.startup.example_plans"), - Source(kind=SourceKind.PLAN_FUNCTIONS, module="dls_bluesky_core.plans"), - Source(kind=SourceKind.PLAN_FUNCTIONS, module="dls_bluesky_core.stubs"), ] events: WorkerEventConfig = Field(default_factory=WorkerEventConfig) diff --git a/src/blueapi/core/bluesky_types.py b/src/blueapi/core/bluesky_types.py index 1a2978213..845a9a05d 100644 --- a/src/blueapi/core/bluesky_types.py +++ b/src/blueapi/core/bluesky_types.py @@ -24,7 +24,7 @@ Triggerable, WritesExternalAssets, ) -from dls_bluesky_core.core import MsgGenerator, PlanGenerator +from dodal.common import MsgGenerator, PlanGenerator from ophyd_async.core import Device as AsyncDevice from pydantic import BaseModel, Field diff --git a/src/blueapi/startup/example_plans.py b/src/blueapi/startup/example_plans.py index b3d969521..1b08d9272 100644 --- a/src/blueapi/startup/example_plans.py +++ b/src/blueapi/startup/example_plans.py @@ -1,30 +1,67 @@ +import operator +from collections.abc import Mapping +from functools import reduce +from typing import Annotated, Any + +import bluesky.plans as bp from bluesky.protocols import Movable, Readable -from dls_bluesky_core.core import inject -from dls_bluesky_core.plans import count -from dls_bluesky_core.stubs import move +from cycler import Cycler, cycler +from dodal.common import MsgGenerator +from dodal.plans.data_session_metadata import attach_data_session_metadata_decorator +from pydantic import validate_call +from scanspec.specs import Spec -from blueapi.core import MsgGenerator +""" +Plans related to the use of the `ScanSpec https://github.com/dls-controls/scanspec` +library for constructing arbitrarily complex N-dimensional trajectories, similar to +Diamond's "mapping scans" using ScanPointGenerator. +""" -def stp_snapshot( - detectors: list[Readable], - temperature: Movable = inject("sample_temperature"), - pressure: Movable = inject("sample_pressure"), +@attach_data_session_metadata_decorator() +@validate_call(config={"arbitrary_types_allowed": True}) +def scan( + detectors: Annotated[ + set[Readable], "Set of readable devices, will take a reading at each point" + ], + axes_to_move: Annotated[ + Mapping[str, Movable], "All axes involved in this scan, names and objects" + ], + spec: Annotated[Spec[str], "ScanSpec modelling the path of the scan"], + metadata: Mapping[str, Any] | None = None, ) -> MsgGenerator: + _md = { + "plan_args": { + "detectors": {det.name for det in detectors}, + "axes_to_move": {k: v.name for k, v in axes_to_move.items()}, + "spec": repr(spec), + }, + "plan_name": "scan", + "shape": spec.shape(), + **(metadata or {}), + } + + cycler = _scanspec_to_cycler(spec, axes_to_move) + yield from bp.scan_nd(detectors, cycler, md=_md) + + +def _scanspec_to_cycler(spec: Spec[str], axes: Mapping[str, Movable]) -> Cycler: """ - Moves devices for pressure and temperature (defaults fetched from the context) - and captures a single frame from a collection of devices + Convert a scanspec to a cycler for compatibility with legacy Bluesky plans such as + `bp.scan_nd`. Use the midpoints of the scanspec since cyclers are normally used + for software triggered scans. Args: - detectors (List[Readable]): A list of devices to read while the sample is at STP - temperature (Optional[Movable]): A device controlling temperature of the sample, - defaults to fetching a device name "sample_temperature" from the context - pressure (Optional[Movable]): A device controlling pressure on the sample, - defaults to fetching a device name "sample_pressure" from the context + spec: A scanspec + axes: Names and axes to move + Returns: - MsgGenerator: Plan - Yields: - Iterator[MsgGenerator]: Bluesky messages + Cycler: A new cycler """ - yield from move({temperature: 0, pressure: 10**5}) - yield from count(detectors, 1) + + midpoints = spec.frames().midpoints + midpoints = {axes[name]: points for name, points in midpoints.items()} + + # Need to "add" the cyclers for all the axes together. The code below is + # effectively: cycler(motor1, [...]) + cycler(motor2, [...]) + ... + return reduce(operator.add, (cycler(*args) for args in midpoints.items())) diff --git a/tests/unit_tests/core/fake_plan_module.py b/tests/unit_tests/core/fake_plan_module.py index 5fe5f1279..273b86699 100644 --- a/tests/unit_tests/core/fake_plan_module.py +++ b/tests/unit_tests/core/fake_plan_module.py @@ -1 +1 @@ -from dls_bluesky_core.plans import scan # noqa: F401 +from blueapi.startup.example_plans import scan # noqa: F401