109 lines
3.8 KiB
Python
Executable File
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())
|