Source code for lightwin.beam_calculation.tracewin.beam_parameters_factory

"""Define a function to generate a :class:`.BeamParameters` for TraceWin."""

from typing import Literal

import numpy as np

from lightwin.core.beam_parameters.beam_parameters import BeamParameters
from lightwin.core.beam_parameters.factory import BeamParametersFactory
from lightwin.core.beam_parameters.helper import reconstruct_sigma
from lightwin.core.elements.element import ELEMENT_TO_INDEX_T


[docs] class BeamParametersFactoryTraceWin(BeamParametersFactory): """A class holding method to generate :class:`.BeamParameters`."""
[docs] def factory_method( self, z_abs: np.ndarray, gamma_kin: np.ndarray, results: dict[str, np.ndarray], element_to_index: ELEMENT_TO_INDEX_T, ) -> BeamParameters: """Create the :class:`.BeamParameters` object.""" z_abs, gamma_kin, beta_kin = self._check_and_set_arrays( z_abs, gamma_kin ) beam_parameters = BeamParameters( z_abs, gamma_kin, beta_kin, sigma_in=None, element_to_index=element_to_index, ) phase_space_names = ("x", "y", "zdelta") data_to_retrieve_sigmas = ( self._extract_phase_space_data_for_sigma(phase_space_name, results) for phase_space_name in phase_space_names ) sigmas = ( reconstruct_sigma( phase_space_name, *data_to_retrieve_sigma, eps_is_normalized=True, gamma_kin=gamma_kin, beta_kin=beta_kin, **self._beam_kwargs, ) for phase_space_name, data_to_retrieve_sigma in zip( phase_space_names, data_to_retrieve_sigmas ) ) self._set_from_sigma( beam_parameters, phase_space_names, sigmas, gamma_kin, beta_kin, ) other_phase_space_names = ("x", "y") phase_space_name = "t" self._set_transverse_from_x_and_y( beam_parameters, other_phase_space_names, phase_space_name ) other_phase_space_name = "zdelta" phase_space_names = ("z", "phiw") self._set_from_other_phase_space( beam_parameters, other_phase_space_name, phase_space_names, gamma_kin, beta_kin, ) if self.is_multipart: phase_space_names = ("x99", "y99", "phiw99") emittances = ( self._extract_emittance_for_99percent( phase_space_name, results ) for phase_space_name in phase_space_names ) self._set_only_emittance( beam_parameters, phase_space_names, emittances ) return beam_parameters
[docs] def _extract_phase_space_data_for_sigma( self, phase_space_name: Literal["x", "y", "zdelta"], results: dict[str, np.ndarray], ) -> tuple[np.ndarray, np.ndarray, np.ndarray]: r""" Retrieve the data necessary to reconstruct :math:`\sigma` beam matrix. Parameters ---------- phase_space_name : Name of a single phase space. results : Results dictionary, which keys are ``tracewin.out`` or ``partran1.out`` headers and which values are corresponding data. Returns ------- sigma_00 : ``(n, )`` array containing top-left component of the :math:`\sigma` beam matrix. sigma_01 : ``(n, )`` array containing top-right component of the :math:`\sigma` beam matrix. eps_normalized : ``(n, )`` array of normalized emittance. """ phase_space_to_keys = { "x": ("SizeX", "sxx'", "ex"), "y": ("SizeY", "syy'", "ey"), "zdelta": ("SizeZ", "szdp", "ezdp"), } assert phase_space_name in phase_space_to_keys keys = phase_space_to_keys[phase_space_name] sigma_00 = results[keys[0]] ** 2 sigma_01 = results[keys[1]] eps_normalized = results[keys[2]] return sigma_00, sigma_01, eps_normalized
[docs] def _extract_emittance_for_99percent( self, phase_space_name: Literal["x99", "y99", "phiw99"], results: dict[str, np.ndarray], ) -> np.ndarray: r""" Retrieve the 99% emittances. .. todo:: normalized or not??? Parameters ---------- phase_space_name : Name of a single phase space. results : Results dictionary, which keys are ``tracewin.out`` or ``partran1.out`` headers and which values are corresponding data. Returns ------- 99% emittance in the desired phase space. """ getters = { "x99": results["ex99"], "y99": results["ey99"], "phiw99": results["ep99"], } assert phase_space_name in getters return getters[phase_space_name]