Skip to content

Commit

Permalink
Refactored threaded ophyd devices.
Browse files Browse the repository at this point in the history
Moved existing threaded ophyd device loaders to the new Instrument()
class. Also got rid of the dedicated "Camera" class, since it's really
just an area detector. There are no longer any ``load_<device>()``
style loading functions.
  • Loading branch information
canismarko committed Oct 4, 2024
1 parent 371b7e2 commit 749b4a4
Show file tree
Hide file tree
Showing 41 changed files with 256 additions and 911 deletions.
2 changes: 1 addition & 1 deletion src/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
from haven.catalog import Catalog
from haven.devices.aps import ApsMachine
from haven.devices.beamline_manager import BeamlineManager, IOCManager
from haven.devices.camera import AravisDetector
from haven.devices.area_detector import AravisDetector
from haven.devices.dxp import DxpDetector
from haven.devices.dxp import add_mcas as add_dxp_mcas
from haven.devices.ion_chamber import IonChamber
Expand Down
3 changes: 0 additions & 3 deletions src/haven/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,12 +45,9 @@
Monochromator,
Robot,
ion_chamber,
load_robots,
registry,
)
from .devices.dxp import load_dxp_detectors # noqa: F401
from .devices.motor import HavenMotor # noqa: F401
from .devices.xspress import load_xspress_detectors # noqa: F401
from .energy_ranges import ERange, KRange, merge_ranges # noqa: F401
from .instrument import Instrument # noqa: F401
from .load_instrument import load_instrument # noqa: F401
Expand Down
2 changes: 1 addition & 1 deletion src/haven/devices/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
from .ion_chamber import IonChamber # noqa: F401
from .monochromator import Monochromator # noqa: F401
from .motor import HavenMotor, Motor # noqa: F401
from .robot import Robot, load_robots # noqa: F401
from .robot import Robot # noqa: F401
from .table import Table # noqa: F401

