From 3e5a02296f540e84455618a000612c87bc413dcb Mon Sep 17 00:00:00 2001 From: x10sa Date: Fri, 10 Jul 2026 15:05:21 +0200 Subject: [PATCH] friday updates --- .../device_configs/pxii-beamline-states.yaml | 2 - pxii_bec/device_configs/pxii-devices.yaml | 12 +- pxii_bec/macros/APscripts.py | 2 +- pxii_bec/macros/calibrate_bpm.py | 157 ++++++++++++------ pxii_bec/macros/katscripts.py | 29 +++- 5 files changed, 137 insertions(+), 65 deletions(-) diff --git a/pxii_bec/device_configs/pxii-beamline-states.yaml b/pxii_bec/device_configs/pxii-beamline-states.yaml index 70c5c96..4ff9e35 100644 --- a/pxii_bec/device_configs/pxii-beamline-states.yaml +++ b/pxii_bec/device_configs/pxii-beamline-states.yaml @@ -54,8 +54,6 @@ states: diag_y: out fl_bright: 'on' aerotech_x: in - aerotech_y: work - aerotech_z: work # aerotech_u: mount # smargon_x: mount # smargon_y: mount diff --git a/pxii_bec/device_configs/pxii-devices.yaml b/pxii_bec/device_configs/pxii-devices.yaml index 20237d9..48d4d9b 100644 --- a/pxii_bec/device_configs/pxii-devices.yaml +++ b/pxii_bec/device_configs/pxii-devices.yaml @@ -70,7 +70,7 @@ aerotech: safe: -50 y: mount: -0.0 - work: -0.022 + work: -0.016 z: mount: 0 work: 0 @@ -303,7 +303,7 @@ bs_y: onFailure: buffer readoutPriority: baseline userParameter: - in: -2.654 + in: -2.454 bs_z: description: Beamstop Z deviceClass: ophyd_devices.EpicsMotor @@ -433,7 +433,7 @@ coll_x: onFailure: buffer readoutPriority: baseline userParameter: - in: -2.72 + in: -2.889 coll_y: description: Collimator Y deviceClass: ophyd_devices.EpicsMotor @@ -445,7 +445,7 @@ coll_y: onFailure: buffer readoutPriority: baseline userParameter: - in: 39.188 + in: 39.139 intermediate: 32 out: 20.002 park: 1 @@ -630,10 +630,10 @@ diag_y: onFailure: buffer readoutPriority: baseline userParameter: - i1: 41 + i1: 40.8 out: 20.0 park: 1 - scint: 36.004 + scint: 35.74 tol: 0.3 type: continuous diag_z: diff --git a/pxii_bec/macros/APscripts.py b/pxii_bec/macros/APscripts.py index b596c46..f1387ab 100644 --- a/pxii_bec/macros/APscripts.py +++ b/pxii_bec/macros/APscripts.py @@ -1658,7 +1658,7 @@ def fluxcal(start_en=13, stop_en=14, step =1): filename = dirname + f"FLUX_x10sa_{timestamp}.txt" with open(filename, "w") as f: - np.savetxt(f, combined, delimiter=",", fmt="%9f") + np.savetxt(f, combined, delimiter=",", fmt=".9f") elapsed_time = time.perf_counter()-tstart diff --git a/pxii_bec/macros/calibrate_bpm.py b/pxii_bec/macros/calibrate_bpm.py index 12484d5..e25b0db 100644 --- a/pxii_bec/macros/calibrate_bpm.py +++ b/pxii_bec/macros/calibrate_bpm.py @@ -46,11 +46,6 @@ def read_currents(): bpm3 = np.mean(vals_bpm3) bpm4 = np.mean(vals_bpm4) - # bpm1 = dev.bcu_bpm1.read()["bcu_bpm1"]["value"] - # bpm2 = dev.bcu_bpm2.read()["bcu_bpm2"]["value"] - # bpm3 = dev.bcu_bpm3.read()["bcu_bpm3"]["value"] - # bpm4 = dev.bcu_bpm4.read()["bcu_bpm4"]["value"] - # print(f"bpm1 = {bpm1:.3f}, bpm2 = {bpm2:.3f}, bpm3 = {bpm3:.3f}, bpm4 = {bpm4:.3f}") return {"bpm1": bpm1, "bpm2": bpm2, "bpm3": bpm3, "bpm4": bpm4} @@ -138,21 +133,6 @@ def run_calibration(): umv(dev.ss_sl_ysize, 3.0) -# Read data from BPM calibration files -# def fit_bpm_data(x_y): -# """ -# Read data from bpm calibration files. -# """ -# filedir = "luts/bpm_calib/" -# rundate= "02072130_" -# name = f"bcu_bpm_{x_y}.csv" -# filename = filedir + rundate + name -# data = np.loadtxt(filename, delimiter=",", skiprows=1) -# xdata = data[:, 0] -# ydata = data[:, 1] -# return xdata, ydata - - def fit_bpm_data(x_y, rundate="02072130_", bpm_name="bcu_bpm"): CALIB_DIR = "luts/bpm_calib/" @@ -193,9 +173,9 @@ def linear_calibration( x_fit = np.linspace(min(xdata), max(xdata), 100) plt.plot(x_fit, m * x_fit + c, "r--", label=f"Fit: Linear") - plt.xlabel("HFM Lat Position") - plt.ylabel("SamCam X") - plt.title("Zoom Calibration") + plt.xlabel("label") + plt.ylabel("label") + plt.title("title") plt.legend() plt.grid(True) plt.tight_layout() @@ -477,8 +457,6 @@ def calibrate_bpm_flux(ave = 5): f.write("Energy,Transmission,BPMSum,Flux\n") print("Energy,Transmission,BPMSum,Flux\n") energies = [12400,7000,8000,9000,10000,11000,13000,14000,15000,16000,18000,20000,25000] - # energies = [7000,8000,9000,10000] - # transmissions = [1, 0.5, 0.2, 0.1, 0.05, 0.01] transmissions = [1, 0.9, 0.8, 0.7, 0.6, 0.5,0.4,0.3,0.2,0.1] for energy in energies: @@ -513,7 +491,7 @@ def calibrate_bpm_flux(ave = 5): umv(dev.id_gap, 20) def analyse_bpm_flux_calibration( - filename="luts/bpm_calib/bpm_flux_comb.csv", + filename="luts/bpm_calib/bpm_flux_20260708b.csv", force_zero_intercept=False, ): data = pd.read_csv(filename) @@ -576,44 +554,117 @@ def analyse_bpm_flux_calibration( print(dict) return results -def get_flux_calibration(energy): - filename = "luts/bpm_calib/bpm_flux_fits_zero.csv" - default_slope = 4.42e8 - default_intercept = -1.66e11 +def linear_bpm_flux_calib(): + filename = 'luts/bpm_calib/fits-25.csv' + df = pd.read_csv(filename) + energies = df["Energy"].to_numpy() + intercepts = df["Intercept"].to_numpy() + slopes = df["Slope"].to_numpy() + # --- Plot --- + plt.figure(figsize=(7, 5)) + plt.scatter(energies, slopes, color="red") - try: - df = pd.read_csv(filename) - energies = df["Energy"].to_numpy() - intercepts = df["Intercept"].to_numpy() - slopes = df["Slope"].to_numpy() - slope_interp = CubicSpline(energies, slopes) - intercept_interp = CubicSpline(energies, intercepts) - slope = slope_interp(energy) - intercept = intercept_interp(energy) - print(f"Using data from calibration file") - except FileNotFoundError: - print("Cannot access calibration file, using default parameters") - slope = default_slope - intercept = default_intercept + x_fit = np.linspace(min(energies), max(energies), 100) + coeffs = np.polyfit(energies, slopes,1) + y_fit = np.poly1d(coeffs) + plt.plot(x_fit, y_fit(x_fit)), + plt.xlabel("Energy eV") + plt.ylabel("Slope") + plt.title(f"Energies vs slopes, coeffs = {coeffs}") + # plt.legend() + plt.grid(True) + plt.tight_layout() + plt.savefig(f"luts/bpm_calib/slopes_vs_energy") + plt.show() + return coeffs + + +# def get_flux_calibration(energy): +# # filename = "luts/bpm_calib/bpm_flux_fits.csv" +# filename = 'luts/bpm_calib/fits-25.csv' +# default_slope = 4.42e8 +# default_intercept = -1.66e11 + +# try: +# df = pd.read_csv(filename) +# energies = df["Energy"].to_numpy() +# intercepts = df["Intercept"].to_numpy() +# slopes = df["Slope"].to_numpy() +# slope_interp = CubicSpline(energies, slopes) +# intercept_interp = CubicSpline(energies, intercepts) +# slope = slope_interp(energy) +# intercept = intercept_interp(energy) +# print(f"Using data from calibration file") +# # --- Plot --- +# plt.figure(figsize=(7, 5)) +# plt.scatter(energies, slopes, color="red") + +# x_fit = np.linspace(min(energies), max(energies), 100) +# coeffs = np.polyfit(energies, slopes,1) +# print("linear co-efficients: ", coeffs) +# y_fit = np.poly1d(coeffs) +# plt.plot(x_fit, y_fit(x_fit)), +# # "r--", label=f"Fit: Slope = {slope:.5g}, Intercept = {intercept:.5g}") + +# plt.xlabel("Energy") +# plt.ylabel("Slope") +# plt.title(f"{energy} eV") +# # plt.legend() +# plt.grid(True) +# plt.tight_layout() +# plt.show() +# except FileNotFoundError: +# print("Cannot access calibration file, using default parameters") +# slope = default_slope +# intercept = default_intercept - return slope, intercept +# return coeffs + + +def bpm2flux(energy=None, bpmsum=None, transm=None): + """ + Calculate the flux from BCU BPM reading. + Option to provide energy, bpmsum reading and transmission. + If these are not given, the current values are used. + + Returns the flux at the sample (after attenuators) and a calculated + value of the full flux if attenuation was 0. + + """ + calibration_min_energy = 6500 + calibration_max_energy = 21000 -def bpm2flux(energy=None,bpmsum=None): if energy is None: energy = get_current_energy() + if bpmsum is None: - bpmsum = dev.bcu_bpmsum.read()['bcu_bpmsum']['value'] + bpmsum = dev.bcu_bpmsum.read()["bcu_bpmsum"]["value"] - print(f"BCU_bpmsum = {bpmsum}") + if transm is None: + transm = dev.transm.read()['transm']['value'] - slope, intercept = get_flux_calibration(energy) + if not calibration_min_energy <= energy <= calibration_max_energy: + raise ValueError( + f"Energy {energy:.0f} eV is outside the calibrated range " + f"{calibration_min_energy:.0f}–" + f"{calibration_max_energy:.0f} eV" + ) - calc = slope * bpmsum + intercept - flux = f"{calc:.5g}" - print(flux) - return float(calc) + coeffs = [ + 1.06436277e5, + -6.38943746e8, + ] + calibration_factor = np.polyval(coeffs, energy) + flux = calibration_factor * bpmsum + full_flux = flux/transm + if transm == 1: + print(f"Transmission = {transm*100:.5g} %, Flux = {flux: .3g} ph/s,\n") + else: + print(f"Transmission = {transm*100: .5g} %, Flux = {flux: .3g} ph/s,\n" + f"Flux with 100 % transmission would be {full_flux: .3g} ph/s") + return float(flux), float(full_flux) diff --git a/pxii_bec/macros/katscripts.py b/pxii_bec/macros/katscripts.py index 2838e09..b456dd3 100755 --- a/pxii_bec/macros/katscripts.py +++ b/pxii_bec/macros/katscripts.py @@ -1494,12 +1494,35 @@ import matplotlib.pyplot as plt from epics import caget -def scan_scin_focus(): +def scan_scin_focus(type = 'fine'): z0 = dev.diag_z.position - z_positions = np.linspace(-9,9,30) - contrasts = [] + if z0-5 <= -10: + min = -9.5 + else: + min = z0-5 + + if z0+5 >=10: + max = 9.5 + else: + max = z0+5 + if type == 'fine': + steps = 100 + elif type == 'coarse': + steps = 30 + else: + steps = 60 + umv(dev.scam_zoom, 1000) + dev.transm.put(0.1) + + auto_exposure("samcam", target=200, max_iter=20) + time.sleep(0.2) + + z_positions = np.linspace(min,max,steps) + + + contrasts = [] for z in z_positions: