X06da production 20260617t100740 #35
@@ -0,0 +1,130 @@
|
||||
bl_bright:
|
||||
description: Backlight Brightness
|
||||
deviceClass: ophyd.EpicsSignal
|
||||
deviceConfig: {read_pv: 'X06DA-ES-BL:SET', auto_monitor: true}
|
||||
onFailure: buffer
|
||||
enabled: True
|
||||
readoutPriority: baseline
|
||||
deviceTags:
|
||||
- state
|
||||
readOnly: False
|
||||
softwareTrigger: false
|
||||
userParameter: {"type": continuous, "on": 1.3, "off": 0, “tol”: 0.01}
|
||||
|
||||
bl_pos:
|
||||
description: Backlight Positioner
|
||||
deviceClass: ophyd.EpicsSignal
|
||||
deviceConfig: {read_pv: 'X06DA-ES-BL:POS-SET', auto_monitor: true}
|
||||
onFailure: buffer
|
||||
enabled: True
|
||||
readoutPriority: baseline
|
||||
deviceTags:
|
||||
- state
|
||||
readOnly: False
|
||||
softwareTrigger: false
|
||||
userParameter: {"type": discrete, "in": 1, "out": 0}
|
||||
|
||||
bs_pos:
|
||||
description: Beamstop Positioner
|
||||
deviceClass: ophyd.EpicsSignal
|
||||
deviceConfig: {read_pv: 'X06DA-ES-BS:POS-SET', auto_monitor: true}
|
||||
onFailure: buffer
|
||||
enabled: True
|
||||
readoutPriority: baseline
|
||||
deviceTags:
|
||||
- state
|
||||
readOnly: False
|
||||
softwareTrigger: false
|
||||
userParameter: {"type": discrete, "in": 1, "out": 0}
|
||||
|
||||
bs_z:
|
||||
description: Beamstop Z
|
||||
deviceClass: ophyd_devices.EpicsMotor
|
||||
deviceConfig: {prefix: 'X06DA-ES-BS:TRZ'}
|
||||
onFailure: buffer
|
||||
enabled: True
|
||||
readoutPriority: baseline
|
||||
deviceTags:
|
||||
- state
|
||||
readOnly: False
|
||||
softwareTrigger: false
|
||||
userParameter: {"type": continuous, "min": 13, "samp": 15, "work_min": 20, "safe": 25, "max_blin": 26, "max_blout": 35}
|
||||
|
||||
coll_y:
|
||||
description: Collimator Y
|
||||
deviceClass: ophyd_devices.EpicsMotor
|
||||
deviceConfig: {prefix: 'X06DA-ES-COL:TRY'}
|
||||
onFailure: buffer
|
||||
enabled: True
|
||||
readoutPriority: baseline
|
||||
deviceTags:
|
||||
- state
|
||||
readOnly: False
|
||||
softwareTrigger: false
|
||||
userParameter: {"type": continuous, "in": 25.42, "intermediate": 15, "out":5.0, "park": 0,"tol":0.05}
|
||||
|
||||
cryo_pos:
|
||||
description: Cryo Positioner
|
||||
deviceClass: ophyd.EpicsSignal
|
||||
deviceConfig: {read_pv: 'X06DA-ES-CS:POS-SET', auto_monitor: true}
|
||||
onFailure: buffer
|
||||
enabled: True
|
||||
readoutPriority: baseline
|
||||
deviceTags:
|
||||
- state
|
||||
readOnly: False
|
||||
softwareTrigger: false
|
||||
userParameter: {"type": discrete, "in": 1, "out": 0}
|
||||
|
||||
det_cov:
|
||||
description: Detector Cover
|
||||
deviceClass: ophyd.EpicsSignal
|
||||
deviceConfig: {read_pv: 'X06DA-ES-DETCOV:SET', auto_monitor: true}
|
||||
onFailure: buffer
|
||||
enabled: True
|
||||
readoutPriority: baseline
|
||||
deviceTags:
|
||||
- state
|
||||
readOnly: False
|
||||
softwareTrigger: false
|
||||
userParameter: {"type": discrete, "open": 2, "close": 1}
|
||||
|
||||
diag_y:
|
||||
description: Scintillator/diode Y
|
||||
deviceClass: ophyd_devices.EpicsMotor
|
||||
deviceConfig: {prefix: 'X06DA-ES-SCL:TRY'}
|
||||
onFailure: buffer
|
||||
enabled: True
|
||||
readoutPriority: baseline
|
||||
deviceTags:
|
||||
- state
|
||||
readOnly: False
|
||||
softwareTrigger: false
|
||||
userParameter: {"type": continuous, "scint": 22, "i1": 29, "out": 5.0,"park": 0,"tol":0.3}
|
||||
|
||||
fl_bright:
|
||||
description: Frontlight Brightness
|
||||
deviceClass: ophyd.EpicsSignal
|
||||
deviceConfig: {read_pv: 'X06DA-ES-FL:SET', auto_monitor: true}
|
||||
onFailure: buffer
|
||||
enabled: True
|
||||
readoutPriority: baseline
|
||||
deviceTags:
|
||||
- state
|
||||
readOnly: False
|
||||
softwareTrigger: false
|
||||
userParameter: {"type": continuous, "on": 3.0, "off": 0, “tol”: 0.01}
|
||||
|
||||
xrf_pos:
|
||||
description: XRF Positioner
|
||||
deviceClass: ophyd.EpicsSignal
|
||||
deviceConfig: {read_pv: 'X06DA-ES-XRF:POS-SET', auto_monitor: true}
|
||||
onFailure: buffer
|
||||
enabled: True
|
||||
readoutPriority: baseline
|
||||
deviceTags:
|
||||
- state
|
||||
readOnly: False
|
||||
softwareTrigger: false
|
||||
userParameter: {"type": discrete, "in": 1, "out": 0}
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
base_config:
|
||||
- !include ./pxiii-devices.yaml
|
||||
#states_config:
|
||||
# - !include ./pxiii-state-devices.yaml
|
||||
|
||||
smargon:
|
||||
description: REST-based device which connects to Smargopolo
|
||||
deviceClass: pxiii_bec.devices.smargopolo_smargon.Smargon
|
||||
deviceConfig: {prefix: 'http://x06da-smargopolo.psi.ch:3000'}
|
||||
onFailure: buffer
|
||||
enabled: True
|
||||
readoutPriority: baseline
|
||||
deviceTags:
|
||||
- smargon
|
||||
- motors
|
||||
readOnly: false
|
||||
softwareTrigger: false
|
||||
|
||||
aerotech:
|
||||
description: REST-based device which connects to AareScan and Aerotech
|
||||
deviceClass: pxiii_bec.devices.aerotech.Aerotech
|
||||
deviceConfig: {prefix: 'http://mx-x06da-queue-01:5234'}
|
||||
onFailure: buffer
|
||||
enabled: True
|
||||
readoutPriority: baseline
|
||||
deviceTags:
|
||||
- aerotech
|
||||
- motors
|
||||
readOnly: false
|
||||
softwareTrigger: false
|
||||
@@ -103,15 +103,17 @@ states:
|
||||
smargon_chi: mount
|
||||
smargon_phi: mount
|
||||
xrf_pos: out
|
||||
det_z: 'mse'
|
||||
|
||||
beam_visualisation:
|
||||
bl_pos: out
|
||||
bl_bright: 'off'
|
||||
bs_pos: in
|
||||
bs_z: safe
|
||||
coll_y: out
|
||||
coll_y: in
|
||||
cryo_pos: out
|
||||
det_cov: 'close'
|
||||
det_z: 'vis'
|
||||
diag_y: scint
|
||||
fl_bright: 'off'
|
||||
aerotech_x: out
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -9,7 +9,7 @@ bl_bright:
|
||||
- state
|
||||
readOnly: False
|
||||
softwareTrigger: false
|
||||
userParameter: {"type": continuous, "on": 1.3, "off": 0, “tol”: 0.01}
|
||||
userParameter: {"type": continuous, "on": 1.56, "off": 0, “tol”: 0.01}
|
||||
|
||||
bl_pos:
|
||||
description: Backlight Positioner
|
||||
|
||||
@@ -1,30 +1,5 @@
|
||||
base_config:
|
||||
- !include ./pxiii-standard-devices.yaml
|
||||
states_config:
|
||||
- !include ./pxiii-state-devices.yaml
|
||||
- !include ./pxiii-devices.yaml
|
||||
#states_config:
|
||||
# - !include ./pxiii-state-devices.yaml
|
||||
|
||||
smargon:
|
||||
description: REST-based device which connects to Smargopolo
|
||||
deviceClass: pxiii_bec.devices.smargopolo_smargon.Smargon
|
||||
deviceConfig: {prefix: 'http://x06da-smargopolo.psi.ch:3000'}
|
||||
onFailure: buffer
|
||||
enabled: True
|
||||
readoutPriority: baseline
|
||||
deviceTags:
|
||||
- smargon
|
||||
- motors
|
||||
readOnly: false
|
||||
softwareTrigger: false
|
||||
|
||||
aerotech:
|
||||
description: REST-based device which connects to AareScan and Aerotech
|
||||
deviceClass: pxiii_bec.devices.aerotech.Aerotech
|
||||
deviceConfig: {prefix: 'http://mx-x06da-queue-01:5234'}
|
||||
onFailure: buffer
|
||||
enabled: True
|
||||
readoutPriority: baseline
|
||||
deviceTags:
|
||||
- aerotech
|
||||
- motors
|
||||
readOnly: false
|
||||
softwareTrigger: false
|
||||
|
||||
@@ -1,7 +1,32 @@
|
||||
"""Planner to move between beamline statesΩ"""
|
||||
"""Planner to move between beamline states"""
|
||||
|
||||
import time
|
||||
from collections import defaultdict, deque
|
||||
from enum import Enum
|
||||
|
||||
# from enums import BeamlineState, TemperatureMode
|
||||
# from matcher import DeviceMatcher, nonzero_is_on
|
||||
|
||||
|
||||
class BeamlineState(str, Enum):
|
||||
"""List of beamline states"""
|
||||
|
||||
ROBOT_SAMPLE_EXCHANGE = "robot_sample_exchange"
|
||||
SAMPLE_ALIGNMENT = "sample_alignment"
|
||||
DATA_COLLECTION = "data_collection"
|
||||
DC_XRF = "DC_XRF"
|
||||
MANUAL_SAMPLE_EXCHANGE = "manual_sample_exchange"
|
||||
BEAM_VISUALISATION = "beam_visualisation"
|
||||
FLUX_MEASUREMENT = "flux_measurement"
|
||||
BEAMSTOP_ALIGNMENT = "beamstop_alignment"
|
||||
MAINTENANCE = "maintenance"
|
||||
XTAL_SNAPSHOT = "xtal_snapshot"
|
||||
|
||||
|
||||
class TemperatureMode(str, Enum):
|
||||
"""List of temperature modes"""
|
||||
|
||||
CRYO = "cryo"
|
||||
ROOM_TEMP = "room_temp"
|
||||
|
||||
|
||||
class StateChangePlanner:
|
||||
@@ -37,7 +62,6 @@ class StateChangePlanner:
|
||||
target.update(self.modifiers[modifier])
|
||||
return target
|
||||
|
||||
|
||||
def move_to(self, state_name, modifier=None):
|
||||
"""Move devices to the correct positions to achieve a given state"""
|
||||
if isinstance(state_name, str):
|
||||
@@ -71,20 +95,81 @@ class StateChangePlanner:
|
||||
def available_states(self):
|
||||
"""Return a list of available states"""
|
||||
return list(self.states.keys())
|
||||
|
||||
def state_devices(self):
|
||||
"""Return the set of devices that participate in
|
||||
beamline state definitions"""
|
||||
|
||||
devices = set()
|
||||
|
||||
for state in self.states.values():
|
||||
devices.update(state.keys())
|
||||
|
||||
return sorted(devices)
|
||||
|
||||
def get_positions(self):
|
||||
"""Return current positions of all SE devices"""
|
||||
return {name: dev.pos for name, dev in self.devices.items()}
|
||||
"""Return current positions of devices that are used
|
||||
in state transitions"""
|
||||
return {name: self.devices[name].pos
|
||||
for name in self.state_devices()}
|
||||
|
||||
def print_positions(self):
|
||||
"""Return current state of all devices"""
|
||||
for name, device in self.devices.items():
|
||||
print(f"{name:10s} : {device.pos:10s} value: {device.actual}")
|
||||
for name in self.state_devices():
|
||||
device = self.devices[name]
|
||||
|
||||
print(f"{name:10s} : {device.pos:10s} value: {device.actual:.5g}")
|
||||
|
||||
def diff_states(self, before):
|
||||
"""Return a dict of {device: (before, after)} pairs for devices that changed state"""
|
||||
after = self.get_positions()
|
||||
return {k: (before[k], after[k]) for k in before if before[k] != after[k]}
|
||||
|
||||
def __get_closest_states(self):
|
||||
"""
|
||||
Return states ordered by number of mismatches.
|
||||
"""
|
||||
|
||||
results = []
|
||||
|
||||
for state in self.states:
|
||||
|
||||
config = self._merged_state(state, None)
|
||||
|
||||
mismatches = []
|
||||
|
||||
for dev, expected in config.items():
|
||||
|
||||
if not self.devices[dev].is_at(expected):
|
||||
mismatches.append(
|
||||
(
|
||||
dev,
|
||||
self.devices[dev].pos,
|
||||
expected,
|
||||
)
|
||||
)
|
||||
|
||||
results.append(
|
||||
(
|
||||
state.name,
|
||||
len(mismatches),
|
||||
mismatches,
|
||||
)
|
||||
)
|
||||
|
||||
return sorted(results, key=lambda x: x[1])
|
||||
|
||||
def closest_states(self, n=5):
|
||||
|
||||
for state, count, mismatches in self.__get_closest_states()[:n]:
|
||||
|
||||
print(f"\n{state}: {count} mismatch(es)")
|
||||
|
||||
for dev, actual, expected in mismatches:
|
||||
print(
|
||||
f" {dev:15s} "
|
||||
f"{actual:10s} -> {expected}"
|
||||
)
|
||||
|
||||
def current_state(self):
|
||||
"""Return all current matching BeamlineState and TemperatureMode combinations,
|
||||
@@ -102,12 +187,8 @@ class StateChangePlanner:
|
||||
config = self._merged_state(state, modifier)
|
||||
|
||||
# Check if all devices match their expected positions
|
||||
if all(self.devices[d].is_at(p)
|
||||
for d, p in config.items()
|
||||
if d not in ignore_keys
|
||||
):
|
||||
# print(f"Current state: {state.name}, Modifier: {modifier.name if modifier else 'None'}")
|
||||
matches.append((state.name, modifier.name if modifier else 'None'))
|
||||
if all(self.devices[d].is_at(p) for d, p in config.items() if d not in ignore_keys):
|
||||
matches.append((state.name, modifier.name if modifier else "None"))
|
||||
|
||||
return matches if matches else None
|
||||
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
def beampos_with_en(planner):
|
||||
deltat = 5
|
||||
bl_energy(6000)
|
||||
record_beampos_until("23:30",planner,interval_minutes=deltat)
|
||||
bl_energy(8000)
|
||||
record_beampos_until("01:00",planner,interval_minutes=deltat)
|
||||
bl_energy(10000)
|
||||
record_beampos_until("03:00",planner,interval_minutes=deltat)
|
||||
bl_energy(12400)
|
||||
record_beampos_until("05:00",planner,interval_minutes=deltat)
|
||||
bl_energy(14000)
|
||||
record_beampos_until("07:00",planner,interval_minutes=deltat)
|
||||
|
||||
@@ -1,14 +1,15 @@
|
||||
""" Build the sample environment devices"""
|
||||
"""Build the sample environment devices"""
|
||||
|
||||
import os
|
||||
import yaml
|
||||
|
||||
# from position_device import PositionDevice
|
||||
|
||||
def motor_resolver(bec_name):
|
||||
|
||||
candidates = [
|
||||
bec_name,
|
||||
bec_name.replace("_", "."),
|
||||
]
|
||||
def motor_resolver(bec_name):
|
||||
"""Used to handle aerotech and smargon motors"""
|
||||
|
||||
candidates = [bec_name, bec_name.replace("_", ".")]
|
||||
|
||||
for path in candidates:
|
||||
try:
|
||||
@@ -24,9 +25,9 @@ def motor_resolver(bec_name):
|
||||
|
||||
raise ValueError(f"Cannot resolve motor for '{bec_name}'")
|
||||
|
||||
def build_devices(yaml_file, mock_devices):
|
||||
""" Build devices from the beamline states yaml"""
|
||||
|
||||
def build_devices(yaml_file, mock_devices):
|
||||
"""Build devices from the beamline states yaml"""
|
||||
|
||||
state_devices = {}
|
||||
|
||||
@@ -41,30 +42,321 @@ def build_devices(yaml_file, mock_devices):
|
||||
if not user:
|
||||
continue
|
||||
|
||||
if bec_name in ("aerotech", "smargon"):
|
||||
|
||||
tol = user.get("tol", 0.1)
|
||||
tol = user.get("tol", 0.01)
|
||||
|
||||
positions = {
|
||||
k: v for k, v in user.items()
|
||||
if k not in ("type", "tol")
|
||||
}
|
||||
for axis in ["x", "y", "z", "u", "chi", "phi"]:
|
||||
|
||||
allow_arbitrary = (user["type"] == "continuous")
|
||||
|
||||
|
||||
positions = user.get(axis)
|
||||
|
||||
pos_dev = PositionDevice(
|
||||
bec_name=bec_name,
|
||||
mot_device = motor_resolver(bec_name),
|
||||
positions=positions,
|
||||
tol=tol,
|
||||
allow_arbitrary=allow_arbitrary,
|
||||
use_mock=bec_name in mock_devices,
|
||||
)
|
||||
if positions is None:
|
||||
continue
|
||||
|
||||
component_name = f"{bec_name}_{axis}"
|
||||
|
||||
pos_dev = PositionDevice(
|
||||
bec_name=component_name,
|
||||
mot_device=motor_resolver(component_name),
|
||||
positions=positions,
|
||||
tol=tol,
|
||||
allow_arbitrary=True,
|
||||
use_mock=component_name in mock_devices,
|
||||
)
|
||||
|
||||
state_devices[component_name] = pos_dev
|
||||
|
||||
else:
|
||||
|
||||
tol = user.get("tol", 0.1)
|
||||
allow_arbitrary = user.get("type") == "continuous"
|
||||
|
||||
positions = {k: v for k, v in user.items() if k not in ("type", "tol")}
|
||||
|
||||
pos_dev = PositionDevice(
|
||||
bec_name=bec_name,
|
||||
mot_device=motor_resolver(bec_name),
|
||||
positions=positions,
|
||||
tol=tol,
|
||||
allow_arbitrary=allow_arbitrary,
|
||||
use_mock=bec_name in mock_devices,
|
||||
)
|
||||
|
||||
state_devices[bec_name] = pos_dev
|
||||
|
||||
state_devices[bec_name] = pos_dev
|
||||
return state_devices
|
||||
|
||||
|
||||
|
||||
def update_position(
|
||||
device,
|
||||
position,
|
||||
value,
|
||||
axis=None,
|
||||
force=False,
|
||||
max_delta=0.5,
|
||||
):
|
||||
"""
|
||||
Update a single saved position in memory.
|
||||
|
||||
Does NOT save or reload. Use save_and_reload() or
|
||||
update_positions() afterwards.
|
||||
"""
|
||||
|
||||
params = device.user_parameter
|
||||
|
||||
# ------------------------------------------------------------------
|
||||
# Nested device (e.g. aerotech.x.in)
|
||||
# ------------------------------------------------------------------
|
||||
if axis is not None:
|
||||
|
||||
if axis not in params:
|
||||
raise KeyError(
|
||||
f"Unknown axis '{axis}'. "
|
||||
f"Valid axes: {list(params.keys())}"
|
||||
)
|
||||
|
||||
axis_params = params[axis].copy()
|
||||
|
||||
if position not in axis_params:
|
||||
raise KeyError(
|
||||
f"Unknown position '{position}'. "
|
||||
f"Valid positions: {list(axis_params.keys())}"
|
||||
)
|
||||
|
||||
old_value = axis_params[position]
|
||||
|
||||
delta = abs(value - old_value)
|
||||
|
||||
if delta > max_delta and not force:
|
||||
raise ValueError(
|
||||
f"Refusing to change "
|
||||
f"{device.name}.{axis}.{position} "
|
||||
f"from {old_value} to {value} "
|
||||
f"(Δ={delta:.3f} > {max_delta}). "
|
||||
f"Use force=True if intentional."
|
||||
)
|
||||
|
||||
axis_params[position] = value
|
||||
|
||||
device.update_user_parameter(
|
||||
{axis: axis_params}
|
||||
)
|
||||
|
||||
print(
|
||||
f"Updated {device.name}.{axis}.{position}: "
|
||||
f"{old_value} -> {value}"
|
||||
)
|
||||
|
||||
return
|
||||
|
||||
# ------------------------------------------------------------------
|
||||
# Flat device (e.g. bs_z)
|
||||
# ------------------------------------------------------------------
|
||||
nested_keys = [
|
||||
k for k, v in params.items()
|
||||
if isinstance(v, dict)
|
||||
]
|
||||
|
||||
if nested_keys:
|
||||
raise ValueError(
|
||||
f"{device.name} has nested parameters "
|
||||
f"({nested_keys}); specify axis=..."
|
||||
)
|
||||
|
||||
if position not in params:
|
||||
raise KeyError(
|
||||
f"Unknown position '{position}'. "
|
||||
f"Valid positions: {list(params.keys())}"
|
||||
)
|
||||
|
||||
old_value = params[position]
|
||||
|
||||
delta = abs(value - old_value)
|
||||
|
||||
if delta > max_delta and not force:
|
||||
raise ValueError(
|
||||
f"Refusing to change "
|
||||
f"{device.name}.{position} "
|
||||
f"from {old_value} to {value} "
|
||||
f"(Δ={delta:.3f} > {max_delta}). "
|
||||
f"Use force=True if intentional."
|
||||
)
|
||||
|
||||
device.update_user_parameter(
|
||||
{position: value}
|
||||
)
|
||||
|
||||
print(
|
||||
f"Updated {device.name}.{position}: "
|
||||
f"{old_value} -> {value}"
|
||||
)
|
||||
|
||||
|
||||
def save_and_reload():
|
||||
"""
|
||||
Save current configuration to YAML and rebuild
|
||||
the beamline environment.
|
||||
"""
|
||||
|
||||
beamline = os.environ["BEAMLINE"]
|
||||
|
||||
env = Environment(beamline=beamline)
|
||||
|
||||
print(f"(saving changes to {env.devices_file})")
|
||||
|
||||
bec.config.save_current_session(env.devices_file)
|
||||
|
||||
return init_beamline_environment()
|
||||
|
||||
|
||||
def update_positions(updates):
|
||||
"""
|
||||
Apply many updates, then save and reload once.
|
||||
|
||||
updates = [
|
||||
{
|
||||
"device": dev.aerotech,
|
||||
"axis": "x",
|
||||
"position": "in",
|
||||
"value": 0,
|
||||
},
|
||||
{
|
||||
"device": dev.bs_z,
|
||||
"position": "max_blout",
|
||||
"value": 68,
|
||||
},
|
||||
]
|
||||
"""
|
||||
|
||||
for update in updates:
|
||||
|
||||
update_position(
|
||||
device=update["device"],
|
||||
position=update["position"],
|
||||
value=update["value"],
|
||||
axis=update.get("axis"),
|
||||
force=update.get("force", False),
|
||||
max_delta=update.get("max_delta", 0.5),
|
||||
)
|
||||
|
||||
return save_and_reload()
|
||||
|
||||
|
||||
def save_current_position(
|
||||
device,
|
||||
position,
|
||||
axis=None,
|
||||
force=False,
|
||||
max_delta=0.5,
|
||||
):
|
||||
"""
|
||||
Save the current motor position as a named position.
|
||||
"""
|
||||
print(f"Saving current postion for {device}")
|
||||
|
||||
params = device.user_parameter
|
||||
|
||||
if axis is not None:
|
||||
|
||||
if axis not in params:
|
||||
raise KeyError(
|
||||
f"Unknown axis '{axis}'. "
|
||||
f"Valid axes: {list(params.keys())}"
|
||||
)
|
||||
|
||||
axis_params = params[axis].copy()
|
||||
|
||||
if position not in axis_params:
|
||||
raise KeyError(
|
||||
f"Unknown position '{position}'. "
|
||||
f"Valid positions: {list(axis_params.keys())}"
|
||||
)
|
||||
|
||||
old_value = axis_params[position]
|
||||
print(f"Old value is {old_value}")
|
||||
|
||||
current_value = get_current_value(device, axis=None)
|
||||
|
||||
delta = abs(current_value - old_value)
|
||||
|
||||
if delta > max_delta and not force:
|
||||
raise ValueError(
|
||||
f"Current position differs from saved value:\n"
|
||||
f" saved = {old_value}\n"
|
||||
f" current = {current_value}\n"
|
||||
f" delta = {delta:.3f}\n"
|
||||
f"Use force=True if intentional."
|
||||
)
|
||||
|
||||
axis_params[position] = current_value
|
||||
|
||||
device.update_user_parameter(
|
||||
{axis: axis_params}
|
||||
)
|
||||
|
||||
print(
|
||||
f"Updated {device.name}.{axis}.{position}: "
|
||||
f"{old_value} -> {current_value}"
|
||||
)
|
||||
|
||||
return
|
||||
# ------------------------------------------------------------------
|
||||
# Flat device (e.g. bs_z)
|
||||
# ------------------------------------------------------------------
|
||||
nested_keys = [
|
||||
k for k, v in params.items()
|
||||
if isinstance(v, dict)
|
||||
]
|
||||
|
||||
if nested_keys:
|
||||
raise ValueError(
|
||||
f"{device.name} has nested parameters "
|
||||
f"({nested_keys}); specify axis=..."
|
||||
)
|
||||
|
||||
if position not in params:
|
||||
raise KeyError(
|
||||
f"Unknown position '{position}'. "
|
||||
f"Valid positions: {list(params.keys())}"
|
||||
)
|
||||
|
||||
old_value = params[position]
|
||||
current_value = get_current_value(device, axis=None)
|
||||
|
||||
delta = abs(current_value - old_value)
|
||||
|
||||
if delta > max_delta and not force:
|
||||
raise ValueError(
|
||||
f"Refusing to change "
|
||||
f"{device.name}.{position} "
|
||||
f"from {old_value} to {current_value} "
|
||||
f"(Δ={delta:.3f} > {max_delta}). "
|
||||
f"Use force=True if intentional."
|
||||
)
|
||||
|
||||
device.update_user_parameter(
|
||||
{position: current_value}
|
||||
)
|
||||
|
||||
print(
|
||||
f"Updated {device.name}.{position}: "
|
||||
f"{old_value} -> {current_value}"
|
||||
)
|
||||
|
||||
|
||||
def get_current_value(device, axis=None):
|
||||
"""
|
||||
Return current motor position.
|
||||
"""
|
||||
|
||||
if axis is not None:
|
||||
motor = getattr(device, axis)
|
||||
else:
|
||||
motor = device
|
||||
|
||||
data = motor.read()
|
||||
|
||||
signal_name = next(iter(data))
|
||||
|
||||
return round(data[signal_name]["value"],3)
|
||||
@@ -0,0 +1,24 @@
|
||||
from datetime import datetime
|
||||
|
||||
def generate_dccm_lut(start_energy=5000, end_energy=14000, step=1000):
|
||||
"""Generate a lookup table for the dcm from start_energy to end_energy in steps of step"""
|
||||
now = datetime.now()
|
||||
fnow = now.strftime("%d%m%H%M")
|
||||
filename = f"luts/{fnow}_lut.csv"
|
||||
with open(filename, "w", encoding="utf-8") as f:
|
||||
# f.write("energy,pitch,roll,perp,ss_xicam_x,ss_xicam_y\n")
|
||||
f.write("energy, pitch\n")
|
||||
|
||||
for energy in range(start_energy, end_energy, step):
|
||||
print(f"Moving to {energy: .0f}eV")
|
||||
bl_energy(energy)
|
||||
pitch = EnergyDefaults.mono_pitch.position
|
||||
# auto_exposure(cam="ss_xicam", max_iter=25)
|
||||
# x = dev.ss_xicam_x.read()["ss_xicam_x"]["value"]
|
||||
# y = dev.ss_xicam_y.read()["ss_xicam_y"]["value"]
|
||||
with open(filename, "a", encoding="utf-8") as f:
|
||||
f.write(
|
||||
# f"{energy:.0f},{pitch:.5g},,{x:.4g},{y:.4g}\n"
|
||||
(f"{energy:.0f},{pitch:.7g}\n")
|
||||
)
|
||||
bl_energy(13000)
|
||||
@@ -1,30 +1,14 @@
|
||||
"""Planner dependencies"""
|
||||
|
||||
|
||||
def planner_deps():
|
||||
"""Define the dependencies between beamline positions"""
|
||||
return {
|
||||
("bs_z", "samp"): [
|
||||
("aerotech_x", "out"),
|
||||
("diag_y", "out"),
|
||||
("coll_y", "out"),
|
||||
],
|
||||
("aerotech_x", "in"): [
|
||||
("diag_y", "out"),
|
||||
("bs_z", "safe"),
|
||||
],
|
||||
("aerotech_x", "out"): [
|
||||
("diag_y", "out"),
|
||||
("bs_z", "safe"),
|
||||
],
|
||||
("diag_y", "scint"): [
|
||||
("aerotech_x", "out"),
|
||||
("bs_z", "safe"),
|
||||
("cryo_pos", "out"),
|
||||
],
|
||||
("diag_y", "i1"): [
|
||||
("aerotech_x", "out"),
|
||||
("bs_z", "safe"),
|
||||
("cryo_pos", "out"),
|
||||
],
|
||||
("bs_z", "samp"): [("aerotech_x", "out"), ("diag_y", "out"), ("coll_y", "out")],
|
||||
("aerotech_x", "in"): [("diag_y", "out"), ("bs_z", "safe")],
|
||||
("aerotech_x", "out"): [("diag_y", "out"), ("bs_z", "safe")],
|
||||
("diag_y", "scint"): [("aerotech_x", "out"), ("bs_z", "safe"), ("cryo_pos", "out")],
|
||||
("diag_y", "i1"): [("aerotech_x", "out"), ("bs_z", "safe"), ("cryo_pos", "out")],
|
||||
("bs_pos", "out"): [("bs_z", "safe")],
|
||||
("bs_pos", "in"): [("bs_z", "safe")],
|
||||
("diag_y", "out"): [("bs_z", "safe")],
|
||||
|
||||
@@ -1,22 +1,23 @@
|
||||
"""
|
||||
This module manages the initialization of devices."""
|
||||
|
||||
# from guards import attach_guards
|
||||
# from policies import attach_policies
|
||||
# from build_devices import build_devices
|
||||
#from guards import attach_guards
|
||||
#from policies import attach_policies
|
||||
#from build_devices import build_devices
|
||||
|
||||
|
||||
class DeviceManager:
|
||||
"""Class for building devices and attaching safety guards and policies."""
|
||||
|
||||
@staticmethod
|
||||
def initialize_devices(state_devices_file, rest_devices_file, mock_devices):
|
||||
# def initialize_devices(state_devices_file, rest_devices_file, mock_devices):
|
||||
def initialize_devices(devices_file, mock_devices):
|
||||
"""
|
||||
Initializes sample environment devices from the specified file.
|
||||
"""
|
||||
devices = build_devices(state_devices_file, mock_devices)
|
||||
rest_devices = build_devices(rest_devices_file, mock_devices)
|
||||
devices.update(rest_devices)
|
||||
devices = build_devices(devices_file, mock_devices)
|
||||
# rest_devices = build_devices(rest_devices_file, mock_devices)
|
||||
# devices.update(rest_devices)
|
||||
attach_guards(devices)
|
||||
attach_policies(devices)
|
||||
return devices
|
||||
|
||||
@@ -15,9 +15,7 @@ class AtPositionGuard:
|
||||
def check(self):
|
||||
"""Check if the device is in the specified position."""
|
||||
if self.device.pos != self.pos:
|
||||
raise GuardViolation(
|
||||
f"{self.device.bec_name} must be in the '{self.pos}' position"
|
||||
)
|
||||
raise GuardViolation(f"{self.device.bec_name} must be in the '{self.pos}' position")
|
||||
# print("move allowed")
|
||||
return True
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@ from dataclasses import dataclass
|
||||
# from dependencies import planner_deps
|
||||
# from beamline_planner import StateChangePlanner
|
||||
|
||||
|
||||
@dataclass
|
||||
class Environment:
|
||||
|
||||
@@ -21,18 +22,16 @@ class Environment:
|
||||
# "rest": "pxi-rest-devices.yaml",
|
||||
# "states": "pxi-beamline-states.yaml",
|
||||
# },
|
||||
"x10sa" : {
|
||||
"x10sa": {
|
||||
"devdir": "/sls/x10sa/config/bec/production/pxii_bec/pxii_bec/device_configs/",
|
||||
"state": "pxii-state-devices.yaml",
|
||||
"rest": "pxii-rest-devices.yaml",
|
||||
"devices": "pxii-devices.yaml",
|
||||
"states": "pxii-beamline-states.yaml",
|
||||
},
|
||||
"x06da" : {
|
||||
"x06da": {
|
||||
"devdir": "/sls/x06da/config/bec/production/pxiii_bec/pxiii_bec/device_configs/",
|
||||
"state": "pxiii-state-devices.yaml",
|
||||
"rest": "pxiii-rest-devices.yaml",
|
||||
"devices": "pxiii-devices.yaml",
|
||||
"states": "pxiii-beamline-states.yaml",
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
def __post_init__(self):
|
||||
@@ -60,34 +59,23 @@ class Environment:
|
||||
"xrf_pos": "mock",
|
||||
}
|
||||
|
||||
mocks = sorted(
|
||||
name
|
||||
for name, backend in self.device_mocks.items()
|
||||
if backend == "mock"
|
||||
)
|
||||
mocks = sorted(name for name, backend in self.device_mocks.items() if backend == "mock")
|
||||
|
||||
reals = sorted(
|
||||
name
|
||||
for name, backend in self.device_mocks.items()
|
||||
if backend == "real"
|
||||
)
|
||||
reals = sorted(name for name, backend in self.device_mocks.items() if backend == "real")
|
||||
|
||||
print(f"Mock devices ({len(mocks)}): {mocks}")
|
||||
print(f"Real devices ({len(reals)}): {reals}")
|
||||
# print(f"Mock devices ({len(mocks)}): {mocks}")
|
||||
# print(f"Real devices ({len(reals)}): {reals}")
|
||||
|
||||
try:
|
||||
cfg = self.beamline_configs[self.beamline]
|
||||
except KeyError:
|
||||
raise ValueError(
|
||||
f"Unknown beamline '{self.beamline}'"
|
||||
)
|
||||
raise ValueError(f"Unknown beamline '{self.beamline}'")
|
||||
|
||||
devdir = cfg["devdir"]
|
||||
|
||||
self.state_devices_file = devdir + cfg["state"]
|
||||
self.rest_devices_file = devdir + cfg["rest"]
|
||||
self.devices_file = devdir + cfg["devices"]
|
||||
self.states_file = devdir + cfg["states"]
|
||||
|
||||
|
||||
mock_start_positions = {
|
||||
"aerotech_x": "in",
|
||||
"aerotech_y": "mount",
|
||||
@@ -107,7 +95,7 @@ class Environment:
|
||||
"smargon_z": "mount",
|
||||
"smargon_chi": "mount",
|
||||
"smargon_phi": "mount",
|
||||
"xrf_pos": "out",
|
||||
"xrf_pos": "out",
|
||||
}
|
||||
|
||||
@property
|
||||
@@ -116,7 +104,8 @@ class Environment:
|
||||
for name, device in self.device_mocks.items():
|
||||
if device == "mock":
|
||||
mock_names.add(name)
|
||||
return mock_names
|
||||
return mock_names
|
||||
|
||||
|
||||
def init_beamline_environment():
|
||||
"""
|
||||
@@ -125,15 +114,11 @@ def init_beamline_environment():
|
||||
|
||||
beamline = os.environ["BEAMLINE"]
|
||||
|
||||
env = Environment(beamline = beamline)
|
||||
env = Environment(beamline=beamline)
|
||||
|
||||
# Initialize devices
|
||||
device_manager = DeviceManager()
|
||||
devices = device_manager.initialize_devices(
|
||||
env.state_devices_file,
|
||||
env.rest_devices_file,
|
||||
env.mock_devices
|
||||
)
|
||||
devices = device_manager.initialize_devices(env.devices_file, env.mock_devices)
|
||||
|
||||
# Initialize states
|
||||
state_manager = DefineStatesManager()
|
||||
@@ -144,7 +129,7 @@ def init_beamline_environment():
|
||||
|
||||
# Setup planner
|
||||
planner = StateChangePlanner(devices, states, allow_modifiers, deps)
|
||||
print("Initializing beamline state planner")
|
||||
print("Initializing beamline state planner and devices")
|
||||
|
||||
# Set mock motor starting positions
|
||||
|
||||
@@ -155,9 +140,4 @@ def init_beamline_environment():
|
||||
except Exception as e:
|
||||
print(f"{e} error when setting {mock_dev}")
|
||||
|
||||
|
||||
return devices, planner
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Executable
+1538
File diff suppressed because it is too large
Load Diff
Executable
+1536
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,10 @@
|
||||
energy, pitch
|
||||
5000,23.29268,23.2913
|
||||
6000,19.24199,19.2387
|
||||
7000,16.40998,16.4054
|
||||
8000,14.31298,14.3076
|
||||
9000,12.69568,12.6896
|
||||
10000,11.40928,11.4026
|
||||
11000,10.36128,10.3540
|
||||
12000,9.49058,9.48285
|
||||
13000,8.75558,8.7474
|
||||
|
@@ -0,0 +1,119 @@
|
||||
Beam size: 25 x 20, Energy: 13001 eV, Zoom: 1000.0
|
||||
Time,Scin_x,Scin_y
|
||||
20:01:35, 1060.6, 1049
|
||||
20:06:37, 1046.3, 1046
|
||||
20:11:40, 1058.1, 1047
|
||||
20:16:42, 1067.3, 1050
|
||||
20:21:45, 1053.8, 1040
|
||||
20:26:48, 1061, 1040
|
||||
20:31:50, 1065.3, 1040
|
||||
20:36:53, 1056, 1044
|
||||
20:41:56, 1074.8, 1044
|
||||
20:46:59, 1054.1, 1040
|
||||
20:52:01, 1046.7, 1055
|
||||
20:57:04, 1066.2, 1045
|
||||
21:02:07, 1049.9, 1050
|
||||
21:04:24, 1038.8, 1034
|
||||
21:09:26, 1053.5, 1043
|
||||
21:14:29, 1055.6, 1051
|
||||
21:19:31, 1064.2, 1041
|
||||
21:24:34, 1061.8, 1050
|
||||
21:29:37, 1056.8, 1043
|
||||
22:57:13, 1101.8, 1095
|
||||
23:02:16, 1103.3, 1096
|
||||
23:07:18, 1105.2, 1098
|
||||
23:12:21, 1102.5, 1098
|
||||
23:17:24, 1103.8, 1100
|
||||
23:22:28, 1100.6, 1100
|
||||
23:27:31, 1105.2, 1100
|
||||
23:30:46, 1079.4, 1068
|
||||
23:35:49, 1096.5, 1074
|
||||
23:40:51, 1070.1, 1075
|
||||
23:45:54, 1090.1, 1074
|
||||
23:50:57, 1088.5, 1080
|
||||
23:55:59, 1077.1, 1076
|
||||
00:01:05, 998.88, 1037
|
||||
00:06:12, 1073.2, 1076
|
||||
00:11:17, 1092.3, 1078
|
||||
00:16:20, 1075, 1073
|
||||
00:21:23, 1095.1, 1071
|
||||
00:26:25, 1083.9, 1069
|
||||
00:31:28, 1082.9, 1071
|
||||
00:36:30, 1083.6, 1073
|
||||
00:41:33, 1081.8, 1067
|
||||
00:46:36, 1084.7, 1066
|
||||
00:51:39, 1087.1, 1068
|
||||
00:56:41, 1083.2, 1066
|
||||
00:59:13, 1057.8, 1053
|
||||
01:04:15, 1076.4, 1062
|
||||
01:09:18, 1082.5, 1064
|
||||
01:14:21, 1080.3, 1063
|
||||
01:19:23, 1069.3, 1044
|
||||
01:24:26, 1080.9, 1067
|
||||
01:29:29, 1075.5, 1068
|
||||
01:34:31, 1061.9, 1058
|
||||
01:39:34, 1079.6, 1048
|
||||
01:44:36, 1079.6, 1069
|
||||
01:49:39, 1077.9, 1056
|
||||
01:54:42, 1083.5, 1060
|
||||
01:59:44, 1056.3, 1045
|
||||
02:04:47, 1083.9, 1057
|
||||
02:09:50, 1076.5, 1059
|
||||
02:14:52, 1075.1, 1061
|
||||
02:19:55, 1073.8, 1061
|
||||
02:24:58, 1095.2, 1056
|
||||
02:30:00, 1088, 1060
|
||||
02:35:03, 1072.4, 1054
|
||||
02:40:06, 1067.7, 1065
|
||||
02:45:09, 1056, 1053
|
||||
02:50:11, 1076.4, 1049
|
||||
02:55:14, 1073.1, 1052
|
||||
02:57:27, 1062, 1044
|
||||
03:02:30, 1061.9, 1050
|
||||
03:07:33, 1046, 1054
|
||||
03:12:35, 1068.2, 1052
|
||||
03:17:38, 1055, 1050
|
||||
03:22:40, 1063.1, 1053
|
||||
03:27:43, 1076.1, 1060
|
||||
03:32:46, 1052.1, 1046
|
||||
03:37:49, 1069.5, 1050
|
||||
03:42:51, 1070.1, 1060
|
||||
03:47:54, 1052, 1047
|
||||
03:52:56, 1056.3, 1056
|
||||
03:57:59, 1068.4, 1055
|
||||
04:03:02, 1059.7, 1052
|
||||
04:08:05, 1052.3, 1046
|
||||
04:13:07, 1058.8, 1054
|
||||
04:18:10, 1072.1, 1053
|
||||
04:23:13, 1057.3, 1058
|
||||
04:28:15, 1062.5, 1046
|
||||
04:33:18, 1058.3, 1050
|
||||
04:38:20, 1055, 1052
|
||||
04:43:24, 1060.3, 1050
|
||||
04:48:26, 1061.3, 1048
|
||||
04:53:29, 1058, 1048
|
||||
04:58:32, 1054.8, 1050
|
||||
05:00:19, 1063.9, 1051
|
||||
05:05:22, 1046.3, 1047
|
||||
05:10:25, 1050.2, 1051
|
||||
05:15:28, 1067.6, 1056
|
||||
05:20:30, 1059.2, 1053
|
||||
05:25:33, 1056.5, 1048
|
||||
05:30:36, 1061.9, 1048
|
||||
05:35:38, 1064.2, 1050
|
||||
05:40:41, 1044.2, 1054
|
||||
05:45:43, 1053.7, 1049
|
||||
05:50:46, 1053.1, 1050
|
||||
05:55:49, 1052, 1050
|
||||
06:00:51, 1057.1, 1043
|
||||
06:05:54, 1046.9, 1049
|
||||
06:10:57, 1059.8, 1049
|
||||
06:15:59, 1041.2, 1037
|
||||
06:21:02, 1063.3, 1047
|
||||
06:26:05, 1043.5, 1052
|
||||
06:31:07, 1050.7, 1049
|
||||
06:36:10, 1042.9, 1045
|
||||
06:41:13, 1053.2, 1052
|
||||
06:46:15, 1044.1, 1053
|
||||
06:51:18, 1065.9, 1050
|
||||
06:56:21, 1052.1, 1048
|
||||
|
@@ -0,0 +1,5 @@
|
||||
Beam size: 25 x 20, Energy: 13001 eV, Zoom: 1000.0
|
||||
Time,Scin_x,Scin_y,BPM_x,BPM_y
|
||||
18:07:53, 1025, 952.3
|
||||
18:08:55, 1011.2, 954.6
|
||||
18:09:58, 1016, 955.2
|
||||
|
@@ -0,0 +1,3 @@
|
||||
Beam size: 25 x 20, Energy: 13001 eV, Zoom: 1000.0
|
||||
Time,Scin_x,Scin_y,BPM_x,BPM_y
|
||||
18:11:14, 1012.7, 953.6
|
||||
|
@@ -0,0 +1,103 @@
|
||||
Beam size: 25 x 20, Energy: 13001 eV, Zoom: 1000.0
|
||||
Time,Scin_x,Scin_y
|
||||
18:13:58, 1018.8, 960.2
|
||||
18:24:01, 1006.3, 963.2
|
||||
18:34:04, 1013.1, 964.3
|
||||
18:44:07, 1022.6, 965.6
|
||||
18:54:09, 1001.1, 969.9
|
||||
19:04:13, 997.26, 972.5
|
||||
19:14:16, 1006, 970.8
|
||||
19:24:18, 1018, 974.5
|
||||
19:34:21, 1019.5, 973.1
|
||||
19:44:24, 1017, 973.4
|
||||
19:54:27, 1005.8, 974.2
|
||||
20:04:30, 999.66, 976.6
|
||||
20:14:33, 1011.8, 978.8
|
||||
20:24:36, 1005.6, 977.5
|
||||
20:34:39, 1021.6, 982.2
|
||||
20:44:41, 1013.7, 982.3
|
||||
20:54:44, 1017.9, 986.4
|
||||
21:04:47, 1010.5, 985.2
|
||||
21:14:50, 996.42, 988.3
|
||||
21:24:53, 1000.6, 991.7
|
||||
21:34:56, 1011.8, 997.8
|
||||
21:44:59, 1002.1, 997.9
|
||||
21:55:02, 1007, 997.2
|
||||
22:05:05, 1000.8, 1004
|
||||
22:15:08, 1010.9, 1007
|
||||
22:25:11, 1004.7, 1006
|
||||
22:35:13, 1017.4, 1012
|
||||
22:45:16, 997.11, 1009
|
||||
22:55:18, 1011.8, 1010
|
||||
23:05:21, 1001, 1009
|
||||
23:15:24, 1012.8, 1016
|
||||
23:25:26, 1001.8, 1014
|
||||
23:35:29, 1003.9, 1010
|
||||
23:45:32, 1004.4, 1013
|
||||
23:55:34, 999.85, 1013
|
||||
00:05:37, 1001.2, 1012
|
||||
00:15:39, 1009.8, 1006
|
||||
00:25:42, 1006.8, 1018
|
||||
00:35:45, 1021.8, 1021
|
||||
00:45:47, 1020.9, 1015
|
||||
00:55:50, 1008.5, 1017
|
||||
01:05:53, 1009.1, 1014
|
||||
01:15:55, 1023.7, 1011
|
||||
01:25:58, 1007.5, 1015
|
||||
01:36:00, 1017.1, 1014
|
||||
01:46:03, 1022.2, 1014
|
||||
01:56:06, 1019.4, 1018
|
||||
02:06:08, 1026.6, 1020
|
||||
02:16:11, 1019.1, 1022
|
||||
02:26:14, 1008.3, 1016
|
||||
02:36:16, 1026.3, 1024
|
||||
02:46:19, 1022.2, 1022
|
||||
02:56:21, 1022.2, 1025
|
||||
03:06:24, 1024.2, 1024
|
||||
03:16:27, 1015.3, 1016
|
||||
03:26:29, 1009.8, 1019
|
||||
03:36:32, 1018.3, 1022
|
||||
03:46:35, 1008.4, 1012
|
||||
03:56:37, 1031.7, 1022
|
||||
04:06:40, 1007.9, 1022
|
||||
04:16:43, 1025.7, 1018
|
||||
04:26:45, 1033.8, 1023
|
||||
04:36:48, 1023.9, 1022
|
||||
04:46:50, 1016.3, 1020
|
||||
04:56:53, 1013.9, 1027
|
||||
05:06:59, 950.12, 1064
|
||||
05:17:06, 1027.9, 1020
|
||||
05:27:09, 1016.3, 1014
|
||||
05:37:12, 1030.9, 1026
|
||||
05:47:15, 1015.2, 1025
|
||||
05:57:18, 1036.6, 1027
|
||||
06:07:20, 1029.6, 1030
|
||||
06:17:23, 1022.2, 1030
|
||||
06:27:25, 1025.7, 1028
|
||||
06:37:28, 1017.4, 1023
|
||||
06:47:31, 1031.5, 1022
|
||||
06:57:34, 1023.2, 1022
|
||||
07:07:36, 1020.3, 1019
|
||||
07:17:39, 1034.7, 1024
|
||||
07:27:42, 1022.5, 1023
|
||||
07:37:44, 1023.7, 1029
|
||||
07:47:47, 1032.3, 1026
|
||||
07:57:49, 1031.6, 1024
|
||||
08:07:52, 1039.3, 1027
|
||||
08:17:55, 1027.3, 1023
|
||||
08:27:57, 1030.3, 1024
|
||||
08:38:00, 1041.4, 1024
|
||||
08:48:03, 1032.9, 1029
|
||||
08:58:05, 1040.5, 1027
|
||||
09:08:08, 1036.3, 1023
|
||||
09:18:10, 1035.9, 1032
|
||||
09:28:13, 1041.2, 1023
|
||||
09:38:16, 1025.8, 1023
|
||||
09:48:18, 1032.3, 1029
|
||||
09:58:21, 1026.9, 1029
|
||||
10:08:24, 1027.9, 1035
|
||||
10:18:26, 1042.4, 1033
|
||||
10:28:29, 1042.8, 1031
|
||||
10:38:31, 1023.6, 1018
|
||||
10:48:34, 1022.5, 1027
|
||||
10:58:37, 1041.1, 1033
|
||||
|
@@ -0,0 +1,73 @@
|
||||
Beam size: 25 x 20, Energy: 13001 eV, Zoom: 1000.0
|
||||
Time,Scin_x,Scin_y,BPM_x,BPM_y
|
||||
12:04:04, 1034.5, 1032
|
||||
12:09:07, 1047.8, 1036
|
||||
12:14:09, 1048.8, 1030
|
||||
12:19:12, 1050.5, 1033
|
||||
12:24:15, 1031.5, 1032
|
||||
12:29:17, 1046.3, 1035
|
||||
12:34:20, 1029.1, 1019
|
||||
12:39:23, 1044, 1034
|
||||
12:44:25, 1042.3, 1021
|
||||
12:49:28, 1037.1, 1032
|
||||
12:54:30, 1055.4, 1030
|
||||
12:59:33, 1034.8, 1038
|
||||
13:04:36, 1042.7, 1031
|
||||
13:09:38, 1044.4, 1039
|
||||
13:14:41, 1039.9, 1037
|
||||
13:19:44, 1038.6, 1039
|
||||
13:24:46, 1035.5, 1033
|
||||
13:29:49, 1034, 1034
|
||||
13:34:52, 1039.5, 1034
|
||||
13:39:54, 1031.9, 1033
|
||||
13:44:57, 1048, 1023
|
||||
13:50:00, 1043.6, 1038
|
||||
13:55:02, 1048.4, 1033
|
||||
14:00:05, 1046.2, 1030
|
||||
14:05:07, 1045.2, 1027
|
||||
14:10:10, 1040.2, 1037
|
||||
14:15:13, 1056.5, 1043
|
||||
14:20:15, 1049.4, 1041
|
||||
14:25:18, 1045.3, 1033
|
||||
14:30:21, 1050.9, 1037
|
||||
14:35:23, 1039.2, 1032
|
||||
14:40:26, 1033.3, 1034
|
||||
14:45:28, 1036, 1039
|
||||
14:50:31, 1036.6, 1039
|
||||
14:55:34, 1038.7, 1040
|
||||
15:00:36, 1033.7, 1027
|
||||
15:05:39, 1055, 1044
|
||||
15:10:42, 1042.3, 1033
|
||||
15:15:44, 1042, 1038
|
||||
15:20:47, 1040.4, 1040
|
||||
15:25:49, 1044, 1042
|
||||
15:30:52, 1033.4, 1035
|
||||
15:35:55, 1047.6, 1038
|
||||
15:40:57, 1040.2, 1036
|
||||
15:46:00, 1051.6, 1039
|
||||
15:51:02, 1036, 1042
|
||||
15:56:05, 1051.8, 1030
|
||||
16:01:08, 1039.8, 1039
|
||||
16:06:10, 1050.7, 1034
|
||||
16:11:13, 1039.6, 1036
|
||||
16:16:16, 1030.3, 1039
|
||||
16:21:18, 1039.4, 1039
|
||||
16:26:21, 1055, 1044
|
||||
16:31:23, 1036.5, 1039
|
||||
16:36:26, 1035.4, 1031
|
||||
16:41:29, 1041.5, 1046
|
||||
16:46:31, 1030.2, 1039
|
||||
16:51:34, 1050.5, 1041
|
||||
16:56:37, 1044.9, 1046
|
||||
17:01:39, 1037, 1038
|
||||
17:06:42, 1036.7, 1046
|
||||
17:11:44, 1030.5, 1037
|
||||
17:16:47, 1040.3, 1043
|
||||
17:21:50, 1033.9, 1046
|
||||
17:26:52, 1050.4, 1040
|
||||
17:31:55, 1043.8, 1040
|
||||
17:36:58, 1033.8, 1032
|
||||
17:42:00, 1053.3, 1043
|
||||
17:47:03, 1051.5, 1049
|
||||
17:52:05, 1049.1, 1045
|
||||
17:57:08, 1029.3, 1037
|
||||
|
@@ -0,0 +1,73 @@
|
||||
Beam size: 25 x 20, Energy: 13001 eV, Zoom: 1000.0
|
||||
Time,Scin_x,Scin_y
|
||||
12:04:04, 1034.5, 1032
|
||||
12:09:07, 1047.8, 1036
|
||||
12:14:09, 1048.8, 1030
|
||||
12:19:12, 1050.5, 1033
|
||||
12:24:15, 1031.5, 1032
|
||||
12:29:17, 1046.3, 1035
|
||||
12:34:20, 1029.1, 1019
|
||||
12:39:23, 1044, 1034
|
||||
12:44:25, 1042.3, 1021
|
||||
12:49:28, 1037.1, 1032
|
||||
12:54:30, 1055.4, 1030
|
||||
12:59:33, 1034.8, 1038
|
||||
13:04:36, 1042.7, 1031
|
||||
13:09:38, 1044.4, 1039
|
||||
13:14:41, 1039.9, 1037
|
||||
13:19:44, 1038.6, 1039
|
||||
13:24:46, 1035.5, 1033
|
||||
13:29:49, 1034, 1034
|
||||
13:34:52, 1039.5, 1034
|
||||
13:39:54, 1031.9, 1033
|
||||
13:44:57, 1048, 1023
|
||||
13:50:00, 1043.6, 1038
|
||||
13:55:02, 1048.4, 1033
|
||||
14:00:05, 1046.2, 1030
|
||||
14:05:07, 1045.2, 1027
|
||||
14:10:10, 1040.2, 1037
|
||||
14:15:13, 1056.5, 1043
|
||||
14:20:15, 1049.4, 1041
|
||||
14:25:18, 1045.3, 1033
|
||||
14:30:21, 1050.9, 1037
|
||||
14:35:23, 1039.2, 1032
|
||||
14:40:26, 1033.3, 1034
|
||||
14:45:28, 1036, 1039
|
||||
14:50:31, 1036.6, 1039
|
||||
14:55:34, 1038.7, 1040
|
||||
15:00:36, 1033.7, 1027
|
||||
15:05:39, 1055, 1044
|
||||
15:10:42, 1042.3, 1033
|
||||
15:15:44, 1042, 1038
|
||||
15:20:47, 1040.4, 1040
|
||||
15:25:49, 1044, 1042
|
||||
15:30:52, 1033.4, 1035
|
||||
15:35:55, 1047.6, 1038
|
||||
15:40:57, 1040.2, 1036
|
||||
15:46:00, 1051.6, 1039
|
||||
15:51:02, 1036, 1042
|
||||
15:56:05, 1051.8, 1030
|
||||
16:01:08, 1039.8, 1039
|
||||
16:06:10, 1050.7, 1034
|
||||
16:11:13, 1039.6, 1036
|
||||
16:16:16, 1030.3, 1039
|
||||
16:21:18, 1039.4, 1039
|
||||
16:26:21, 1055, 1044
|
||||
16:31:23, 1036.5, 1039
|
||||
16:36:26, 1035.4, 1031
|
||||
16:41:29, 1041.5, 1046
|
||||
16:46:31, 1030.2, 1039
|
||||
16:51:34, 1050.5, 1041
|
||||
16:56:37, 1044.9, 1046
|
||||
17:01:39, 1037, 1038
|
||||
17:06:42, 1036.7, 1046
|
||||
17:11:44, 1030.5, 1037
|
||||
17:16:47, 1040.3, 1043
|
||||
17:21:50, 1033.9, 1046
|
||||
17:26:52, 1050.4, 1040
|
||||
17:31:55, 1043.8, 1040
|
||||
17:36:58, 1033.8, 1032
|
||||
17:42:00, 1053.3, 1043
|
||||
17:47:03, 1051.5, 1049
|
||||
17:52:05, 1049.1, 1045
|
||||
17:57:08, 1029.3, 1037
|
||||
|
@@ -0,0 +1,15 @@
|
||||
Beam size: 25 x 20, Energy: 13001 eV, Zoom: 1000.0
|
||||
Time,Scin_x,Scin_y
|
||||
20:01:35, 1060.6, 1049
|
||||
20:06:37, 1046.3, 1046
|
||||
20:11:40, 1058.1, 1047
|
||||
20:16:42, 1067.3, 1050
|
||||
20:21:45, 1053.8, 1040
|
||||
20:26:48, 1061, 1040
|
||||
20:31:50, 1065.3, 1040
|
||||
20:36:53, 1056, 1044
|
||||
20:41:56, 1074.8, 1044
|
||||
20:46:59, 1054.1, 1040
|
||||
20:52:01, 1046.7, 1055
|
||||
20:57:04, 1066.2, 1045
|
||||
21:02:07, 1049.9, 1050
|
||||
|
@@ -0,0 +1,8 @@
|
||||
Beam size: 25 x 20, Energy: 13001 eV, Zoom: 1000.0
|
||||
Time,Scin_x,Scin_y
|
||||
21:04:24, 1038.8, 1034
|
||||
21:09:26, 1053.5, 1043
|
||||
21:14:29, 1055.6, 1051
|
||||
21:19:31, 1064.2, 1041
|
||||
21:24:34, 1061.8, 1050
|
||||
21:29:37, 1056.8, 1043
|
||||
|
@@ -0,0 +1,9 @@
|
||||
Beam size: 25 x 20, Energy: 6000 eV, Zoom: 1000.0
|
||||
Time,Scin_x,Scin_y,BPM_x,BPM_y
|
||||
22:57:13, 1101.8, 1095
|
||||
23:02:16, 1103.3, 1096
|
||||
23:07:18, 1105.2, 1098
|
||||
23:12:21, 1102.5, 1098
|
||||
23:17:24, 1103.8, 1100
|
||||
23:22:28, 1100.6, 1100
|
||||
23:27:31, 1105.2, 1100
|
||||
|
@@ -0,0 +1,20 @@
|
||||
Beam size: 25 x 20, Energy: 8000 eV, Zoom: 1000.0
|
||||
Time,Scin_x,Scin_y,BPM_x,BPM_y
|
||||
23:30:46, 1079.4, 1068
|
||||
23:35:49, 1096.5, 1074
|
||||
23:40:51, 1070.1, 1075
|
||||
23:45:54, 1090.1, 1074
|
||||
23:50:57, 1088.5, 1080
|
||||
23:55:59, 1077.1, 1076
|
||||
00:01:05, 998.88, 1037
|
||||
00:06:12, 1073.2, 1076
|
||||
00:11:17, 1092.3, 1078
|
||||
00:16:20, 1075, 1073
|
||||
00:21:23, 1095.1, 1071
|
||||
00:26:25, 1083.9, 1069
|
||||
00:31:28, 1082.9, 1071
|
||||
00:36:30, 1083.6, 1073
|
||||
00:41:33, 1081.8, 1067
|
||||
00:46:36, 1084.7, 1066
|
||||
00:51:39, 1087.1, 1068
|
||||
00:56:41, 1083.2, 1066
|
||||
|
@@ -0,0 +1,26 @@
|
||||
Beam size: 25 x 20, Energy: 10000 eV, Zoom: 1000.0
|
||||
Time,Scin_x,Scin_y,BPM_x,BPM_y
|
||||
00:59:13, 1057.8, 1053
|
||||
01:04:15, 1076.4, 1062
|
||||
01:09:18, 1082.5, 1064
|
||||
01:14:21, 1080.3, 1063
|
||||
01:19:23, 1069.3, 1044
|
||||
01:24:26, 1080.9, 1067
|
||||
01:29:29, 1075.5, 1068
|
||||
01:34:31, 1061.9, 1058
|
||||
01:39:34, 1079.6, 1048
|
||||
01:44:36, 1079.6, 1069
|
||||
01:49:39, 1077.9, 1056
|
||||
01:54:42, 1083.5, 1060
|
||||
01:59:44, 1056.3, 1045
|
||||
02:04:47, 1083.9, 1057
|
||||
02:09:50, 1076.5, 1059
|
||||
02:14:52, 1075.1, 1061
|
||||
02:19:55, 1073.8, 1061
|
||||
02:24:58, 1095.2, 1056
|
||||
02:30:00, 1088, 1060
|
||||
02:35:03, 1072.4, 1054
|
||||
02:40:06, 1067.7, 1065
|
||||
02:45:09, 1056, 1053
|
||||
02:50:11, 1076.4, 1049
|
||||
02:55:14, 1073.1, 1052
|
||||
|
@@ -0,0 +1,27 @@
|
||||
Beam size: 25 x 20, Energy: 12400 eV, Zoom: 1000.0
|
||||
Time,Scin_x,Scin_y,BPM_x,BPM_y
|
||||
02:57:27, 1062, 1044
|
||||
03:02:30, 1061.9, 1050
|
||||
03:07:33, 1046, 1054
|
||||
03:12:35, 1068.2, 1052
|
||||
03:17:38, 1055, 1050
|
||||
03:22:40, 1063.1, 1053
|
||||
03:27:43, 1076.1, 1060
|
||||
03:32:46, 1052.1, 1046
|
||||
03:37:49, 1069.5, 1050
|
||||
03:42:51, 1070.1, 1060
|
||||
03:47:54, 1052, 1047
|
||||
03:52:56, 1056.3, 1056
|
||||
03:57:59, 1068.4, 1055
|
||||
04:03:02, 1059.7, 1052
|
||||
04:08:05, 1052.3, 1046
|
||||
04:13:07, 1058.8, 1054
|
||||
04:18:10, 1072.1, 1053
|
||||
04:23:13, 1057.3, 1058
|
||||
04:28:15, 1062.5, 1046
|
||||
04:33:18, 1058.3, 1050
|
||||
04:38:20, 1055, 1052
|
||||
04:43:24, 1060.3, 1050
|
||||
04:48:26, 1061.3, 1048
|
||||
04:53:29, 1058, 1048
|
||||
04:58:32, 1054.8, 1050
|
||||
|
@@ -0,0 +1,26 @@
|
||||
Beam size: 25 x 20, Energy: 14000 eV, Zoom: 1000.0
|
||||
Time,Scin_x,Scin_y
|
||||
05:00:19, 1063.9, 1051
|
||||
05:05:22, 1046.3, 1047
|
||||
05:10:25, 1050.2, 1051
|
||||
05:15:28, 1067.6, 1056
|
||||
05:20:30, 1059.2, 1053
|
||||
05:25:33, 1056.5, 1048
|
||||
05:30:36, 1061.9, 1048
|
||||
05:35:38, 1064.2, 1050
|
||||
05:40:41, 1044.2, 1054
|
||||
05:45:43, 1053.7, 1049
|
||||
05:50:46, 1053.1, 1050
|
||||
05:55:49, 1052, 1050
|
||||
06:00:51, 1057.1, 1043
|
||||
06:05:54, 1046.9, 1049
|
||||
06:10:57, 1059.8, 1049
|
||||
06:15:59, 1041.2, 1037
|
||||
06:21:02, 1063.3, 1047
|
||||
06:26:05, 1043.5, 1052
|
||||
06:31:07, 1050.7, 1049
|
||||
06:36:10, 1042.9, 1045
|
||||
06:41:13, 1053.2, 1052
|
||||
06:46:15, 1044.1, 1053
|
||||
06:51:18, 1065.9, 1050
|
||||
06:56:21, 1052.1, 1048
|
||||
|
@@ -17,6 +17,17 @@ import numpy as np
|
||||
# )
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class FitDefaults:
|
||||
"""Default values for fitting routines"""
|
||||
|
||||
# Constants for default models, baselines, and parameters
|
||||
MODEL = "Voigt"
|
||||
BASELINE = "Linear"
|
||||
SETTLE_TIME = 0.1
|
||||
RELATIVE_MODE = True
|
||||
|
||||
|
||||
# Method functions
|
||||
def calculate_step_size(start: float, stop: float, steps: int) -> float:
|
||||
"""
|
||||
|
||||
@@ -58,15 +58,16 @@ def make_diag_y_policy(d):
|
||||
def diag_y_policy(target):
|
||||
cfg = d["diag_y"].positions
|
||||
# Don't move in if the goniometer is in
|
||||
if d["aerotech_x"].actual >= d['aerotech_x'].positions['in'] and target > cfg["out"]:
|
||||
if d["aerotech_x"].actual >= d["aerotech_x"].positions["in"] and target > cfg["out"]:
|
||||
raise GuardViolation(
|
||||
f"Diagnostic device cannot move beyond {cfg['out']} mm when goniometer is not OUT"
|
||||
)
|
||||
# Don't move if cryocooler is in
|
||||
if d['cryo_pos'].pos == 'in' and target > cfg['out']:
|
||||
if d["cryo_pos"].pos == "in" and target > cfg["out"]:
|
||||
raise GuardViolation(
|
||||
f"Diagnostic device cannot move beyond {cfg['out']} mm when cryocooler is IN"
|
||||
)
|
||||
|
||||
return diag_y_policy
|
||||
|
||||
|
||||
|
||||
@@ -147,7 +147,7 @@ def mono_pitch_scan(plot=True):
|
||||
print("Scanning monochromator pitch and moving to peak, with plotting.")
|
||||
go_to_peak(
|
||||
EnergyDefaults.mono_pitch,
|
||||
EnergyDefaults.signals["sig1"],
|
||||
EnergyDefaults.signals["sig2"],
|
||||
-EnergyDefaults.pitch_scan["halfwidth"],
|
||||
EnergyDefaults.pitch_scan["halfwidth"],
|
||||
steps=EnergyDefaults.pitch_scan["steps"],
|
||||
@@ -160,7 +160,7 @@ def mono_pitch_scan(plot=True):
|
||||
print("Scanning monochromator pitch and moving to peak, without plotting.")
|
||||
go_to_peak(
|
||||
EnergyDefaults.mono_pitch,
|
||||
EnergyDefaults.signals["sig1"],
|
||||
EnergyDefaults.signals["sig2"],
|
||||
-EnergyDefaults.pitch_scan["halfwidth"],
|
||||
EnergyDefaults.pitch_scan["halfwidth"],
|
||||
steps=EnergyDefaults.pitch_scan["steps"],
|
||||
@@ -189,8 +189,10 @@ def get_dccm_motors_positions(energy_ev):
|
||||
# dccm_motor_values = get_value_from_lut(energy_ev)
|
||||
th1_angle = -convert_from_energy(energy_ev, print_result=False)["bragg_angle_deg"]
|
||||
th2_angle = convert_from_energy(energy_ev, temp=298, print_result=False)["bragg_angle_deg"]
|
||||
# add fudge factor
|
||||
th2_angle_fudge = th2_angle + 0.006
|
||||
# dccm_motor_values.update({"theta1_angle": th1_angle, "theta2_angle": th2_angle})
|
||||
dccm_motor_values = {"theta1_angle": th1_angle, "theta2_angle": th2_angle}
|
||||
dccm_motor_values = {"theta1_angle": th1_angle, "theta2_angle": th2_angle_fudge}
|
||||
return dccm_motor_values
|
||||
|
||||
|
||||
|
||||
@@ -4,16 +4,6 @@ from dataclasses import dataclass
|
||||
import numpy as np
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class FitDefaults:
|
||||
"""Default values for fitting routines"""
|
||||
|
||||
# Constants for default models, baselines, and parameters
|
||||
MODEL = "Voigt"
|
||||
BASELINE = "Linear"
|
||||
SETTLE_TIME = 0.1
|
||||
RELATIVE_MODE = True
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class EnergyDefaults:
|
||||
@@ -32,7 +22,7 @@ class EnergyDefaults:
|
||||
mono_pitch = dev.dccm_theta2
|
||||
# LUT_table = "luts/energy_lut.csv"
|
||||
stripe_thresholds = {"silicon": 9000, "rhodium": 40000}
|
||||
pitch_scan = {"halfwidth": 0.15, "steps": 30}
|
||||
pitch_scan = {"halfwidth": 0.01, "steps": 25}
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
|
||||
Reference in New Issue
Block a user