Source code for pyhdtoolkit.cpymadtools.lhc._coupling

"""
.. _lhc-coupling:

**Coupling Utilities**

The functions below are betatron coupling utilities for the ``LHC``.
"""
import tfs

from cpymad.madx import Madx
from loguru import logger
from optics_functions.coupling import coupling_via_cmatrix

from pyhdtoolkit.cpymadtools import twiss
from pyhdtoolkit.cpymadtools.constants import MONITOR_TWISS_COLUMNS


# This is a duplicate of the function in _routines.py, merge at some point
[docs]def correct_lhc_global_coupling( madx: Madx, /, beam: int = 1, telescopic_squeeze: bool = True, calls: int = 100, tolerance: float = 1.0e-21 ) -> None: """ .. versionadded:: 0.20.0 A littly tricky matching routine to perform a decent global coupling correction using the ``LHC`` coupling knobs. .. important:: This routine makes use of some matching tricks and uses the ``SUMM`` table's ``dqmin`` variable for the matching. It should be considered a helpful little trick, but it is not a perfect solution. Args: madx (cpymad.madx.Madx): an instanciated `~cpymad.madx.Madx` object. Positional only. beam (int): which beam you want to perform the matching for, should be `1` or `2`. Defaults to `1`. telescopic_squeeze (bool): If set to `True`, uses the coupling knobs for Telescopic Squeeze configuration. Defaults to `True`. calls (int): max number of varying calls to perform when matching. Defaults to 100. tolerance (float): tolerance for successfull matching. Defaults to :math:`10^{-21}`. Example: .. code-block:: python correct_lhc_global_coupling(madx, sequence="lhcb1", telescopic_squeeze=True) """ suffix = "_sq" if telescopic_squeeze else "" sequence = f"lhcb{beam:d}" logger.debug(f"Attempting to correct global coupling through matching, on sequence '{sequence}'") real_knob, imag_knob = f"CMRS.b{beam:d}{suffix}", f"CMIS.b{beam:d}{suffix}" logger.debug(f"Matching using the coupling knobs '{real_knob}' and '{imag_knob}'") madx.command.match(sequence=sequence) madx.command.gweight(dqmin=1, Q1=0) madx.command.global_(dqmin=0, Q1=62.28) madx.command.vary(name=real_knob, step=1.0e-8) madx.command.vary(name=imag_knob, step=1.0e-8) madx.command.lmdif(calls=calls, tolerance=tolerance) madx.command.endmatch()
[docs]def get_lhc_bpms_twiss_and_rdts(madx: Madx, /) -> tfs.TfsDataFrame: """ .. versionadded:: 0.19.0 Runs a ``TWISS`` on the currently active sequence for all ``LHC`` BPMs. The coupling RDTs are also computed through a CMatrix approach via `optics_functions.coupling.coupling_via_cmatrix`. Args: madx (cpymad.madx.Madx): an instanciated `~cpymad.madx.Madx` object. Positional only. Returns: A `~tfs.frame.TfsDataFrame` of the ``TWISS`` table with basic default columns, as well as one new column for each of the coupling RDTs. The coupling RDTs are returned as complex numbers. Example: .. code-block:: python twiss_with_rdts = get_lhc_bpms_twiss_and_rdts(madx) """ twiss_tfs = twiss.get_pattern_twiss(madx, patterns=["^BPM.*B[12]$"], columns=MONITOR_TWISS_COLUMNS) twiss_tfs.columns = twiss_tfs.columns.str.upper() # optics_functions needs capitalized names twiss_tfs.NAME = twiss_tfs.NAME.str.upper() twiss_tfs[["F1001", "F1010"]] = coupling_via_cmatrix(twiss_tfs, output=["rdts"]) return twiss_tfs