Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

Image RemovedImage Added


Table of Contents

...

  • BmadLiveModel: a python class responsible for watching the accelerator and updating a live instance of PyTao based on extant machine settings
  • The live model PVA service: a process that runs it's own BmadLiveModel and publishes data to table PVsSource code can be viewed on GitHub, and API documentation is available online.GitHub mirror: F2_live_model.gitAPI 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.Tao

Device Monitoring

Connection This object connects to the production controls system is handled mainly via EPICS Channel Access , and connects callback functions to each live quantity (PV) of interest. When live quantities change, these callbacks will either (a) submit update instructions to a shared queue or (b) request a recalculation of the live momentum profile by the LEM-watcher thread. Additionally, a second daemon thread (model-update) will periodically empty the queue and execute all the scheduled update commands and then update the BmadLiveModel.live and .LEM data structures.

Modes of use

The BmadLiveModel operates in three distinct modes, depending on the input flags at construction:

...

f2m = BmadLiveModel(design_only=True)

...

f2m = BmadLiveModel(instanced=True)
f2m.refresh_all()
# --> your code here

...

f2m = BmadLiveModel()
f2m.start()
# --> your code here
f2m.stop

or:

with BmadLiveModel() as f2m:
    # --> your code here

...

PVs (as well as limited use of AIDA-PVA for klystron timing statuses). During real-time updating, there are three "watcher" daemon threads that monitor extant machine settings. Each thread will submit instructions for updates to the simulation to one of two shared update queues.

acc1-watcher and acc2-watcher

These are the main passive device monitoring threads. acc1 is responsible for monitoring all quadrupole magnets in the accelerator, while acc2 id responsible for monitoring dipoles, sextupoles and other miscellaneous devices.

Concurrency design

This class makes use of both async functions (by way of PV callbacks), and thread-based parallelism for controls system monitoring, processing of update requests and data structure changes to optimize performance and minimize delays between changes being broadcast over the network and being mirrored in the model. There are three major concurrent features:

Device Monitoring

Real-time controls-system monitoring is accomplished using PV callback functions.

  • RF-related PVs (i.e. klystron ENLDS, phases etc) will request a LEM update, which will trigger the LEM-watcher to recalculate the live momentum profile
  • Other PVs (magnet BACTs etc) will directly directly submit the update of a given parameter to a shared queue. To do so, each function must:
    • convert the new value into Bmad units (i.e. from kGm → T, GeV → eV etc)
    • submit a tuple of (element name, attribute, value) to the command queue

LEM-watcher

This thread is responsible for calculating the live beam momentum profile as described below, and submitting update requests for cavity voltages and phases to the command queue.

model-update

This thread is responsible for executing all the submitted update requests using Tao, and to updating derived quantities (BLEM) and python data structures.

...

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 monitors the klystron complement and bend magnet settings to calculate the live momentum profile of the beam
  • Periodically, the server will use the live momentum profile to calculate energy errors and magnet settings, which are published to a table PV

Further notes on LEMDetailed overview of LEM implementation: LEM_notes-23.pdf

Calculating the live momentum profile

  1. start by estimating the momentum profile based on reported klystron amplitudes & phases

    Latex
    \[ E_{est}(s) = \sum_1^{N_{klys}(s)} ENLD_i cos(PDES_{SBST} + PDES_i)
  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

    Latex
    \[ f = \frac{E_{design}(end)}{E_{est}(end)} \quad \rightarrow \quad E_{live}(s) = f * E_{est}(s)
    1. under the hood this fudge factor just scales all the cavity voltages in a given region up/down
    2. the fudge factor will be closer to 1 when ENLDs are current and linac phases are accurate

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

    Latex
    \[ BDES_{LEM} = \left \frac{E_{live}(s)}{E_{design}(s)} \right BDES_{design}
  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) 

      Latex
      \[ B\rho(s) = \frac{E_{live}(s)}{299.792458*10^4}
      
      \[ BDES_{LEM} = B\rho * k_{design} * l_{eff}
  3. calculate relative to extant settings

    Latex
    \[ BDES_{LEM} = \left \frac{E_{live}(s)}{E_{old}(s)} \right * BDES_{extant}
    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

LEM-watcher

Daemon thread spawned by BmadLiveModel, responsible for calculating the live beam momentum profile as described below, and for submitting update requests for cavity voltages and phases to the command queue, as well as linac amplitude, chirp and fudge values

PyTao updates

The BmadLiveModel python class loads the FACET2E lattice and runs a local copy of pytao.Tao. This instance of tao is both the engine used by the class to update the live lattice, as well as a part of the public interface of the code. BmadLiveModel.tao is a publicly accessible attribute of the class itself

model-update

This thread is responsible for executing all the submitted update requests using Tao, and for updating derived quantities (BLEM) and python data structures.

  1. empty the device update 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
  4. empty the LEM update queue and set the live.LEM amplitude, chirp and fudge values

PVA model server(s)

The principal use case for the BmadLiveModel is running a real-time live model server. This server runs its own BmadLiveModel, and then publishes live model data to scalar and table PVs 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.

For performance, there are actually two production services. Both recalculate and update PVs once per second.

  • Model Server 1: This server is responsible for updating live twiss parameters and LEM data.
  • Model Server 2: This service is responsible for publishing R matrices

Access to the live Bmad model server (for twiss/rmat data), should be provided through is mediated by the python meme serviceThe formats of the published tables are as folllows:

Implementation: F2_live_model code

The code for all the infrastructure described in this document lives together. Source code can be viewed on GitHub, and API documentation is available online.

  • SLAC network master repository: /afs/slac/g/cd/swe/git/repos/slac/FACET/F2_live_model.git
  • Production deployment: /usr/local/tools/python/F2_live_model
  • GitHub mirror: F2_live_model.git
  • The public interface to the code is documented here: f2-live-model.readthedocs.io/

Details

Model server data description

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, s, z, length, E_ref, E_act, E_err, BLEM, BDES, BDES_SAVEfinal data TBD (but single NTTable seems simpler than lcls-style per-device PVs)EREF, EACT, EERR, BLEM_DESIGN, BLEM_EXTANT

Additionally, the service will publish scalar PVs of the estimated linac amplitudes/chirps/fudges by calculated by LEM. Their names are as follows:

...

where <XX> is a "LEM region", either L0, L1, L2 or L3, for a total of an additional 12 quantities.

Dependencies

PVs. (ex: BMAD:SYS0:1:FACET2E:LEM:L2_FUDGE). There is an additional read/write PV: BMAD:SYS0:1:FACET2E:LEM:PROFILE which stores the last known extant momentum profile to which current rf settings are compared. 

Dependencies

...

...

Source file descriptions

Source: F2_live_model/Details
docs/sphinx config files
config~/docs/model config files for sphinx
    facet2e.yamlconfig for the FACET2E live model & server
    unaliased-elements.csvsupplemental text file of device alias (control system name) info
~/.readthedocs.yamlconfig for readthedocs.io doc generation
~/structs.pyauxiliary data structures for holding beamline data
~/bmad.pyimplements the BmadLiveModel class
~/

server.py

live model PVA service

demo.ipynb

Jupyter notebook with simple examples of how to use BmadLiveModel