You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
When trying to run a bluesky plan with ophyd-epics-devices motors and area detectors, I came across a bug where trying to read a PV from either of these devices would result in a RuntimeError:
RuntimeError: Task <Task pending name='Task-65' coro=<RunEngine._run() running at /dls/science/users/ton99817/projects/p45/venv/lib/python3.9/site-packages/bluesky/run_engine.py:1583> cb=[_chain_future.<locals>._call_set_state() at /dls_sw/apps/python/anaconda/4.6.14/64/envs/python3.9/lib/python3.9/asyncio/futures.py:391]> got Future <Future pending> attached to a different loop
After some investigation by @coretl it was discovered that this is because upon collecting these devices, their event loops are set to be the current user event loop, not the bluesky event loop. This means some bluesky plan stubs (like read) don't work, because they check the ._valid property of the devices and ensure they are running on the bluesky event loop. It was subsequently fixed by directly handling and setting the event loop to be the bluesky event loop in the script.
Steps to recreate
from ophyd.v2.core import DeviceCollector
from ophyd_epics_devices.areadetector import MyHDFFlyerSim
from ophyd_epics_devices.motor import Motor
import bluesky.preprocessors as bpp
import bluesky.plan_stubs as bps
from bluesky import RunEngine
RE = RunEngine()
with DeviceCollector():
rot_motor = Motor("BL46P-MO-MAP-01:STAGE:A")
x_motor = Motor("BL46P-MO-MAP-01:STAGE:X")
camera = MyHDFFlyerSim("BL46P-EA-DET-01:", drv_prefix="DET:")
@bpp.run_decorator()
@bpp.stage_decorator([camera])
def collect_sample_projections(start_angle: float, stop_angle: float, num_projections: int):
yield from bps.abs_set(camera.hdf.file_path, "/dls/science/users/ton99817/projects")
yield from bps.abs_set(camera.hdf.file_name, "p45test.h5")
exposure_time = yield from bps.rd(camera.drv.acquire_time)
RE(collect_sample_projections(0.0, 0.0, 10))
In this case, I was running the script above inside "dls/science/users/ton99817/projects/p45", with this snippet of code saved at "dls/science/users/ton99817/projects/p45/src/p45/bluesky/plan.py". Running this script with the minimal dependencies required (bluesky, ophyd and aioca, with ophyd installed from the github repo) produced the following output:
Run aborted
Traceback (most recent call last):
File "/dls/science/users/ton99817/projects/p45/venv/lib/python3.9/site-packages/bluesky/run_engine.py", line 1523, in _run
msg = self._plan_stack[-1].send(resp)
File "/dls/science/users/ton99817/projects/p45/venv/lib/python3.9/site-packages/bluesky/utils/__init__.py", line 1147, in dec_inner
return (yield from plan)
File "/dls/science/users/ton99817/projects/p45/venv/lib/python3.9/site-packages/bluesky/preprocessors.py", line 333, in run_wrapper
yield from contingency_wrapper(plan, except_plan=except_plan, else_plan=close_run)
File "/dls/science/users/ton99817/projects/p45/venv/lib/python3.9/site-packages/bluesky/preprocessors.py", line 575, in contingency_wrapper
ret = yield from plan
File "/dls/science/users/ton99817/projects/p45/venv/lib/python3.9/site-packages/bluesky/utils/__init__.py", line 1147, in dec_inner
return (yield from plan)
File "/dls/science/users/ton99817/projects/p45/venv/lib/python3.9/site-packages/bluesky/preprocessors.py", line 965, in stage_wrapper
return (yield from finalize_wrapper(inner(), unstage_devices()))
File "/dls/science/users/ton99817/projects/p45/venv/lib/python3.9/site-packages/bluesky/preprocessors.py", line 511, in finalize_wrapper
ret = yield from plan
File "/dls/science/users/ton99817/projects/p45/venv/lib/python3.9/site-packages/bluesky/preprocessors.py", line 963, in inner
return (yield from plan)
File "/dls/science/users/ton99817/projects/p45/src/p45/bluesky/plan.py", line 39, in collect_sample_projections
exposure_time = yield from bps.rd(camera.drv.acquire_time)
File "/dls/science/users/ton99817/projects/p45/venv/lib/python3.9/site-packages/bluesky/plan_stubs.py", line 371, in rd
ret = yield from read(obj)
File "/dls/science/users/ton99817/projects/p45/venv/lib/python3.9/site-packages/bluesky/plan_stubs.py", line 96, in read
return (yield Msg('read', obj))
File "/dls/science/users/ton99817/projects/p45/venv/lib/python3.9/site-packages/bluesky/run_engine.py", line 1583, in _run
new_response = await coro(msg)
File "/dls/science/users/ton99817/projects/p45/venv/lib/python3.9/site-packages/bluesky/run_engine.py", line 1835, in _read
ret = await maybe_await(obj.read(*msg.args, **msg.kwargs))
File "/dls/science/users/ton99817/projects/p45/venv/lib/python3.9/site-packages/bluesky/utils/__init__.py", line 1779, in maybe_await
return await ret
File "/dls/science/users/ton99817/projects/p45/venv/lib/python3.9/site-packages/ophyd/v2/epics.py", line 90, in read
await self._valid.wait()
File "/dls_sw/apps/python/anaconda/4.6.14/64/envs/python3.9/lib/python3.9/asyncio/locks.py", line 226, in wait
await fut
RuntimeError: Task <Task pending name='Task-65' coro=<RunEngine._run() running at /dls/science/users/ton99817/projects/p45/venv/lib/python3.9/site-packages/bluesky/run_engine.py:1583> cb=[_chain_future.<locals>._call_set_state() at /dls_sw/apps/python/anaconda/4.6.14/64/envs/python3.9/lib/python3.9/asyncio/futures.py:391]> got Future <Future pending> attached to a different loop
Traceback (most recent call last):
File "/dls/science/users/ton99817/projects/p45/src/p45/bluesky/plan.py", line 78, in <module>
RE(
File "/dls/science/users/ton99817/projects/p45/venv/lib/python3.9/site-packages/bluesky/run_engine.py", line 893, in __call__
plan_return = self._resume_task(init_func=_build_task)
File "/dls/science/users/ton99817/projects/p45/venv/lib/python3.9/site-packages/bluesky/run_engine.py", line 1032, in _resume_task
raise exc
File "/dls/science/users/ton99817/projects/p45/venv/lib/python3.9/site-packages/bluesky/run_engine.py", line 1663, in _run
raise err
File "/dls/science/users/ton99817/projects/p45/venv/lib/python3.9/site-packages/bluesky/run_engine.py", line 1523, in _run
msg = self._plan_stack[-1].send(resp)
File "/dls/science/users/ton99817/projects/p45/venv/lib/python3.9/site-packages/bluesky/utils/__init__.py", line 1147, in dec_inner
return (yield from plan)
File "/dls/science/users/ton99817/projects/p45/venv/lib/python3.9/site-packages/bluesky/preprocessors.py", line 333, in run_wrapper
yield from contingency_wrapper(plan, except_plan=except_plan, else_plan=close_run)
File "/dls/science/users/ton99817/projects/p45/venv/lib/python3.9/site-packages/bluesky/preprocessors.py", line 575, in contingency_wrapper
ret = yield from plan
File "/dls/science/users/ton99817/projects/p45/venv/lib/python3.9/site-packages/bluesky/utils/__init__.py", line 1147, in dec_inner
return (yield from plan)
File "/dls/science/users/ton99817/projects/p45/venv/lib/python3.9/site-packages/bluesky/preprocessors.py", line 965, in stage_wrapper
return (yield from finalize_wrapper(inner(), unstage_devices()))
File "/dls/science/users/ton99817/projects/p45/venv/lib/python3.9/site-packages/bluesky/preprocessors.py", line 511, in finalize_wrapper
ret = yield from plan
File "/dls/science/users/ton99817/projects/p45/venv/lib/python3.9/site-packages/bluesky/preprocessors.py", line 963, in inner
return (yield from plan)
File "/dls/science/users/ton99817/projects/p45/src/p45/bluesky/plan.py", line 39, in collect_sample_projections
exposure_time = yield from bps.rd(camera.drv.acquire_time)
File "/dls/science/users/ton99817/projects/p45/venv/lib/python3.9/site-packages/bluesky/plan_stubs.py", line 371, in rd
ret = yield from read(obj)
File "/dls/science/users/ton99817/projects/p45/venv/lib/python3.9/site-packages/bluesky/plan_stubs.py", line 96, in read
return (yield Msg('read', obj))
File "/dls/science/users/ton99817/projects/p45/venv/lib/python3.9/site-packages/bluesky/run_engine.py", line 1583, in _run
new_response = await coro(msg)
File "/dls/science/users/ton99817/projects/p45/venv/lib/python3.9/site-packages/bluesky/run_engine.py", line 1835, in _read
ret = await maybe_await(obj.read(*msg.args, **msg.kwargs))
File "/dls/science/users/ton99817/projects/p45/venv/lib/python3.9/site-packages/bluesky/utils/__init__.py", line 1779, in maybe_await
return await ret
File "/dls/science/users/ton99817/projects/p45/venv/lib/python3.9/site-packages/ophyd/v2/epics.py", line 90, in read
await self._valid.wait()
File "/dls_sw/apps/python/anaconda/4.6.14/64/envs/python3.9/lib/python3.9/asyncio/locks.py", line 226, in wait
await fut
RuntimeError: Task <Task pending name='Task-65' coro=<RunEngine._run() running at /dls/science/users/ton99817/projects/p45/venv/lib/python3.9/site-packages/bluesky/run_engine.py:1583> cb=[_chain_future.<locals>._call_set_state() at /dls_sw/apps/python/anaconda/4.6.14/64/envs/python3.9/lib/python3.9/asyncio/futures.py:391]> got Future <Future pending> attached to a different loop
To rectify the issue, the bluesky plan file can be changed to:
from ophyd.v2.core import DeviceCollector
from ophyd_epics_devices.areadetector import MyHDFFlyerSim
from ophyd_epics_devices.motor import Motor
import bluesky.preprocessors as bpp
import bluesky.plan_stubs as bps
from bluesky import RunEngine
RE = RunEngine()
import asyncio
from bluesky.run_engine import _bluesky_event_loop
asyncio.set_event_loop(_bluesky_event_loop)
with DeviceCollector():
rot_motor = Motor("BL46P-MO-MAP-01:STAGE:A")
x_motor = Motor("BL46P-MO-MAP-01:STAGE:X")
camera = MyHDFFlyerSim("BL46P-EA-DET-01:", drv_prefix="DET:")
@bpp.run_decorator()
@bpp.stage_decorator([camera])
def collect_sample_projections(start_angle: float, stop_angle: float, num_projections: int):
yield from bps.abs_set(camera.hdf.file_path, "/dls/science/users/ton99817/projects")
yield from bps.abs_set(camera.hdf.file_name, "p45test.h5")
exposure_time = yield from bps.rd(camera.drv.acquire_time)
The text was updated successfully, but these errors were encountered:
coretl
changed the title
Motor and AreaDetector devices do not set their event loops as the bluesky event loop, meaning some bluesky plan stubs fail.
v2: Motor and AreaDetector devices do not set their event loops as the bluesky event loop, meaning some bluesky plan stubs fail.
Mar 15, 2023
coretl
transferred this issue from bluesky/ophyd-epics-devices
Mar 15, 2023
Overview of the issue
When trying to run a bluesky plan with ophyd-epics-devices motors and area detectors, I came across a bug where trying to read a PV from either of these devices would result in a RuntimeError:
After some investigation by @coretl it was discovered that this is because upon collecting these devices, their event loops are set to be the current user event loop, not the bluesky event loop. This means some bluesky plan stubs (like read) don't work, because they check the
._valid
property of the devices and ensure they are running on the bluesky event loop. It was subsequently fixed by directly handling and setting the event loop to be the bluesky event loop in the script.Steps to recreate
In this case, I was running the script above inside "dls/science/users/ton99817/projects/p45", with this snippet of code saved at "dls/science/users/ton99817/projects/p45/src/p45/bluesky/plan.py". Running this script with the minimal dependencies required (bluesky, ophyd and aioca, with ophyd installed from the github repo) produced the following output:
To rectify the issue, the bluesky plan file can be changed to:
The text was updated successfully, but these errors were encountered: