Skip to content

Commit

Permalink
Merge pull request #302 from spc-group/hints
Browse files Browse the repository at this point in the history
Hinted signals for the ion chambers
  • Loading branch information
canismarko authored Nov 19, 2024
2 parents 7c5d70f + 870532a commit a1efa7a
Show file tree
Hide file tree
Showing 31 changed files with 624 additions and 539 deletions.
3 changes: 2 additions & 1 deletion environment.yml
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,8 @@ dependencies:
- bluesky-adaptive
- bluesky >=1.8.1
- ophyd >=1.6.3
- ophyd-async >= 0.6.0
# - ophyd-async > 0.8.0a4
- git+https://github.com/bluesky/ophyd-async.git # switch back to pip once a new release (0.8.0a5) is available
- apstools == 1.6.20 # Leave at 1.6.20 until this is fixed: https://github.com/BCDA-APS/apstools/issues/1022
- pcdsdevices # For extra signal types
- pydm >=1.18.0
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ classifiers = [
"Topic :: System :: Hardware",
]
keywords = ["synchrotron", "xray", "bluesky"]
dependencies = ["aioca", "aiokafka", "bluesky", "ophyd", "ophyd-async>=0.7.0", "databroker", "apsbss", "xraydb",
dependencies = ["aioca", "aiokafka", "bluesky", "ophyd", "ophyd-async>=0.8.0a3", "databroker", "apsbss", "xraydb",
"mergedeep", "xrayutilities", "bluesky-queueserver-api", "tomlkit",
"apstools", "databroker", "ophyd-registry", "caproto", "pcdsdevices",
"strenum", "bluesky-adaptive", "tiled[client]"]
Expand Down
115 changes: 67 additions & 48 deletions src/haven/devices/delay.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@
from typing import Type

from ophyd_async.core import (
ConfigSignal,
DeviceVector,
SignalRW,
StandardReadable,
StandardReadableFormat,
StrictEnum,
SubsetEnum,
T,
)
from ophyd_async.epics.signal import epics_signal_r, epics_signal_rw, epics_signal_x
from ophyd_async.epics.core import epics_signal_r, epics_signal_rw, epics_signal_x


class StrEnum(str, enum.Enum):
Expand All @@ -36,22 +36,31 @@ def epics_signal_io(datatype: Type[T], prefix: str, name: str = "") -> SignalRW[


class DG645Channel(StandardReadable):
Reference = SubsetEnum["T0", "A", "B", "C", "D", "E", "F", "G", "H"]
class Reference(StrictEnum):
T0 = "T0"
A = "A"
B = "B"
C = "C"
D = "D"
E = "E"
F = "F"
G = "G"
H = "H"

def __init__(self, prefix: str, name: str = ""):
with self.add_children_as_readables(ConfigSignal):
with self.add_children_as_readables(StandardReadableFormat.CONFIG_SIGNAL):
self.reference = epics_signal_io(self.Reference, f"{prefix}ReferenceM")
self.delay = epics_signal_io(float, f"{prefix}DelayA")
super().__init__(name=name)


class DG645Output(StandardReadable):
class Polarity(StrEnum):
class Polarity(StrictEnum):
NEG = "NEG"
POS = "POS"

def __init__(self, prefix: str, name: str = ""):
with self.add_children_as_readables(ConfigSignal):
with self.add_children_as_readables(StandardReadableFormat.CONFIG_SIGNAL):
self.polarity = epics_signal_io(self.Polarity, f"{prefix}OutputPolarityB")
self.amplitude = epics_signal_io(float, f"{prefix}OutputAmpA")
self.offset = epics_signal_io(float, f"{prefix}OutputOffsetA")
Expand All @@ -62,16 +71,46 @@ def __init__(self, prefix: str, name: str = ""):

class DG645DelayOutput(DG645Output):
def __init__(self, prefix: str, name: str = ""):
with self.add_children_as_readables(ConfigSignal):
with self.add_children_as_readables(StandardReadableFormat.CONFIG_SIGNAL):
self.trigger_prescale = epics_signal_io(int, f"{prefix}TriggerPrescaleL")
self.trigger_phase = epics_signal_io(int, f"{prefix}TriggerPhaseL")
super().__init__(prefix=prefix, name=name)


class DG645Delay(StandardReadable):

class BaudRate(SubsetEnum):
B4800 = "4800"
B9600 = "9600"
B19200 = "19200"
B38400 = "38400"
B57600 = "57600"
B115200 = "115200"

class TriggerSource(SubsetEnum):
INTERNAL = "Internal"
EXT_RISING_EDGE = "Ext rising edge"
EXT_FALLING_EDGE = "Ext falling edge"
SS_EXT_RISE_EDGE = "SS ext rise edge"
SS_EXT_FALL_EDGE = "SS ext fall edge"
SINGLE_SHOT = "Single shot"
LINE = "Line"

class TriggerInhibit(SubsetEnum):
OFF = "Off"
TRIGGERS = "Triggers"
AB = "AB"
AB_CD = "AB,CD"
AB_CD_EF = "AB,CD,EF"
AB_CD_EF_GH = "AB,CD,EF,GH"

class BurstConfig(SubsetEnum):
ALL_CYCLES = "All Cycles"
FIRST_CYCLE = "1st Cycle"

def __init__(self, prefix: str, name: str = ""):
# Conventional signals
with self.add_children_as_readables(ConfigSignal):
with self.add_children_as_readables(StandardReadableFormat.CONFIG_SIGNAL):
self.label = epics_signal_rw(str, f"{prefix}Label")
self.device_id = epics_signal_r(str, f"{prefix}IdentSI")
self.status = epics_signal_r(str, f"{prefix}StatusSI")
Expand All @@ -82,10 +121,7 @@ def __init__(self, prefix: str, name: str = ""):
self.status_checking = epics_signal_rw(bool, f"{prefix}StatusCheckingBO")
self.reset_serial = epics_signal_x(f"{prefix}IfaceSerialResetBO")
self.serial_state = epics_signal_io(bool, f"{prefix}IfaceSerialStateB")
self.serial_baud = epics_signal_io(
SubsetEnum["4800", "9600", "19200", "38400", "57600", "115200"],
f"{prefix}IfaceSerialBaudM",
)
self.serial_baud = epics_signal_io(self.BaudRate, f"{prefix}IfaceSerialBaudM")
self.reset_gpib = epics_signal_x(f"{prefix}IfaceGpibResetBO")
self.gpib_state = epics_signal_io(bool, f"{prefix}IfaceGpibStateB")
self.gpib_address = epics_signal_io(int, f"{prefix}IfaceGpibAddrL")
Expand All @@ -103,46 +139,29 @@ def __init__(self, prefix: str, name: str = ""):
self.gateway = epics_signal_io(str, f"{prefix}IfaceGatewayS")
# Individual delay channels
with self.add_children_as_readables():
self.channels = DeviceVector(
{
"A": DG645Channel(f"{prefix}A"),
"B": DG645Channel(f"{prefix}B"),
"C": DG645Channel(f"{prefix}C"),
"D": DG645Channel(f"{prefix}D"),
"E": DG645Channel(f"{prefix}E"),
"F": DG645Channel(f"{prefix}F"),
"G": DG645Channel(f"{prefix}G"),
"H": DG645Channel(f"{prefix}H"),
}
)
self.channel_A = DG645Channel(f"{prefix}A")
self.channel_B = DG645Channel(f"{prefix}B")
self.channel_C = DG645Channel(f"{prefix}C")
self.channel_D = DG645Channel(f"{prefix}D")
self.channel_E = DG645Channel(f"{prefix}E")
self.channel_F = DG645Channel(f"{prefix}F")
self.channel_G = DG645Channel(f"{prefix}G")
self.channel_H = DG645Channel(f"{prefix}H")
# 2-channel delay outputs
with self.add_children_as_readables():
self.outputs = DeviceVector(
{
"T0": DG645Output(f"{prefix}T0"),
"AB": DG645DelayOutput(f"{prefix}AB"),
"CD": DG645DelayOutput(f"{prefix}CD"),
"EF": DG645DelayOutput(f"{prefix}EF"),
"GH": DG645DelayOutput(f"{prefix}GH"),
}
)
self.output_T0 = DG645Output(f"{prefix}T0")
self.output_AB = DG645DelayOutput(f"{prefix}AB")
self.output_CD = DG645DelayOutput(f"{prefix}CD")
self.output_EF = DG645DelayOutput(f"{prefix}EF")
self.output_GH = DG645DelayOutput(f"{prefix}GH")
# Trigger control
with self.add_children_as_readables(ConfigSignal):
with self.add_children_as_readables(StandardReadableFormat.CONFIG_SIGNAL):
self.trigger_source = epics_signal_io(
SubsetEnum[
"Internal",
"Ext rising edge",
"Ext falling edge",
"SS ext rise edge",
"SS ext fall edge",
"Single shot",
"Line",
],
self.TriggerSource,
f"{prefix}TriggerSourceM",
)
self.trigger_inhibit = epics_signal_io(
SubsetEnum["Off", "Triggers", "AB", "AB,CD", "AB,CD,EF", "AB,CD,EF,GH"],
f"{prefix}TriggerInhibitM",
self.TriggerInhibit, f"{prefix}TriggerInhibitM"
)
self.trigger_level = epics_signal_io(float, f"{prefix}TriggerLevelA")
self.trigger_rate = epics_signal_io(float, f"{prefix}TriggerRateA")
Expand All @@ -152,11 +171,11 @@ def __init__(self, prefix: str, name: str = ""):
self.trigger_holdoff = epics_signal_io(float, f"{prefix}TriggerHoldoffA")
self.trigger_prescale = epics_signal_io(int, f"{prefix}TriggerPrescaleL")
# Burst settings
with self.add_children_as_readables(ConfigSignal):
with self.add_children_as_readables(StandardReadableFormat.CONFIG_SIGNAL):
self.burst_mode = epics_signal_io(bool, f"{prefix}BurstModeB")
self.burst_count = epics_signal_io(int, f"{prefix}BurstCountL")
self.burst_config = epics_signal_io(
SubsetEnum["All Cycles", "1st Cycle"], f"{prefix}BurstConfigB"
self.BurstConfig, f"{prefix}BurstConfigB"
)
self.burst_delay = epics_signal_io(float, f"{prefix}BurstDelayA")
self.burst_period = epics_signal_io(float, f"{prefix}BurstPeriodA")
Expand Down
7 changes: 5 additions & 2 deletions src/haven/devices/detectors/aravis.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
from ophyd_async.core import SubsetEnum
from ophyd_async.epics.adaravis import AravisDetector as DetectorBase
from ophyd_async.epics.signal import epics_signal_rw_rbv
from ophyd_async.epics.core import epics_signal_rw_rbv

from .area_detectors import HavenDetector

AravisTriggerSource = SubsetEnum["Software", "Line1"]

class AravisTriggerSource(SubsetEnum):
SOFTWARE = "Software"
LINE1 = "Line1"


class AravisDetector(HavenDetector, DetectorBase):
Expand Down
4 changes: 2 additions & 2 deletions src/haven/devices/energy_positioner.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
CALCULATE_TIMEOUT,
AsyncStatus,
CalculatableTimeout,
HintedSignal,
Signal,
StandardReadableFormat,
)

from ..positioner import Positioner
Expand Down Expand Up @@ -78,7 +78,7 @@ def __init__(
forward=self.set_energy,
inverse=self.get_energy,
)
with self.add_children_as_readables(HintedSignal):
with self.add_children_as_readables(StandardReadableFormat.HINTED_SIGNAL):
self.readback = derived_signal_r(
float,
derived_from={"mono": self.monochromator.energy.user_readback},
Expand Down
Loading

0 comments on commit a1efa7a

Please sign in to comment.