Source code for csaxs_bec.bec_ipython_client.plugins.cSAXS.diagnostics
from __future__ import annotations
import builtins
# ------------------------------------------------------------
# Access to dev (as before)
# ------------------------------------------------------------
if builtins.__dict__.get("dev") is not None:
dev = builtins.__dict__.get("dev")
# ------------------------------------------------------------
# Safe device access
# ------------------------------------------------------------
def _safe_dev(name):
try:
return getattr(dev, name)
except Exception:
return None
# ============================================================
# Base classes
# ============================================================
[docs]
class SingleSignalDiag:
"""Diagnostics for a single-signal device with gain control."""
def __init__(self, name, label, gain_dev, signal_dev):
self._name = name
self._label = label
self._gain = gain_dev
self._signal = signal_dev
def show_all(self):
print(self._label)
print("-" * len(self._label))
if self._gain is None or self._signal is None:
print("device not available in config\n")
return
try:
cfg = self._gain.get()
except Exception as e:
print(f"error accessing gain: {e}\n")
return
try:
val = self._signal.signal.get()
sval = f"{val:.4f}"
except Exception:
sval = "N/A"
print(f"gain : {cfg.gain:.0e}")
print(f"coupling : {cfg.coupling}")
print(f"speed : {cfg.speed}")
print(f"readback : {sval}")
print("")
print("hint:")
print(f" gain : csaxs.diagnostics.{self._name}.gain(1e5)")
print(f" raw : dev.{getattr(self._signal, 'name', '?')}.signal.get()")
print("")
def gain(self, value):
if self._gain is None:
print("gain device not available")
return
self._gain.set_gain(value)
[docs]
class MultiSignalDiag:
"""Diagnostics for multiple signals sharing one gain."""
def __init__(self, name, label, gain_dev, signal_devs: dict):
self._name = name
self._label = label
self._gain = gain_dev
self._signals = signal_devs # dict: label -> device
def show_all(self):
print(self._label)
print("-" * len(self._label))
if self._gain is None or any(v is None for v in self._signals.values()):
print("device not available in config\n")
return
try:
cfg = self._gain.get()
except Exception as e:
print(f"error accessing gain: {e}\n")
return
print(f"gain : {cfg.gain:.0e}")
print(f"coupling : {cfg.coupling}")
print(f"speed : {cfg.speed}")
print("readback:")
for key, sig in self._signals.items():
try:
val = sig.signal.get()
sval = f"{val:.4f}"
except Exception:
sval = "N/A"
print(f" {key:<10}: {sval}")
print("")
print("hint:")
print(f" gain : csaxs.diagnostics.{self._name}.gain(1e5)")
print("")
def gain(self, value):
if self._gain is None:
print("gain device not available")
return
self._gain.set_gain(value)
[docs]
class BPMDiag:
"""Diagnostics for a BPM device."""
def __init__(self, name, label, gain_dev, rb_dev):
self._name = name
self._label = label
self._gain = gain_dev
self._rb = rb_dev
def show_all(self):
print(self._label)
print("-" * len(self._label))
if self._gain is None or self._rb is None:
print("device not available in config\n")
return
try:
cfg = self._gain.get()
rb = self._rb.get()
except Exception as e:
print(f"error accessing device: {e}\n")
return
print(f"gain : {cfg.gain:.0e}")
print(f"coupling : {cfg.coupling}")
print(f"speed : {cfg.speed}")
print("readback:")
print(f" pos_x : {rb.pos_x:.3e}")
print(f" pos_y : {rb.pos_y:.3e}")
print(f" intensity : {rb.intensity:.3f}")
print("")
print("hint:")
print(f" gain : csaxs.diagnostics.{self._name}.gain(1e6)")
print(f" raw : dev.{getattr(self._rb, 'name', '?')}.pos_x.get()")
print("")
def gain(self, value):
if self._gain is None:
print("gain device not available")
return
self._gain.set_gain(value)
# ============================================================
# Diagnostics root (user-facing object)
# ============================================================
[docs]
class cSAXSDiagnostics:
"""User-visible diagnostics namespace."""
def __init__(self):
# BPMs
self.bpm_xbox1 = BPMDiag(
name="bpm_xbox1",
label="BPM XBox1 (OP hutch)",
gain_dev=_safe_dev("gain_bpm_xbox1"),
rb_dev=_safe_dev("bpm_xbox1_slowrb"),
)
self.bpm_xbox2 = BPMDiag(
name="bpm_xbox2",
label="BPM XBox2 (ES hutch)",
gain_dev=_safe_dev("gain_bpm_xbox2"),
rb_dev=_safe_dev("bpm_xbox2_slowrb"),
)
# Single-signal diagnostics
self.bim = SingleSignalDiag(
name="bim",
label="BIM XBox3 (ES)",
gain_dev=_safe_dev("gain_bim_xbox3"),
signal_dev=_safe_dev("bim_xbox3_slowrb"),
)
self.beamstop = SingleSignalDiag(
name="beamstop",
label="Beamstop diode (flight tube)",
gain_dev=_safe_dev("gain_beamstop_diode"),
signal_dev=_safe_dev("beamstop_intensity"),
)
# Multi-signal (fixed your diode issue)
self.polarization = MultiSignalDiag(
name="polarization",
label="Polarization diodes (XBox1)",
gain_dev=_safe_dev("gain_diodes_xbox1"),
signal_devs={
"horizontal": _safe_dev("diode_horizontal_xbox1_slowrb"),
"vertical": _safe_dev("diode_vertical_xbox1_slowrb"),
},
)
def show_all(self):
print("CSAXS diagnostics")
print("=================\n")
self.bpm_xbox1.show_all()
self.bpm_xbox2.show_all()
self.bim.show_all()
self.beamstop.show_all()
self.polarization.show_all()