# -----------------------------------------------------------------------------
Expand Down
29 changes: 0 additions & 29 deletions src/haven/devices/aerotech.py
Original file line number Diff line number Diff line change
Expand Up @@ -572,35 +572,6 @@ def __init__(
super().__init__(name=name)


async def load_aerotech_stages(
config: Mapping = None,
registry: InstrumentRegistry = default_registry,
connect: bool = True,
) -> List[AerotechStage]:
"""Load Aerotech XY stages defined in the configuration files'
``[aerotech_stage]`` sections.
"""
if config is None:
config = load_config()
devices = []
for name, stage_data in config.get("aerotech_stage", {}).items():
mprefix = stage_data["prefix"]
devices.append(
AerotechStage(
name=name,
vertical_prefix=f"{mprefix}{stage_data['pv_vert']}",
horizontal_prefix=f"{mprefix}{stage_data['pv_horiz']}",
delay_prefix=stage_data["delay_prefix"],
)
)
if connect:
devices = await connect_devices(
devices, mock=not config["beamline"]["is_connected"], registry=registry
)
return devices


# -----------------------------------------------------------------------------
# :author: Mark Wolfman
# :email: [email protected]
Expand Down
9 changes: 1 addition & 8 deletions src/haven/devices/aps.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@


class ApsMachine(ApsMachineParametersDevice):
_ophyd_labels_ = {"synchrotrons"}
_default_read_attrs = [
"current",
"lifetime",
Expand All @@ -31,14 +32,6 @@ class ApsMachine(ApsMachineParametersDevice):
shutter_status = Cpt(EpicsSignalRO, "RF-ACIS:FePermit:Sect1To35IdM.RVAL")


def load_aps(config=None):
"""Load devices related to the synchrotron as a whole."""
if config is None:
config = load_config()
# Load storage ring device
return make_device(ApsMachine, name="APS", labels={"synchrotrons"})


# -----------------------------------------------------------------------------
# :author: Mark Wolfman
# :email: [email protected]
Expand Down
83 changes: 58 additions & 25 deletions src/haven/devices/area_detector.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,10 @@
from ophyd import Component as Cpt
from ophyd import DetectorBase as OphydDetectorBase
from ophyd import (
CamBase,
Device,
EigerDetectorCam,
EpicsSignal,
Kind,
Lambda750kCam,
OphydObject,
Expand All @@ -32,6 +34,7 @@
ImagePlugin_V31,
ImagePlugin_V34,
OverlayPlugin,
OverlayPlugin_V34,
PvaPlugin_V31,
PvaPlugin_V34,
ROIPlugin_V31,
Expand All @@ -42,6 +45,7 @@
from ophyd.areadetector.plugins import TIFFPlugin_V31, TIFFPlugin_V34
from ophyd.flyers import FlyerInterface
from ophyd.status import Status, StatusBase, SubscriptionStatus
from ophyd.sim import make_fake_device

from .. import exceptions
from .._iconfig import load_config
Expand Down Expand Up @@ -323,7 +327,7 @@ def __init__(
try:
self.write_path_template = self.write_path_template.format(
name=self.parent.name,
root_path=config.get("area_detector", {}).get("root_path", "tmp"),
root_path=config.get("area_detector_root_path", "tmp"),
)
except KeyError:
warnings.warn(f"Could not format write_path_template {write_path_template}")
Expand Down Expand Up @@ -502,31 +506,60 @@ class Eiger500K(SingleTrigger, DetectorBase):
]


def load_area_detectors(config=None) -> set:
if config is None:
config = load_config()
class AravisCam(AsyncCamMixin, CamBase):
gain_auto = ADCpt(EpicsSignal, "GainAuto")
acquire_time_auto = ADCpt(EpicsSignal, "ExposureAuto")


class AravisDetector(SingleImageModeTrigger, DetectorBase):
"""
A gige-vision camera described by EPICS.
"""

_default_configuration_attrs = (
"cam",
"hdf",
"stats1",
"stats2",
"stats3",
"stats4",
)
_default_read_attrs = ("cam", "hdf", "stats1", "stats2", "stats3", "stats4")

cam = ADCpt(AravisCam, "cam1:")
image = ADCpt(ImagePlugin_V34, "image1:")
pva = ADCpt(PvaPlugin_V34, "Pva1:")
overlays = ADCpt(OverlayPlugin_V34, "Over1:")
roi1 = ADCpt(ROIPlugin_V34, "ROI1:", kind=Kind.config)
roi2 = ADCpt(ROIPlugin_V34, "ROI2:", kind=Kind.config)
roi3 = ADCpt(ROIPlugin_V34, "ROI3:", kind=Kind.config)
roi4 = ADCpt(ROIPlugin_V34, "ROI4:", kind=Kind.config)
stats1 = ADCpt(StatsPlugin_V34, "Stats1:", kind=Kind.normal)
stats2 = ADCpt(StatsPlugin_V34, "Stats2:", kind=Kind.normal)
stats3 = ADCpt(StatsPlugin_V34, "Stats3:", kind=Kind.normal)
stats4 = ADCpt(StatsPlugin_V34, "Stats4:", kind=Kind.normal)
stats5 = ADCpt(StatsPlugin_V34, "Stats5:", kind=Kind.normal)
hdf = ADCpt(HDF5FilePlugin, "HDF1:", kind=Kind.normal)
# tiff = ADCpt(TIFFFilePlugin, "TIFF1:", kind=Kind.normal)


def make_area_detector(prefix:str, name: str, device_class: str, mock=True) -> Device:
# Create the area detectors defined in the configuration
devices = []
for name, adconfig in config.get("area_detector", {}).items():
try:
DeviceClass = globals().get(adconfig["device_class"])
except TypeError:
# Not a sub-dictionary, so move on
continue
# Check that it's a valid device class
if DeviceClass is None:
msg = f"area_detector.{name}.device_class={adconfig['device_class']}"
raise exceptions.UnknownDeviceConfiguration(msg)
# Create the device co-routine
devices.append(
make_device(
DeviceClass,
prefix=f"{adconfig['prefix']}:",
name=name,
labels={"area_detectors", "detectors"},
)
)
return devices
try:
DeviceClass = globals().get(device_class)
except TypeError:
msg = f"area_detector.{name}.device_class={device_class}"
raise exceptions.UnknownDeviceConfiguration(msg)
# Create a simulated version if needed
if mock:
DeviceClass = make_fake_device(DeviceClass)
# Create the device co-routine
device = DeviceClass(
prefix=prefix,
name=name,
labels={"area_detectors", "detectors"},
)
return device


# -----------------------------------------------------------------------------
Expand Down
22 changes: 2 additions & 20 deletions src/haven/devices/beamline_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,23 +78,5 @@ def __new__(
new_cls = type("BeamlineManager", (cls,), comps)
return object.__new__(new_cls)

def __init__(self, *args, iocs={}, **kwargs):
super().__init__(*args, **kwargs)


def load_beamline_manager(config=None):
# Load configuration for the beamline manager
if config is None:
config = load_config()
try:
cfg = config["beamline_manager"]
except KeyError:
return
# Set up the beamline manager
return make_device(
BeamlineManager,
prefix=cfg["prefix"],
name=cfg["name"],
labels={"beamline_manager"},
iocs=cfg["iocs"],
)
def __init__(self, prefix: str, *, name: str, iocs={}, labels={"beamline_manager"}, **kwargs):
super().__init__(name=name, prefix=prefix, labels=labels, **kwargs)
133 changes: 0 additions & 133 deletions src/haven/devices/camera.py

This file was deleted.

Loading

0 comments on commit 749b4a4

Please sign in to comment.