WIP: widget development #48
No files matched your search
@@ -70,6 +70,36 @@ es1ic2_try:
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
|
||||
ic0:
|
||||
readoutPriority: baseline
|
||||
description: Ionization chamber 0
|
||||
deviceClass: superxas_bec.devices.ionization_chambers.ionization_chamber.IonizationChamber0
|
||||
deviceConfig:
|
||||
prefix: "X10DA-"
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
|
||||
ic1:
|
||||
readoutPriority: baseline
|
||||
description: Ionization chamber 1
|
||||
deviceClass: superxas_bec.devices.ionization_chambers.ionization_chamber.IonizationChamber1
|
||||
deviceConfig:
|
||||
prefix: "X10DA-"
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
|
||||
ic2:
|
||||
readoutPriority: baseline
|
||||
description: Ionization chamber 2
|
||||
deviceClass: superxas_bec.devices.ionization_chambers.ionization_chamber.IonizationChamber2
|
||||
deviceConfig:
|
||||
prefix: "X10DA-"
|
||||
onFailure: retry
|
||||
enabled: true
|
||||
softwareTrigger: false
|
||||
|
||||
###################################
|
||||
## Sample Manipulator ##
|
||||
###################################
|
||||
|
||||
Whitespace-only changes.
@@ -0,0 +1,411 @@
|
||||
"""Ionization chamber device class"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import TYPE_CHECKING, Literal
|
||||
|
||||
from bec_lib.logger import bec_logger
|
||||
from ophyd import DynamicDeviceComponent as Dcpt
|
||||
from ophyd import EpicsSignal, EpicsSignalRO
|
||||
from ophyd_devices import CompareStatus
|
||||
from ophyd_devices.interfaces.base_classes.psi_device_base import PSIDeviceBase
|
||||
|
||||
from superxas_bec.devices.ionization_chambers.ionization_chamber_enums import (
|
||||
GAIN_MAP,
|
||||
AmplifierBias,
|
||||
AmplifierError,
|
||||
AmplifierFilter,
|
||||
AmplifierFilterAutoFilt,
|
||||
AmplifierFilterStatus,
|
||||
AmplifierGain10X,
|
||||
AmplifierSuppr,
|
||||
AmplifierZeroCheck,
|
||||
)
|
||||
|
||||
if TYPE_CHECKING: # pragma: no cover
|
||||
from bec_lib.devicemanager import ScanInfo
|
||||
|
||||
logger = bec_logger.logger
|
||||
|
||||
|
||||
class IonizationChamberError(Exception):
|
||||
"""Exception for the Ionization Chambers"""
|
||||
|
||||
|
||||
class IonizationChamber0(PSIDeviceBase):
|
||||
"""Ionization Chamber 0, prefix should be 'X10DA-'."""
|
||||
|
||||
USER_ACCESS = ["set_gain", "set_filter"]
|
||||
|
||||
num = 1
|
||||
amp_signals = {
|
||||
"cGain_ENUM": (
|
||||
EpicsSignal,
|
||||
{
|
||||
"read_pv": f"ES-KEITH{num}:getGain",
|
||||
"write_pv": f"ES-KEITH{num}:setGain",
|
||||
"kind": "config",
|
||||
"doc": f"Gain of Keithley {num} -> IC{num-1}",
|
||||
},
|
||||
),
|
||||
"cGain10X_ENUM": (
|
||||
EpicsSignal,
|
||||
{
|
||||
"read_pv": f"ES-KEITH{num}:getGain10X",
|
||||
"write_pv": f"ES-KEITH{num}:setGain10X",
|
||||
"kind": "config",
|
||||
"doc": f"Gain 10x of Keithley {num} -> IC{num-1}",
|
||||
},
|
||||
),
|
||||
"cFilterStatus_ENUM": (
|
||||
EpicsSignal,
|
||||
{
|
||||
"read_pv": f"ES-KEITH{num}:getFilter",
|
||||
"write_pv": f"ES-KEITH{num}:setFilter",
|
||||
"kind": "config",
|
||||
"doc": f"Filter Status of Keithley {num} -> IC{num-1}",
|
||||
},
|
||||
),
|
||||
"cFilter_ENUM": (
|
||||
EpicsSignal,
|
||||
{
|
||||
"read_pv": f"ES-KEITH{num}:getRiseTime",
|
||||
"write_pv": f"ES-KEITH{num}:setRiseTime",
|
||||
"kind": "config",
|
||||
"doc": f"Filter of Keithley {num} -> IC{num-1}",
|
||||
},
|
||||
),
|
||||
"cFilterAutoFilt_ENUM": (
|
||||
EpicsSignal,
|
||||
{
|
||||
"read_pv": f"ES-KEITH{num}:getAutoFilt",
|
||||
"write_pv": f"ES-KEITH{num}:setAutoFilt",
|
||||
"kind": "config",
|
||||
"doc": f"Filter Status of Keithley {num} -> IC{num-1}",
|
||||
},
|
||||
),
|
||||
"cZeroCheck_ENUM": (
|
||||
EpicsSignal,
|
||||
{
|
||||
"read_pv": f"ES-KEITH{num}:getZeroCheck",
|
||||
"write_pv": f"ES-KEITH{num}:setZeroCheck",
|
||||
"kind": "config",
|
||||
"doc": f"ZeroCheck of Keithley {num} -> IC{num-1}",
|
||||
},
|
||||
),
|
||||
"cBias_ENUM": (
|
||||
EpicsSignal,
|
||||
{
|
||||
"read_pv": f"ES-KEITH{num}:getBias",
|
||||
"write_pv": f"ES-KEITH{num}:setBias",
|
||||
"kind": "config",
|
||||
"doc": f"Bias of Keithley {num} -> IC{num-1}",
|
||||
},
|
||||
),
|
||||
"cSuppr_ENUM": (
|
||||
EpicsSignal,
|
||||
{
|
||||
"read_pv": f"ES-KEITH{num}:getSuppr",
|
||||
"write_pv": f"ES-KEITH{num}:setSuppr",
|
||||
"kind": "config",
|
||||
"doc": f"Suppression of Keithley {num} -> IC{num-1}",
|
||||
},
|
||||
),
|
||||
"cError_ENUM": (
|
||||
EpicsSignalRO,
|
||||
{
|
||||
"read_pv": f"ES-KEITH{num}:getError",
|
||||
"kind": "config",
|
||||
"doc": f"Error of Keithley {num} -> IC{num-1}",
|
||||
},
|
||||
),
|
||||
}
|
||||
amp = Dcpt(amp_signals)
|
||||
|
||||
def __init__(self, name: str, prefix: str = "", scan_info: ScanInfo | None = None, **kwargs):
|
||||
self.timeout_for_pvwait = 2.5
|
||||
super().__init__(name=name, prefix=prefix, scan_info=scan_info, **kwargs)
|
||||
|
||||
def set_keithley(self) -> None:
|
||||
"""Make sure Keithley is in a normal operation mode"""
|
||||
status_list = []
|
||||
if self.amp.cZeroCheck_ENUM.get() != AmplifierZeroCheck.OFF:
|
||||
status_list.append(self.amp.cZeroCheck_ENUM.set(AmplifierZeroCheck.OFF))
|
||||
if self.amp.cAutoFilt_Enum.get() != AmplifierFilterAutoFilt.MANUAL:
|
||||
status_list.append(self.amp.cAutoFilt_Enum.set(AmplifierFilterAutoFilt.MANUAL))
|
||||
if self.amp.cBias_ENUM.get() != AmplifierBias.OFF:
|
||||
status_list.append(self.amp.cBias_ENUM.set(AmplifierBias.OFF))
|
||||
if self.amp.cSuppr_ENUM.get() != AmplifierSuppr.OFF:
|
||||
status_list.append(self.amp.cSuppr_ENUM.set(AmplifierSuppr.OFF))
|
||||
for s in status_list:
|
||||
s.wait(timeout=self.timeout_for_pvwait)
|
||||
|
||||
error = self.amp.cError_ENUM.get()
|
||||
if error in [
|
||||
AmplifierError.EEPROM_ERROR,
|
||||
AmplifierError.INVALID_COMMAND,
|
||||
AmplifierError.INVALID_OPTION,
|
||||
AmplifierError.NOT_IN_REMOTE,
|
||||
AmplifierError.SELFTEST_FAILED,
|
||||
AmplifierError.SUPPR_CONFLICT,
|
||||
AmplifierError.ZEROCHECK_ON,
|
||||
AmplifierError.ZEROCORR_FAILED,
|
||||
]:
|
||||
raise IonizationChamberError(f"Keithley {self.num} error {AmplifierError(error)}")
|
||||
|
||||
def set_gain(self, gain: float) -> None:
|
||||
"""Configure the gain setting of the specified channel
|
||||
|
||||
Args:
|
||||
gain(float): Amplifier gain to set. Accepts either a float/int or a string,
|
||||
e.g. 1e6 or "1e6". Must be one of: 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9, 1e10.
|
||||
|
||||
Raises:
|
||||
ValueError: If `gain` cannot be converted to a float, or does not
|
||||
match one of the supported gain values.
|
||||
"""
|
||||
|
||||
try:
|
||||
key = float(gain)
|
||||
except (TypeError, ValueError) as exc:
|
||||
raise ValueError(f"Invalid gain: {gain!r}") from exc
|
||||
|
||||
try:
|
||||
enum_val = GAIN_MAP[key]
|
||||
except KeyError as exc:
|
||||
raise ValueError(
|
||||
f"Unsupported gain: {gain!r}. Must be one of {sorted(GAIN_MAP)}"
|
||||
) from exc
|
||||
|
||||
self.set_keithley()
|
||||
|
||||
if self.amp.cGain10X_ENUM.get() != AmplifierGain10X.G1X:
|
||||
logger.warning(
|
||||
f"Keithley {self.num} was not in Gain10X == {AmplifierGain10X.G1X}, will try to set it to this value"
|
||||
)
|
||||
self.amp.cGain10X_ENUM.put(AmplifierGain10X.G1X)
|
||||
status = CompareStatus(self.amp.cGain10X_ENUM, AmplifierGain10X.G1X)
|
||||
status.wait(self.timeout_for_pvwait)
|
||||
|
||||
self.amp.cGain_ENUM.put(enum_val)
|
||||
status = CompareStatus(self.amp.cGain_ENUM, enum_val)
|
||||
status.wait(self.timeout_for_pvwait)
|
||||
|
||||
def set_filter(
|
||||
self,
|
||||
value: Literal[
|
||||
"10us", "30us", "100us", "300us", "1ms", "3ms", "10ms", "30ms", "100ms", "300ms"
|
||||
],
|
||||
) -> None:
|
||||
"""Configure the filter setting of the specified channel
|
||||
|
||||
Args:
|
||||
value (Literal["10us", "30us", "100us", "300us", "1ms", "3ms", "10ms", "30ms", "100ms", "300ms"]) :Desired filter
|
||||
"""
|
||||
self.set_keithley()
|
||||
|
||||
if self.amp.cFilterStatus_ENUM.get() != AmplifierFilterStatus.ON:
|
||||
logger.warning(f"Keithley {self.num} filter was switched off, switch it on now")
|
||||
self.amp.cFilterStatus_ENUM.put(AmplifierFilterStatus.ON)
|
||||
status = CompareStatus(self.amp.cFilterStatus_ENUM, AmplifierFilterStatus.ON)
|
||||
status.wait(self.timeout_for_pvwait)
|
||||
|
||||
match value:
|
||||
case "10us":
|
||||
self.amp.cFilter_ENUM.put(AmplifierFilter.F10US)
|
||||
case "30us":
|
||||
self.amp.cFilter_ENUM.put(AmplifierFilter.F30US)
|
||||
case "100us":
|
||||
self.amp.cFilter_ENUM.put(AmplifierFilter.F100US)
|
||||
case "300us":
|
||||
self.amp.cFilter_ENUM.put(AmplifierFilter.F300US)
|
||||
case "1ms":
|
||||
self.amp.cFilter_ENUM.put(AmplifierFilter.F1MS)
|
||||
case "3ms":
|
||||
self.amp.cFilter_ENUM.put(AmplifierFilter.F3MS)
|
||||
case "10ms":
|
||||
self.amp.cFilter_ENUM.put(AmplifierFilter.F10MS)
|
||||
case "30ms":
|
||||
self.amp.cFilter_ENUM.put(AmplifierFilter.F30MS)
|
||||
case "100ms":
|
||||
self.amp.cFilter_ENUM.put(AmplifierFilter.F100MS)
|
||||
case "300ms":
|
||||
self.amp.cFilter_ENUM.put(AmplifierFilter.F300MS)
|
||||
|
||||
|
||||
class IonizationChamber1(IonizationChamber0):
|
||||
"""Ionization Chamber 1, prefix should be 'X10DA-'."""
|
||||
|
||||
num = 2
|
||||
amp_signals = {
|
||||
"cGain_ENUM": (
|
||||
EpicsSignal,
|
||||
{
|
||||
"read_pv": f"ES-KEITH{num}:getGain",
|
||||
"write_pv": f"ES-KEITH{num}:setGain",
|
||||
"kind": "config",
|
||||
"doc": f"Gain of Keithley {num} -> IC{num-1}",
|
||||
},
|
||||
),
|
||||
"cGain10X_ENUM": (
|
||||
EpicsSignal,
|
||||
{
|
||||
"read_pv": f"ES-KEITH{num}:getGain10X",
|
||||
"write_pv": f"ES-KEITH{num}:setGain10X",
|
||||
"kind": "config",
|
||||
"doc": f"Gain 10x of Keithley {num} -> IC{num-1}",
|
||||
},
|
||||
),
|
||||
"cFilterStatus_ENUM": (
|
||||
EpicsSignal,
|
||||
{
|
||||
"read_pv": f"ES-KEITH{num}:getFilter",
|
||||
"write_pv": f"ES-KEITH{num}:setFilter",
|
||||
"kind": "config",
|
||||
"doc": f"Filter Status of Keithley {num} -> IC{num-1}",
|
||||
},
|
||||
),
|
||||
"cFilter_ENUM": (
|
||||
EpicsSignal,
|
||||
{
|
||||
"read_pv": f"ES-KEITH{num}:getRiseTime",
|
||||
"write_pv": f"ES-KEITH{num}:setRiseTime",
|
||||
"kind": "config",
|
||||
"doc": f"Filter of Keithley {num} -> IC{num-1}",
|
||||
},
|
||||
),
|
||||
"cFilterAutoFilt_ENUM": (
|
||||
EpicsSignal,
|
||||
{
|
||||
"read_pv": f"ES-KEITH{num}:getAutoFilt",
|
||||
"write_pv": f"ES-KEITH{num}:setAutoFilt",
|
||||
"kind": "config",
|
||||
"doc": f"Filter Status of Keithley {num} -> IC{num-1}",
|
||||
},
|
||||
),
|
||||
"cZeroCheck_ENUM": (
|
||||
EpicsSignal,
|
||||
{
|
||||
"read_pv": f"ES-KEITH{num}:getZeroCheck",
|
||||
"write_pv": f"ES-KEITH{num}:setZeroCheck",
|
||||
"kind": "config",
|
||||
"doc": f"ZeroCheck of Keithley {num} -> IC{num-1}",
|
||||
},
|
||||
),
|
||||
"cBias_ENUM": (
|
||||
EpicsSignal,
|
||||
{
|
||||
"read_pv": f"ES-KEITH{num}:getBias",
|
||||
"write_pv": f"ES-KEITH{num}:setBias",
|
||||
"kind": "config",
|
||||
"doc": f"Bias of Keithley {num} -> IC{num-1}",
|
||||
},
|
||||
),
|
||||
"cSuppr_ENUM": (
|
||||
EpicsSignal,
|
||||
{
|
||||
"read_pv": f"ES-KEITH{num}:getSuppr",
|
||||
"write_pv": f"ES-KEITH{num}:setSuppr",
|
||||
"kind": "config",
|
||||
"doc": f"Suppression of Keithley {num} -> IC{num-1}",
|
||||
},
|
||||
),
|
||||
"cError_ENUM": (
|
||||
EpicsSignalRO,
|
||||
{
|
||||
"read_pv": f"ES-KEITH{num}:getError",
|
||||
"kind": "config",
|
||||
"doc": f"Error of Keithley {num} -> IC{num-1}",
|
||||
},
|
||||
),
|
||||
}
|
||||
amp = Dcpt(amp_signals)
|
||||
|
||||
|
||||
class IonizationChamber2(IonizationChamber0):
|
||||
"""Ionization Chamber 2, prefix should be 'X10DA-'."""
|
||||
|
||||
num = 3
|
||||
amp_signals = {
|
||||
"cGain_ENUM": (
|
||||
EpicsSignal,
|
||||
{
|
||||
"read_pv": f"ES-KEITH{num}:getGain",
|
||||
"write_pv": f"ES-KEITH{num}:setGain",
|
||||
"kind": "config",
|
||||
"doc": f"Gain of Keithley {num} -> IC{num-1}",
|
||||
},
|
||||
),
|
||||
"cGain10X_ENUM": (
|
||||
EpicsSignal,
|
||||
{
|
||||
"read_pv": f"ES-KEITH{num}:getGain10X",
|
||||
"write_pv": f"ES-KEITH{num}:setGain10X",
|
||||
"kind": "config",
|
||||
"doc": f"Gain 10x of Keithley {num} -> IC{num-1}",
|
||||
},
|
||||
),
|
||||
"cFilterStatus_ENUM": (
|
||||
EpicsSignal,
|
||||
{
|
||||
"read_pv": f"ES-KEITH{num}:getFilter",
|
||||
"write_pv": f"ES-KEITH{num}:setFilter",
|
||||
"kind": "config",
|
||||
"doc": f"Filter Status of Keithley {num} -> IC{num-1}",
|
||||
},
|
||||
),
|
||||
"cFilter_ENUM": (
|
||||
EpicsSignal,
|
||||
{
|
||||
"read_pv": f"ES-KEITH{num}:getRiseTime",
|
||||
"write_pv": f"ES-KEITH{num}:setRiseTime",
|
||||
"kind": "config",
|
||||
"doc": f"Filter of Keithley {num} -> IC{num-1}",
|
||||
},
|
||||
),
|
||||
"cFilterAutoFilt_ENUM": (
|
||||
EpicsSignal,
|
||||
{
|
||||
"read_pv": f"ES-KEITH{num}:getAutoFilt",
|
||||
"write_pv": f"ES-KEITH{num}:setAutoFilt",
|
||||
"kind": "config",
|
||||
"doc": f"Filter Status of Keithley {num} -> IC{num-1}",f"ES-KEITH{num}:
|
||||
},
|
||||
),
|
||||
"cZeroCheck_ENUM": (
|
||||
EpicsSignal,
|
||||
{
|
||||
"read_pv": f"ES-KEITH{num}:getZeroCheck",
|
||||
"write_pv": f"ES-KEITH{num}:setZeroCheck",
|
||||
"kind": "config",
|
||||
"doc": f"ZeroCheck of Keithley {num} -> IC{num-1}",
|
||||
},
|
||||
),
|
||||
"cBias_ENUM": (
|
||||
EpicsSignal,
|
||||
{
|
||||
"read_pv": f"ES-KEITH{num}:getBias",
|
||||
"write_pv": f"ES-KEITH{num}:setBias",
|
||||
"kind": "config",
|
||||
"doc": f"Bias of Keithley {num} -> IC{num-1}",
|
||||
},
|
||||
),
|
||||
"cSuppr_ENUM": (
|
||||
EpicsSignal,
|
||||
{
|
||||
"read_pv": f"ES-KEITH{num}:getSuppr",
|
||||
"write_pv": f"ES-KEITH{num}:setSuppr",
|
||||
"kind": "config",
|
||||
"doc": f"Suppression of Keithley {num} -> IC{num-1}",
|
||||
},
|
||||
),
|
||||
"cError_ENUM": (
|
||||
EpicsSignalRO,
|
||||
{
|
||||
"read_pv": f"ES-KEITH{num}:getError",
|
||||
"kind": "config",
|
||||
"doc": f"Error of Keithley {num} -> IC{num-1}",
|
||||
},
|
||||
),
|
||||
}
|
||||
amp = Dcpt(amp_signals)
|
||||
@@ -0,0 +1,101 @@
|
||||
import enum
|
||||
|
||||
|
||||
class AmplifierGain(int, enum.Enum):
|
||||
"""Enum class for the gain of the channel"""
|
||||
|
||||
G1E3 = 0
|
||||
G1E4 = 1
|
||||
G1E5 = 2
|
||||
G1E6 = 3
|
||||
G1E7 = 4
|
||||
G1E8 = 5
|
||||
G1E9 = 6
|
||||
G1E10 = 7
|
||||
|
||||
|
||||
GAIN_MAP = {
|
||||
1e3: AmplifierGain.G1E3,
|
||||
1e4: AmplifierGain.G1E4,
|
||||
1e5: AmplifierGain.G1E5,
|
||||
1e6: AmplifierGain.G1E6,
|
||||
1e7: AmplifierGain.G1E7,
|
||||
1e8: AmplifierGain.G1E8,
|
||||
1e9: AmplifierGain.G1E9,
|
||||
1e10: AmplifierGain.G1E10,
|
||||
}
|
||||
|
||||
|
||||
class AmplifierGain10X(int, enum.Enum):
|
||||
"""Enum class for the 10X gain selection"""
|
||||
|
||||
G1X = 0
|
||||
G10X = 1
|
||||
|
||||
|
||||
class AmplifierFilter(int, enum.Enum):
|
||||
"""Enum class for the filter of the channel"""
|
||||
|
||||
F10US = 0
|
||||
F30US = 1
|
||||
F100US = 2
|
||||
F300US = 3
|
||||
F1MS = 4
|
||||
F3MS = 5
|
||||
F10MS = 6
|
||||
F30MS = 7
|
||||
F100MS = 8
|
||||
F300MS = 9
|
||||
|
||||
|
||||
class AmplifierFilterStatus(int, enum.Enum):
|
||||
"""Enum class for the filter status"""
|
||||
|
||||
OFF = 0
|
||||
ON = 1
|
||||
|
||||
|
||||
class AmplifierFilterAutoFilt(int, enum.Enum):
|
||||
"""Enum class for the filter auto filt functionality"""
|
||||
|
||||
MANUAL = 0
|
||||
AUTO = 1
|
||||
|
||||
|
||||
class AmplifierZeroCheck(int, enum.Enum):
|
||||
"""Enum class for the zero check"""
|
||||
|
||||
OFF = 0
|
||||
ON = 1
|
||||
AUTO = 2
|
||||
|
||||
|
||||
class AmplifierBias(int, enum.Enum):
|
||||
"""Enum class for the bias"""
|
||||
|
||||
OFF = 0
|
||||
ON = 1
|
||||
|
||||
|
||||
class AmplifierSuppr(int, enum.Enum):
|
||||
"""Enum class for the suppression"""
|
||||
|
||||
OFF = 0
|
||||
ON = 1
|
||||
|
||||
|
||||
class AmplifierError(int, enum.Enum):
|
||||
"""Enum class for amplifier errors"""
|
||||
|
||||
OK = 0
|
||||
GAIN_CONFLICT = 1
|
||||
OVERLOAD = 2
|
||||
EEPROM_ERROR = 3
|
||||
ZEROCORR_FAILED = 4
|
||||
ZEROCHECK_ON = 5
|
||||
INPUT_TOO_LARGE = 6
|
||||
SUPPR_CONFLICT = 7
|
||||
SELFTEST_FAILED = 8
|
||||
NOT_IN_REMOTE = 9
|
||||
INVALID_OPTION = 10
|
||||
INVALID_COMMAND = 11
|
||||
Reference in new issue
Block a user