Source code for pylhc.bpm_calibration

"""
BPM Calibration
---------------

This script computes the calibration factors for the LHC BPMs using either a
beta from phase method or a dispersion one by comparison of beam optics
quantities calculated independent of and dependent on BPM calibration.
Namely, the default method compares beta-functions calculated from phase
advances (BPM-calibration independent) and from amplitude of betatron
oscillation (calibration dependent).
The other method compares dispersion, and its use is currently discouraged due
to worse resolution.

Arguments:

*--Required--*

- **inputdir** *(Path)*:

    Measurements path.

    flags: **['--input']**


- **ips** *(int)*:

    IPs to compute calibration factors for.

    flags: **['--ips']**

    choices: ``[1, 4, 5]``


- **outputdir** *(Path)*:

    Output directory where to write the calibration factors.

    flags: **['--outputdir']**


*--Optional--*

- **method** *(str)*:

    Method to be used to compute the calibration factors. The Beta
    function is used by default.

    flags: **['--method']**

    choices: ``('beta', 'dispersion')``

    default: ``beta``
"""

from pathlib import Path

import tfs
from generic_parser import EntryPointParameters, entrypoint
from omc3.optics_measurements.constants import EXT
from omc3.utils import logging_tools

from pylhc.calibration.beta import get_calibration_factors_from_beta
from pylhc.calibration.dispersion import get_calibration_factors_from_dispersion
from pylhc.constants.calibration import CALIBRATION_NAME, IPS, METHODS

LOG = logging_tools.get_logger(__name__)


def _get_params() -> dict:
    """
    Parse Commandline Arguments and return them as options.

    Returns:
        dict
    """

    return EntryPointParameters(
        inputdir={"type": Path, "required": True, "help": "Measurements path."},
        outputdir={
            "type": Path,
            "required": True,
            "help": "Output directory where to write the calibration factors.",
        },
        ips={
            "type": int,
            "nargs": "+",
            "choices": IPS,
            "required": False,
            "help": "IPs to compute calibration factors for.",
        },
        method={
            "type": str,
            "required": False,
            "choices": METHODS,
            "default": METHODS[0],
            "help": (
                "Method to be used to compute the calibration factors. "
                "The Beta function is used by default."
            ),
        },
    )


[docs] @entrypoint(_get_params(), strict=True) def main(opt): # Compute the calibration factors and their errors according to the method if opt.method == "beta": factors = get_calibration_factors_from_beta(opt.ips, opt.inputdir) elif opt.method == "dispersion": factors = get_calibration_factors_from_dispersion(opt.ips, opt.inputdir) # Fill NaN with 1 because of missing BPMs and that fit cannot be done everywhere for plane in factors: factors[plane] = factors[plane].infer_objects().fillna(1) LOG.debug("".join([f"\nPlane {plane}:\n{factors[plane]}" for plane in factors])) # Write the TFS file to the desired output directory opt.outputdir.mkdir(parents=True, exist_ok=True) for plane in factors: tfs.write( opt.outputdir / f"{CALIBRATION_NAME[opt.method]}{plane.lower()}{EXT}", factors[plane].reset_index(), save_index=False, ) return factors
if __name__ == "__main__": main()