Dailiy commit
This commit is contained in:
@@ -48,6 +48,9 @@ class AerotechFlyscanBase(AsyncFlyScanBase):
|
||||
Low-level base class for standard scans at the PX beamlines at SLS. Theese scans use the
|
||||
A3200 rotation stage and the actual experiment is performed using an AeroBasic script
|
||||
controlled via global variables.
|
||||
|
||||
IMPORTANT: The AeroBasic scripts take care of the PSO configuration.
|
||||
|
||||
"""
|
||||
scan_report_hint = "table"
|
||||
arg_input = {}
|
||||
@@ -126,17 +129,17 @@ class AerotechFlyscanBase(AsyncFlyScanBase):
|
||||
|
||||
|
||||
class MeasureStandardWedge(AerotechFlyscanBase):
|
||||
""" Standard wedge scan
|
||||
""" Standard wedge scan using the OMEGA motor
|
||||
|
||||
Measure a standard continous line scan from `start` to `start` + `range`
|
||||
during `scan_time` on the Omega axis.
|
||||
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, scan_time=20)
|
||||
>>> scans.standard_wedge(start=42, range=10, move_time=20)
|
||||
|
||||
Parameters
|
||||
----------
|
||||
@@ -144,26 +147,26 @@ class MeasureStandardWedge(AerotechFlyscanBase):
|
||||
Scan start position of the axis.
|
||||
range : (float, float)
|
||||
Scan range of the axis.
|
||||
scan_time : (float)
|
||||
Total fly time for the movement [s].
|
||||
move_time : (float)
|
||||
Total travel time for the movement [s].
|
||||
ready_rate : float, optional
|
||||
No clue what is this... (default=500)
|
||||
"""
|
||||
scan_name = "standard_wedge"
|
||||
required_kwargs = ["start", "range", "scan_time"]
|
||||
required_kwargs = ["start", "range", "move_time"]
|
||||
|
||||
def __init__(self, *args, parameter: dict = None, **kwargs):
|
||||
self.axis = ['omega']
|
||||
self.axis = ['abr.omega']
|
||||
# Set parameters from meaningful inputs
|
||||
self.scan_start = parameter['kwargs'].get("start")
|
||||
self.scan_range = parameter['kwargs'].get("range")
|
||||
self.scan_scan_time = parameter['kwargs'].get("scan_time")
|
||||
self.scan_move_time = parameter['kwargs'].get("move_time")
|
||||
self.scan_ready_rate = parameter['kwargs'].get("ready_rate", 500)
|
||||
self.abr_command = AbrCmd.MEASURE_STANDARD
|
||||
self.abr_globals = {
|
||||
"var_1" : self.scan_start,
|
||||
"var_2" : self.scan_range,
|
||||
"var_3" : self.scan_scan_time,
|
||||
"var_3" : self.scan_move_time,
|
||||
"var_4" : self.scan_ready_rate,
|
||||
}
|
||||
# Call base class
|
||||
@@ -171,40 +174,88 @@ class MeasureStandardWedge(AerotechFlyscanBase):
|
||||
|
||||
|
||||
|
||||
class MeasureScanSlits(AerotechFlyscanBase):
|
||||
""" Slit scan
|
||||
|
||||
Measure a standard slit scan.
|
||||
class MeasureVerticalLine(AerotechFlyscanBase):
|
||||
""" Vertical line scan using the GMY motor
|
||||
|
||||
Simple relative continous line scan that records a single vertical line
|
||||
with PSO output. There's no actual stepping, it's only used for velocity
|
||||
calculation.
|
||||
|
||||
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.slit_scan(start=42, range=10, scan_time=20)
|
||||
>>> scans.measure_vline(range_y=12, steps_y=40, exp_time=0.1)
|
||||
|
||||
Parameters
|
||||
----------
|
||||
delta_x : (float, float)
|
||||
Scan range with slit in x.
|
||||
delta_y : (float, float)
|
||||
Scan range with slit in y.
|
||||
velocity : (float)
|
||||
Scan velocity [mm/s].
|
||||
range_y : float
|
||||
Step size [mm].
|
||||
steps_y : int
|
||||
Scan range of the axis.
|
||||
exp_time : float
|
||||
Eeffective exposure time per step [s]
|
||||
"""
|
||||
scan_name = "slit_scan"
|
||||
required_kwargs = ["delta_x", "delta_y", "velocity"]
|
||||
scan_name = "measure_vline"
|
||||
required_kwargs = ["exp_time", "range_y", "steps_y"]
|
||||
|
||||
def __init__(self, *args, parameter: dict = None, **kwargs):
|
||||
self.axis = []
|
||||
self.axis = ['abr.gmy']
|
||||
# Set parameters from meaningful inputs
|
||||
self.scan_exp_time = parameter['kwargs'].get("exp_time")
|
||||
self.scan_range_y = parameter['kwargs'].get("range_y")
|
||||
self.scan_stepnum_y = parameter['kwargs'].get("steps_y")
|
||||
self.scan_stepsize_y = self.scan_range_y / self.scan_stepnum_y
|
||||
|
||||
self.abr_command = AbrCmd.VERTICAL_LINE_SCAN
|
||||
self.abr_globals = {
|
||||
'var_1': self.scan_exp_time,
|
||||
'var_2': self.scan_stepsize_y,
|
||||
'var_3': self.scan_stepnum_y,
|
||||
}
|
||||
# Call base class
|
||||
super().__init__(parameter=parameter, **kwargs)
|
||||
|
||||
|
||||
|
||||
class MeasureScanSlits(AerotechFlyscanBase):
|
||||
""" Coordinated scan
|
||||
|
||||
Measure a hardware coordinated relative line scan with the X- and Y axes.
|
||||
This is used to accurately track solid supports with long linear grooves,
|
||||
as theese might be slightly rotated.
|
||||
|
||||
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.slit_scan(range=[10, 0.3], scan_time=20)
|
||||
|
||||
Parameters
|
||||
----------
|
||||
range_x : float
|
||||
Move distance in X [mm].
|
||||
range_y : float
|
||||
Move distance in Y [mm].
|
||||
velocity : float
|
||||
Effective movement velocity [mm/s].
|
||||
"""
|
||||
scan_name = "slit_scan"
|
||||
required_kwargs = ["range", "velocity"]
|
||||
|
||||
def __init__(self, *args, parameter: dict = None, **kwargs):
|
||||
self.axis = ["abr.gmx", "abr.gmy"]
|
||||
# Set parameters from meaningful inputs
|
||||
self.abr_command = AbrCmd.SLIT_SCAN
|
||||
self.scan_delta_x = parameter['kwargs'].get("delta_x")
|
||||
self.scan_delta_y = parameter['kwargs'].get("delta_y")
|
||||
self.scan_range_x = parameter['kwargs'].get("range_x")
|
||||
self.scan_range_y = parameter['kwargs'].get("range_y")
|
||||
self.scan_velocity = parameter['kwargs'].get("velocity")
|
||||
self.abr_globals = {
|
||||
"var_1" : self.scan_delta_x,
|
||||
"var_2" : self.scan_delta_y,
|
||||
"var_1" : self.scan_range_x,
|
||||
"var_2" : self.scan_range_y,
|
||||
"var_3" : self.scan_velocity,
|
||||
}
|
||||
# Call base class
|
||||
@@ -215,40 +266,45 @@ class MeasureScanSlits(AerotechFlyscanBase):
|
||||
class MeasureRasterSimple(AerotechFlyscanBase):
|
||||
""" Simple raster scan
|
||||
|
||||
Measure a simplified raster scan, assuming the goniometer is currently
|
||||
at the CENTER of TOP-LEFT CELL.
|
||||
Measure a simplified relative zigzag raster scan in the X-Y plane.
|
||||
The scan is relative assumes the goniometer is currently at the CENTER of
|
||||
the first cell (i.e. TOP-LEFT). Each line is executed as a single continous
|
||||
movement, i.e. there's no actual stepping in the X direction.
|
||||
|
||||
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.raster_simple(exp_time=0.5, cell_width=0.2, cell_height=0.2, ncols=10, nrows=10)
|
||||
>>> scans.raster_simple(exp_time=0.1, range_x=4, range_y=4, steps_x=80, steps_y=80)
|
||||
|
||||
Parameters
|
||||
----------
|
||||
exp_time : (float)
|
||||
Exposure time per point [s].
|
||||
cell_width : (float)
|
||||
exp_time : float
|
||||
Effective exposure time for each cell along the X axis [s].
|
||||
range_x : float
|
||||
Scan step size [mm].
|
||||
cell_height : (float)
|
||||
range_y : float
|
||||
Scan step size [mm].
|
||||
ncols : (int)
|
||||
Number of scan steps.
|
||||
nrows : (int)
|
||||
Number of scan steps.
|
||||
steps_x : int
|
||||
Number of scan steps in X (fast). Only used for velocity calculation.
|
||||
steps_y : int
|
||||
Number of scan steps in Y (slow).
|
||||
"""
|
||||
scan_name = "raster_simple"
|
||||
required_kwargs = ["exp_time", "cell_width", "cell_height", "ncols", "nrows"]
|
||||
required_kwargs = ["exp_time", "range_x", "range_y", "steps_x", "steps_y"]
|
||||
|
||||
def __init__(self, *args, parameter: dict = None, **kwargs):
|
||||
self.axis = []
|
||||
self.axis = ['abr.gmx', 'abr.gmy']
|
||||
# Set parameters from meaningful inputs
|
||||
self.scan_exp_time = parameter['kwargs'].get("exp_time")
|
||||
self.scan_stepsize_x = parameter['kwargs'].get("cell_width")
|
||||
self.scan_stepsize_y = parameter['kwargs'].get("cell_height")
|
||||
self.scan_stepnum_x = parameter['kwargs'].get("ncols")
|
||||
self.scan_stepnum_y = parameter['kwargs'].get("nrows")
|
||||
self.scan_range_x = parameter['kwargs'].get("range_x")
|
||||
self.scan_range_y = parameter['kwargs'].get("range_y")
|
||||
self.scan_stepnum_x = parameter['kwargs'].get("steps_x")
|
||||
self.scan_stepnum_y = parameter['kwargs'].get("steps_y")
|
||||
self.scan_stepsize_x = self.scan_range_x / self.scan_stepnum_x
|
||||
self.scan_stepsize_y = self.scan_range_y / self.scan_stepnum_y
|
||||
|
||||
self.abr_command = AbrCmd.RASTER_SCAN_SIMPLE
|
||||
self.abr_raster_reset = True
|
||||
self.abr_globals = {
|
||||
@@ -269,29 +325,33 @@ class MeasureRasterSimple(AerotechFlyscanBase):
|
||||
class MeasureSASTT(AerotechFlyscanBase):
|
||||
""" Small angle scanning tensor tomography scan
|
||||
|
||||
Measure a Small Angle Scanning Tensor Tomography scan on the specified
|
||||
grid assuming the goniometer is currently at the CENTER of the required
|
||||
grid.
|
||||
Measure a single projection for Small Angle Scanning Tensor Tomography.
|
||||
It's essentially a separate grid scan, that can be modified independently.
|
||||
The scan is relative and assumes the goniometer is currently at the CENTER
|
||||
of the first cell (i.e. TOP-LEFT). Each line is executed as a single
|
||||
continous movement, there's no actual stepping in the X direction.
|
||||
|
||||
NOTE: Not all beamlines have all SASTT modes implemented.
|
||||
|
||||
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.measure_sastt(exp_time=1.0, cell_width=0.01, cell_height=0.01, ncols=100, nrows=100)
|
||||
>>> scans.measure_sastt(exp_time=0.01, range_x=1, range_y=1, steps_x=200, steps_y=200)
|
||||
|
||||
Parameters
|
||||
----------
|
||||
exp_time : (float)
|
||||
Exposure time per point [s].
|
||||
cell_width : (float)
|
||||
exp_time : float
|
||||
Effective exposure time for each cell along the X axis [s].
|
||||
range_x : float
|
||||
Scan step size [mm].
|
||||
cell_height : (float)
|
||||
range_y : float
|
||||
Scan step size [mm].
|
||||
ncols : (int)
|
||||
Number of scan steps.
|
||||
nrows : (int)
|
||||
Number of scan steps.
|
||||
steps_x : int
|
||||
Number of scan steps in X (fast). Only used for velocity calculation.
|
||||
steps_y : int
|
||||
Number of scan steps in Y (slow).
|
||||
odd_tweak : (float)
|
||||
Distance to be added before the open shutter command [mm].
|
||||
Used only in scan version=3. Should be small (default: 0)!
|
||||
@@ -305,10 +365,10 @@ class MeasureSASTT(AerotechFlyscanBase):
|
||||
3 = snake scan alternating PSO window for even/odd rows
|
||||
"""
|
||||
scan_name = "measure_sastt"
|
||||
required_kwargs = ["exp_time", "cell_width", "cell_height", "ncols", "nrows"]
|
||||
required_kwargs = ["exp_time", "range_x", "range_y", "steps_x", "steps_y"]
|
||||
|
||||
def __init__(self, *args, parameter: dict = None, **kwargs):
|
||||
self.axis = []
|
||||
self.axis = ['abr.gmx', 'abr.gmy']
|
||||
# Set parameters from meaningful inputs
|
||||
self.scan_version = int(parameter['kwargs'].get("version", 1))
|
||||
if self.scan_version==1:
|
||||
@@ -319,14 +379,18 @@ class MeasureSASTT(AerotechFlyscanBase):
|
||||
self.abr_command = AbrCmd.SCAN_SASTT_V3
|
||||
else:
|
||||
raise RuntimeError(f"Non existing SAS-TT scan mode: {self.scan_version}")
|
||||
|
||||
|
||||
# Set parameters from meaningful inputs
|
||||
self.scan_exp_time = parameter['kwargs'].get("exp_time")
|
||||
self.scan_stepsize_x = parameter['kwargs'].get("cell_width")
|
||||
self.scan_stepsize_y = parameter['kwargs'].get("cell_height")
|
||||
self.scan_stepnum_x = parameter['kwargs'].get("ncols")
|
||||
self.scan_stepnum_y = parameter['kwargs'].get("nrows")
|
||||
self.scan_range_x = parameter['kwargs'].get("range_x")
|
||||
self.scan_range_y = parameter['kwargs'].get("range_y")
|
||||
self.scan_stepnum_x = parameter['kwargs'].get("steps_x")
|
||||
self.scan_stepnum_y = parameter['kwargs'].get("steps_y")
|
||||
self.scan_even_tweak = parameter['kwargs'].get("even_tweak", 0)
|
||||
self.scan_odd_tweak = parameter['kwargs'].get("odd_tweak", 0)
|
||||
self.scan_stepsize_x = self.scan_range_x / self.scan_stepnum_x
|
||||
self.scan_stepsize_y = self.scan_range_y / self.scan_stepnum_y
|
||||
|
||||
self.abr_globals = {
|
||||
'var_1': self.scan_exp_time,
|
||||
'var_2': self.scan_stepsize_x,
|
||||
@@ -342,90 +406,57 @@ class MeasureSASTT(AerotechFlyscanBase):
|
||||
|
||||
|
||||
|
||||
class MeasureVerticalLine(AerotechFlyscanBase):
|
||||
""" Vertical line scan using the GMY motor
|
||||
|
||||
Simple fly scan that records a single vertical line.
|
||||
The line is nummCells * cellHeight long and the exposureTime is per cell.
|
||||
|
||||
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.measure_vline(cell_height=12, cell_num=10, cell_time=20)
|
||||
|
||||
Parameters
|
||||
----------
|
||||
cell_height : (float)
|
||||
Step size [mm].
|
||||
cell_num : (int)
|
||||
Scan range of the axis.
|
||||
cell_time : (float)
|
||||
Exposure time per cell [s]
|
||||
"""
|
||||
scan_name = "measure_vline"
|
||||
required_kwargs = ["cell_time", "cell_height", "cell_num"]
|
||||
|
||||
def __init__(self, *args, parameter: dict = None, **kwargs):
|
||||
self.axis = ['gmy']
|
||||
# Set parameters from meaningful inputs
|
||||
self.scan_cell_time = parameter['kwargs'].get("cell_time")
|
||||
self.scan_stepsize_y = parameter['kwargs'].get("cell_height")
|
||||
self.scan_stepnum_y = parameter['kwargs'].get("cell_num")
|
||||
self.abr_command = AbrCmd.VERTICAL_LINE_SCAN
|
||||
self.abr_globals = {
|
||||
'var_1': self.scan_cell_time,
|
||||
'var_2': self.scan_stepsize_y,
|
||||
'var_3': self.scan_stepnum_y,
|
||||
}
|
||||
# Call base class
|
||||
super().__init__(parameter=parameter, **kwargs)
|
||||
|
||||
|
||||
|
||||
class MeasureScreening(AerotechFlyscanBase):
|
||||
""" Sample screening scan
|
||||
|
||||
Sample screening scan that scans intervals on the rotation axis taking
|
||||
1 image/interval. This makes sure that we hit diffraction peaks if there
|
||||
are any crystals.
|
||||
|
||||
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.measure_screening(start=42, range=10, scan_time=20, degrees=180, frames=1800)
|
||||
>>> scans.measure_screening(start=42, range=180, steps=18, exp_time=0.1, oscrange=2.0)
|
||||
|
||||
Parameters
|
||||
----------
|
||||
start : float
|
||||
Scan start position of the axis.
|
||||
Absolute scan start position of the omega axis [deg].
|
||||
range : float
|
||||
Scan range of the axis.
|
||||
scan_time : float
|
||||
Total scan time for the movement [s].
|
||||
degrees : (???)
|
||||
frames : (???)
|
||||
delta : (???)
|
||||
(default: 0.5).
|
||||
Total screened range of the omega axis relative to 'start' [deg].
|
||||
steps : int
|
||||
Number of blurred intervals.
|
||||
exp_time : float
|
||||
Exposure time per blurred interval [s].
|
||||
oscrange : float
|
||||
Motion blurring of each interval [deg]
|
||||
delta : float
|
||||
Safety margin for sub-range movements (default: 0.5) [deg].
|
||||
"""
|
||||
scan_name = "measure_screening"
|
||||
required_kwargs = ["start", "range", "scan_time", "degrees", "frames"]
|
||||
required_kwargs = ["start", "range", "steps", "exp_time", "oscrange"]
|
||||
|
||||
def __init__(self, *args, parameter: dict = None, **kwargs):
|
||||
self.axis = ['gmy']
|
||||
# Set parameters from meaningful inputs
|
||||
self.scan_start = parameter['kwargs'].get("start")
|
||||
self.scan_range = parameter['kwargs'].get("range")
|
||||
self.scan_scan_time = parameter['kwargs'].get("scan_time")
|
||||
self.scan_degrees = parameter['kwargs'].get("degrees")
|
||||
self.scan_frames = parameter['kwargs'].get("frames")
|
||||
self.scan_range_o = parameter['kwargs'].get("range")
|
||||
self.scan_stepnum_o = parameter['kwargs'].get("steps")
|
||||
self.scan_exp_time = parameter['kwargs'].get("exp_time")
|
||||
self.scan_oscrange = parameter['kwargs'].get("oscrange")
|
||||
self.scan_delta = parameter['kwargs'].get("delta", 0.5)
|
||||
self.scan_stepsize_o = self.scan_range_o / self.scan_stepnum_o
|
||||
self.abr_command = AbrCmd.SCREENING
|
||||
self.abr_globals = {
|
||||
"var_1" : self.scan_start,
|
||||
"var_2" : self.scan_range,
|
||||
"var_3" : self.scan_scan_time,
|
||||
"var_4" : self.scan_degrees,
|
||||
"var_5" : self.scan_frames,
|
||||
"var_2" : self.scan_oscrange,
|
||||
"var_3" : self.scan_exp_time,
|
||||
"var_4" : self.scan_stepsize_o,
|
||||
"var_5" : self.scan_stepnum_o,
|
||||
"var_6" : self.scan_delta,
|
||||
}
|
||||
# Call base class
|
||||
@@ -436,28 +467,32 @@ class MeasureScreening(AerotechFlyscanBase):
|
||||
class MeasureFastOmega(AerotechFlyscanBase):
|
||||
""" Fast omega scan
|
||||
|
||||
MEasures a fast rotational scan with the rotation stage (omega).
|
||||
Performs a fast rotational scan with the rotation stage (omega). It ramps
|
||||
up to constant speed and sets off PSO for the expected travel time. I.e.
|
||||
not really a PSO output (as it ignores acceleration distance) but it's
|
||||
expected to trigger at-speed for 'range' distance.
|
||||
|
||||
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.measure_fast_omega(start=42, range=180, scan_time=20)
|
||||
>>> scans.measure_fast_omega(start=42, range=180, move_time=1.0)
|
||||
|
||||
Parameters
|
||||
----------
|
||||
start : float
|
||||
Scan start position of the axis.
|
||||
Scan start position of the axis [deg].
|
||||
range : float
|
||||
Scan range of the axis.
|
||||
scan_time : float
|
||||
Total scan time for the movement [s].
|
||||
At-speed range of the axis relative to 'start' + acceleration
|
||||
distance [deg].
|
||||
move_time : float
|
||||
Total time for the at-speed movement and trigger [s].
|
||||
rate : (???)
|
||||
(default: 200).
|
||||
"""
|
||||
scan_name = "measure_fast_omega"
|
||||
required_kwargs = ["start", "range", "scan_time"]
|
||||
required_kwargs = ["start", "range", "move_time"]
|
||||
|
||||
def __init__(self, *args, parameter: dict = None, **kwargs):
|
||||
self.axis = ['omega']
|
||||
@@ -465,14 +500,14 @@ class MeasureFastOmega(AerotechFlyscanBase):
|
||||
logger.info(parameter)
|
||||
self.scan_start = parameter['kwargs'].get("start")
|
||||
self.scan_range = parameter['kwargs'].get("range")
|
||||
self.scan_scan_time = parameter['kwargs'].get("scan_time")
|
||||
self.scan_rate = parameter['kwargs'].get("rate", 200)
|
||||
self.scan_move_time = parameter['kwargs'].get("move_time")
|
||||
self.scan_acceleration = parameter['kwargs'].get("acceleration", 200)
|
||||
self.abr_command = AbrCmd.SUPER_FAST_OMEGA
|
||||
self.abr_globals = {
|
||||
"var_1" : self.scan_start,
|
||||
"var_2" : self.scan_range,
|
||||
"var_3" : self.scan_scan_time,
|
||||
"var_4" : self.scan_rate,
|
||||
"var_3" : self.scan_move_time,
|
||||
"var_4" : self.scan_acceleration,
|
||||
}
|
||||
# Call base class
|
||||
super().__init__(parameter=parameter, **kwargs)
|
||||
@@ -482,42 +517,47 @@ class MeasureFastOmega(AerotechFlyscanBase):
|
||||
class MeasureStillWedge(AerotechFlyscanBase):
|
||||
""" Still wedge scan
|
||||
|
||||
Measure a simple step scan with the omega stage with PSO triggering.
|
||||
The scan is similar to the continous wedge scan.
|
||||
|
||||
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.measure_still_wedge(start=42, range=90, scan_time=20, oscrange=15)
|
||||
>>> scans.measure_still_wedge(start=42, range=180, exp_time=0.1, steps=60)
|
||||
|
||||
Parameters
|
||||
----------
|
||||
start : (float)
|
||||
Scan start position of the axis.
|
||||
Scan start position of the axis [mm].
|
||||
range : (float)
|
||||
Scan range of the axis.
|
||||
scan_time : (float)
|
||||
Total scan time for the movement [s].
|
||||
oscrange : (float)
|
||||
Scan range of the omega axis [mm].
|
||||
exp_time : (float)
|
||||
Exposure time per point [s].
|
||||
steps : int
|
||||
Number of actual steps.
|
||||
sleep_after_shutter_close : (float)
|
||||
[s] (default: 0.01).
|
||||
"""
|
||||
scan_name = "measure_still_wedge"
|
||||
required_kwargs = ["start", "range", "exp_time", "oscrange"]
|
||||
required_kwargs = ["start", "range", "exp_time", "steps"]
|
||||
|
||||
def __init__(self, *args, parameter: dict = None, **kwargs):
|
||||
self.axis = ['omega']
|
||||
self.axis = ['abr.omega']
|
||||
# Set parameters from meaningful inputs
|
||||
self.scan_start = parameter['kwargs'].get("start")
|
||||
self.scan_range = parameter['kwargs'].get("range")
|
||||
self.scan_scan_time = parameter['kwargs'].get("scan_time")
|
||||
self.scan_oscrange = parameter['kwargs'].get("oscrange")
|
||||
self.scan_stepnum_o = parameter['kwargs'].get("steps")
|
||||
self.scan_exp_time = parameter['kwargs'].get("exp_time")
|
||||
self.scan_shutter_sleep = parameter['kwargs'].get("sleep_after_shutter_close", 0.01)
|
||||
self.scan_stepsize_o = self.scan_stepnum_o / self.scan_stepnum_o
|
||||
self.abr_command = AbrCmd.STILL_WEDGE
|
||||
self.abr_globals = {
|
||||
"var_1" : self.scan_start,
|
||||
"var_2" : self.scan_range,
|
||||
"var_3" : self.scan_scan_time,
|
||||
"var_4" : self.scan_oscrange,
|
||||
"var_3" : self.scan_exp_time,
|
||||
"var_4" : self.scan_stepsize_o,
|
||||
"var_5" : self.scan_shutter_sleep,
|
||||
}
|
||||
# Call base class
|
||||
@@ -528,37 +568,37 @@ class MeasureStillWedge(AerotechFlyscanBase):
|
||||
class MeasureStills(AerotechFlyscanBase):
|
||||
""" Still image sequence scan
|
||||
|
||||
Measures a series of still images without any motor movement.
|
||||
IMPORTANT: use idle_time=0.0 to prevent shutter open/close
|
||||
Measures a series of PSO triggered images without any motor movement.
|
||||
NOTE: Use idle_time=0.0 to prevent shutter open/close.
|
||||
|
||||
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.measure_stills(nframes=100, exp_time=0.1, idle_time=30)
|
||||
>>> scans.measure_stills(steps=100, exp_time=0.1, idle_time=3)
|
||||
|
||||
Parameters
|
||||
----------
|
||||
nframes : int
|
||||
steps : int
|
||||
Total number of frames to be recorded.
|
||||
exposure_time : float
|
||||
exp_time : float
|
||||
Exposure time of each frame [s].
|
||||
idle_time : float
|
||||
Sleep time between the frames [s].
|
||||
"""
|
||||
scan_name = "measure_stills"
|
||||
required_kwargs = ["exp_time", "nframes", "idle_time"]
|
||||
required_kwargs = ["exp_time", "steps", "idle_time"]
|
||||
|
||||
def __init__(self, *args, parameter: dict = None, **kwargs):
|
||||
self.axis = []
|
||||
# Set parameters from meaningful inputs
|
||||
self.scan_exp_time = parameter['kwargs'].get("exp_time")
|
||||
self.scan_num_frames = parameter['kwargs'].get("nframes")
|
||||
self.scan_numsteps = parameter['kwargs'].get("steps")
|
||||
self.scan_idle_time = parameter['kwargs'].get("idle_time")
|
||||
self.abr_command = AbrCmd.STILLS
|
||||
self.abr_globals = {
|
||||
"var_1" : self.scan_num_frames,
|
||||
"var_1" : self.scan_numsteps,
|
||||
"var_2" : self.scan_exp_time,
|
||||
"var_3" : self.scan_idle_time,
|
||||
}
|
||||
@@ -570,42 +610,44 @@ class MeasureStills(AerotechFlyscanBase):
|
||||
class MeasureSingleOscillation(AerotechFlyscanBase):
|
||||
""" Single oscillation scan
|
||||
|
||||
Short line scan with the omega axis with PSO trigger.
|
||||
|
||||
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.measure_single_osc(start=42, range=180, scan_time=20)
|
||||
>>> scans.measure_single_osc(start=42, range=180, move_time=20)
|
||||
|
||||
Parameters
|
||||
----------
|
||||
start : float
|
||||
Scan start position of the axis.
|
||||
Scan start position of the omegaaxis [mm].
|
||||
range : float
|
||||
Oscillation range of the axis.
|
||||
scan_time : float
|
||||
Oscillation range of the axis [mm].
|
||||
move_time : float
|
||||
Total scan time for the movement [s].
|
||||
delta : (???)
|
||||
(default: 0).
|
||||
Safety margin for movement (default: 0).
|
||||
settle : (???)
|
||||
(default: 0.5).
|
||||
"""
|
||||
scan_name = "measure_single_osc"
|
||||
required_kwargs = ["start", "range", "scan_time"]
|
||||
required_kwargs = ["start", "range", "move_time"]
|
||||
|
||||
def __init__(self, *args, parameter: dict = None, **kwargs):
|
||||
self.axis = ['omega']
|
||||
self.axis = ['abr.omega']
|
||||
# Set parameters from meaningful inputs
|
||||
self.scan_start = parameter['kwargs'].get("start")
|
||||
self.scan_range = parameter['kwargs'].get("range")
|
||||
self.scan_scan_time = parameter['kwargs'].get("scan_time")
|
||||
self.scan_move_time = parameter['kwargs'].get("move_time")
|
||||
self.scan_delta = parameter['kwargs'].get("delta", 0)
|
||||
self.scan_settle = parameter['kwargs'].get("settle", 0.5)
|
||||
self.abr_command = AbrCmd.SINGLE_OSCILLATION
|
||||
self.abr_globals = {
|
||||
"var_1" : self.scan_start,
|
||||
"var_2" : self.scan_range,
|
||||
"var_3" : self.scan_scan_time,
|
||||
"var_3" : self.scan_move_time,
|
||||
"var_4" : self.scan_delta,
|
||||
"var_5" : self.scan_settle,
|
||||
}
|
||||
@@ -617,41 +659,44 @@ class MeasureSingleOscillation(AerotechFlyscanBase):
|
||||
class MeasureRepeatedOscillation(AerotechFlyscanBase):
|
||||
""" Repeated oscillation scan
|
||||
|
||||
Repeated relative line scans with the omega axis with PSO enable trigger.
|
||||
The lines are performed in zigzag mode with PSO triggering.
|
||||
|
||||
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.measure_multi_osc(start=42, range=180, scan_time=20)
|
||||
>>> scans.measure_multi_osc(steps=50, range=30, move_time=3)
|
||||
|
||||
Parameters
|
||||
----------
|
||||
nframes : int
|
||||
???
|
||||
scan_time : float
|
||||
steps : int
|
||||
Number of cycles to repeat the scan
|
||||
move_time : float
|
||||
Total scan time for the movement [s].
|
||||
range : float
|
||||
Oscillation range of the axis.
|
||||
Relative oscillation range of the omega axis [deg].
|
||||
settle : (???)
|
||||
(default: 0).
|
||||
Movement settle time after each line (default: 0) [s].
|
||||
delta : (???)
|
||||
(default: 0.5).
|
||||
Safety margin for movement (default: 0.5) [deg].
|
||||
"""
|
||||
scan_name = "measure_multi_osc"
|
||||
required_kwargs = ["nframes", "range", "scan_time"]
|
||||
required_kwargs = ["steps", "range", "scan_time"]
|
||||
|
||||
def __init__(self, *args, parameter: dict = None, **kwargs):
|
||||
self.axis = ['omega']
|
||||
# Set parameters from meaningful inputs
|
||||
self.scan_num_frames = parameter['kwargs'].get("nframes")
|
||||
self.scan_stepnum = parameter['kwargs'].get("steps")
|
||||
self.scan_range = parameter['kwargs'].get("range")
|
||||
self.scan_scan_time = parameter['kwargs'].get("scan_time")
|
||||
self.scan_move_time = parameter['kwargs'].get("move_time")
|
||||
self.scan_sleep = parameter['kwargs'].get("sleep", 0)
|
||||
self.scan_delta = parameter['kwargs'].get("delta", 0.5)
|
||||
self.abr_command = AbrCmd.REPEAT_SINGLE_OSCILLATION
|
||||
self.abr_globals = {
|
||||
"var_1" : self.scan_num_frames,
|
||||
"var_2" : self.scan_scan_time,
|
||||
"var_1" : self.scan_stepnum,
|
||||
"var_2" : self.scan_move_time,
|
||||
"var_3" : self.scan_range,
|
||||
"var_4" : self.scan_sleep,
|
||||
"var_5" : self.scan_delta,
|
||||
@@ -664,12 +709,15 @@ class MeasureRepeatedOscillation(AerotechFlyscanBase):
|
||||
class MeasureMSOX(AerotechFlyscanBase):
|
||||
""" Standard MSOX scan
|
||||
|
||||
MSOX experiment for Florian, i.e. a glorified oscillation scan this time
|
||||
with absolute positions. The lines are unidirectional with PSO triggering.
|
||||
|
||||
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.measure_msox(start=42, range=10, exp_time=0.1)
|
||||
>>> scans.measure_msox(start=42, range=30, move_time=3.0)
|
||||
|
||||
Parameters
|
||||
----------
|
||||
@@ -677,32 +725,32 @@ class MeasureMSOX(AerotechFlyscanBase):
|
||||
Scan start position of the axis.
|
||||
range : float
|
||||
Scan range of the axis.
|
||||
exp_time : float
|
||||
move_time : float
|
||||
Exposure time for each point [s].
|
||||
num_datasets : int
|
||||
???
|
||||
rest_time : float
|
||||
???
|
||||
steps : int
|
||||
Number of repeats.
|
||||
settle_time : float
|
||||
Settle time before line start (default=0) [s].
|
||||
"""
|
||||
scan_name = "measure_msox"
|
||||
required_kwargs = ["start", "range", "exp_time"]
|
||||
required_kwargs = ["start", "range", "move_time"]
|
||||
|
||||
def __init__(self, *args, parameter: dict = None, **kwargs):
|
||||
self.axis = ['omega']
|
||||
self.axis = ['abr.omega']
|
||||
# Set parameters from meaningful inputs
|
||||
self.scan_start = parameter['kwargs'].get("start")
|
||||
self.scan_range = parameter['kwargs'].get("range")
|
||||
self.scan_exp_time = parameter['kwargs'].get("exp_time")
|
||||
self.scan_num_datasets = parameter['kwargs'].get("num_datasets", 1)
|
||||
self.scan_rest_time = parameter['kwargs'].get("rest_time", 0)
|
||||
self.scan_move_time = parameter['kwargs'].get("move_time")
|
||||
self.scan_stepnum = parameter['kwargs'].get("steps", 1)
|
||||
self.scan_settle_time = parameter['kwargs'].get("settle_time", 0)
|
||||
self.abr_command = AbrCmd.MSOX
|
||||
self.abr_reset = True
|
||||
self.abr_globals = {
|
||||
"var_1" : self.scan_start,
|
||||
"var_2" : self.scan_range,
|
||||
"var_3" : self.scan_exp_time,
|
||||
"var_4" : self.scan_num_datasets,
|
||||
"var_5" : self.scan_rest_time,
|
||||
"var_3" : self.scan_move_time,
|
||||
"var_4" : self.scan_stepnum,
|
||||
"var_5" : self.scan_settle_time,
|
||||
"var_6" : 0,
|
||||
"var_7" : 0,
|
||||
"var_8" : 0,
|
||||
@@ -717,6 +765,11 @@ class MeasureMSOX(AerotechFlyscanBase):
|
||||
class MeasureGrid(AerotechFlyscanBase):
|
||||
""" General grid scan
|
||||
|
||||
Performs an X-Y-Omega coordinated grid scan:
|
||||
X axis is absolute (fast axis)
|
||||
Y axis is relative to start
|
||||
Omega starts at the current value and is synchronized to X
|
||||
|
||||
Note: This was probably never used in its current form, because the
|
||||
code had an undefined variable 'self.position'
|
||||
|
||||
@@ -731,12 +784,14 @@ class MeasureGrid(AerotechFlyscanBase):
|
||||
----------
|
||||
positions : 2D-array
|
||||
Scan position of each axis, i.e. (N, 3) shaped array.
|
||||
ncols : int
|
||||
Nmber of columns.
|
||||
steps_x : int
|
||||
Number of points along the X axis (fast).
|
||||
steps_y : int
|
||||
Number of points in the Y axis (slow).
|
||||
angle:
|
||||
???
|
||||
Triggered angular range on the synchronized omega [deg]
|
||||
exp_time : (float)
|
||||
Exposure time for each point [s].
|
||||
Exposure time for each point, only used for number of points and velocity [s].
|
||||
"""
|
||||
scan_name = "measure_raster"
|
||||
required_kwargs = ["positions", "ncols", "angle", "exp_time"]
|
||||
@@ -750,16 +805,19 @@ class MeasureGrid(AerotechFlyscanBase):
|
||||
scan_gmy_step = 0.010
|
||||
|
||||
def __init__(self, *args, parameter: dict = None, **kwargs):
|
||||
self.axis = ['omega']
|
||||
self.axis = ['abr.omega', 'abr.gmx', 'abr.gmy']
|
||||
# Set parameters from meaningful inputs
|
||||
self.abr_command = AbrCmd.RASTER_SCAN
|
||||
self.abr_reset = True
|
||||
self.scan_positions = parameter['kwargs'].get("positions")
|
||||
self.scan_stepnum_x = parameter['kwargs'].get("ncols")
|
||||
self.scan_stepnum_y = self.scan_positions / self.scan_stepnum_x
|
||||
self.scan_angle = parameter['kwargs'].get("angle")
|
||||
self.scan_stepnum_x = parameter['kwargs'].get("steps_x")
|
||||
self.scan_stepnum_y = parameter['kwargs'].get("steps_y")
|
||||
self.scan_anglerange = parameter['kwargs'].get("angle")
|
||||
self.scan_exp_time = parameter['kwargs'].get("exp_time")
|
||||
|
||||
if len(self.scan_positions) != self.scan_stepnum_x * self.scan_stepnum_y:
|
||||
raise RuntimeError("Number of points and positions do not match")
|
||||
|
||||
if len(self.scan_positions)==1:
|
||||
raise RuntimeWarning("Raster scan with one cell makes no sense")
|
||||
|
||||
@@ -784,26 +842,17 @@ class MeasureGrid(AerotechFlyscanBase):
|
||||
self.scan_gmy_step = np.linalg.norm([self.scan_ystep, self.scan_zstep])
|
||||
|
||||
# ToDo: Check with Zac what are theese parameters
|
||||
self.scan_omega_position = yield from self.stubs.send_rpc_and_wait("abs", "omega.readback.get")
|
||||
self.scan_start_o = yield from self.stubs.send_rpc_and_wait("abs", "omega.readback.get")
|
||||
self.scan_gmx_offset = yield from self.stubs.send_rpc_and_wait("abs", "gmx.readback.get")
|
||||
|
||||
# ToDo : This was left out
|
||||
# self._raster_starting_x = start_x
|
||||
# self._raster_starting_y = y1
|
||||
# self._raster_starting_z = z1
|
||||
# self._raster_step_y = ystep
|
||||
# self._raster_step_z = zstep
|
||||
# self._raster_current_row = 0
|
||||
# self._raster_num_rows = rows
|
||||
|
||||
# Configure the global variables
|
||||
self.abr_globals = {
|
||||
"var_1" : self.scan_omega_position,
|
||||
"var_1" : self.scan_start_o,
|
||||
"var_2" : self.scan_start_x,
|
||||
"var_3" : self.scan_end_x,
|
||||
"var_4" : self.scan_stepnum_x,
|
||||
"var_5" : self.scan_stepnum_y,
|
||||
"var_6" : self.scan_angle,
|
||||
"var_6" : self.scan_anglerange,
|
||||
"var_7" : self.scan_exp_time,
|
||||
"var_8" : HALF_PERIOD,
|
||||
"var_9" : self.scan_gmx_offset,
|
||||
@@ -815,6 +864,11 @@ class MeasureGrid(AerotechFlyscanBase):
|
||||
class MeasureGridStill(AerotechFlyscanBase):
|
||||
""" Still grid scan
|
||||
|
||||
Performs an X-Y-Omega coordinated grid scan in stepping mode:
|
||||
X axis is absolute
|
||||
Y axis is relative to start
|
||||
Omega starts at the current value and is synchronized to X
|
||||
|
||||
Note: This was probably never used in its current form, because the
|
||||
code had an undefined variable 'self.position'
|
||||
|
||||
@@ -823,7 +877,7 @@ class MeasureGridStill(AerotechFlyscanBase):
|
||||
|
||||
Example
|
||||
-------
|
||||
>>> scans.measure_raster(positions=[[11, 2, 3.4], [11, 2, 3.5], ...], columns=20, exp_time=0.1, delay=0.05)
|
||||
>>> scans.measure_raster(positions=[[11, 2, 3.4], [11, 2, 3.5], ...], steps_x=20, steps_y=20, exp_time=0.1, delay=0.05)
|
||||
|
||||
Parameters
|
||||
----------
|
||||
@@ -839,7 +893,7 @@ class MeasureGridStill(AerotechFlyscanBase):
|
||||
???
|
||||
"""
|
||||
scan_name = "measure_raster_still"
|
||||
required_kwargs = ["positions", "columns", "exp_time", "delay"]
|
||||
required_kwargs = ["positions", "steps_x", "steps_y", "exp_time", "delay"]
|
||||
|
||||
# Default values
|
||||
scan_start_x = None
|
||||
@@ -850,16 +904,19 @@ class MeasureGridStill(AerotechFlyscanBase):
|
||||
scan_gmy_step = 0.010
|
||||
|
||||
def __init__(self, *args, parameter: dict = None, **kwargs):
|
||||
self.axis = ['omega']
|
||||
self.axis = ['abr.gmx', 'abr.gmy', 'abr.omega']
|
||||
# Set parameters from meaningful inputs
|
||||
self.abr_command = AbrCmd.RASTER_SCAN_STILL
|
||||
self.abr_reset = True
|
||||
self.scan_positions = parameter['kwargs'].get("positions")
|
||||
self.scan_stepnum_x = parameter['kwargs'].get("columns")
|
||||
self.scan_stepnum_y = self.scan_positions / self.scan_stepnum_x
|
||||
self.scan_stepnum_x = parameter['kwargs'].get("steps_x")
|
||||
self.scan_stepnum_y = parameter['kwargs'].get("steps_y")
|
||||
self.scan_exp_time = parameter['kwargs'].get("exp_time")
|
||||
self.scan_delay = parameter['kwargs'].get("delay")
|
||||
|
||||
if len(self.scan_positions) != self.scan_stepnum_x * self.scan_stepnum_y:
|
||||
raise RuntimeError("Number of points and positions do not match")
|
||||
|
||||
if len(self.scan_positions)==1:
|
||||
raise RuntimeWarning("Raster scan with one cell makes no sense")
|
||||
# Call base class
|
||||
@@ -886,15 +943,6 @@ class MeasureGridStill(AerotechFlyscanBase):
|
||||
self.scan_omega_position = yield from self.stubs.send_rpc_and_wait("abs", "omega.readback.get")
|
||||
self.scan_gmx_offset = yield from self.stubs.send_rpc_and_wait("abs", "gmx.readback.get")
|
||||
|
||||
# ToDo : This was left out
|
||||
# self._raster_starting_x = start_x
|
||||
# self._raster_starting_y = y1
|
||||
# self._raster_starting_z = z1
|
||||
# self._raster_step_y = ystep
|
||||
# self._raster_step_z = zstep
|
||||
# self._raster_current_row = 0
|
||||
# self._raster_num_rows = rows
|
||||
|
||||
self.abr_globals = {
|
||||
"var_1" : self.scan_omega_position,
|
||||
"var_2" : self.scan_start_x,
|
||||
@@ -922,13 +970,13 @@ class MeasureJungfrau(AerotechFlyscanBase):
|
||||
|
||||
Parameters
|
||||
----------
|
||||
columns : int
|
||||
steps_x : int
|
||||
???
|
||||
rows : int
|
||||
steps_y : int
|
||||
???
|
||||
width : int
|
||||
range_x : int
|
||||
???
|
||||
height : int
|
||||
range_y : int
|
||||
???
|
||||
exp_time : float
|
||||
Exposure time per point [s].
|
||||
@@ -936,15 +984,17 @@ class MeasureJungfrau(AerotechFlyscanBase):
|
||||
(default: 0.1).
|
||||
"""
|
||||
scan_name = "measure_jungfrau"
|
||||
required_kwargs = ["columns", "rows", "width", "height", "exp_time"]
|
||||
required_kwargs = ["steps_x", "steps_y", "range_x", "range_y", "exp_time"]
|
||||
|
||||
def __init__(self, *args, parameter: dict = None, **kwargs):
|
||||
self.axis = ['omega']
|
||||
# Set parameters from meaningful inputs
|
||||
self.scan_num_cols = parameter['kwargs'].get("columns")
|
||||
self.scan_num_rows = parameter['kwargs'].get("rows")
|
||||
self.scan_width = parameter['kwargs'].get("width")
|
||||
self.scan_height = parameter['kwargs'].get("height")
|
||||
self.scan_stepnum_x = parameter['kwargs'].get("steps_x")
|
||||
self.scan_stepnum_y = parameter['kwargs'].get("steps_y")
|
||||
self.scan_range_x = parameter['kwargs'].get("range_x")
|
||||
self.scan_range_y = parameter['kwargs'].get("range_y")
|
||||
self.scan_stepsize_x = self.scan_range_x / self.scan_stepnum_x
|
||||
self.scan_stepsize_y = self.scan_range_y / self.scan_stepnum_y
|
||||
self.scan_exp_time = parameter['kwargs'].get("exp_time")
|
||||
self.scan_sleep = parameter['kwargs'].get("sleep", 0.1)
|
||||
self.abr_timeout = None if self.scan_sleep <= 0 else 5.0 + (self.scan_num_rows * self.scan_sleep) + (self.scan_num_cols * self.scan_num_rows * self.scan_exp_time)
|
||||
@@ -952,10 +1002,10 @@ class MeasureJungfrau(AerotechFlyscanBase):
|
||||
self.abr_reset = True
|
||||
self.abr_complete = True
|
||||
self.abr_globals = {
|
||||
"var_1" : self.scan_num_cols,
|
||||
"var_2" : self.scan_num_rows,
|
||||
"var_3" : self.scan_width,
|
||||
"var_4" : self.scan_height,
|
||||
"var_1" : self.scan_stepnum_x,
|
||||
"var_2" : self.scan_stepnum_y,
|
||||
"var_3" : self.scan_stepsize_x,
|
||||
"var_4" : self.scan_stepsize_y,
|
||||
"var_5" : self.scan_exp_time,
|
||||
"var_6" : self.scan_sleep,
|
||||
"var_7" : 0,
|
||||
|
||||
Reference in New Issue
Block a user