diff --git a/csaxs_bec/bec_ipython_client/plugins/cSAXS/intensity_map_predict_gap.py b/csaxs_bec/bec_ipython_client/plugins/cSAXS/intensity_map_predict_gap.py new file mode 100644 index 0000000..dbdc992 --- /dev/null +++ b/csaxs_bec/bec_ipython_client/plugins/cSAXS/intensity_map_predict_gap.py @@ -0,0 +1,26 @@ +"""Undulator gap predictor emitted by plot_intensity_map.py. +Edit the fitted constants in the signature to retune.""" + +import numpy as np + + +def predict_gap(energy, n=3, gap_min=5.0, + E_inf=3.2878, c0=2.46086, c1=-0.468091, c2=0.0): + """Undulator gap [mm] to place `energy` [keV] on harmonic `n`. + Fitted constants are the defaults below; edit them to retune. + Returns NaN where the energy is unreachable on that harmonic.""" + energy = np.asarray(energy, float) + arg = E_inf * n / energy - 1.0 # required K^2/2; must be > 0 + with np.errstate(invalid="ignore", divide="ignore"): + y = np.log(arg) + if abs(c2) < 1e-12: + g = (y - c0) / c1 + else: + disc = c1 * c1 - 4.0 * c2 * (c0 - y) + sq = np.sqrt(np.where(disc >= 0, disc, np.nan)) + r1 = (-c1 + sq) / (2.0 * c2) + r2 = (-c1 - sq) / (2.0 * c2) + g = np.where(c1 + 2.0 * c2 * r1 < 0, r1, r2) + g = np.where(arg > 0, g, np.nan) # above harmonic cutoff + g = np.where(g >= gap_min, g, np.nan) # below mechanical minimum + return g