Files
csaxs_bec/bin/utils/saxs_params.py

109 lines
3.8 KiB
Python
Executable File

""" Script used for parsing scan parameters from a CSV file as created by the motormap GUI.
This needs to be reviewed and tested during the deployment phase."""
# pylint: skip-file
import csv
import os
from collections import defaultdict
from collections.abc import Callable
from copy import deepcopy
import numpy as np
class ScanItem:
def __init__(self, offset_xy: Callable) -> None:
self.entry = None
self.offset_xy = offset_xy
self.split_upon_points = 8000
def to_scan_params(self) -> list[dict]:
interval_x = int(
np.round(
np.abs(float(self.entry["X [start]"]) - float(self.entry["X [end]"]))
/ (float(self.entry["step_x [mu]"]) * 1e-3)
)
)
interval_y = int(
np.round(
np.abs(float(self.entry["Y [start]"]) - float(self.entry["Y [end]"]))
/ (float(self.entry["step_y [mu]"]) * 1e-3)
)
)
# if interval_x < 1 or interval_y < 1:
# raise ValueError("Bugger off...")
base_scan_params = {
"start_x": float(self.entry["X [start]"]) + self.offset_xy()[0],
"start_y": float(self.entry["Y [start]"]) + self.offset_xy()[1],
"end_x": float(self.entry["X [end]"]) + self.offset_xy()[0],
"end_y": float(self.entry["Y [end]"]) + self.offset_xy()[1],
"interval_x": interval_x,
"interval_y": interval_y,
"exp_time": float(self.entry["exp_time [s]"]),
"readout_time": 3e-3,
"md": {"sample_name": self.entry["sample name"]},
# "tilt": self.entry["tilt [deg]"]
}
if interval_x * interval_y <= self.split_upon_points:
return [base_scan_params]
scan_params = []
# if we have more than 10000 points, split them along x
num_blocks = int(np.ceil((interval_x * interval_y) / self.split_upon_points))
start_end_positions = np.linspace(
base_scan_params["start_x"], base_scan_params["end_x"], num_blocks + 1
)
for block in range(num_blocks):
block_params = deepcopy(base_scan_params)
block_params["start_x"] = start_end_positions[block]
block_params["end_x"] = start_end_positions[block + 1]
block_params["interval_x"] = int(
np.round(
np.abs(block_params["start_x"] - block_params["end_x"])
/ (float(self.entry["step_x [mu]"]) * 1e-3)
)
)
scan_params.append(block_params)
return scan_params
class SAXSParams:
def __init__(self, offset: Callable):
self.offset_xy = offset
self.data = defaultdict(lambda: ScanItem(offset))
self.global_suffix = 0
def load_from_csv(self, file_path: str) -> None:
"""
Load the acquisition parameter from a csv file.
"""
if not os.path.exists(file_path):
raise FileNotFoundError(
f"The specified CSV file could not be found. Please check that the given path is correct: {file_path}."
)
with open(os.path.expanduser(file_path), "r") as file:
csv_reader = csv.DictReader(file)
for row in csv_reader:
if self.data.get(row["sample name"], None) is None:
self.data[row["sample name"]].entry = row
else:
self.data[f'{row["sample name"]}_{self.global_suffix}'].entry = row
self.global_suffix += 1
if __name__ == "__main__":
from pprint import pprint
INPUT_FILE = "/sls/X12SA/data/e21206/Data10/software/test_script.csv"
def my_offset():
return [0, 0]
params = SAXSParams(my_offset)
params.load_from_csv(INPUT_FILE)
for key in params.data:
pprint(params.data[key].to_scan_params())