Files
x11ma/script/beamline_alignment/Beamline_configuration.py
gac-x11ma 8ecd1f36c6 Startup
2025-11-19 10:59:01 +01:00

305 lines
10 KiB
Python
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import os
import json
#
#RED = "\033[91m"
#RESET = "\033[0m"
# see also Python Projekte/Strings in Datei speichern
BEAMLINE_PARAMETERS_FILE = "/home/gac-x11ma/pshell/home/script/beamline_alignment/bml_align_params.json"
def save_parameters():
msg = "Save as ..."
# User inputs the file path
path = get_string(msg, default = "/home/gac-x11ma/pshell/home/script/beamline_alignment/0012.json", alternatives = None, password = False)
# 1 Check if the user cancelled
if path is None:
print("Aborted by user.")
return # ✅ exit the function immediately
# 2 Get the parent folder of the file
folder = os.path.dirname(path)
# print(folder)
# 3 ⃣Check if the folder existst
if not os.path.isdir(folder):
print ("Aborted. Folder: " + folder + " does not exist.")
return # ✅ exit the function cleanly
# 4 Mapping from component + parameter to individual read string (Dictionary) Each component contains its parameters, with the corresponding read string and optional tolerance
with open(BEAMLINE_PARAMETERS_FILE, "r") as f:
machine_parameters = json.load(f)
parameters = {}
nan_occurred = False
# 5⃣ Read each parameter from the machine
for comp, param_dict in machine_parameters.items():
print("\nComponent: " + comp)
parameters[comp] = {}
for p, info in param_dict.items():
cmd = info["read_cmd"]
#print(cmd)
tol = info["tolerance"]
#print(tol)
try:
value = caget(cmd)
if isinstance(value, str):
display_value = value
else:
#value = string(value) c ensure float
display_value = str(value)
print(comp + "_" + p + " = " + display_value)
# print(value)
except:
# print("Problem")
# value = float('nan')
nan_occurred = True
print(comp + p + " = NaN")
parameters[comp][p] = {"value": value, "tolerance": tol}
# # 6 Save parameters to JSON file
try:
with open(path, "w") as f:
json.dump(parameters, f, indent=4, allow_nan=True)
print("Parameters successfully saved in: " + path)
except:
print("Error while saving file.")
# Warn if NaN occurred
if nan_occurred:
print("There were NaN-Values")
def select_components(selected_components=None):
#Allows the user (or another function) to select one
#or more components either interactively or
#by providing a list. It validates the selection against
#the available components in the JSON file.
msg = "Select components: "
# Load machine parameters
try:
with open(BEAMLINE_PARAMETERS_FILE, "r") as f:
machine_parameters = json.load(f)
except:
print("Error loading machine_parameters.json")
return None
# Extract component names
all_components = list(machine_parameters.keys())
# print("Available components:")
# for comp in all_components:
# print("- " + comp)
# --- determine components to display ---
if selected_components is None:
# user didn't specify -> use all from JSON
presented_to_select = all_components[:]
presented_to_select.append("all")
selected = get_string(msg, default = None, alternatives = presented_to_select, password = False)
#print(selected)
if selected is None:
print("Selection aborted by user.")
return None
elif selected == "all":
# Display components
print("Selected components:")
for comp in all_components:
print("- " + comp)
return all_components
else:
selected_components = [selected] if not isinstance(selected, list) else selected
print("Selected components:")
for comp in selected_components:
print("- " + comp)
return selected_components
elif selected_components == "all":
# Display components
print("Selected components:")
for comp in all_components:
print("- " + comp)
return all_components
else:
# ensure it is a list
if not isinstance(selected_components, list):
print("Error: selected_components must be a list of the form \"[\"Diag\", \"CMU\", ...]\" or \"all\".")
return
# validate each component
invalid = [c for c in selected_components if c not in all_components]
if invalid:
print("Error: Invalid component(s):")
for comp in invalid:
print("- " + comp)
print("Valid components are:")
for comp in all_components:
print("- " + comp)
return None
else:
print("Selected components:")
for comp in selected_components:
print("- " + comp)
return selected_components
def display_parameters(selected_components=None):
# Displays parameters for selected components.
# - Uses select_components() to choose components.
# - Prints each parameter with its value.
# - If a parameter value is missing or cannot be read, prints NaN.
# 1⃣ Get the selected components (interactive or via argument)
selection = select_components(selected_components)
if selection is None:
return # user cancelled or invalid input
# 2⃣ Load the machine parameters JSON
try:
with open(BEAMLINE_PARAMETERS_FILE, "r") as f:
machine_parameters = json.load(f)
except:
print("Error loading machine_parameters.json")
return
# 3⃣ Loop through components and display their parameters
for comp in selection:
print("\nComponent: " + comp)
params = machine_parameters.get(comp, {})
if not params:
print(" No parameters found.")
continue
for key, param_info in params.items():
# param_info enthält z.B. den read_cmd
read_cmd = param_info.get("read_cmd") # JSON muss für jeden Parameter den entsprechenden Befehl enthalten
try:
display_value = caget(read_cmd)
print(read_cmd + " = " + str(display_value))
except:
display_value = "NaN"
# print(" " + key + ": " + display_value)
def restore_parameters(selected_components=None):
# """
# Restore parameter values from a previously saved JSON file.
# The user selects which components to restore, and only parameters
# marked as "restorable": true in machine_parameters.json will be written back.
# """
msg = "Open *.json configuration file ..."
# User inputs the file path
# --- Step 1: Select file ---
restore_file = get_string(msg, default = "/home/gac-x11ma/pshell/home/script/beamline_alignment/0012.json", alternatives = None, password = False)
if restore_file is None:
print("Restore aborted: no file specified.")
return
try:
with open(restore_file, "r") as f:
saved_data = json.load(f)
except:
print("Error loading restore file:", restore_file)
return
# --- Step 2: Load machine parameters ---
try:
with open(BEAMLINE_PARAMETERS_FILE, "r") as f:
machine_parameters = json.load(f)
except:
print("Error loading machine_parameters.json")
return
# --- Step 3: Select components ---
selection = select_components(selected_components)
if selection is None:
return # user cancelled or invalid input
# --- Step 4:️⃣ Load the machine parameters JSON
try:
with open(BEAMLINE_PARAMETERS_FILE, "r") as f:
machine_parameters = json.load(f)
except:
print("Error loading machine_parameters.json")
return
# --- Step 5: Restore loop ---
for comp in selection:
print("\nComponent: " + comp)
params = machine_parameters.get(comp, {})
if not params:
print(" No parameters found.")
continue
saved_params = saved_data.get(comp, {})
if not saved_params:
print(" No saved values for this component.")
continue
for key, param_info in params.items():
if not param_info.get("restorable", False):
continue
# --- get saved value ---
saved_entry = saved_params.get(key, None)
if saved_entry is not None and 'value' in saved_entry:
saved_value = saved_entry['value']
else:
saved_value = "NaN"
# param_info enthält z.B. den read_cmd
read_cmd = param_info.get("read_cmd") # JSON muss für jeden Parameter den entsprechenden Befehl enthalten
write_cmd = param_info.get("write_cmd") # JSON muss für jeden Parameter den entsprechenden Befehl enthalten
tolerance = param_info.get("tolerance")
try:
display_value = caget(read_cmd)
# print(read_cmd + " = " + str(display_value) + ", saved value = " + str(saved_value))
# difference = float(display_value) - float(saved_value)
# --- compute difference if possible ---
if saved_value != "NaN" and display_value != "NaN":
try:
difference = abs(float(display_value) - float(saved_value))
except:
difference = "NaN"
else:
difference = "NaN"
print(read_cmd + " = " + str(display_value) + ", diff = " + str(round(difference, 5)) + ", tolerance = " + str(round(tolerance, 5)))
if float(difference) > float(tolerance):
print("Set " + read_cmd + " to " + str(round(saved_value, 5)))
write_cmd_new = "\"" + write_cmd + "\""
#print(write_cmd_new)
caput(write_cmd, float(saved_value))
else:
print("OK.")
except:
display_value = "NaN"
# print(" " + key + ": " + display_value)
# print("Component:", comp)
# run('beamline_init/with_x-rays/functions/SlitCalib.py')