KLYS support - #64
Conversation
There was a problem hiding this comment.
Including Klystrons in the device database leads to some interesting exceptions that we haven't had to deal with before. We'll have to discuss more in detail. I think some of these issues could be resolved with better integration with a device class.
My main comment is that the klystron_metadata interface inserts exception PVs after the fact. I think that's something that we could include in the accessor_names.yaml by using a "private" key like _overrides to store a dictionary of devices with known exceptions.
eloise-nebula
left a comment
There was a problem hiding this comment.
Thank you William! This solution looks great and provides a nice interface for anyone else who wants to use the same pattern to do their own overrides.
Approving, but make sure you remove/edit the get_klystron_metadata function that references a file that doesn't exist anymore.
Title: Consolidate klystron sub-cavity rows and add KLYS accessor support
Summary
Oracle's
lcls_elements.csvstores each klystron station as four separatesub-cavity rows (e.g.
K21_5A,K21_5B,K21_5C,K21_5D) all sharing thesame EPICS cs_name (
KLYS:LI21:51). This PR consolidates those into one rowper station (
K21_5) inlcls_elements.sqlite3and propagates that through todevice.sqlite3, aligning the database representation with how lcls-liveidentifies and addresses klystron stations.
It also adds a
KLYS:accessor block toaccessor_names.yamlso that thestandard KLYS PV suffixes (
ENLD,PHAS,PDES, etc.) are mapped todeveloper-friendly names, and introduces
klystron_metadata.yamlto encodeper-station PV overrides for the nine stations that deviate from the normal
KLYS:LI{sector}:{station}1:{SUFFIX}pattern (GUN, L0A, L0B, L1S, L1X,K24_1/2/3, and K26_3).
Motivation
lcls-live's
KlystronDataMapmodels one entry per station. Having four rowsper station in
device.sqlite3caused redundant entries, made beampath andaccessor lookups ambiguous, and prevented klystrons from receiving correct PV
accessor assignments during the database build.
Changes
slac_db/create/lcls_elements.py_Parser._parse_csv(): added sub-cavity deduplication. For anyLCAVrowwhose element name ends in
A-Dand whose cs_name containsKLYS, thetrailing letter is stripped to form the canonical station name (e.g.
K21_5A->K21_5). Only the first encountered sub-cavity per station iskept; subsequent ones are discarded. The dedup key is the station name rather
than the cs_name, which makes it robust against dirty data in the source CSV
(two stations in sectors 12-19 have truncated or digit-transposed cs_names:
K12_3AhasLI12:KLYS:3instead ofLI12:KLYS:31, andK17_8ChasLI17:KLYS:18instead ofLI17:KLYS:81).KLYS:LI{sector}:{station}1(sectors 20-30)LI{sector}:KLYS:{station}1(sectors 12-19)slac_db/package_data/accessor_names.yamlAdded a
KLYS:device type block mapping the ten standard KLYS PV suffixesto accessor names that match lcls-live's
KlystronDataMapfield names:ENLDenergy_gainPHASphasePACTphase_actualPDESphase_desiredBEAMCODE1_STATbeamcode1BEAMCODE2_STATbeamcode2SWRDswrdSTATstatHDSChdscDSTAdstaslac_db/package_data/klystron_metadata.yaml(new file)Follows the pattern of
wire_metadata.yaml. Encodes per-station PV overridesfor the nine stations that cannot be expressed by the normal KLYS accessor
pattern. Two categories:
Entirely different PV bases — no
KLYS:prefix; all amplitude and phasePVs are overridden and fault/beamcode PVs are set to absent (
''):K20_6— GUN klystron (GUN:IN20:1:GN1_*)K20_7— L0A injector linac (ACCL:IN20:300:L0A_*_DS{n}, beamcode-dependent)K20_8— L0B injector linac (ACCL:IN20:400:L0B_*_DS{n}, beamcode-dependent)K21_1— L1S sub-booster (ACCL:LI21:1:L1S_*_DS{n}, beamcode-dependent)K21_2— L1X 3rd-harmonic linearizer (ACCL:LI21:180:L1X_*_DS{n}, beamcode-dependent)Normal KLYS base, phase PV overridden only (beamcode-specific):
K24_1—ACCL:LI24:100:KLY_PDES:SETDATA_{bc}K24_2—ACCL:LI24:200:KLY_PDES:SETDATA_{bc}K24_3—ACCL:LI24:300:KLY_PDES:SETDATA_{bc}Always disabled:
K26_3— mothballed klystron;in_use: false, no fault or beamcode PVsslac_db/metadata.pyget_klystron_metadata()following theget_wire_metadata()pattern.Reads
klystron_metadata.yamland returns a flat dict per station mappingaccessor names to PV addresses. Beamcode-specific sub-dicts (
beamcode1,beamcode2) are expanded with a suffix, e.g.phase_act_pvnameunderbeamcode1becomes the accessor namephase_actual_beamcode1.slac_db/create/combined.py_Parser._accessor_meta(): klystron stations havekeyword=LCAVin Oracle(shared with TCAVs). The accessor lookup now checks whether
KLYSappearsin the cs_name and uses
"KLYS"as the accessor map key in that case,ensuring the new
KLYS:block inaccessor_names.yamlis applied._Parser._apply_klystron_accessor_overrides(): called after the normalaccessor build, reads
get_klystron_metadata()and replaces accessor entriesfor the special stations with the correct override PV addresses. Empty
overrides (absent PVs) are removed from the accessors table entirely.
Result
After rebuilding
lcls_elements.sqlite3thendevice.sqlite3:across areas L1, L1F, L2, L2F, L3, LI25, matching the lcls-live station list.
device.sqlite3carries the correct accessor set,e.g. for a normal station (K21_5):
energy_gain, phase, phase_actual, phase_desired,
beamcode1, beamcode2, swrd, stat, hdsc, dsta
phase_actual_beamcode1, phase_desired_beamcode1,
phase_actual_beamcode2, phase_desired_beamcode2
Rebuild steps required