resonance.api.utils¶
resonance.api.utils
¶
Utility functions for beamline operations.
This module provides helper functions for common beamline tasks like motor alignment, grid scan generation, and data analysis.
create_grid_scan(x_range, y_range, exposure_time=1.0, x_motor='Sample X', y_motor='Sample Y')
¶
Create a 2D grid scan DataFrame.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
x_range
|
tuple[float, float, int]
|
X range as (start, stop, num_points) |
required |
y_range
|
tuple[float, float, int]
|
Y range as (start, stop, num_points) |
required |
exposure_time
|
float
|
Exposure time for all points (default: 1.0) |
1.0
|
x_motor
|
str
|
X motor name (default: "Sample X") |
'Sample X'
|
y_motor
|
str
|
Y motor name (default: "Sample Y") |
'Sample Y'
|
Returns:
| Type | Description |
|---|---|
DataFrame
|
Scan definition ready for scan_from_dataframe |
Examples:
>>> # Create 3x3 grid
>>> grid = create_grid_scan(
... x_range=(10, 12, 3),
... y_range=(0, 2, 3),
... exposure_time=1.0
... )
>>> print(len(grid)) # 9 points
9
Source code in src/resonance/api/utils.py
create_line_scan(motor, start, stop, num_points, exposure_time=1.0)
¶
Create a 1D line scan DataFrame.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
motor
|
str
|
Motor name |
required |
start
|
float
|
Start position |
required |
stop
|
float
|
Stop position |
required |
num_points
|
int
|
Number of points |
required |
exposure_time
|
float
|
Exposure time for all points (default: 1.0) |
1.0
|
Returns:
| Type | Description |
|---|---|
DataFrame
|
Scan definition ready for scan_from_dataframe |
Examples:
>>> scan = create_line_scan(
... motor="Sample X",
... start=10,
... stop=15,
... num_points=11,
... exposure_time=1.5
... )
Source code in src/resonance/api/utils.py
create_energy_scan(energies, exposure_time=1.0, energy_motor='Beamline Energy')
¶
Create an energy scan DataFrame.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
energies
|
ndarray
|
Array of photon energies |
required |
exposure_time
|
float | ndarray
|
Exposure time(s) (default: 1.0) |
1.0
|
energy_motor
|
str
|
Energy motor name (default: "Beamline Energy") |
'Beamline Energy'
|
Returns:
| Type | Description |
|---|---|
DataFrame
|
Scan definition ready for scan_from_dataframe |
Examples:
>>> # Carbon K-edge
>>> energies = np.linspace(280, 320, 200)
>>> scan = create_energy_scan(energies, exposure_time=1.0)
>>>
>>> # Variable exposure times
>>> energies = np.linspace(280, 320, 200)
>>> exposure = np.ones(200)
>>> exposure[100:150] = 2.0 # Longer at edge
>>> scan = create_energy_scan(energies, exposure_time=exposure)
Source code in src/resonance/api/utils.py
find_peak_position(scan_data, motor_col, signal_col, use_mean=True)
¶
Find peak position in 1D scan data.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
scan_data
|
DataFrame
|
Scan results from scan_from_dataframe |
required |
motor_col
|
str
|
Motor position column name (e.g., "Sample X_position") |
required |
signal_col
|
str
|
Signal column name (e.g., "Photodiode_mean") |
required |
use_mean
|
bool
|
Use _mean column if True, else use raw column (default: True) |
True
|
Returns:
| Type | Description |
|---|---|
tuple[float, float]
|
(peak_position, peak_value) |
Examples:
>>> results = await server.scan_from_dataframe(scan_df, ...)
>>> peak_x, peak_signal = find_peak_position(
... results,
... motor_col="Sample X_position",
... signal_col="Photodiode_mean"
... )
>>> print(f"Peak at {peak_x:.2f} with signal {peak_signal:.3f}")
Source code in src/resonance/api/utils.py
calculate_center_of_mass(scan_data, motor_col, signal_col, use_mean=True)
¶
Calculate center of mass for alignment.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
scan_data
|
DataFrame
|
Scan results from scan_from_dataframe |
required |
motor_col
|
str
|
Motor position column name |
required |
signal_col
|
str
|
Signal column name |
required |
use_mean
|
bool
|
Use _mean column if True (default: True) |
True
|
Returns:
| Type | Description |
|---|---|
float
|
Center of mass position |
Examples:
>>> results = await server.scan_from_dataframe(scan_df, ...)
>>> com = calculate_center_of_mass(
... results,
... motor_col="Sample X_position",
... signal_col="Photodiode_mean"
... )
>>> # Move to center of mass
>>> await server.motor.set("Sample X", com)
Source code in src/resonance/api/utils.py
resample_scan_data(scan_data, motor_col, num_points, columns_to_interpolate=None)
¶
Resample scan data to uniform grid.
Useful for combining scans with different point densities.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
scan_data
|
DataFrame
|
Original scan data |
required |
motor_col
|
str
|
Motor position column for interpolation axis |
required |
num_points
|
int
|
Number of points in resampled data |
required |
columns_to_interpolate
|
list[str] | None
|
Columns to interpolate (default: all numeric columns) |
None
|
Returns:
| Type | Description |
|---|---|
DataFrame
|
Resampled data with uniform spacing |
Examples:
>>> # Resample to 100 points
>>> resampled = resample_scan_data(
... results,
... motor_col="Beamline Energy_position",
... num_points=100
... )
Source code in src/resonance/api/utils.py
merge_scans(scans, motor_col, average_overlaps=True)
¶
Merge multiple scans into a single dataset.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
scans
|
list[DataFrame]
|
List of scan DataFrames to merge |
required |
motor_col
|
str
|
Motor position column to use for alignment |
required |
average_overlaps
|
bool
|
Average overlapping points (default: True) |
True
|
Returns:
| Type | Description |
|---|---|
DataFrame
|
Merged scan data |
Examples:
>>> # Combine multiple energy ranges
>>> scan1 = await nexafs_scan(server, np.linspace(280, 290, 50))
>>> scan2 = await nexafs_scan(server, np.linspace(288, 300, 100))
>>> merged = merge_scans([scan1, scan2], motor_col="energy")
Source code in src/resonance/api/utils.py
knife_edge_analysis(scan_data, motor_col, signal_col, threshold=0.5, direct_beam='above')
¶
Analyze knife-edge scan to find edge position.
Useful for aligning samples to incident beam.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
scan_data
|
DataFrame
|
Scan results from scan_from_dataframe |
required |
motor_col
|
str
|
Motor position column name |
required |
signal_col
|
str
|
Signal column name |
required |
threshold
|
float
|
Fraction of max signal to define edge (default: 0.5) |
0.5
|
direct_beam
|
Literal['above', 'below']
|
Direction of direct beam relative to edge (default: "above") |
'above'
|
Returns:
| Type | Description |
|---|---|
float
|
Estimated edge position |
Examples:
>>> results = await server.scan_from_dataframe(scan_df, ...)
>>> edge_pos = knife_edge_analysis(
... results,
... motor_col="Sample Z_position",
... signal_col="Photodiode_mean"
... )
>>> print(f"Edge position at {edge_pos:.2f}")