You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 50 Next »

Overview

This page summarizes the design & implementation of the interface between the live FACET-II controls system and the FACET2E Bmad model.

GitHub mirror: F2_live_model.git

API documentation: f2-live-model.readthedocs.io/

BmadLiveModel

The goal of this class is to provide access to an instance of Tao that can view/manipulate the FACET2 Bmad model with settings that match those of the actual production accelerator.

The BmadLiveModel python class loads the FACET2E lattice and runs a local copy of pytao.SubprocessTao This object connects to the production controls system via EPICS Channel Access, and connects callback functions to each live quantity (PV) of interest. When live quantities change, these callbacks will submit update instructions to a shared queue. Additionally, a daemon thread (model-update) will periodically empty the queue and execute all the scheduled update commands and then update the BmadLiveModel.live data structure.

Modes of use

The BmadLiveModel can be used in three distinct modes, depending on the input flags at construction:

Modekw argCode snippetNotes
design model onlydesign_only
f2m = BmadLiveModel(design_only=True)
static data only, BmadLiveModel.live is not defined
live model data with manual updatesinstanced
f2m = BmadLiveModel(instanced=True)
f2m.refresh_all()
# --> your code here
This mode is designed for making lattice tweaks in Tao relative to extant machine settings
live model data with real-time streaming
f2m = BmadLiveModel()
f2m.start()
# --> your code here
f2m.stop

or:

with BmadLiveModel() as f2m:
    # --> your code here
Use of the context manager is the "most pythonic" practice, but manual start() and stop() functions are also defined


Daemon process design

This class makes use of both thread-level and process-level parallelism. Controls system monitoring, processing of update requests and data structure changes are handled asynchronously by callback functions and a model-update daemon thread. The Tao instance itself is contained in a separate subprocess via pytao.SubprocessTao.  Controls monitoring and device update management are handled asynchronously to optimize performance and minimize delays between changes being broadcast over the network and being mirrored in the model. Tao itself is wrapped in a subprocess for handling Fortran errors, and calls to BmadLiveModel.tao will still block the main python executable

PV callback functions are responsible for the following actions:

  1. convert the new value into Bmad units (i.e. from kGm → T, GeV → eV etc)
  2. submit a tuple of (element name, attribute, value) to the queue

Separately, the model-update thread will run forever in a loop, at each iteration it will:

  1. empty the command queue of (approximately*) all submitted updates
  2. run all the set ele commands, then re-calculate lattice parameters
  3. update the live.p0c, live.e_tot, live.twiss, live.quads, live.bends, live.rf data structures (← or update on request?)

LEM

LEM (LINAC energy management) is a set of algorithms responsible for estimating the beam momentum profile and calculating the corresponding lattice quad settings. This code only calculates the momentum profile, errors and magnet settings. Actually setting magnets in the accelerator will be handled by a LEM server GUI (coming soon...).

  • BmadLiveModel will set cavity voltages to correctly represent the current live momentum profile based on rf amplitudes & phases (+ a fudge factor)
  • Periodically, the server will use the live momentum profile to calculate energy errors and magnet settings, which are published to a PV

Calculating the live momentum profile

  1. start with an estimated momentum profile based on reported klystron amplitudes & phases

  2. The estimated momentum profile is unlikely to add up to exactly the correct energy, so we need to scale things by a fudge factor to match reality. Since the actual final energy of the beam in each linac is known form the bend magnet settings, we can calculate this number by comparing the estimated final energy to the actual energy

    1. under the hood this fudge factor just scales all the cavity voltages in a given region up/down

Calculating magnet settings

  1. calculate relative to design values using a dimensionless "LEM error", i.e. the ratio of the live momentum profile to the design profile

  2.  calculate relative to design values using design multipole coefficients (lcls style)
    1. get design multipole coefficients (k0_des, k1_des for bends/quads), and (effective) magnet lengths l_eff from the model
    2. calculate the live magnetic rigidity & required field strength (where E_live is in GeV) 

  3. calculate relative to extant settings

    1. note: requires a previously implemented BLEM → if LEM is bootstrapping (i.e. run for the first time without reference to a previous trim) just skip the matching quads
    2. matching quads should always scale from extant values


F2 Live Model Server

The live model server runs its own BmadLiveModel, and periodically writes live model data for NTTables accessible on the controls system via EPICS PVAccess. The code for the live model itself is relatively simple, and is derived from the lcls_live_model server.

Access to the live Bmad model server (for twiss/rmat data), should be provided through the python meme service

The format of the publish tables are as folllows:

PV nametable columnsnotes
BMAD:SYS0:1:FACET2E:LIVE:TWISSelement, device_name, s, z, length, p0c, alpha_x, beta_x, eta_x, etap_x, psi_x,  alpha_y, ..., psi_y
BMAD:SYS0:1:FACET2E:LIVE:RMATelement, device_name, s, z, length, r11, r12, r13, r14, r15, r16, r21, r22, ..., r65, r66linear maps from the beginning of the linac to the downstream face of each element
BMAD:SYS0:1:FACET2E:LIVE:URMATelement, device_name, s, z, length, r11, r12, r13, r14, r15, r16, r21, r22, ..., r65, r66single-element linear maps (i.e. from the upstream to downstream face of each)
BMAD:SYS0:1:FACET2E:DESIGN:TWISSelement, device_name, s, z, length, p0c, alpha_x, beta_x, eta_x, etap_x, psi_x,  alpha_y, ..., psi_y
BMAD:SYS0:1:FACET2E:DESIGN:RMATelement, device_name, s, z, length, r11, r12, r13, r14, r15, r16, r21, r22, ..., r65, r66
BMAD:SYS0:1:FACET2E:DESIGN:URMATelement, device_name, s, z, length, r11, r12, r13, r14, r15, r16, r21, r22, ..., r65, r66
BMAD:SYS0:1:FACET2E:LEM_DATAelement, device_name, EREF, EACT, BREF, BACT, BERR, more ??final data TBD (but single NTTable seems simpler than lcls-style per-device PVs)


Implementation details

Dependencies

The live model needs to run on the production network (primarily on facet-srv02)

Source files

Source: F2_live_model/Details
~/docs/config files for sphinx
~/.readthedocs.yamlconfig for readthedocs.io doc generation
~/structs.pyauxiliary data structures for holding beamline data
~/bmad.pyimplements the BmadLiveModel class
~/server.pylive model PVA service
  • No labels