DataMap examples¶
DataMaps
are configurable objects with the purpose of translating PV values to simulation inputs. They do not retain any values. Rather, they provide methods .to_tao(pvdata)
, .to_bmad(pvdata)
that will produce input for Tao and Bmad, respectively, from a dict-like pvdata
object with the actual PV names and values.
In [1]:
Copied!
# Useful for debugging
%load_ext autoreload
%autoreload 2
%config InlineBackend.figure_format = 'retina'
# Useful for debugging
%load_ext autoreload
%autoreload 2
%config InlineBackend.figure_format = 'retina'
PVDATA¶
Get some actual data that we will use to map
In [2]:
Copied!
import json
import os
import json
import os
In [3]:
Copied!
PVDATA = json.load(open('data/PVDATA-2021-04-21T08:10:25.000000-07:00.json'))
len(PVDATA)
PVDATA = json.load(open('data/PVDATA-2021-04-21T08:10:25.000000-07:00.json'))
len(PVDATA)
Out[3]:
740
Tabular¶
Often PVs have a simple linear mapping to simulation inputs. The TabularDataMap
helps with this
In [4]:
Copied!
from lcls_live.datamaps.tabular import TabularDataMap
import pandas as pd
import dataclasses
from lcls_live.datamaps.tabular import TabularDataMap
import pandas as pd
import dataclasses
In [5]:
Copied!
# Make some tabular data
dat0 = [
{'name': 'BC1_offset',
'pvname':'BMLN:LI21:235:MOTR', # mm
'bmad_factor': 0.001,
'bmad_name': 'O_BC1_OFFSET',
'bmad_attribute': 'offset'
},
{'name': 'BC2_offset',
'pvname':'BMLN:LI24:805:MOTR', # mm
'bmad_factor': 0.001,
'bmad_name': 'O_BC2_OFFSET',
'bmad_attribute': 'offset'
},
{
'name': 'L1_phase',
'description': 'Controls the L1 phase, which is the single klystron L21_1. We will disable this for now, because the KlystronDataMap handles the phase directly.',
'pvname': 'ACCL:LI21:1:L1S_S_PV',
'bmad_name':'O_L1',
'bmad_factor': 0, # We'll disable this for now. The Klystron handles it.
'bmad_attribute':'phase_deg'
}
]
dat_hxr = [
{
'name': 'L2_phase',
'pvname': 'ACCL:LI22:1:PDES',
'bmad_name':'O_L2',
'bmad_factor': 1,
'bmad_attribute':'phase_deg'
},
{
'name': 'L3_phase',
'pvname': 'ACCL:LI25:1:PDES',
'bmad_name':'O_L3',
'bmad_attribute':'phase_deg',
'bmad_offset': 0
},
]
# SXR has different PVs
dat_sxr = [
{
'name': 'L2_phase',
'pvname': 'ACCL:LI22:1:PDES:SETDATA_1',
'bmad_name':'O_L2',
'bmad_factor': 1,
'bmad_attribute':'phase_deg'
},
{
'name': 'L3_phase',
'pvname': 'ACCL:LI25:1:PDES:SETDATA_1',
'bmad_name':'O_L3',
'bmad_attribute':'phase_deg',
'bmad_offset': 0
},
]
#Note that there are sone NaNs here. That's okay.
df = pd.DataFrame(dat0+dat_hxr)
df
# Make some tabular data
dat0 = [
{'name': 'BC1_offset',
'pvname':'BMLN:LI21:235:MOTR', # mm
'bmad_factor': 0.001,
'bmad_name': 'O_BC1_OFFSET',
'bmad_attribute': 'offset'
},
{'name': 'BC2_offset',
'pvname':'BMLN:LI24:805:MOTR', # mm
'bmad_factor': 0.001,
'bmad_name': 'O_BC2_OFFSET',
'bmad_attribute': 'offset'
},
{
'name': 'L1_phase',
'description': 'Controls the L1 phase, which is the single klystron L21_1. We will disable this for now, because the KlystronDataMap handles the phase directly.',
'pvname': 'ACCL:LI21:1:L1S_S_PV',
'bmad_name':'O_L1',
'bmad_factor': 0, # We'll disable this for now. The Klystron handles it.
'bmad_attribute':'phase_deg'
}
]
dat_hxr = [
{
'name': 'L2_phase',
'pvname': 'ACCL:LI22:1:PDES',
'bmad_name':'O_L2',
'bmad_factor': 1,
'bmad_attribute':'phase_deg'
},
{
'name': 'L3_phase',
'pvname': 'ACCL:LI25:1:PDES',
'bmad_name':'O_L3',
'bmad_attribute':'phase_deg',
'bmad_offset': 0
},
]
# SXR has different PVs
dat_sxr = [
{
'name': 'L2_phase',
'pvname': 'ACCL:LI22:1:PDES:SETDATA_1',
'bmad_name':'O_L2',
'bmad_factor': 1,
'bmad_attribute':'phase_deg'
},
{
'name': 'L3_phase',
'pvname': 'ACCL:LI25:1:PDES:SETDATA_1',
'bmad_name':'O_L3',
'bmad_attribute':'phase_deg',
'bmad_offset': 0
},
]
#Note that there are sone NaNs here. That's okay.
df = pd.DataFrame(dat0+dat_hxr)
df
Out[5]:
name | pvname | bmad_factor | bmad_name | bmad_attribute | description | bmad_offset | |
---|---|---|---|---|---|---|---|
0 | BC1_offset | BMLN:LI21:235:MOTR | 0.001 | O_BC1_OFFSET | offset | NaN | NaN |
1 | BC2_offset | BMLN:LI24:805:MOTR | 0.001 | O_BC2_OFFSET | offset | NaN | NaN |
2 | L1_phase | ACCL:LI21:1:L1S_S_PV | 0.000 | O_L1 | phase_deg | Controls the L1 phase, which is the single kly... | NaN |
3 | L2_phase | ACCL:LI22:1:PDES | 1.000 | O_L2 | phase_deg | NaN | NaN |
4 | L3_phase | ACCL:LI25:1:PDES | NaN | O_L3 | phase_deg | NaN | 0.0 |
In [6]:
Copied!
# Make the DataMap object, identifying the columns to be used
DM = TabularDataMap(df, pvname='pvname', element='bmad_name', attribute='bmad_attribute', factor='bmad_factor', offset='bmad_offset')
DM.pvlist
# Make the DataMap object, identifying the columns to be used
DM = TabularDataMap(df, pvname='pvname', element='bmad_name', attribute='bmad_attribute', factor='bmad_factor', offset='bmad_offset')
DM.pvlist
Out[6]:
['BMLN:LI21:235:MOTR', 'BMLN:LI24:805:MOTR', 'ACCL:LI21:1:L1S_S_PV', 'ACCL:LI22:1:PDES', 'ACCL:LI25:1:PDES']
In [7]:
Copied!
# Process the data for Bmad commands
DM.as_bmad(PVDATA)
# Process the data for Bmad commands
DM.as_bmad(PVDATA)
Out[7]:
['O_BC1_OFFSET[offset] = 0.001 * 247.85581047127175', 'O_BC2_OFFSET[offset] = 0.001 * 385.0', 'O_L1[phase_deg] = 0.0 * -22.43420088792822', 'O_L2[phase_deg] = -36.284427384073055', 'O_L3[phase_deg] = 0.0']
In [8]:
Copied!
# or Tao commands
DM.as_tao(PVDATA)
# or Tao commands
DM.as_tao(PVDATA)
Out[8]:
['set ele O_BC1_OFFSET offset = 0.001 * 247.85581047127175', 'set ele O_BC2_OFFSET offset = 0.001 * 385.0', 'set ele O_L1 phase_deg = 0.0 * -22.43420088792822', 'set ele O_L2 phase_deg = -36.284427384073055', 'set ele O_L3 phase_deg = 0.0']
In [9]:
Copied!
# Save, and reload
JSON_OUT = 'linac_TabularDataMap.json'
DM.to_json(JSON_OUT)
DM2 = TabularDataMap.from_json(open(JSON_OUT).read())
DM2.data
# Save, and reload
JSON_OUT = 'linac_TabularDataMap.json'
DM.to_json(JSON_OUT)
DM2 = TabularDataMap.from_json(open(JSON_OUT).read())
DM2.data
Out[9]:
name | pvname | bmad_factor | bmad_name | bmad_attribute | description | bmad_offset | |
---|---|---|---|---|---|---|---|
0 | BC1_offset | BMLN:LI21:235:MOTR | 0.001 | O_BC1_OFFSET | offset | None | NaN |
1 | BC2_offset | BMLN:LI24:805:MOTR | 0.001 | O_BC2_OFFSET | offset | None | NaN |
2 | L1_phase | ACCL:LI21:1:L1S_S_PV | 0.000 | O_L1 | phase_deg | Controls the L1 phase, which is the single kly... | NaN |
3 | L2_phase | ACCL:LI22:1:PDES | 1.000 | O_L2 | phase_deg | None | NaN |
4 | L3_phase | ACCL:LI25:1:PDES | NaN | O_L3 | phase_deg | None | 0.0 |
In [10]:
Copied!
# cleanup
os.remove(JSON_OUT)
# cleanup
os.remove(JSON_OUT)
from CSV¶
In [11]:
Copied!
# Read a previously made csv file. This has slightly different columns
df2 = pd.read_csv('../lcls_live/data/cu_hxr/quad_mapping.csv')[0:10]
df2.columns
# Read a previously made csv file. This has slightly different columns
df2 = pd.read_csv('../lcls_live/data/cu_hxr/quad_mapping.csv')[0:10]
df2.columns
Out[11]:
Index(['device_name', 'attribute', 'unit', 'bmad_ele_name', 'bmad_factor', 'bmad_attribute', 'example_value'], dtype='object')
In [12]:
Copied!
df2['pvname'] = df2['device_name']+':'+df2['attribute']
DM2 = TabularDataMap(df2, pvname='pvname', element='bmad_ele_name', attribute='bmad_attribute', factor='bmad_factor', offset='')
DM2.pvlist
df2['pvname'] = df2['device_name']+':'+df2['attribute']
DM2 = TabularDataMap(df2, pvname='pvname', element='bmad_ele_name', attribute='bmad_attribute', factor='bmad_factor', offset='')
DM2.pvlist
Out[12]:
['QUAD:LI21:211:BDES', 'QUAD:LI21:221:BDES', 'QUAD:LI21:243:BDES', 'QUAD:LI21:251:BDES', 'QUAD:LI21:271:BDES', 'QUAD:LI21:335:BDES', 'QUAD:LI24:713:BDES', 'QUAD:LI24:740:BDES', 'QUAD:LI24:860:BDES', 'QUAD:LI24:892:BDES']
In [13]:
Copied!
# Here these aren't in our PVDATA
DM2.as_tao(PVDATA)
# Here these aren't in our PVDATA
DM2.as_tao(PVDATA)
Out[13]:
['set ele QM11 b1_gradient = -1/(10.0*0.108) * 4.2315152', 'set ele CQ11 b1_gradient = -1/(10.0*0.108) * -0.0204323', 'set ele SQ13 b1_gradient = -1/(10.0*0.160) * 0.0', 'set ele CQ12 b1_gradient = -1/(10.0*0.108) * -0.2459959', 'set ele QM12 b1_gradient = -1/(10.0*0.108) * -6.1242668', 'set ele QM15 b1_gradient = -1/(10.0*0.108) * -5.47263', 'set ele QM21 b1_gradient = -1/(10.0*0.461) * 35.4159609', 'set ele CQ21 b1_gradient = -1/(10.0*0.108) * -0.0621288', 'set ele CQ22 b1_gradient = -1/(10.0*0.108) * 1.35389', 'set ele QM22 b1_gradient = -1/(10.0*0.461) * -40.7820027']
In [14]:
Copied!
# We could check beforehand:
missing = [name for name in DM2.pvlist if name not in PVDATA]
len(missing)
# We could check beforehand:
missing = [name for name in DM2.pvlist if name not in PVDATA]
len(missing)
Out[14]:
0
Quads from Pytao¶
In [15]:
Copied!
from pytao import Tao
tao = Tao('-init $LCLS_LATTICE/bmad/models/cu_hxr/tao.init -slice OTR2:END -noplot')
from pytao import Tao
tao = Tao('-init $LCLS_LATTICE/bmad/models/cu_hxr/tao.init -slice OTR2:END -noplot')
In [16]:
Copied!
def quad_pvinfo(tao, ele):
"""
Returns dict of PV information for use in a DataMap
"""
head = tao.ele_head(ele)
attrs = tao.ele_gen_attribs(ele)
device = head['alias']
d = {}
d['bmad_name'] = ele
d['pvname_rbv'] = device+':BACT'
d['pvname'] = device+':BDES'
d['bmad_factor'] = -1/attrs['L']/10
d['bmad_attribute'] = 'b1_gradient'
return d
quad_pvinfo(tao, 'QM01')
def quad_pvinfo(tao, ele):
"""
Returns dict of PV information for use in a DataMap
"""
head = tao.ele_head(ele)
attrs = tao.ele_gen_attribs(ele)
device = head['alias']
d = {}
d['bmad_name'] = ele
d['pvname_rbv'] = device+':BACT'
d['pvname'] = device+':BDES'
d['bmad_factor'] = -1/attrs['L']/10
d['bmad_attribute'] = 'b1_gradient'
return d
quad_pvinfo(tao, 'QM01')
Out[16]:
{'bmad_name': 'QM01', 'pvname_rbv': 'QUAD:IN20:631:BACT', 'pvname': 'QUAD:IN20:631:BDES', 'bmad_factor': -0.9259259259259259, 'bmad_attribute': 'b1_gradient'}
In [17]:
Copied!
quad_names = tao.lat_list('quad::*', 'ele.name', flags='-no_slaves')
dfq = pd.DataFrame([quad_pvinfo(tao, ele) for ele in quad_names])
dfq
quad_names = tao.lat_list('quad::*', 'ele.name', flags='-no_slaves')
dfq = pd.DataFrame([quad_pvinfo(tao, ele) for ele in quad_names])
dfq
Out[17]:
bmad_name | pvname_rbv | pvname | bmad_factor | bmad_attribute | |
---|---|---|---|---|---|
0 | QM01 | QUAD:IN20:631:BACT | QUAD:IN20:631:BDES | -0.925926 | b1_gradient |
1 | QM02 | QUAD:IN20:651:BACT | QUAD:IN20:651:BDES | -0.925926 | b1_gradient |
2 | QB | QUAD:IN20:731:BACT | QUAD:IN20:731:BDES | -0.936330 | b1_gradient |
3 | QM03 | QUAD:IN20:771:BACT | QUAD:IN20:771:BDES | -0.925926 | b1_gradient |
4 | QM04 | QUAD:IN20:781:BACT | QUAD:IN20:781:BDES | -0.925926 | b1_gradient |
... | ... | ... | ... | ... | ... |
180 | QHXH47 | QUAD:UNDH:4780:BACT | QUAD:UNDH:4780:BDES | -1.190476 | b1_gradient |
181 | QUE1 | QUAD:DMPH:300:BACT | QUAD:DMPH:300:BDES | -0.181818 | b1_gradient |
182 | QUE2 | QUAD:DMPH:380:BACT | QUAD:DMPH:380:BDES | -0.181818 | b1_gradient |
183 | QDMP1 | QUAD:DMPH:500:BACT | QUAD:DMPH:500:BDES | -0.232558 | b1_gradient |
184 | QDMP2 | QUAD:DMPH:600:BACT | QUAD:DMPH:600:BDES | -0.232558 | b1_gradient |
185 rows × 5 columns
In [18]:
Copied!
QUAD_DATAMAP = TabularDataMap(dfq, pvname='pvname', element='bmad_name', attribute = 'bmad_attribute', factor='bmad_factor')
QUAD_DATAMAP = TabularDataMap(dfq, pvname='pvname', element='bmad_name', attribute = 'bmad_attribute', factor='bmad_factor')
In [19]:
Copied!
#JSONFILE = os.path.join(data_dir, 'cu_hxr/quad_TabularDataMap.json')
#QUAD_DATAMAP.to_json(JSONFILE)
#JSONFILE = os.path.join(data_dir, 'cu_hxr/quad_TabularDataMap.json')
#QUAD_DATAMAP.to_json(JSONFILE)
Measurements for Tao¶
In [20]:
Copied!
# The syntax is flexible enough to use for getting measurements for Tao
ENERGY_MEAS = [
{
'name': 'L1_energy',
'pvname': 'BEND:LI21:231:EDES', # or EDES
'tao_datum': 'BC1.energy[1]',
'factor': 1e9
},
{
'name': 'L2_energy',
'pvname': 'BEND:LI24:790:EDES', # or EDES
'tao_datum': 'BC2.energy[1]',
'factor': 1e9
},
{
'name': 'L3_HXR_energy',
'pvname': 'BEND:DMPH:400:EDES', # or EDES
'tao_datum': 'L3.energy[2]',
'factor': 1e9
}
#{
#'name': 'L3_SXR_energy',
#'pvname': 'BEND:DMPS:400:EDES', # or EDES
#'factor': 1e9
#},
]
df = pd.DataFrame(ENERGY_MEAS)
DM = TabularDataMap(df, pvname='pvname', element='tao_datum', factor='factor',
tao_format = 'set data {element}|meas = {value}',
bmad_format = '! No equivalent Bmad format for: set data {element}|meas = {value}'
)
DM.as_tao(PVDATA)
# The syntax is flexible enough to use for getting measurements for Tao
ENERGY_MEAS = [
{
'name': 'L1_energy',
'pvname': 'BEND:LI21:231:EDES', # or EDES
'tao_datum': 'BC1.energy[1]',
'factor': 1e9
},
{
'name': 'L2_energy',
'pvname': 'BEND:LI24:790:EDES', # or EDES
'tao_datum': 'BC2.energy[1]',
'factor': 1e9
},
{
'name': 'L3_HXR_energy',
'pvname': 'BEND:DMPH:400:EDES', # or EDES
'tao_datum': 'L3.energy[2]',
'factor': 1e9
}
#{
#'name': 'L3_SXR_energy',
#'pvname': 'BEND:DMPS:400:EDES', # or EDES
#'factor': 1e9
#},
]
df = pd.DataFrame(ENERGY_MEAS)
DM = TabularDataMap(df, pvname='pvname', element='tao_datum', factor='factor',
tao_format = 'set data {element}|meas = {value}',
bmad_format = '! No equivalent Bmad format for: set data {element}|meas = {value}'
)
DM.as_tao(PVDATA)
Out[20]:
['set data BC1.energy[1]|meas = 1000000000.0 * 0.22', 'set data BC2.energy[1]|meas = 1000000000.0 * 4.5', 'set data L3.energy[2]|meas = 1000000000.0 * 11.0']
In [21]:
Copied!
# and this will produce
DM.as_bmad(PVDATA)
# and this will produce
DM.as_bmad(PVDATA)
Out[21]:
['! No equivalent Bmad format for: set data BC1.energy[1]|meas = 1000000000.0 * 0.22', '! No equivalent Bmad format for: set data BC2.energy[1]|meas = 1000000000.0 * 4.5', '! No equivalent Bmad format for: set data L3.energy[2]|meas = 1000000000.0 * 11.0']
In [22]:
Copied!
# Save
#JSON_OUT = os.path.join(data_dir, 'cu_hxr/tao_energy_measurements_TabularDataMap.json')
#DM.to_json(JSON_OUT)
# Save
#JSON_OUT = os.path.join(data_dir, 'cu_hxr/tao_energy_measurements_TabularDataMap.json')
#DM.to_json(JSON_OUT)
Subboosters¶
In [23]:
Copied!
from lcls_live.datamaps.klystron import subbooster_pvinfo, SUBBOOSTER_SECTORS
from lcls_live.datamaps.klystron import subbooster_pvinfo, SUBBOOSTER_SECTORS
In [24]:
Copied!
SUBBOOSTERS = []
for sector in SUBBOOSTER_SECTORS:
dat = subbooster_pvinfo(sector, beamcode=1) # beamcode=1 => HXR, beamcode=2 => SXR
dat['bmad_name'] = f'SBST_{sector}'
dat['bmad_attribute'] = 'phase_deg'
SUBBOOSTERS.append(dat)
df = pd.DataFrame(SUBBOOSTERS)
df
SUBBOOSTERS = []
for sector in SUBBOOSTER_SECTORS:
dat = subbooster_pvinfo(sector, beamcode=1) # beamcode=1 => HXR, beamcode=2 => SXR
dat['bmad_name'] = f'SBST_{sector}'
dat['bmad_attribute'] = 'phase_deg'
SUBBOOSTERS.append(dat)
df = pd.DataFrame(SUBBOOSTERS)
df
Out[24]:
name | phase_pvname | desciption | bmad_name | bmad_attribute | |
---|---|---|---|---|---|
0 | SBST_21 | SBST:LI21:1:PHAS | Normal subbooster | SBST_21 | phase_deg |
1 | SBST_22 | SBST:LI22:1:PHAS | Normal subbooster | SBST_22 | phase_deg |
2 | SBST_23 | SBST:LI23:1:PHAS | Normal subbooster | SBST_23 | phase_deg |
3 | SBST_24 | SBST:LI24:1:PHAS | Normal subbooster | SBST_24 | phase_deg |
4 | SBST_25 | SBST:LI25:1:PHAS | Normal subbooster | SBST_25 | phase_deg |
5 | SBST_26 | SBST:LI26:1:PHAS | Normal subbooster | SBST_26 | phase_deg |
6 | SBST_27 | SBST:LI27:1:PHAS | Normal subbooster | SBST_27 | phase_deg |
7 | SBST_28 | SBST:LI28:1:PHAS | Normal subbooster | SBST_28 | phase_deg |
8 | SBST_29 | ACCL:LI29:0:KLY_PDES | Special feedback subbooster, beamcode 1 | SBST_29 | phase_deg |
9 | SBST_30 | ACCL:LI30:0:KLY_PDES | Special feedback subbooster, beamcode 1 | SBST_30 | phase_deg |
Beginning Twiss measurements¶
In [25]:
Copied!
def beginning_meas(name, pvprefix):
dat = [
{
'name': f'{name}_beta_x_meas',
'pvname': f'{pvprefix}:BETA_X',
'bmad_name': 'beginning',
'bmad_attribute': 'beta_a'
},
{
'name': f'{name}_beta_y_meas',
'pvname': f'{pvprefix}:BETA_Y',
'bmad_name': 'beginning',
'bmad_attribute': 'beta_b'
},
{
'name': f'{name}_alpha_x_meas',
'pvname': f'{pvprefix}:ALPHA_X',
'bmad_name': 'beginning',
'bmad_attribute': 'alpha_a'
},
{
'name': f'{name}_alpha_y_meas',
'pvname': f'{pvprefix}:ALPHA_Y',
'bmad_name': 'beginning',
'bmad_attribute': 'alpha_b'
},
]
df= pd.DataFrame(dat)
return TabularDataMap(df, pvname='pvname', element='bmad_name', attribute = 'bmad_attribute')
OTR2_BEGINNING = beginning_meas('OTR2', 'OTRS:IN20:571')
OTR2_BEGINNING.data
def beginning_meas(name, pvprefix):
dat = [
{
'name': f'{name}_beta_x_meas',
'pvname': f'{pvprefix}:BETA_X',
'bmad_name': 'beginning',
'bmad_attribute': 'beta_a'
},
{
'name': f'{name}_beta_y_meas',
'pvname': f'{pvprefix}:BETA_Y',
'bmad_name': 'beginning',
'bmad_attribute': 'beta_b'
},
{
'name': f'{name}_alpha_x_meas',
'pvname': f'{pvprefix}:ALPHA_X',
'bmad_name': 'beginning',
'bmad_attribute': 'alpha_a'
},
{
'name': f'{name}_alpha_y_meas',
'pvname': f'{pvprefix}:ALPHA_Y',
'bmad_name': 'beginning',
'bmad_attribute': 'alpha_b'
},
]
df= pd.DataFrame(dat)
return TabularDataMap(df, pvname='pvname', element='bmad_name', attribute = 'bmad_attribute')
OTR2_BEGINNING = beginning_meas('OTR2', 'OTRS:IN20:571')
OTR2_BEGINNING.data
Out[25]:
name | pvname | bmad_name | bmad_attribute | |
---|---|---|---|---|
0 | OTR2_beta_x_meas | OTRS:IN20:571:BETA_X | beginning | beta_a |
1 | OTR2_beta_y_meas | OTRS:IN20:571:BETA_Y | beginning | beta_b |
2 | OTR2_alpha_x_meas | OTRS:IN20:571:ALPHA_X | beginning | alpha_a |
3 | OTR2_alpha_y_meas | OTRS:IN20:571:ALPHA_Y | beginning | alpha_b |
In [26]:
Copied!
WS02_BEGINNING = beginning_meas('WS02', 'WIRE:IN20:561')
WS02_BEGINNING = beginning_meas('WS02', 'WIRE:IN20:561')
KlystronDataMap¶
In [27]:
Copied!
from lcls_live.datamaps.klystron import KlystronDataMap, klystron_pvinfo, existing_LCLS_klystrons_sector_station
from lcls_live.datamaps.klystron import KlystronDataMap, klystron_pvinfo, existing_LCLS_klystrons_sector_station
In [28]:
Copied!
# Get a sector, station that exists
existing_LCLS_klystrons_sector_station
# Get a sector, station that exists
existing_LCLS_klystrons_sector_station
Out[28]:
((20, 6), (20, 7), (20, 8), (21, 1), (21, 2), (21, 3), (21, 4), (21, 5), (21, 6), (21, 7), (21, 8), (22, 1), (22, 2), (22, 3), (22, 4), (22, 5), (22, 6), (22, 7), (22, 8), (23, 1), (23, 2), (23, 3), (23, 4), (23, 5), (23, 6), (23, 7), (23, 8), (24, 1), (24, 2), (24, 3), (24, 4), (24, 5), (24, 6), (25, 1), (25, 2), (25, 3), (25, 4), (25, 5), (25, 6), (25, 7), (25, 8), (26, 1), (26, 2), (26, 4), (26, 5), (26, 6), (26, 7), (26, 8), (27, 1), (27, 2), (27, 3), (27, 4), (27, 5), (27, 6), (27, 7), (27, 8), (28, 1), (28, 2), (28, 3), (28, 4), (28, 5), (28, 6), (28, 7), (28, 8), (29, 1), (29, 2), (29, 3), (29, 4), (29, 5), (29, 6), (29, 7), (29, 8), (30, 1), (30, 2), (30, 3), (30, 4), (30, 5), (30, 6), (30, 7), (30, 8))
In [29]:
Copied!
# This will return a flat dict of info
klystron_pvinfo(30, 6)
# This will return a flat dict of info
klystron_pvinfo(30, 6)
Out[29]:
{'name': 'K30_6', 'sector': 30, 'station': 6, 'description': 'Klystron in sector 30, station 6, beamcode 1', 'enld_pvname': 'KLYS:LI30:61:ENLD', 'phase_pvname': 'KLYS:LI30:61:PHAS', 'accelerate_pvname': 'KLYS:LI30:61:BEAMCODE1_STAT', 'swrd_pvname': 'KLYS:LI30:61:SWRD', 'stat_pvname': 'KLYS:LI30:61:STAT', 'hdsc_pvname': 'KLYS:LI30:61:HDSC', 'dsta_pvname': 'KLYS:LI30:61:DSTA'}
In [30]:
Copied!
?KlystronDataMap
?KlystronDataMap
Init signature: KlystronDataMap( name: str, sector: int, station: int, description: str = '', enld_pvname: str = '', phase_pvname: str = '', accelerate_pvname: str = '', swrd_pvname: str = '', stat_pvname: str = '', hdsc_pvname: str = '', dsta_pvname: str = '', ) -> None Docstring: Attributes ---------- bmad_name : str pvlist : list[str] Methods ------- evaluate(pvdata) : Returns ------- dict of: enld : float energy gain in MeV phase : float phase in deg in_use : bool as_bmad(pvdata) Returns ------- list of str: Bmad lattice strings to set values extracted from pvdata as_tao(pvdata) Returns ------- list of str: Tao command strings to_json(file=None) Returns ------- JSON string, or writes to file if given. @classmethod from_json(s): Returns a new KlystronDataMap from a JSON string or file File: ~/Code/GitHub/lcls-live/lcls_live/datamaps/klystron.py Type: type Subclasses:
In [31]:
Copied!
# This makes an object
KlystronDataMap(**klystron_pvinfo(21, 6, beamcode=1))
# This makes an object
KlystronDataMap(**klystron_pvinfo(21, 6, beamcode=1))
Out[31]:
KlystronDataMap(name='K21_6', sector=21, station=6, description='Klystron in sector 21, station 6, beamcode 1', enld_pvname='KLYS:LI21:61:ENLD', phase_pvname='KLYS:LI21:61:PHAS', accelerate_pvname='KLYS:LI21:61:BEAMCODE1_STAT', swrd_pvname='KLYS:LI21:61:SWRD', stat_pvname='KLYS:LI21:61:STAT', hdsc_pvname='KLYS:LI21:61:HDSC', dsta_pvname='KLYS:LI21:61:DSTA')
In [32]:
Copied!
k = KlystronDataMap(**klystron_pvinfo(21, 6, beamcode=1))
# These are the PV names needed to mapping data
k.pvlist
k = KlystronDataMap(**klystron_pvinfo(21, 6, beamcode=1))
# These are the PV names needed to mapping data
k.pvlist
Out[32]:
['KLYS:LI21:61:ENLD', 'KLYS:LI21:61:PHAS', 'KLYS:LI21:61:BEAMCODE1_STAT', 'KLYS:LI21:61:SWRD', 'KLYS:LI21:61:STAT', 'KLYS:LI21:61:HDSC', 'KLYS:LI21:61:DSTA']
In [33]:
Copied!
# This will extract those and produce useful information
k.evaluate(PVDATA)
# This will extract those and produce useful information
k.evaluate(PVDATA)
Out[33]:
{'enld': 249.342, 'phase': -0.2623023986816406, 'in_use': True}
In [34]:
Copied!
# Actual inputs for a simulation
k.as_bmad(PVDATA)
# Actual inputs for a simulation
k.as_bmad(PVDATA)
Out[34]:
['K21_6[ENLD_MeV] = 249.342', 'K21_6[phase_deg] = -0.2623023986816406', 'K21_6[in_use] = 1']
In [35]:
Copied!
# A complete JSON string for serialization
k.to_json()
# A complete JSON string for serialization
k.to_json()
Out[35]:
'{"name": "K21_6", "sector": 21, "station": 6, "description": "Klystron in sector 21, station 6, beamcode 1", "enld_pvname": "KLYS:LI21:61:ENLD", "phase_pvname": "KLYS:LI21:61:PHAS", "accelerate_pvname": "KLYS:LI21:61:BEAMCODE1_STAT", "swrd_pvname": "KLYS:LI21:61:SWRD", "stat_pvname": "KLYS:LI21:61:STAT", "hdsc_pvname": "KLYS:LI21:61:HDSC", "dsta_pvname": "KLYS:LI21:61:DSTA"}'
In [36]:
Copied!
# Make a large list
KLYSTRON_DATAMAPS = []
for sector, station in existing_LCLS_klystrons_sector_station:
#print(sector, station)
info = klystron_pvinfo(sector, station)
k = KlystronDataMap(**info)
KLYSTRON_DATAMAPS.append(k)
# Make a large list
KLYSTRON_DATAMAPS = []
for sector, station in existing_LCLS_klystrons_sector_station:
#print(sector, station)
info = klystron_pvinfo(sector, station)
k = KlystronDataMap(**info)
KLYSTRON_DATAMAPS.append(k)
In [37]:
Copied!
# Check that our data is sufficient
for k in KLYSTRON_DATAMAPS:
for pv in k.pvlist:
if pv not in PVDATA:
print(k.name, pv)
# Check that our data is sufficient
for k in KLYSTRON_DATAMAPS:
for pv in k.pvlist:
if pv not in PVDATA:
print(k.name, pv)
K20_6 GUN:IN20:1:GN1_AAVG K20_6 GUN:IN20:1:GN1_PAVG K20_7 ACCL:IN20:300:L0A_AACT_DS0 K20_7 ACCL:IN20:300:L0A_PACT_DS0 K20_8 ACCL:IN20:400:L0B_AACT_DS0 K20_8 ACCL:IN20:400:L0B_PACT_DS0 K21_1 ACCL:LI21:1:L1S_AACT_DS0 K21_1 ACCL:LI21:1:L1S_PACT_DS0 K21_2 ACCL:LI21:180:L1X_AACT_DS0 K21_2 ACCL:LI21:180:L1X_PACT_DS0 K24_1 ACCL:LI24:100:KLY_PDES:SETDATA_1 K24_2 ACCL:LI24:200:KLY_PDES:SETDATA_1 K24_3 ACCL:LI24:300:KLY_PDES:SETDATA_1
In [38]:
Copied!
s = KLYSTRON_DATAMAPS[0].to_json()
s
s = KLYSTRON_DATAMAPS[0].to_json()
s
Out[38]:
'{"name": "K20_6", "sector": 20, "station": 6, "description": "Klystron in sector 20, station 6, beamcode 1 for the GUN", "enld_pvname": "GUN:IN20:1:GN1_AAVG", "phase_pvname": "GUN:IN20:1:GN1_PAVG", "accelerate_pvname": "", "swrd_pvname": "", "stat_pvname": "", "hdsc_pvname": "", "dsta_pvname": ""}'
In [39]:
Copied!
KlystronDataMap.from_json(s)
KlystronDataMap.from_json(s)
Out[39]:
KlystronDataMap(name='K20_6', sector=20, station=6, description='Klystron in sector 20, station 6, beamcode 1 for the GUN', enld_pvname='GUN:IN20:1:GN1_AAVG', phase_pvname='GUN:IN20:1:GN1_PAVG', accelerate_pvname='', swrd_pvname='', stat_pvname='', hdsc_pvname='', dsta_pvname='')