First helical scan passed
This commit is contained in:
@@ -452,7 +452,15 @@ samimg:
|
|||||||
readoutPriority: async
|
readoutPriority: async
|
||||||
readOnly: false
|
readOnly: false
|
||||||
softwareTrigger: false
|
softwareTrigger: false
|
||||||
|
samimg_ad:
|
||||||
|
description: Sample camera image via AD plugin
|
||||||
|
deviceClass: ophyd_devices.devices.areadetector.plugins.ImagePlugin_V35
|
||||||
|
deviceConfig: {prefix: 'X06DA-SAMCAM:image1:'}
|
||||||
|
onFailure: buffer
|
||||||
|
enabled: false
|
||||||
|
readoutPriority: monitored
|
||||||
|
readOnly: true
|
||||||
|
softwareTrigger: false
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -113,7 +113,7 @@ class AerotechAbrMixin(CustomPrepare):
|
|||||||
scanargs = self.parent.scaninfo.scan_msg.info["kwargs"]
|
scanargs = self.parent.scaninfo.scan_msg.info["kwargs"]
|
||||||
scanname = self.parent.scaninfo.scan_msg.info["scan_name"]
|
scanname = self.parent.scaninfo.scan_msg.info["scan_name"]
|
||||||
|
|
||||||
if scanname in ("standardscan"):
|
if scanname in ("standardscan", "helicalscan"):
|
||||||
d["scan_command"] = AbrCmd.MEASURE_STANDARD
|
d["scan_command"] = AbrCmd.MEASURE_STANDARD
|
||||||
d["var_1"] = scanargs["start"]
|
d["var_1"] = scanargs["start"]
|
||||||
d["var_2"] = scanargs["range"]
|
d["var_2"] = scanargs["range"]
|
||||||
@@ -186,7 +186,7 @@ class AerotechAbrStage(BECDeviceBase):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
custom_prepare_cls = AerotechAbrMixin
|
custom_prepare_cls = AerotechAbrMixin
|
||||||
USER_ACCESS = ["reset", "kickoff", "complete", "set_axis_mode"]
|
USER_ACCESS = ["reset", "kickoff", "bluekickoff", "complete", "set_axis_mode"]
|
||||||
|
|
||||||
taskStop = Component(EpicsSignal, "-AERO:TSK-STOP", put_complete=True, kind=Kind.omitted)
|
taskStop = Component(EpicsSignal, "-AERO:TSK-STOP", put_complete=True, kind=Kind.omitted)
|
||||||
status = Component(EpicsSignal, "-AERO:STAT", put_complete=True, kind=Kind.omitted)
|
status = Component(EpicsSignal, "-AERO:STAT", put_complete=True, kind=Kind.omitted)
|
||||||
@@ -236,10 +236,7 @@ class AerotechAbrStage(BECDeviceBase):
|
|||||||
task2 = Component(EpicsSignalRO, "-AERO:TSK2-DONE", auto_monitor=True)
|
task2 = Component(EpicsSignalRO, "-AERO:TSK2-DONE", auto_monitor=True)
|
||||||
task3 = Component(EpicsSignalRO, "-AERO:TSK3-DONE", auto_monitor=True)
|
task3 = Component(EpicsSignalRO, "-AERO:TSK3-DONE", auto_monitor=True)
|
||||||
task4 = Component(EpicsSignalRO, "-AERO:TSK4-DONE", auto_monitor=True)
|
task4 = Component(EpicsSignalRO, "-AERO:TSK4-DONE", auto_monitor=True)
|
||||||
|
scan_done = Component(EpicsSignal, "-GRD:SCAN-DONE", kind=Kind.config)
|
||||||
# A few PVs still needed from grid
|
|
||||||
raster_scan_done = Component(EpicsSignal, "-GRD:SCAN-DONE", kind=Kind.config)
|
|
||||||
raster_num_rows = Component(EpicsSignal, "-GRD:ROW-DONE", kind=Kind.config)
|
|
||||||
|
|
||||||
def set_axis_mode(self, mode: str, settle_time=0.1) -> None:
|
def set_axis_mode(self, mode: str, settle_time=0.1) -> None:
|
||||||
"""Set axis mode to direct/measurement mode.
|
"""Set axis mode to direct/measurement mode.
|
||||||
@@ -328,9 +325,10 @@ class AerotechAbrStage(BECDeviceBase):
|
|||||||
|
|
||||||
# Subscribe and wait for update
|
# Subscribe and wait for update
|
||||||
status = SubscriptionStatus(
|
status = SubscriptionStatus(
|
||||||
self.raster_scan_done, is_busy, timeout=timeout, settle_time=0.1
|
self.scan_done, is_busy, timeout=timeout, settle_time=0.1
|
||||||
)
|
)
|
||||||
return status
|
status.wait()
|
||||||
|
# return status
|
||||||
|
|
||||||
def blueunstage(self, settle_time=0.1):
|
def blueunstage(self, settle_time=0.1):
|
||||||
"""Stops current script and releases the axes"""
|
"""Stops current script and releases the axes"""
|
||||||
@@ -353,7 +351,7 @@ class AerotechAbrStage(BECDeviceBase):
|
|||||||
# Subscribe and wait for update
|
# Subscribe and wait for update
|
||||||
# status = SubscriptionStatus(self.task1, is_idle, timeout=timeout, settle_time=0.5)
|
# status = SubscriptionStatus(self.task1, is_idle, timeout=timeout, settle_time=0.5)
|
||||||
status = SubscriptionStatus(
|
status = SubscriptionStatus(
|
||||||
self.raster_scan_done, is_idle, timeout=timeout, settle_time=0.5
|
self.scan_done, is_idle, timeout=timeout, settle_time=0.5
|
||||||
)
|
)
|
||||||
return status
|
return status
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,12 @@
|
|||||||
|
"""
|
||||||
|
``SmarGon`` --- SmarGon control software
|
||||||
|
******************************************
|
||||||
|
|
||||||
|
The module provides an object to control the SmarGon goniometer axes at PX III.
|
||||||
|
The SmarGon axes are interfaced as positioners.
|
||||||
|
"""
|
||||||
import time
|
import time
|
||||||
from threading import Thread
|
from threading import Thread, Lock
|
||||||
import requests
|
import requests
|
||||||
from ophyd import Component, Kind, Signal, PVPositioner
|
from ophyd import Component, Kind, Signal, PVPositioner
|
||||||
from ophyd.status import SubscriptionStatus
|
from ophyd.status import SubscriptionStatus
|
||||||
@@ -14,6 +21,11 @@ except ModuleNotFoundError:
|
|||||||
logger = logging.getLogger("SmarGon")
|
logger = logging.getLogger("SmarGon")
|
||||||
|
|
||||||
|
|
||||||
|
# SmarGon contoller can't really handle multiple connections
|
||||||
|
# Use this mutex to ensure one access at a time
|
||||||
|
mutex = Lock()
|
||||||
|
|
||||||
|
|
||||||
class SmarGonSignal(Signal):
|
class SmarGonSignal(Signal):
|
||||||
"""SmarGonSignal (R/W)
|
"""SmarGonSignal (R/W)
|
||||||
|
|
||||||
@@ -31,17 +43,16 @@ class SmarGonSignal(Signal):
|
|||||||
|
|
||||||
def put(self, value, *, timestamp=None, **kwargs):
|
def put(self, value, *, timestamp=None, **kwargs):
|
||||||
"""Overriden put to add communication with smargopolo"""
|
"""Overriden put to add communication with smargopolo"""
|
||||||
# Validate new value
|
# Validate new value and get timestamp
|
||||||
self.check_value(value)
|
self.check_value(value)
|
||||||
|
|
||||||
if timestamp is None:
|
if timestamp is None:
|
||||||
timestamp = time.time()
|
timestamp = time.time()
|
||||||
|
|
||||||
# Perform the actual write to SmargoPolo
|
# Perform the actual write to SmargoPolo
|
||||||
#pylint: disable=protected-access
|
# pylint: disable=protected-access
|
||||||
r = self.parent._go_n_put(f"{self.write_addr}?{self.addr.upper()}={value}")
|
r = self.parent._go_n_put(f"{self.write_addr}?{self.addr.upper()}={value}")
|
||||||
|
|
||||||
#pylint: disable=attribute-defined-outside-init
|
# pylint: disable=attribute-defined-outside-init
|
||||||
old_value = self._readback
|
old_value = self._readback
|
||||||
self._timestamp = timestamp
|
self._timestamp = timestamp
|
||||||
self._readback = r[self.addr.upper()]
|
self._readback = r[self.addr.upper()]
|
||||||
@@ -68,11 +79,10 @@ class SmarGonSignal(Signal):
|
|||||||
raise ValueError(f"Target {value} outside of limits {self.limits}")
|
raise ValueError(f"Target {value} outside of limits {self.limits}")
|
||||||
|
|
||||||
def get(self, **kwargs):
|
def get(self, **kwargs):
|
||||||
#pylint: disable=protected-access
|
# pylint: disable=protected-access
|
||||||
r = self.parent._go_n_get(self.write_addr)
|
r = self.parent._go_n_get(self.write_addr)
|
||||||
# print(r)
|
|
||||||
|
|
||||||
#pylint: disable=attribute-defined-outside-init
|
# pylint: disable=attribute-defined-outside-init
|
||||||
self._value = r[self.addr.upper()] if isinstance(r, dict) else r
|
self._value = r[self.addr.upper()] if isinstance(r, dict) else r
|
||||||
return super().get(**kwargs)
|
return super().get(**kwargs)
|
||||||
|
|
||||||
@@ -80,7 +90,7 @@ class SmarGonSignal(Signal):
|
|||||||
class SmarGonSignalRO(Signal):
|
class SmarGonSignalRO(Signal):
|
||||||
"""Small helper class for read-only parameters PVs from SmarGon.
|
"""Small helper class for read-only parameters PVs from SmarGon.
|
||||||
|
|
||||||
TODO: Add monitoring
|
Reads and optionally monitors a variable on the SmarGon.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, *args, read_addr="readbackSCS", auto_monitor=False, **kwargs):
|
def __init__(self, *args, read_addr="readbackSCS", auto_monitor=False, **kwargs):
|
||||||
@@ -94,7 +104,7 @@ class SmarGonSignalRO(Signal):
|
|||||||
self._mon.start()
|
self._mon.start()
|
||||||
|
|
||||||
def get(self, **kwargs):
|
def get(self, **kwargs):
|
||||||
#pylint: disable=protected-access
|
# pylint: disable=protected-access
|
||||||
r = self.parent._go_n_get(self.read_addr)
|
r = self.parent._go_n_get(self.read_addr)
|
||||||
|
|
||||||
if isinstance(r, dict):
|
if isinstance(r, dict):
|
||||||
@@ -104,7 +114,7 @@ class SmarGonSignalRO(Signal):
|
|||||||
return self._readback
|
return self._readback
|
||||||
|
|
||||||
def poll(self):
|
def poll(self):
|
||||||
""" Fooo"""
|
"""Fooo"""
|
||||||
time.sleep(2)
|
time.sleep(2)
|
||||||
while True:
|
while True:
|
||||||
time.sleep(0.25)
|
time.sleep(0.25)
|
||||||
@@ -117,7 +127,8 @@ class SmarGonSignalRO(Signal):
|
|||||||
class SmarGonAxis(PVPositioner):
|
class SmarGonAxis(PVPositioner):
|
||||||
"""SmarGon client deice
|
"""SmarGon client deice
|
||||||
|
|
||||||
This class controls the SmarGon goniometer via the REST interface.
|
This class controls the SmarGon goniometer via the REST interface. All
|
||||||
|
SmarGon axes share a common mutex to manage actual HW access.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
USER_ACCESS = ["omove"]
|
USER_ACCESS = ["omove"]
|
||||||
@@ -132,10 +143,9 @@ class SmarGonAxis(PVPositioner):
|
|||||||
setpoint = Component(SmarGonSignal, kind=Kind.normal)
|
setpoint = Component(SmarGonSignal, kind=Kind.normal)
|
||||||
done = Component(Signal, value=1, kind=Kind.normal)
|
done = Component(Signal, value=1, kind=Kind.normal)
|
||||||
# moving = Component(SmarGonMovingSignalRO, kind=Kind.config)
|
# moving = Component(SmarGonMovingSignalRO, kind=Kind.config)
|
||||||
moving = 1
|
|
||||||
_tol = 0.001
|
_tol = 0.001
|
||||||
|
|
||||||
#pylint: disable=too-many-arguments
|
# pylint: disable=too-many-arguments
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
prefix="SCS",
|
prefix="SCS",
|
||||||
@@ -173,11 +183,11 @@ class SmarGonAxis(PVPositioner):
|
|||||||
print(r)
|
print(r)
|
||||||
|
|
||||||
def move(self, position, wait=True, timeout=None, moved_cb=None):
|
def move(self, position, wait=True, timeout=None, moved_cb=None):
|
||||||
""" Move command that's masked by BEC"""
|
"""Move command that's masked by BEC"""
|
||||||
return self.omove(position, wait, timeout, moved_cb)
|
return self.omove(position, wait, timeout, moved_cb)
|
||||||
|
|
||||||
def omove(self, position, wait=True, timeout=None, moved_cb=None):
|
def omove(self, position, wait=True, timeout=None, moved_cb=None):
|
||||||
""" Original move command without the BEC wrappers"""
|
"""Original move command without the BEC wrappers"""
|
||||||
status = self.setpoint.set(position, settle_time=0.1)
|
status = self.setpoint.set(position, settle_time=0.1)
|
||||||
if not wait:
|
if not wait:
|
||||||
return status
|
return status
|
||||||
@@ -185,12 +195,11 @@ class SmarGonAxis(PVPositioner):
|
|||||||
status.wait()
|
status.wait()
|
||||||
|
|
||||||
def on_target(*, value, **_):
|
def on_target(*, value, **_):
|
||||||
distance = abs(value-position)
|
distance = abs(value - position)
|
||||||
print(distance)
|
print(distance)
|
||||||
return bool(distance<self._tol)
|
return bool(distance < self._tol)
|
||||||
status = SubscriptionStatus(
|
|
||||||
self.readback, on_target, timeout=timeout, settle_time=0.1
|
status = SubscriptionStatus(self.readback, on_target, timeout=timeout, settle_time=0.1)
|
||||||
)
|
|
||||||
return status
|
return status
|
||||||
|
|
||||||
def _pos_changed(self, timestamp=None, value=None, **kwargs):
|
def _pos_changed(self, timestamp=None, value=None, **kwargs):
|
||||||
@@ -199,7 +208,12 @@ class SmarGonAxis(PVPositioner):
|
|||||||
def _go_n_get(self, address, **kwargs):
|
def _go_n_get(self, address, **kwargs):
|
||||||
"""Helper function to connect to smargopolo"""
|
"""Helper function to connect to smargopolo"""
|
||||||
cmd = f"{self.sg_url.get()}/{address}"
|
cmd = f"{self.sg_url.get()}/{address}"
|
||||||
r = requests.get(cmd, timeout=1, **kwargs)
|
try:
|
||||||
|
with mutex:
|
||||||
|
r = requests.get(cmd, timeout=1, **kwargs)
|
||||||
|
except TimeoutError:
|
||||||
|
with mutex:
|
||||||
|
r = requests.get(cmd, timeout=1, **kwargs)
|
||||||
if not r.ok:
|
if not r.ok:
|
||||||
raise RuntimeError(
|
raise RuntimeError(
|
||||||
f"[{self.name}] Error getting {address}; reply was {r.status_code} => {r.reason}"
|
f"[{self.name}] Error getting {address}; reply was {r.status_code} => {r.reason}"
|
||||||
@@ -209,7 +223,12 @@ class SmarGonAxis(PVPositioner):
|
|||||||
def _go_n_put(self, address, **kwargs):
|
def _go_n_put(self, address, **kwargs):
|
||||||
"""Helper function to connect to smargopolo"""
|
"""Helper function to connect to smargopolo"""
|
||||||
cmd = f"{self.sg_url.get()}/{address}"
|
cmd = f"{self.sg_url.get()}/{address}"
|
||||||
r = requests.put(cmd, timeout=1, **kwargs)
|
try:
|
||||||
|
with mutex:
|
||||||
|
r = requests.put(cmd, timeout=1, **kwargs)
|
||||||
|
except TimeoutError:
|
||||||
|
with mutex:
|
||||||
|
r = requests.put(cmd, timeout=1, **kwargs)
|
||||||
if not r.ok:
|
if not r.ok:
|
||||||
raise RuntimeError(
|
raise RuntimeError(
|
||||||
f"[{self.name}] Error putting {address}; reply was {r.status_code} => {r.reason}"
|
f"[{self.name}] Error putting {address}; reply was {r.status_code} => {r.reason}"
|
||||||
|
|||||||
@@ -3,4 +3,5 @@ from .mx_measurements import (
|
|||||||
MeasureVerticalLine,
|
MeasureVerticalLine,
|
||||||
MeasureRasterSimple,
|
MeasureRasterSimple,
|
||||||
MeasureScreening,
|
MeasureScreening,
|
||||||
|
MeasureHelical,
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -4,6 +4,8 @@ Scan primitives for standard BEC scans at the PX beamlines at SLS.
|
|||||||
Theese scans define the event model and can be called from higher levels.
|
Theese scans define the event model and can be called from higher levels.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
import time
|
||||||
|
import numpy as np
|
||||||
from bec_lib import bec_logger
|
from bec_lib import bec_logger
|
||||||
from bec_server.scan_server.scans import AsyncFlyScanBase
|
from bec_server.scan_server.scans import AsyncFlyScanBase
|
||||||
|
|
||||||
@@ -247,3 +249,107 @@ class MeasureScreening(AerotechFlyscanBase):
|
|||||||
|
|
||||||
scan_name = "screeningscan"
|
scan_name = "screeningscan"
|
||||||
required_kwargs = ["start", "range", "steps", "exp_time", "oscrange"]
|
required_kwargs = ["start", "range", "steps", "exp_time", "oscrange"]
|
||||||
|
|
||||||
|
|
||||||
|
class MeasureHelical(AerotechFlyscanBase):
|
||||||
|
"""Helical scan using the OMEGA motor
|
||||||
|
|
||||||
|
Measure an absolute continous line scan from `start` to `start` + `range`
|
||||||
|
during `move_time` on the Omega axis with PSO output.
|
||||||
|
|
||||||
|
The scan itself is executed by the scan service running on the Aerotech
|
||||||
|
controller. Ophyd just configures, launches it and waits for completion.
|
||||||
|
|
||||||
|
Example
|
||||||
|
-------
|
||||||
|
>>> scans.standard_wedge(start=42, range=10, move_time=20)
|
||||||
|
|
||||||
|
Parameters
|
||||||
|
----------
|
||||||
|
start : float
|
||||||
|
Scan start position of the axis.
|
||||||
|
range : float
|
||||||
|
Scan range of the axis.
|
||||||
|
move_time : float
|
||||||
|
Total travel time for the movement [s].
|
||||||
|
ready_rate : float, optional
|
||||||
|
No clue what is this... (default=500)
|
||||||
|
sg_start : (float, float, float, float, float)
|
||||||
|
Complete SmarGon coordinate in tuple form.
|
||||||
|
sg_end : (float, float, float, float, float)
|
||||||
|
Complete SmarGon coordinate in tuple form.
|
||||||
|
sg_steps : int
|
||||||
|
Number of steps with SmarGon.
|
||||||
|
"""
|
||||||
|
|
||||||
|
scan_name = "helicalscan"
|
||||||
|
required_kwargs = ["start", "range", "move_time", "sg_start", "sg_end", "sg_steps"]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def pre_scan(self):
|
||||||
|
"""Mostly just checking if ABR stage is ok..."""
|
||||||
|
|
||||||
|
# Smargon has no velocity control
|
||||||
|
self.smargon_start = np.array(self.caller_kwargs.get("sg_start"))
|
||||||
|
self.smargon_end = np.array(self.caller_kwargs.get("sg_end"))
|
||||||
|
self.smargon_steps = self.caller_kwargs.get("sg_steps")
|
||||||
|
self.smargon_range = self.smargon_end - self.smargon_start
|
||||||
|
self.smargon_step_size = self.smargon_range / self.smargon_steps
|
||||||
|
self.smargon_step_time = self.caller_kwargs.get("move_time") / self.smargon_steps
|
||||||
|
|
||||||
|
logger.info(f"Start:\t{self.smargon_start}")
|
||||||
|
logger.info(f"End:\t{self.smargon_end}")
|
||||||
|
logger.info(f"Steps:\t{self.smargon_steps}")
|
||||||
|
logger.info(f"Range:\t{self.smargon_range}")
|
||||||
|
logger.info(f"StepSize:\t{self.smargon_step_size}")
|
||||||
|
logger.info(f"StepTime:\t{self.smargon_step_time}")
|
||||||
|
|
||||||
|
# TODO: Move roughly to start position???
|
||||||
|
st0 = yield from self.stubs.send_rpc("shx", "omove", self.smargon_start[0])
|
||||||
|
st1 = yield from self.stubs.send_rpc("shy", "omove", self.smargon_start[1])
|
||||||
|
st2 = yield from self.stubs.send_rpc("shz", "omove", self.smargon_start[2])
|
||||||
|
st3 = yield from self.stubs.send_rpc("chi", "omove", self.smargon_start[3])
|
||||||
|
st4 = yield from self.stubs.send_rpc("phi", "omove", self.smargon_start[4])
|
||||||
|
st0.wait()
|
||||||
|
st1.wait()
|
||||||
|
st2.wait()
|
||||||
|
st3.wait()
|
||||||
|
st4.wait()
|
||||||
|
|
||||||
|
# Call super
|
||||||
|
yield from super().pre_scan()
|
||||||
|
|
||||||
|
def scan_core(self):
|
||||||
|
"""The actual scan logic comes here."""
|
||||||
|
# Kick off the run
|
||||||
|
yield from self.stubs.send_rpc_and_wait("abr", "kickoff")
|
||||||
|
logger.info("Measurement launched on the ABR stage...")
|
||||||
|
|
||||||
|
logger.info("Performing SmarGon stepping...")
|
||||||
|
for ss in range(self.smargon_steps):
|
||||||
|
sg_pos = self.smargon_start + ss * self.smargon_step_size
|
||||||
|
# Move to position but don't care
|
||||||
|
st0 = yield from self.stubs.send_rpc("shx", "omove", sg_pos[0])
|
||||||
|
st1 = yield from self.stubs.send_rpc("shy", "omove", sg_pos[1])
|
||||||
|
st2 = yield from self.stubs.send_rpc("shz", "omove", sg_pos[2])
|
||||||
|
st3 = yield from self.stubs.send_rpc("chi", "omove", sg_pos[3])
|
||||||
|
st4 = yield from self.stubs.send_rpc("phi", "omove", sg_pos[4])
|
||||||
|
t_start = time.time()
|
||||||
|
st0.wait()
|
||||||
|
st1.wait()
|
||||||
|
st2.wait()
|
||||||
|
st3.wait()
|
||||||
|
st4.wait()
|
||||||
|
t_end = time.time()
|
||||||
|
t_elapsed = t_end-t_start
|
||||||
|
time.sleep(max(self.smargon_step_time-t_elapsed, 0))
|
||||||
|
|
||||||
|
# Wait for scan task to finish
|
||||||
|
if self.abr_complete:
|
||||||
|
if self.abr_timeout is not None:
|
||||||
|
st = yield from self.stubs.send_rpc_and_wait("abr", "complete", self.abr_timeout)
|
||||||
|
st.wait()
|
||||||
|
else:
|
||||||
|
st = yield from self.stubs.send_rpc_and_wait("abr", "complete")
|
||||||
|
st.wait()
|
||||||
|
|||||||
@@ -0,0 +1,52 @@
|
|||||||
|
from bec_widgets.cli.client_utils import BECGuiClient
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def ascan(
|
||||||
|
motor,
|
||||||
|
scan_start,
|
||||||
|
scan_end,
|
||||||
|
steps,
|
||||||
|
exp_time,
|
||||||
|
datasource,
|
||||||
|
**kwargs
|
||||||
|
):
|
||||||
|
"""Demo step scan with plotting
|
||||||
|
|
||||||
|
This is a small BEC user-space demo step scan. It tries to be a
|
||||||
|
standard BEC scan, while still setting up the environment.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
--------
|
||||||
|
ascan(dev.dccm_energy, 12,13, steps=21, exp_time=0.1, datasource=dev.dccm_xbpm)
|
||||||
|
"""
|
||||||
|
# if not bl_check_beam():
|
||||||
|
# raise RuntimeError("Beamline is not in ready state")
|
||||||
|
|
||||||
|
# # GUI setup
|
||||||
|
# # Get or create gui
|
||||||
|
# gui = BECGuiClient()
|
||||||
|
# gui.start()
|
||||||
|
# window = None
|
||||||
|
# for _, val in gui.windows.items():
|
||||||
|
# if val.title == "Current scan":
|
||||||
|
# window = val.widget
|
||||||
|
# window.clear_all()
|
||||||
|
# if window is None:
|
||||||
|
# window = gui.new("Current scan")
|
||||||
|
|
||||||
|
# dock = window.add_dock(f"ScanDisplay {motor}")
|
||||||
|
# plt1 = dock.add_widget('BECWaveformWidget')
|
||||||
|
# plt1.plot(x_name=motor, y_name=datasource)
|
||||||
|
# plt1.set_x_label(motor)
|
||||||
|
# plt1.set_y_label(datasource)
|
||||||
|
|
||||||
|
|
||||||
|
print("Handing over to 'scans.line_scan'")
|
||||||
|
if 'relative' in kwargs:
|
||||||
|
del kwargs['relative']
|
||||||
|
scans.line_scan(motor, scan_start, scan_end, steps=steps, exp_time=exp_time, relative=False, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
Reference in New Issue
Block a user