Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,13 @@ description = "Bluesky plans and tools for the Imaging Group"
dependencies = [
"bluesky",
"ophyd",
"ophyd_async @ git+https://github.com/bluesky/ophyd-async.git",
"ophyd_async==0.21.1",
"pandas",
"ipython",
"matplotlib",
"databroker",
"scipy",
"dls-dodal",
"dls-dodal>=2.6.2",
"typer",
'ipython',
'scanspec @ git+https://github.com/bluesky/scanspec.git',
Expand Down
50 changes: 25 additions & 25 deletions src/imaging_bluesky/p49/devices/__init__.py
Original file line number Diff line number Diff line change
@@ -1,33 +1,33 @@
from dodal.common.beamlines.beamline_utils import device_factory, get_path_provider
from dodal.utils import BeamlinePrefix, get_beamline_name
from ophyd_async.epics.adaravis import AravisDetector
from ophyd_async.fastcs.panda import HDFPanda
# from dodal.common.beamlines.beamline_utils import device_factory, get_path_provider
# from dodal.utils import BeamlinePrefix, get_beamline_name
# from ophyd_async.epics.adaravis import AravisDetector
# from ophyd_async.fastcs.panda import HDFPanda

from imaging_bluesky.p49.devices.stages import Stages
# from imaging_bluesky.p49.devices.stages import Stages

BL = get_beamline_name("p49")
PREFIX = BeamlinePrefix(BL)
# BL = get_beamline_name("p49")
# PREFIX = BeamlinePrefix(BL)


@device_factory()
def panda() -> HDFPanda:
return HDFPanda(
f"{PREFIX.beamline_prefix}-MO-PANDA-01:",
path_provider=get_path_provider(),
name="panda",
)
# @device_factory()
# def panda() -> HDFPanda:
# return HDFPanda(
# f"{PREFIX.beamline_prefix}-MO-PANDA-01:",
# path_provider=get_path_provider(),
# name="panda",
# )


@device_factory()
def detector() -> AravisDetector:
return AravisDetector(
f"{PREFIX.beamline_prefix}-EA-DET-01:",
path_provider=get_path_provider(),
drv_suffix="DET:",
fileio_suffix="HDF5:",
)
# @device_factory()
# def detector() -> AravisDetector:
# return AravisDetector(
# f"{PREFIX.beamline_prefix}-EA-DET-01:",
# path_provider=get_path_provider(),
# drv_suffix="DET:",
# fileio_suffix="HDF5:",
# )


@device_factory()
def alignment_stages() -> Stages:
return Stages(PREFIX.beamline_prefix)
# @device_factory()
# def alignment_stages() -> Stages:
# return Stages(PREFIX.beamline_prefix)
22 changes: 11 additions & 11 deletions src/imaging_bluesky/p49/devices/stages.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
from ophyd_async.core import (
StandardReadable,
)
from ophyd_async.epics.motor import Motor
# from ophyd_async.core import (
# StandardReadable,
# )
# from ophyd_async.epics.motor import Motor


class Stages(StandardReadable):
"""Collection of motors to control the alignment stage"""
# class Stages(StandardReadable):
# """Collection of motors to control the alignment stage"""

def __init__(self, beamline_prefix: str, name: str = "") -> None:
with self.add_children_as_readables():
self.x = Motor(beamline_prefix + "-MO-MAP-01:STAGE:X", "x")
self.theta = Motor(beamline_prefix + "-MO-MAP-01:STAGE:A", "theta")
super().__init__(name=name)
# def __init__(self, beamline_prefix: str, name: str = "") -> None:
# with self.add_children_as_readables():
# self.x = Motor(beamline_prefix + "-MO-MAP-01:STAGE:X", "x")
# self.theta = Motor(beamline_prefix + "-MO-MAP-01:STAGE:A", "theta")
# super().__init__(name=name)
4 changes: 2 additions & 2 deletions src/imaging_bluesky/p49/plans/__init__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
from .panda_plan import fly_scan
# from .panda_plan import fly_scan

__all__ = ["fly_scan"]
# __all__ = ["fly_scan"]
199 changes: 100 additions & 99 deletions src/imaging_bluesky/p49/plans/panda_plan.py
Original file line number Diff line number Diff line change
@@ -1,114 +1,115 @@
from math import ceil
# from math import ceil

import bluesky.plan_stubs as bps
import bluesky.preprocessors as bpp
from bluesky.utils import MsgGenerator
from dodal.plan_stubs.data_session import attach_data_session_metadata_decorator
from ophyd_async.core import DetectorTrigger, FlyMotorInfo, StandardFlyer, TriggerInfo
from ophyd_async.epics.adaravis import AravisDetector
from ophyd_async.epics.motor import Motor
from ophyd_async.fastcs.panda import (
HDFPanda,
PandaPcompDirection,
PcompInfo,
StaticPcompTriggerLogic,
)
# import bluesky.plan_stubs as bps
# import bluesky.preprocessors as bpp
# from bluesky.utils import MsgGenerator
# from dodal.plan_stubs.data_session import attach_data_session_metadata_decorator
# from ophyd_async.core import DetectorTrigger, FlyMotorInfo, StandardFlyer, TriggerInfo
# from ophyd_async.epics.adaravis import AravisDetector
# from ophyd_async.epics.motor import Motor
# from ophyd_async.fastcs.panda import (
# HDFPanda,
# PandaPcompDirection,
# PcompInfo,
# StaticPcompTriggerLogic,
# )

# for calculations
MRES_X = -0.000125
MRES_THETA = 0.018
# # for calculations
# MRES_X = -0.000125
# MRES_THETA = 0.018


def fly_scan(
start: int,
stop: int,
num: int,
duration: float,
motor: Motor,
panda: HDFPanda,
detector: AravisDetector,
) -> MsgGenerator:
"""
Perform a fly scan.
# def fly_scan(
# start: int,
# stop: int,
# num: int,
# duration: float,
# motor: Motor,
# panda: HDFPanda,
# detector: AravisDetector,
# ) -> MsgGenerator:
# """
# Perform a fly scan.

Args:
start (float): Starting position in mm.
stop (float): Ending position in mm.
num (int): Number of steps.
duration (float): Duration to acquire each frame, in seconds.
motor (Motor): Motor instance.
panda (HDFPanda): Data acquisition device.
# Args:
# start (float): Starting position in mm.
# stop (float): Ending position in mm.
# num (int): Number of steps.
# duration (float): Duration to acquire each frame, in seconds.
# motor (Motor): Motor instance.
# panda (HDFPanda): Data acquisition device.

Yields:
- Messages for the scan process (MsgGenerator).
"""
# Yields:
# - Messages for the scan process (MsgGenerator).
# """

# Describes the Panda PCOMP block.
# It is responsible for generating the triggers based on a position and step size.
panda_pcomp = StandardFlyer(StaticPcompTriggerLogic(panda.pcomp[1]))
# # Describes the Panda PCOMP block.
# # It is responsible for generating the triggers based on a position and step size.
# panda_pcomp = StandardFlyer(StaticPcompTriggerLogic(panda.pcomp[1]))

# MRES changes depending on the motor.
# Getting this value from the motor will be soon available through an async function
if motor.name == "alignment_stages-x":
MRES = MRES_X
elif motor.name == "alignment_stages-theta":
MRES = MRES_THETA
else:
raise ValueError(f"Motor name ({motor.name}) not supported")
# # MRES changes depending on the motor.
# # Getting this value from the motor will be
# #soon available through an async function
# if motor.name == "alignment_stages-x":
# MRES = MRES_X
# elif motor.name == "alignment_stages-theta":
# MRES = MRES_THETA
# else:
# raise ValueError(f"Motor name ({motor.name}) not supported")

@attach_data_session_metadata_decorator()
@bpp.run_decorator()
@bpp.stage_decorator([panda, panda_pcomp])
def inner_plan():
width = (stop - start) / (num - 1)
start_pos = start - (width / 2)
stop_pos = stop + (width / 2)
motor_info = FlyMotorInfo(
start_position=start_pos,
end_position=stop_pos,
time_for_move=num * duration,
)
# Info used to generate the triggers.
panda_pcomp_info = PcompInfo(
start_postion=ceil(start_pos / abs(MRES)),
pulse_width=1,
rising_edge_step=ceil(abs(width / MRES)),
number_of_pulses=num,
direction=PandaPcompDirection.NEGATIVE
if width / MRES > 0
else PandaPcompDirection.POSITIVE,
)
# @attach_data_session_metadata_decorator()
# @bpp.run_decorator()
# @bpp.stage_decorator([panda, panda_pcomp])
# def inner_plan():
# width = (stop - start) / (num - 1)
# start_pos = start - (width / 2)
# stop_pos = stop + (width / 2)
# motor_info = FlyMotorInfo(
# start_position=start_pos,
# end_position=stop_pos,
# time_for_move=num * duration,
# )
# # Info used to generate the triggers.
# panda_pcomp_info = PcompInfo(
# start_postion=ceil(start_pos / abs(MRES)),
# pulse_width=1,
# rising_edge_step=ceil(abs(width / MRES)),
# number_of_pulses=num,
# direction=PandaPcompDirection.NEGATIVE
# if width / MRES > 0
# else PandaPcompDirection.POSITIVE,
# )

# Info on configuring the data writer block for the Panda device.
# This sets the number of frames that are expected.
panda_hdf_info = TriggerInfo(
number_of_events=num,
trigger=DetectorTrigger.CONSTANT_GATE,
livetime=duration,
deadtime=1e-5,
)
# # Info on configuring the data writer block for the Panda device.
# # This sets the number of frames that are expected.
# panda_hdf_info = TriggerInfo(
# number_of_events=num,
# trigger=DetectorTrigger.CONSTANT_GATE,
# livetime=duration,
# deadtime=1e-5,
# )

detector_info = TriggerInfo(
number_of_events=num,
trigger=DetectorTrigger.CONSTANT_GATE,
livetime=duration - 0.1,
deadtime=0.1,
)
# detector_info = TriggerInfo(
# number_of_events=num,
# trigger=DetectorTrigger.CONSTANT_GATE,
# livetime=duration - 0.1,
# deadtime=0.1,
# )

# The order of these prepare calls does not matter, as we are setting the PVs.
yield from bps.prepare(motor, motor_info)
yield from bps.prepare(panda, panda_hdf_info)
yield from bps.prepare(detector, detector_info)
yield from bps.prepare(panda_pcomp, panda_pcomp_info, wait=True)
# # The order of these prepare calls does not matter, as we are setting the PVs.
# yield from bps.prepare(motor, motor_info)
# yield from bps.prepare(panda, panda_hdf_info)
# yield from bps.prepare(detector, detector_info)
# yield from bps.prepare(panda_pcomp, panda_pcomp_info, wait=True)

# Kickoff the motor last to ensure other components are initialized first.
# Otherwise, the motor might move before other devices are ready.
yield from bps.kickoff(panda)
yield from bps.kickoff(panda_pcomp, wait=True)
yield from bps.kickoff(detector, wait=True)
yield from bps.kickoff(motor, wait=True)
# # Kickoff the motor last to ensure other components are initialized first.
# # Otherwise, the motor might move before other devices are ready.
# yield from bps.kickoff(panda)
# yield from bps.kickoff(panda_pcomp, wait=True)
# yield from bps.kickoff(detector, wait=True)
# yield from bps.kickoff(motor, wait=True)

# Needs to wait for each flyable object to complete.
yield from bps.complete_all(motor, panda_pcomp, panda, detector, wait=True)
# # Needs to wait for each flyable object to complete.
# yield from bps.complete_all(motor, panda_pcomp, panda, detector, wait=True)

yield from inner_plan()
# yield from inner_plan()
Loading
Loading