diff --git a/lcls_tools/common/data/bmad_modeling/bmad_modeling.py b/lcls_tools/common/data/bmad_modeling/bmad_modeling.py index 0f31b425..2951f5ab 100644 --- a/lcls_tools/common/data/bmad_modeling/bmad_modeling.py +++ b/lcls_tools/common/data/bmad_modeling/bmad_modeling.py @@ -5,11 +5,12 @@ from datetime import datetime, timedelta from lcls_live.datamaps import get_datamaps from lcls_live.archiver import lcls_archiver_restore - +from lcls_tools.common.data.model_general_calcs import bdes_to_kmod YAML_LOCATION = os.path.join(os.path.dirname(__file__), "yaml/") +print(YAML_LOCATION) -def get_rf_quads_pvlist(tao, all_data_maps, beam_code=1): +def get_rf_quads_pvlist(tao, all_data_maps, beam_code='1'): """Returns pvlist from lcls_live datamaps for given beam_path for Cu beampaths beam_code can be 1 or 2""" pvlist = set() @@ -31,6 +32,7 @@ def get_rf_quads_pvlist(tao, all_data_maps, beam_code=1): for pv in map.pvlist: if "BEAMCODE" in pv: pv = map.accelerate_pvname + pv = pv[0:21] + beam_code + pv[22:] pvlist.add(pv) return list(pvlist) @@ -45,6 +47,7 @@ def get_energy_gain_pvlist(beam_path): except FileNotFoundError: print(f"Could not find yaml file {yaml_file_name}") return None + engy_meas['L3'] = engy_meas['L3'].replace('?', beam_path[3].upper()) [pvlist.append(engy_meas[key]) for key in engy_meas.keys()] return pvlist @@ -205,6 +208,45 @@ def get_tao_cmds(pvdata, data_maps): return lines +def create_cu_sxr_dualenergy_var(tao): + tao.cmd("set global lattice_calc_on = F") + quad_list = ['QBP33', 'QBP34', 'QDBL1', 'QDBL2', 'QDL11'] + tao.var_v1_create('qm.LTUS', 1, 5) + [k_min, k_max] = get_k_limits(quad_list) + for qI, quad in enumerate(quad_list): + tao.var_create('qm.LTUS[1]', quad, 'K1', 1, 0, 1E-4, + k_min[qI], k_max[qI], 'limit', 'F', 'F', 0.01) + tao.cmd("set global lattice_calc_on = T") + + +def update_k_limits(tao, quad_var): + """Update K limit from EPICS for QUAD variables""" + var_v1 = tao.var_v1_array(quad_var) + quad_list = [item['ele_name'] for item in var_v1['data']] + kmin, kmax = get_k_limits(tao, quad_list) + for qI, quad in enumerate(quad_list): + tao.cmd(f'set var q_LTUS[{qI+1}]|low_lim = {kmin[qI]}') + tao.cmd(f'set var q_LTUS[{qI+1}]|high_lim = {kmax[qI]}') + + +def get_k_limits(tao, quad_list): + """Get BDES limits from EPICS and return as K limits""" + k_min, k_max = [], [] + for ii, quad in enumerate(quad_list): + device = tao.ele_head(quad)['alias'] + e_tot = tao.ele_gen_attribs(quad)['P0C'] + len = tao.ele_gen_attribs(quad)['L'] + for attr in [':BMIN', ':BMAX']: + pv = device + attr + b_lim = epics.caget(pv) + k_lim = bdes_to_kmod(e_tot, len, b_lim) + if 'MIN' in attr: + k_min.append(k_lim) + if 'MAX' in attr: + k_max.append(k_lim) + return k_min, k_max + + def create_emitmeas_datum(tao, element): tao.cmd("set global lattice_calc_on = F") tao.data_d2_create(f"emitmeas{element}", 1, "twiss^^1^^4") @@ -213,29 +255,25 @@ def create_emitmeas_datum(tao, element): "beta.a", ele_name=element, merit_type="target", - weight=10, - ) + weight=10) tao.datum_create( f"emitmeas{element}.twiss[2]", "alpha.a", ele_name=element, merit_type="target", - weight=10, - ) + weight=10) tao.datum_create( f"emitmeas{element}.twiss[3]", "beta.b", ele_name=element, merit_type="target", - weight=10, - ) + weight=10) tao.datum_create( f"emitmeas{element}.twiss[4]", "alpha.b", ele_name=element, merit_type="target", - weight=10, - ) + weight=10) tao.data_set_design_value() tao.cmd("set global lattice_calc_on = T") @@ -251,6 +289,8 @@ def get_expected_energy_gain(pvdata, region, beam_path): previous_region = "GUN" else: previous_region = "L" + str(int(region[1]) - 1) + if region == "L3": + engy_meas['L3'] = engy_meas['L3'].replace('?', beam_path[3].upper()) expected_gain = pvdata[engy_meas[region]] - pvdata[engy_meas[previous_region]] return expected_gain @@ -295,19 +335,26 @@ def update_energy_gain_sc(tao, pvdata, region, mdl_obj): print(region_e_tot) -def update_energy_gain_cu(tao, pvdata, mdl_obj): +def update_energy_gain_cu(tao, pvdata, region, mdl_obj): """ Updates Cu Linac energy gain profile based on bending magnets, calculates a fudge and modifies model's cavity amplitudes and phases """ - expected_gain = get_expected_energy_gain(mdl_obj.region) + expected_gain = get_expected_energy_gain(pvdata, region, mdl_obj.beam_path) init_cmds = ["veto dat *", "veto var *"] - if mdl_obj.region == "L2": - tao.cmd(f"set dat BC1.energy[2]|meas = {expected_gain} ") - optimize_cmds = init_cmds + ["use dat BC2.energy[1]", "use var linac_fudge[2]"] - if mdl_obj.region == "L3": - tao.cmd(f"set dat L3[2]|meas ={expected_gain} ") - optimize_cmds = init_cmds + ["use dat L3.energy[2]", "use var linac_fudge[3]"] + if region == "L2": + L1_energy = 1E9 * 0.22 + L2_energy = L1_energy + 1E9 * expected_gain + tao.cmd(f"set dat BC2.energy[2]|meas = {L2_energy} ") + optimize_cmds = init_cmds + ["use dat BC2.energy[2]", + "use var linac_fudge[2]"] + if region == "L3": + L2_energy = tao.data_parameter('BC2.energy[2]', + 'meas_value')[0]['data'][0] + L3_energy = L2_energy + 1E9 * expected_gain + tao.cmd(f"set dat L3[2]|meas ={L3_energy} ") + optimize_cmds = init_cmds + ["use dat L3.energy[2]", + "use var linac_fudge[3]"] tao.cmds(optimize_cmds) r = tao.cmd("run") print(r) diff --git a/lcls_tools/common/data/bmad_modeling/yaml/energy_measurements.yml b/lcls_tools/common/data/bmad_modeling/yaml/energy_measurements.yml index f25160bb..42f12884 100644 --- a/lcls_tools/common/data/bmad_modeling/yaml/energy_measurements.yml +++ b/lcls_tools/common/data/bmad_modeling/yaml/energy_measurements.yml @@ -3,10 +3,11 @@ cu: L0: REFS:IN20:751:EDES L1: REFS:LI21:231:EDES L2: REFS:LI24:790:EDES - L3: REFS:LI30:901:EDES + L3: REFS:DMP?:400:EDES + sc: GUN: REFS:GUNB:950:EDES L0: REFS:COL0:950:EDES L1: REFS:BC1B:400:EDES L2: REFS:BC2B:500:EDES - L3: REFS:BYP:400:EDES + L3: REFS:DMP?:400:EDES