SnapNStep works, Sequence fails on Aerotech axis
This commit is contained in:
@@ -64,18 +64,18 @@ es1_roty:
|
|||||||
# readoutPriority: monitored
|
# readoutPriority: monitored
|
||||||
# softwareTrigger: false
|
# softwareTrigger: false
|
||||||
|
|
||||||
# es1_tasks:
|
es1_tasks:
|
||||||
# description: 'Automation1 task management interface'
|
description: 'Automation1 task management interface'
|
||||||
# deviceClass: tomcat_bec.devices.aa1Tasks
|
deviceClass: tomcat_bec.devices.aa1Tasks
|
||||||
# deviceConfig:
|
deviceConfig:
|
||||||
# prefix: 'X02DA-ES1-SMP1:TASK:'
|
prefix: 'X02DA-ES1-SMP1:TASK:'
|
||||||
# deviceTags:
|
deviceTags:
|
||||||
# - es1
|
- es1
|
||||||
# enabled: true
|
enabled: true
|
||||||
# onFailure: buffer
|
onFailure: buffer
|
||||||
# readOnly: false
|
readOnly: false
|
||||||
# readoutPriority: monitored
|
readoutPriority: monitored
|
||||||
# softwareTrigger: false
|
softwareTrigger: false
|
||||||
|
|
||||||
|
|
||||||
# es1_psod:
|
# es1_psod:
|
||||||
@@ -92,18 +92,18 @@ es1_roty:
|
|||||||
# softwareTrigger: true
|
# softwareTrigger: true
|
||||||
|
|
||||||
|
|
||||||
# es1_ddaq:
|
es1_ddaq:
|
||||||
# description: 'Automation1 position recording interface'
|
description: 'Automation1 position recording interface'
|
||||||
# deviceClass: tomcat_bec.devices.aa1AxisDriveDataCollection
|
deviceClass: tomcat_bec.devices.aa1AxisDriveDataCollection
|
||||||
# deviceConfig:
|
deviceConfig:
|
||||||
# prefix: 'X02DA-ES1-SMP1:ROTY:DDC:'
|
prefix: 'X02DA-ES1-SMP1:ROTY:DDC:'
|
||||||
# deviceTags:
|
deviceTags:
|
||||||
# - es1
|
- es1
|
||||||
# enabled: true
|
enabled: true
|
||||||
# onFailure: buffer
|
onFailure: buffer
|
||||||
# readOnly: false
|
readOnly: false
|
||||||
# readoutPriority: monitored
|
readoutPriority: monitored
|
||||||
# softwareTrigger: false
|
softwareTrigger: false
|
||||||
|
|
||||||
|
|
||||||
#camera:
|
#camera:
|
||||||
@@ -152,7 +152,7 @@ gfdaq:
|
|||||||
readoutPriority: monitored
|
readoutPriority: monitored
|
||||||
softwareTrigger: false
|
softwareTrigger: false
|
||||||
|
|
||||||
daq_stream0:
|
gf_stream0:
|
||||||
description: stdDAQ preview (2 every 555)
|
description: stdDAQ preview (2 every 555)
|
||||||
deviceClass: tomcat_bec.devices.StdDaqPreviewDetector
|
deviceClass: tomcat_bec.devices.StdDaqPreviewDetector
|
||||||
deviceConfig:
|
deviceConfig:
|
||||||
@@ -166,21 +166,6 @@ daq_stream0:
|
|||||||
readoutPriority: monitored
|
readoutPriority: monitored
|
||||||
softwareTrigger: false
|
softwareTrigger: false
|
||||||
|
|
||||||
daq_stream1:
|
|
||||||
description: stdDAQ preview (1 at 5 Hz)
|
|
||||||
deviceClass: tomcat_bec.devices.StdDaqPreviewDetector
|
|
||||||
deviceConfig:
|
|
||||||
url: 'tcp://129.129.95.111:20001'
|
|
||||||
deviceTags:
|
|
||||||
- std-daq
|
|
||||||
- gfcam
|
|
||||||
enabled: true
|
|
||||||
onFailure: buffer
|
|
||||||
readOnly: false
|
|
||||||
readoutPriority: monitored
|
|
||||||
softwareTrigger: false
|
|
||||||
|
|
||||||
|
|
||||||
pcocam:
|
pcocam:
|
||||||
description: PCO.edge camera client
|
description: PCO.edge camera client
|
||||||
deviceClass: tomcat_bec.devices.PcoEdge5M
|
deviceClass: tomcat_bec.devices.PcoEdge5M
|
||||||
|
|||||||
@@ -36,19 +36,22 @@ class AerotechDriveDataCollectionMixin(CustomDeviceMixin):
|
|||||||
# NOTE: Scans don't have to fully configure the device
|
# NOTE: Scans don't have to fully configure the device
|
||||||
if "ddc_trigger" in scanargs:
|
if "ddc_trigger" in scanargs:
|
||||||
d["ddc_trigger"] = scanargs["ddc_trigger"]
|
d["ddc_trigger"] = scanargs["ddc_trigger"]
|
||||||
if "ddc_num_points" in scanargs:
|
|
||||||
|
if "ddc_num_points" in scanargs and scanargs["ddc_num_points"] is not None:
|
||||||
d["num_points_total"] = scanargs["ddc_num_points"]
|
d["num_points_total"] = scanargs["ddc_num_points"]
|
||||||
|
elif "daq_num_points" in scanargs and scanargs["daq_num_points"] is not None:
|
||||||
|
d["num_points_total"] = scanargs["daq_num_points"]
|
||||||
else:
|
else:
|
||||||
# Try to figure out number of points
|
# Try to figure out number of points
|
||||||
num_points = 1
|
num_points = 1
|
||||||
points_valid = False
|
points_valid = False
|
||||||
if "steps" in scanargs and scanargs['steps'] is not None:
|
if "steps" in scanargs and scanargs["steps"] is not None:
|
||||||
num_points *= scanargs["steps"]
|
num_points *= scanargs["steps"]
|
||||||
points_valid = True
|
points_valid = True
|
||||||
elif "exp_burst" in scanargs and scanargs['exp_burst'] is not None:
|
if "exp_burst" in scanargs and scanargs["exp_burst"] is not None:
|
||||||
num_points *= scanargs["exp_burst"]
|
num_points *= scanargs["exp_burst"]
|
||||||
points_valid = True
|
points_valid = True
|
||||||
elif "repeats" in scanargs and scanargs['repeats'] is not None:
|
if "repeats" in scanargs and scanargs["repeats"] is not None:
|
||||||
num_points *= scanargs["repeats"]
|
num_points *= scanargs["repeats"]
|
||||||
points_valid = True
|
points_valid = True
|
||||||
if points_valid:
|
if points_valid:
|
||||||
@@ -143,6 +146,10 @@ class aa1AxisDriveDataCollection(PSIDeviceBase):
|
|||||||
"""Bluesky-style stage"""
|
"""Bluesky-style stage"""
|
||||||
self._switch.set("Start", settle_time=0.2).wait()
|
self._switch.set("Start", settle_time=0.2).wait()
|
||||||
|
|
||||||
|
def blueunstage(self):
|
||||||
|
"""Bluesky-style unstage"""
|
||||||
|
self._switch.set("Stop", settle_time=0.2).wait()
|
||||||
|
|
||||||
def reset(self):
|
def reset(self):
|
||||||
"""Reset incremental readback"""
|
"""Reset incremental readback"""
|
||||||
self._switch.set("ResetRB", settle_time=0.1).wait()
|
self._switch.set("ResetRB", settle_time=0.1).wait()
|
||||||
@@ -170,6 +177,8 @@ class aa1AxisDriveDataCollection(PSIDeviceBase):
|
|||||||
elif index == 1:
|
elif index == 1:
|
||||||
status = SubscriptionStatus(self._readstatus1, neg_edge, settle_time=0.5)
|
status = SubscriptionStatus(self._readstatus1, neg_edge, settle_time=0.5)
|
||||||
self._readback1.set(1).wait()
|
self._readback1.set(1).wait()
|
||||||
|
else:
|
||||||
|
raise ValueError(f"[{self.name}] Invalid data acquisition channel {index}")
|
||||||
|
|
||||||
# Start asynchronous readback
|
# Start asynchronous readback
|
||||||
status.wait()
|
status.wait()
|
||||||
|
|||||||
@@ -34,7 +34,8 @@ program
|
|||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
// Internal parameters - dont use
|
// Internal parameters - dont use
|
||||||
var $axis as axis = ROTY
|
var $axis as axis = ROTY
|
||||||
var $ii as integer
|
var $ii as integer
|
||||||
|
var $axisFaults as integer = 0
|
||||||
var $iDdcSafeSpace as integer = 4096
|
var $iDdcSafeSpace as integer = 4096
|
||||||
|
|
||||||
// Set acceleration
|
// Set acceleration
|
||||||
@@ -126,7 +127,12 @@ program
|
|||||||
if $eScanType == ScanType.POS || $eScanType == ScanType.NEG
|
if $eScanType == ScanType.POS || $eScanType == ScanType.NEG
|
||||||
PsoDistanceConfigureArrayDistances($axis, $iPsoArrayPosAddr, $iPsoArrayPosSize, 0)
|
PsoDistanceConfigureArrayDistances($axis, $iPsoArrayPosAddr, $iPsoArrayPosSize, 0)
|
||||||
MoveAbsolute($axis, $fPosEnd, $fVelScan)
|
MoveAbsolute($axis, $fPosEnd, $fVelScan)
|
||||||
WaitForInPosition($axis)
|
WaitForMotionDone($axis)
|
||||||
|
|
||||||
|
$axisFaults = StatusGetAxisItem($axis, AxisDataSignal.AxisFault)
|
||||||
|
if $axisFaults
|
||||||
|
TaskSetError(TaskGetIndex(), "AxisFault on axis ROTY")
|
||||||
|
end
|
||||||
elseif $eScanType == ScanType.POSNEG || $eScanType == ScanType.NEGPOS
|
elseif $eScanType == ScanType.POSNEG || $eScanType == ScanType.NEGPOS
|
||||||
for $ii = 0 to ($iNumRepeat-1)
|
for $ii = 0 to ($iNumRepeat-1)
|
||||||
// Feedback on progress
|
// Feedback on progress
|
||||||
@@ -134,11 +140,15 @@ program
|
|||||||
if ($ii % 2) == 0
|
if ($ii % 2) == 0
|
||||||
PsoDistanceConfigureArrayDistances($axis, $iPsoArrayPosAddr, $iPsoArrayPosSize, 0)
|
PsoDistanceConfigureArrayDistances($axis, $iPsoArrayPosAddr, $iPsoArrayPosSize, 0)
|
||||||
MoveAbsolute($axis, $fPosEnd, $fVelScan)
|
MoveAbsolute($axis, $fPosEnd, $fVelScan)
|
||||||
WaitForInPosition($axis)
|
|
||||||
elseif ($ii % 2) == 1
|
elseif ($ii % 2) == 1
|
||||||
PsoDistanceConfigureArrayDistances($axis, $iPsoArrayNegAddr, $iPsoArrayNegSize, 0)
|
PsoDistanceConfigureArrayDistances($axis, $iPsoArrayNegAddr, $iPsoArrayNegSize, 0)
|
||||||
MoveAbsolute($axis, $fPosStart, $fVelScan)
|
MoveAbsolute($axis, $fPosStart, $fVelScan)
|
||||||
WaitForInPosition($axis)
|
end
|
||||||
|
WaitForMotionDone($axis)
|
||||||
|
|
||||||
|
$axisFaults = StatusGetAxisItem($axis, AxisDataSignal.AxisFault)
|
||||||
|
if $axisFaults
|
||||||
|
TaskSetError(TaskGetIndex(), "AxisFault on axis ROTY")
|
||||||
end
|
end
|
||||||
Dwell(0.2)
|
Dwell(0.2)
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -78,6 +78,7 @@ program
|
|||||||
///////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////
|
||||||
$iglobal[2] = $iNumSteps
|
$iglobal[2] = $iNumSteps
|
||||||
for $ii = 0 to ($iNumSteps-1)
|
for $ii = 0 to ($iNumSteps-1)
|
||||||
|
$rglobal[4] = $ii
|
||||||
MoveAbsolute($axis, $fStartPosition + $ii * $fStepSize, $fVelScan)
|
MoveAbsolute($axis, $fStartPosition + $ii * $fStepSize, $fVelScan)
|
||||||
WaitForMotionDone($axis)
|
WaitForMotionDone($axis)
|
||||||
|
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ class AerotechTasksMixin(CustomDeviceMixin):
|
|||||||
|
|
||||||
# Perform bluesky-style configuration
|
# Perform bluesky-style configuration
|
||||||
if len(d) > 0:
|
if len(d) > 0:
|
||||||
logger.warning(f"[{self.parent.name}] Configuring with:\n{d}")
|
# logger.warning(f"[{self.parent.name}] Configuring with:\n{d}")
|
||||||
self.parent.configure(d=d)
|
self.parent.configure(d=d)
|
||||||
|
|
||||||
# The actual staging
|
# The actual staging
|
||||||
@@ -55,12 +55,16 @@ class AerotechTasksMixin(CustomDeviceMixin):
|
|||||||
|
|
||||||
def on_unstage(self):
|
def on_unstage(self):
|
||||||
"""Stop the currently selected task"""
|
"""Stop the currently selected task"""
|
||||||
self.parent.switch.set("Stop").wait()
|
self.parent.blueunstage()
|
||||||
|
|
||||||
def on_stop(self):
|
def on_stop(self):
|
||||||
"""Stop the currently selected task"""
|
"""Stop the currently selected task"""
|
||||||
self.parent.switch.set("Stop").wait()
|
self.parent.switch.set("Stop").wait()
|
||||||
|
|
||||||
|
def on_kickoff(self):
|
||||||
|
"""Start execution of the selected task"""
|
||||||
|
self.parent.bluekickoff()
|
||||||
|
|
||||||
|
|
||||||
class aa1Tasks(PSIDeviceBase):
|
class aa1Tasks(PSIDeviceBase):
|
||||||
"""Task management API
|
"""Task management API
|
||||||
@@ -146,6 +150,10 @@ class aa1Tasks(PSIDeviceBase):
|
|||||||
raise RuntimeError("Failed to load task, please check the Aerotech IOC")
|
raise RuntimeError("Failed to load task, please check the Aerotech IOC")
|
||||||
return status
|
return status
|
||||||
|
|
||||||
|
def blueunstage(self):
|
||||||
|
"""Bluesky style unstage, stops execution"""
|
||||||
|
self.switch.set("Stop").wait()
|
||||||
|
|
||||||
def bluekickoff(self):
|
def bluekickoff(self):
|
||||||
"""Bluesky style kickoff"""
|
"""Bluesky style kickoff"""
|
||||||
# Launch and check success
|
# Launch and check success
|
||||||
@@ -155,6 +163,10 @@ class aa1Tasks(PSIDeviceBase):
|
|||||||
raise RuntimeError("Failed to load task, please check the Aerotech IOC")
|
raise RuntimeError("Failed to load task, please check the Aerotech IOC")
|
||||||
return status
|
return status
|
||||||
|
|
||||||
|
def kickoff(self):
|
||||||
|
"""Missing kickoff, for real?"""
|
||||||
|
self.custom_prepare.on_kickoff()
|
||||||
|
|
||||||
##########################################################################
|
##########################################################################
|
||||||
# Bluesky flyer interface
|
# Bluesky flyer interface
|
||||||
def complete(self) -> DeviceStatus:
|
def complete(self) -> DeviceStatus:
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ Created on Thu Jun 27 17:28:43 2024
|
|||||||
@author: mohacsi_i
|
@author: mohacsi_i
|
||||||
"""
|
"""
|
||||||
from time import sleep
|
from time import sleep
|
||||||
from ophyd import Signal, SignalRO, Component, EpicsSignal, EpicsSignalRO, Kind, DeviceStatus
|
from ophyd import Signal, Component, EpicsSignal, EpicsSignalRO, Kind, DeviceStatus
|
||||||
from ophyd.device import DynamicDeviceComponent
|
from ophyd.device import DynamicDeviceComponent
|
||||||
from ophyd_devices.interfaces.base_classes.psi_detector_base import (
|
from ophyd_devices.interfaces.base_classes.psi_detector_base import (
|
||||||
CustomDetectorMixin,
|
CustomDetectorMixin,
|
||||||
@@ -174,6 +174,10 @@ class GigaFrostCameraMixin(CustomDetectorMixin):
|
|||||||
d["image_height"] = scanargs["image_height"]
|
d["image_height"] = scanargs["image_height"]
|
||||||
if "exp_time" in scanargs and scanargs["exp_time"] is not None:
|
if "exp_time" in scanargs and scanargs["exp_time"] is not None:
|
||||||
d["exposure_time_ms"] = scanargs["exp_time"]
|
d["exposure_time_ms"] = scanargs["exp_time"]
|
||||||
|
if "acq_time" in scanargs and scanargs["acq_time"] is not None:
|
||||||
|
d["exposure_time_ms"] = scanargs["acq_time"]
|
||||||
|
if "acq_period" in scanargs and scanargs["acq_period"] is not None:
|
||||||
|
d["exposure_period_ms"] = scanargs["acq_period"]
|
||||||
if "exp_burst" in scanargs and scanargs["exp_burst"] is not None:
|
if "exp_burst" in scanargs and scanargs["exp_burst"] is not None:
|
||||||
d["exposure_num_burst"] = scanargs["exp_burst"]
|
d["exposure_num_burst"] = scanargs["exp_burst"]
|
||||||
if "acq_mode" in scanargs and scanargs["acq_mode"] is not None:
|
if "acq_mode" in scanargs and scanargs["acq_mode"] is not None:
|
||||||
@@ -497,6 +501,7 @@ class GigaFrostCamera(PSIDetectorBase):
|
|||||||
|
|
||||||
# There's no status readback from the camera, so we just wait
|
# There's no status readback from the camera, so we just wait
|
||||||
sleep_time = self.cfgExposure.value * self.cfgCntNum.value * 0.001 + 0.2
|
sleep_time = self.cfgExposure.value * self.cfgCntNum.value * 0.001 + 0.2
|
||||||
|
logger.warning(f"Gigafrost sleeping for {sleep_time} sec")
|
||||||
sleep(sleep_time)
|
sleep(sleep_time)
|
||||||
return DeviceStatus(self, done=True, success=True, settle_time=sleep_time)
|
return DeviceStatus(self, done=True, success=True, settle_time=sleep_time)
|
||||||
|
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ Created on Wed Dec 6 11:33:54 2023
|
|||||||
import time
|
import time
|
||||||
from ophyd import Component, EpicsSignal, EpicsSignalRO, Kind
|
from ophyd import Component, EpicsSignal, EpicsSignalRO, Kind
|
||||||
from ophyd.status import SubscriptionStatus, DeviceStatus
|
from ophyd.status import SubscriptionStatus, DeviceStatus
|
||||||
from ophyd_devices import BECDeviceBase
|
from ophyd_devices.interfaces.base_classes.psi_detector_base import PSIDetectorBase as BECDeviceBase
|
||||||
from ophyd_devices.interfaces.base_classes.psi_detector_base import (
|
from ophyd_devices.interfaces.base_classes.psi_detector_base import (
|
||||||
CustomDetectorMixin as CustomPrepare,
|
CustomDetectorMixin as CustomPrepare,
|
||||||
)
|
)
|
||||||
@@ -54,6 +54,10 @@ class PcoEdgeCameraMixin(CustomPrepare):
|
|||||||
d["exposure_time_ms"] = scanargs["exp_time"]
|
d["exposure_time_ms"] = scanargs["exp_time"]
|
||||||
if "exp_period" in scanargs and scanargs["exp_period"] is not None:
|
if "exp_period" in scanargs and scanargs["exp_period"] is not None:
|
||||||
d["exposure_period_ms"] = scanargs["exp_period"]
|
d["exposure_period_ms"] = scanargs["exp_period"]
|
||||||
|
if "acq_time" in scanargs and scanargs["acq_time"] is not None:
|
||||||
|
d["exposure_time_ms"] = scanargs["acq_time"]
|
||||||
|
if "acq_period" in scanargs and scanargs["acq_period"] is not None:
|
||||||
|
d["exposure_period_ms"] = scanargs["acq_period"]
|
||||||
# if 'exp_burst' in scanargs and scanargs['exp_burst'] is not None:
|
# if 'exp_burst' in scanargs and scanargs['exp_burst'] is not None:
|
||||||
# d['exposure_num_burst'] = scanargs['exp_burst']
|
# d['exposure_num_burst'] = scanargs['exp_burst']
|
||||||
# if 'acq_mode' in scanargs and scanargs['acq_mode'] is not None:
|
# if 'acq_mode' in scanargs and scanargs['acq_mode'] is not None:
|
||||||
@@ -469,5 +473,5 @@ class PcoEdge5M(HelgeCameraBase):
|
|||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
|
||||||
# Drive data collection
|
# Drive data collection
|
||||||
cam = PcoEdge5M("X02DA-CCDCAM2:", name="mcpcam")
|
cam = PcoEdge5M(prefix="X02DA-CCDCAM2:", name="mcpcam")
|
||||||
cam.wait_for_connection()
|
cam.wait_for_connection()
|
||||||
|
|||||||
@@ -1,2 +1,2 @@
|
|||||||
from .tutorial_fly_scan import AcquireDark, AcquireWhite, AcquireRefs, TutorialFlyScanContLine
|
from .tutorial_fly_scan import AcquireDark, AcquireWhite, AcquireRefs, TutorialFlyScanContLine
|
||||||
from .tomcat_scans import TomcatStepScan, TomcatSnapNStep, TomcatSimpleSequence
|
from .tomcat_scans import TomcatSnapNStep, TomcatSimpleSequence
|
||||||
|
|||||||
@@ -18,95 +18,11 @@ import os
|
|||||||
import time
|
import time
|
||||||
|
|
||||||
from bec_lib import bec_logger
|
from bec_lib import bec_logger
|
||||||
from bec_server.scan_server.scans import AsyncFlyScanBase, ScanBase, ScanArgType
|
from bec_server.scan_server.scans import AsyncFlyScanBase, ScanArgType
|
||||||
|
|
||||||
logger = bec_logger.logger
|
logger = bec_logger.logger
|
||||||
|
|
||||||
|
|
||||||
class TomcatStepScan(ScanBase):
|
|
||||||
"""Simple software step scan for Tomcat
|
|
||||||
|
|
||||||
Example class for simple BEC-based step scan using the low-level API. It's just a standard
|
|
||||||
'line_scan' with the only difference that overrides burst behavior to use camera burst instead
|
|
||||||
of individual software triggers.
|
|
||||||
|
|
||||||
NOTE: As decided by Tomcat, the scans should not manage the scope of devices
|
|
||||||
- All enabled devices are expected to be configured for acquisition by the end of stage
|
|
||||||
- Some devices can configure themselves from mandatory scan parameters (steps, burst)
|
|
||||||
- Other devices can be optionally configured by keyword arguments
|
|
||||||
- Devices will try to stage using whatever was set on them before
|
|
||||||
|
|
||||||
Example:
|
|
||||||
--------
|
|
||||||
>>> scans.tomcatstepscan(scan_start=-25, scan_end=155, steps=180, exp_time=0.005, exp_burst=5)
|
|
||||||
|
|
||||||
Common keyword arguments:
|
|
||||||
-------------------------
|
|
||||||
image_width : int
|
|
||||||
image_height : int
|
|
||||||
ddc_trigger : str
|
|
||||||
"""
|
|
||||||
|
|
||||||
scan_name = "tomcatstepscan"
|
|
||||||
scan_type = "step"
|
|
||||||
required_kwargs = ["scan_start", "scan_end", "steps"]
|
|
||||||
gui_config = {
|
|
||||||
"Movement parameters": ["steps"],
|
|
||||||
"Acquisition parameters": ["exp_time", "exp_burst"],
|
|
||||||
}
|
|
||||||
|
|
||||||
def update_scan_motors(self):
|
|
||||||
self.scan_motors = ["es1_roty"]
|
|
||||||
|
|
||||||
def _get_scan_motors(self):
|
|
||||||
self.scan_motors = ["es1_roty"]
|
|
||||||
|
|
||||||
def __init__(
|
|
||||||
self,
|
|
||||||
scan_start: float,
|
|
||||||
scan_end: float,
|
|
||||||
steps: int,
|
|
||||||
exp_time: float=0.005,
|
|
||||||
settling_time: float=0.2,
|
|
||||||
exp_burst: int=1,
|
|
||||||
**kwargs,
|
|
||||||
):
|
|
||||||
# Converting generic kwargs to tomcat device configuration parameters
|
|
||||||
super().__init__(
|
|
||||||
exp_time=exp_time,
|
|
||||||
settling_time=settling_time,
|
|
||||||
burst_at_each_point=1,
|
|
||||||
optim_trajectory=None,
|
|
||||||
**kwargs,
|
|
||||||
)
|
|
||||||
|
|
||||||
# For position calculation
|
|
||||||
self.motor = "es1_roty"
|
|
||||||
self.scan_start = scan_start
|
|
||||||
self.scan_end = scan_end
|
|
||||||
self.scan_steps = steps
|
|
||||||
self.scan_stepsize = (scan_end - scan_start) / steps
|
|
||||||
|
|
||||||
def _calculate_positions(self) -> None:
|
|
||||||
"""Pre-calculate scan positions"""
|
|
||||||
for ii in range(self.scan_steps + 1):
|
|
||||||
self.positions.append(self.scan_start + ii * self.scan_stepsize)
|
|
||||||
|
|
||||||
def _at_each_point(self, ind=None, pos=None):
|
|
||||||
""" Overriden at_each_point, using detector burst instaead of manual triggering"""
|
|
||||||
yield from self._move_scan_motors_and_wait(pos)
|
|
||||||
time.sleep(self.settling_time)
|
|
||||||
|
|
||||||
trigger_time = 0.001*self.exp_time * self.burst_at_each_point
|
|
||||||
yield from self.stubs.trigger(min_wait=trigger_time)
|
|
||||||
# yield from self.stubs.trigger(group='trigger', point_id=self.point_id)
|
|
||||||
# time.sleep(trigger_time)
|
|
||||||
|
|
||||||
yield from self.stubs.read(group="monitored", point_id=self.point_id)
|
|
||||||
# yield from self.stubs.read(group="monitored", point_id=self.point_id, wait_group=None)
|
|
||||||
self.point_id += 1
|
|
||||||
|
|
||||||
|
|
||||||
class TomcatSnapNStep(AsyncFlyScanBase):
|
class TomcatSnapNStep(AsyncFlyScanBase):
|
||||||
"""Simple software step scan forTomcat
|
"""Simple software step scan forTomcat
|
||||||
|
|
||||||
@@ -115,7 +31,7 @@ class TomcatSnapNStep(AsyncFlyScanBase):
|
|||||||
|
|
||||||
Example
|
Example
|
||||||
-------
|
-------
|
||||||
>>> scans.tomcatsnapnstepscan(scan_start=-25, scan_end=155, steps=180, exp_time=0.005, exp_burst=5)
|
>>> scans.tomcatsnapnstepscan(scan_start=-25, scan_end=155, steps=180, acq_time=5, exp_burst=5)
|
||||||
"""
|
"""
|
||||||
|
|
||||||
scan_name = "tomcatsnapnstepscan"
|
scan_name = "tomcatsnapnstepscan"
|
||||||
@@ -126,10 +42,10 @@ class TomcatSnapNStep(AsyncFlyScanBase):
|
|||||||
required_kwargs = ["scan_start", "scan_end", "steps"]
|
required_kwargs = ["scan_start", "scan_end", "steps"]
|
||||||
gui_config = {
|
gui_config = {
|
||||||
"Movement parameters": ["steps"],
|
"Movement parameters": ["steps"],
|
||||||
"Acquisition parameters": ["exp_time", "exp_burst"],
|
"Acquisition parameters": ["acq_time", "exp_burst"],
|
||||||
}
|
}
|
||||||
|
|
||||||
def _get_scan_motors(self):
|
def _update_scan_motors(self):
|
||||||
self.scan_motors = ["es1_roty"]
|
self.scan_motors = ["es1_roty"]
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
@@ -137,8 +53,8 @@ class TomcatSnapNStep(AsyncFlyScanBase):
|
|||||||
scan_start: float,
|
scan_start: float,
|
||||||
scan_end: float,
|
scan_end: float,
|
||||||
steps: int,
|
steps: int,
|
||||||
exp_time:float=0.005,
|
|
||||||
settling_time:float=0.2,
|
settling_time:float=0.2,
|
||||||
|
acq_time:float=5.0,
|
||||||
exp_burst:int=1,
|
exp_burst:int=1,
|
||||||
sync:str="event",
|
sync:str="event",
|
||||||
**kwargs,
|
**kwargs,
|
||||||
@@ -147,14 +63,12 @@ class TomcatSnapNStep(AsyncFlyScanBase):
|
|||||||
self.scan_start = scan_start
|
self.scan_start = scan_start
|
||||||
self.scan_end = scan_end
|
self.scan_end = scan_end
|
||||||
self.scan_steps = steps
|
self.scan_steps = steps
|
||||||
self.scan_stepsize = (scan_end - scan_start) / steps
|
self.exp_time = acq_time
|
||||||
self.scan_ntotal = exp_burst * (steps + 1)
|
|
||||||
self.exp_time = exp_time
|
|
||||||
self.exp_burst = exp_burst
|
self.exp_burst = exp_burst
|
||||||
self.settling_time = settling_time
|
self.settling_time = settling_time
|
||||||
self.scan_sync = sync
|
self.scan_sync = sync
|
||||||
|
|
||||||
# General device configuration
|
# Gigafrost trigger mode
|
||||||
kwargs["parameter"]["kwargs"]["acq_mode"] = "ext_enable"
|
kwargs["parameter"]["kwargs"]["acq_mode"] = "ext_enable"
|
||||||
|
|
||||||
# Used for Aeroscript file substitutions for the task interface
|
# Used for Aeroscript file substitutions for the task interface
|
||||||
@@ -165,7 +79,8 @@ class TomcatSnapNStep(AsyncFlyScanBase):
|
|||||||
kwargs["parameter"]["kwargs"]["script_file"] = "bec.ascript"
|
kwargs["parameter"]["kwargs"]["script_file"] = "bec.ascript"
|
||||||
|
|
||||||
super().__init__(
|
super().__init__(
|
||||||
exp_time=exp_time,
|
acq_time=acq_time,
|
||||||
|
exp_burst=exp_burst,
|
||||||
settling_time=settling_time,
|
settling_time=settling_time,
|
||||||
burst_at_each_point=1,
|
burst_at_each_point=1,
|
||||||
optim_trajectory=None,
|
optim_trajectory=None,
|
||||||
@@ -182,12 +97,12 @@ class TomcatSnapNStep(AsyncFlyScanBase):
|
|||||||
}
|
}
|
||||||
filesubs = {
|
filesubs = {
|
||||||
"startpos": self.scan_start,
|
"startpos": self.scan_start,
|
||||||
"stepsize": self.scan_stepsize,
|
"stepsize": (self.scan_end - self.scan_start) / self.scan_steps,
|
||||||
"numsteps": self.scan_steps,
|
"numsteps": self.scan_steps,
|
||||||
"exptime": 2 * self.exp_time * self.exp_burst,
|
"exptime": 0.002 * self.exp_time * self.exp_burst,
|
||||||
"settling": self.settling_time,
|
"settling": self.settling_time,
|
||||||
"psotrigger": p_modes[self.scan_sync],
|
"psotrigger": p_modes[self.scan_sync],
|
||||||
"npoints": self.scan_ntotal,
|
"npoints": self.exp_burst * (self.scan_steps + 1),
|
||||||
}
|
}
|
||||||
return filesubs
|
return filesubs
|
||||||
|
|
||||||
@@ -196,7 +111,7 @@ class TomcatSnapNStep(AsyncFlyScanBase):
|
|||||||
# Load the test file
|
# Load the test file
|
||||||
filename = os.path.join(os.path.dirname(__file__), "../devices/aerotech/" + filename)
|
filename = os.path.join(os.path.dirname(__file__), "../devices/aerotech/" + filename)
|
||||||
logger.info(f"Attempting to load file {filename}")
|
logger.info(f"Attempting to load file {filename}")
|
||||||
with open(filename) as f:
|
with open(filename, "r", encoding="utf-8") as f:
|
||||||
templatetext = f.read()
|
templatetext = f.read()
|
||||||
|
|
||||||
# Substitute jinja template
|
# Substitute jinja template
|
||||||
@@ -208,12 +123,15 @@ class TomcatSnapNStep(AsyncFlyScanBase):
|
|||||||
"""The actual scan routine"""
|
"""The actual scan routine"""
|
||||||
print("TOMCAT Running scripted scan (via Jinjad AeroScript)")
|
print("TOMCAT Running scripted scan (via Jinjad AeroScript)")
|
||||||
t_start = time.time()
|
t_start = time.time()
|
||||||
|
# Kickoff
|
||||||
|
yield from self.stubs.send_rpc_and_wait("es1_tasks", "kickoff")
|
||||||
|
|
||||||
# Complete
|
# Complete
|
||||||
# FIXME: this will swallow errors
|
# FIXME: this will swallow errors
|
||||||
# yield from self.stubs.complete(device="es1_tasks")
|
# yield from self.stubs.complete(device="es1_tasks")
|
||||||
st = yield from self.stubs.send_rpc_and_wait("es1_tasks", "complete")
|
yield from self.stubs.send_rpc_and_wait("es1_tasks", "complete")
|
||||||
# st.wait()
|
|
||||||
|
# Check final state
|
||||||
task_states = yield from self.stubs.send_rpc_and_wait("es1_tasks", "taskStates.get")
|
task_states = yield from self.stubs.send_rpc_and_wait("es1_tasks", "taskStates.get")
|
||||||
if task_states[4] == 8:
|
if task_states[4] == 8:
|
||||||
raise RuntimeError(f"Task {4} finished in ERROR state")
|
raise RuntimeError(f"Task {4} finished in ERROR state")
|
||||||
@@ -243,7 +161,7 @@ class TomcatSimpleSequence(AsyncFlyScanBase):
|
|||||||
|
|
||||||
Example
|
Example
|
||||||
-------
|
-------
|
||||||
>>> scans.tomcatsimplesequencescan(33, 180, 180, exp_time=0.005, exp_burst=1800, repeats=10)
|
>>> scans.tomcatsimplesequencescan(33, 180, 180, acq_time=5, exp_burst=1800, repeats=10)
|
||||||
"""
|
"""
|
||||||
|
|
||||||
scan_name = "tomcatsimplesequencescan"
|
scan_name = "tomcatsimplesequencescan"
|
||||||
@@ -255,7 +173,7 @@ class TomcatSimpleSequence(AsyncFlyScanBase):
|
|||||||
"Acquisition parameters": [
|
"Acquisition parameters": [
|
||||||
"gate_high",
|
"gate_high",
|
||||||
"gate_low",
|
"gate_low",
|
||||||
"exp_time",
|
"acq_time",
|
||||||
"exp_burst",
|
"exp_burst",
|
||||||
"sync",
|
"sync",
|
||||||
],
|
],
|
||||||
@@ -271,7 +189,7 @@ class TomcatSimpleSequence(AsyncFlyScanBase):
|
|||||||
gate_low: float,
|
gate_low: float,
|
||||||
repeats: int = 1,
|
repeats: int = 1,
|
||||||
repmode: str = "PosNeg",
|
repmode: str = "PosNeg",
|
||||||
exp_time: float = 0.005,
|
acq_time: float = 5,
|
||||||
exp_burst: float = 180,
|
exp_burst: float = 180,
|
||||||
sync: str = "pso",
|
sync: str = "pso",
|
||||||
**kwargs,
|
**kwargs,
|
||||||
@@ -282,13 +200,13 @@ class TomcatSimpleSequence(AsyncFlyScanBase):
|
|||||||
self.gate_low = gate_low
|
self.gate_low = gate_low
|
||||||
self.scan_repnum = repeats
|
self.scan_repnum = repeats
|
||||||
self.scan_repmode = repmode.upper()
|
self.scan_repmode = repmode.upper()
|
||||||
self.exp_time = exp_time
|
self.exp_time = acq_time
|
||||||
self.exp_burst = exp_burst
|
self.exp_burst = exp_burst
|
||||||
self.scan_sync = sync
|
self.scan_sync = sync
|
||||||
|
|
||||||
# Synthetic values
|
# Synthetic values
|
||||||
self.scan_ntotal = exp_burst * repeats
|
self.scan_ntotal = exp_burst * repeats
|
||||||
self.scan_velocity = gate_high / (exp_time * exp_burst)
|
self.scan_velocity = gate_high / (0.001*acq_time * exp_burst)
|
||||||
self.scan_acceleration = 500
|
self.scan_acceleration = 500
|
||||||
self.scan_safedistance = 10
|
self.scan_safedistance = 10
|
||||||
self.scan_accdistance = (
|
self.scan_accdistance = (
|
||||||
@@ -314,7 +232,7 @@ class TomcatSimpleSequence(AsyncFlyScanBase):
|
|||||||
kwargs["parameter"]["kwargs"]["script_file"] = "bec.ascript"
|
kwargs["parameter"]["kwargs"]["script_file"] = "bec.ascript"
|
||||||
|
|
||||||
super().__init__(
|
super().__init__(
|
||||||
exp_time=exp_time,
|
acq_time=acq_time,
|
||||||
settling_time=0.5,
|
settling_time=0.5,
|
||||||
relative=False,
|
relative=False,
|
||||||
burst_at_each_point=1,
|
burst_at_each_point=1,
|
||||||
@@ -327,7 +245,7 @@ class TomcatSimpleSequence(AsyncFlyScanBase):
|
|||||||
# Load the test file
|
# Load the test file
|
||||||
filename = os.path.join(os.path.dirname(__file__), "../devices/aerotech/" + filename)
|
filename = os.path.join(os.path.dirname(__file__), "../devices/aerotech/" + filename)
|
||||||
logger.info(f"Attempting to load file {filename}")
|
logger.info(f"Attempting to load file {filename}")
|
||||||
with open(filename) as f:
|
with open(filename, 'r', encoding="utf-8") as f:
|
||||||
templatetext = f.read()
|
templatetext = f.read()
|
||||||
|
|
||||||
# Substitute jinja template
|
# Substitute jinja template
|
||||||
@@ -339,12 +257,14 @@ class TomcatSimpleSequence(AsyncFlyScanBase):
|
|||||||
"""The actual scan routine"""
|
"""The actual scan routine"""
|
||||||
print("TOMCAT Running scripted scan (via Jinjad AeroScript)")
|
print("TOMCAT Running scripted scan (via Jinjad AeroScript)")
|
||||||
t_start = time.time()
|
t_start = time.time()
|
||||||
|
# Kickoff
|
||||||
|
yield from self.stubs.send_rpc_and_wait("es1_tasks", "kickoff")
|
||||||
|
|
||||||
# Complete
|
# Complete
|
||||||
# FIXME: this will swallow errors
|
# FIXME: this will swallow errors
|
||||||
# yield from self.stubs.complete(device="es1_tasks")
|
# yield from self.stubs.complete(device="es1_tasks")
|
||||||
st = yield from self.stubs.send_rpc_and_wait("es1_tasks", "complete")
|
yield from self.stubs.send_rpc_and_wait("es1_tasks", "complete")
|
||||||
# st.wait()
|
|
||||||
task_states = yield from self.stubs.send_rpc_and_wait("es1_tasks", "taskStates.get")
|
task_states = yield from self.stubs.send_rpc_and_wait("es1_tasks", "taskStates.get")
|
||||||
if task_states[4] == 8:
|
if task_states[4] == 8:
|
||||||
raise RuntimeError(f"Task {4} finished in ERROR state")
|
raise RuntimeError(f"Task {4} finished in ERROR state")
|
||||||
|
|||||||
Reference in New Issue
Block a user