# -*- coding: utf-8 -*-
"""
Typed option objects for the ALBuMS pipeline:
- EquilibriumOptions : everything that defines a beam-equilibrium solve.
- TheoryOptions : the run-time inputs shared by the instability theories.
- OptimiserOptions : the settings of the tuning-angle optimisation.
- ScanOptions : grid-evaluation settings for scans.
- PlotOptions : display settings for the 2D scan and optimisation plots.
"""
from __future__ import annotations
from dataclasses import dataclass
from typing import Any
import numpy as np
[docs]@dataclass(frozen=True)
class EquilibriumOptions:
"""Everything that defines a beam-equilibrium solve.
Attributes
----------
**Common options** (read by every equilibrium solver)
I0 : float or None
Beam current in [A]. None until set; SystemState raises if a solve
is attempted while it is still None.
tau_boundary : float or None
Half-window in [s] for the potential and form-factor integrals.
If None, 0.1 times the RF period (0.1 * ring.T1) is used.
passive_harmonic_cavity : bool
If True the harmonic cavity is treated as passive (beam-driven); if
False as active (generator-driven).
auto_set_MC_theta : bool
If True the main-cavity synchronous phase is set automatically from the
energy loss before solving. Not read by the active-Bosch solver, which
derives the main-cavity phase from xi instead (see auto_set_for_xi).
optimal_tunning : bool
If True the harmonic-cavity detuning is set to its optimal value for the
target bunch lengthening before solving.
**Bosch (passive) specific**
max_counter : int
Maximum number of fixed-point iterations of the Bosch form-factor loop.
**Bosch (active) specific**
auto_set_for_xi : bool
If True the cavity settings are chosen to reach the requested force
ratio xi instead of being used as given.
xi : float or None
Target main-to-harmonic force ratio used when auto_set_for_xi is True.
**Venturini and Alves specific**
F_init : array-like or None
Initial guess for the per-cavity amplitude form factor. None starts from
all ones.
set_MC_phase_HCpassive : bool
If True, correct the main-cavity phase in the passive-harmonic-cavity
case when the beam losses exceed the main-cavity voltage.
**Alves specific**
niter : int
Maximum number of iterations of the self-consistent equilibrium loop.
tol : float
Convergence tolerance on the form factor for the self-consistent loop.
beta : float
Under-relaxation factor between 0 and 1 damping each update step of the
loop.
m : int
Number of azimuthal harmonics kept in the form-factor expansion.
print_flag : bool
If True, print convergence diagnostics during the loop.
filling : array-like or None
Filling pattern (per-bucket current weights); None means uniform
filling.
impedance : object or None
Additional longitudinal impedance source or sources added to the
cavity impedances; None for cavities only.
"""
# Common options.
I0: float | None = None
tau_boundary: float | None = None
passive_harmonic_cavity: bool = True
auto_set_MC_theta: bool = True
optimal_tunning: bool = True
# Bosch (passive) specific.
max_counter: int = 200
# Bosch (active) specific.
auto_set_for_xi: bool = False
xi: float | None = None
# Venturini and Alves specific.
F_init: Any = None
set_MC_phase_HCpassive: bool = False
# Alves specific.
niter: int = 200
tol: float = 1e-8
beta: float = 0.1
m: int = 3
print_flag: bool = False
filling: Any = None
impedance: Any = None
[docs]@dataclass(frozen=True)
class TheoryOptions:
"""Run-time inputs shared by the instability theories.
Attributes
----------
**ZeroFrequency specific**
mode_coupling : bool
If True the zero-frequency stability test includes mode coupling. Pair
False with a flow using the no-coupling Robinson theory.
**HOMCoupledBunch specific**
f_HOM : float or array-like
Higher-order-mode resonant frequency or frequencies in [Hz] for the
coupled-bunch theory. 0 disables the HOM.
Z_HOM : float or array-like
Shunt impedance or impedances of the HOM in ohms.
"""
# ZeroFrequency specific.
mode_coupling: bool = True
# HOMCoupledBunch specific.
f_HOM: float | np.ndarray = 0
Z_HOM: float | np.ndarray = 0
[docs]@dataclass(frozen=True)
class OptimiserOptions:
"""Settings for the harmonic-cavity tuning-angle optimisation.
Attributes
----------
method_opti : str
scipy.optimize.minimize method for the R-factor maximisation.
tol_opti : float
Convergence tolerance for the R-factor maximisation.
maxiter_opti : int
Maximum number of iterations for the R-factor maximisation.
rhobeg_opti : float
Initial COBYLA step size (rhobeg) for the R-factor maximisation.
method : str
scipy.optimize.minimize method for the psi minimisation.
tol : float
Convergence tolerance for the psi minimisation.
loop_option : bool
If True, after the optimisation step the tuning angle outward until a
stable operating point is found.
add_psi_loop : float
Increment in degrees applied to the tuning angle on each iteration of the
stabilisation loop.
max_loop : int
Maximum number of stabilisation-loop iterations before giving up.
auto_psi_input : bool
If True, derive the initial tuning-angle guess from xi_init_input instead
of the supplied initial guess.
xi_init_input : float
Target force ratio used to derive the initial tuning-angle guess when
auto_psi_input is True.
debug : bool
If True, print optimisation diagnostics.
"""
method_opti: str = "COBYLA"
tol_opti: float = 0.01
maxiter_opti: int = 1000
rhobeg_opti: float = 0.1
method: str = "Nelder-Mead"
tol: float = 0.05
loop_option: bool = False
add_psi_loop: float = 0.02
max_loop: int = 200
auto_psi_input: bool = False
xi_init_input: float = 0.8
debug: bool = False
[docs]@dataclass(frozen=True)
class ScanOptions:
"""Grid-evaluation settings for the parameter and optimisation scans.
These control how the grid is swept, not what is plotted (see PlotOptions).
Attributes
----------
skip : bool
If True, stop scanning a row early once grid points stop converging.
Saves time on regions that are uniformly non-physical.
"""
skip: bool = False
[docs]@dataclass(frozen=True)
class PlotOptions:
"""Display settings for the 2D scan and optimisation plots.
Every knob has a documented default in one place.
Attributes
----------
contour : bool
If True, overlay contour lines on the colour map.
title : bool
If True, set the axes title to the scan name.
axes : matplotlib.axes.Axes or None
Existing axes to draw on; None creates a new figure and axes.
colorbar : bool
If True, draw the colour bar.
cbar_v : tuple of (float or None, float or None)
The (vmin, vmax) colour-map limits; (None, None) auto-scales.
show_legend : bool
If True, draw the instability-marker legend.
n_contour : int
Number of contour levels.
marker_size : float
Scatter marker size for instability flags.
alpha : float
Scatter marker transparency.
manual_clabel : bool
If True, place contour labels interactively.
colorplot : bool
If True, draw the filled colour map (set False for contour-only plots).
contour_alpha : float
Contour line transparency.
contour_linestyles : str
Contour line style.
cmap : str
Matplotlib colour map name for the background image.
log_color : bool
If True, log-normalise the background colour map via matplotlib LogNorm
(cbar_v sets the LogNorm limits). Only strictly positive data is shown;
use for quantities spanning orders of magnitude (e.g. growth rates).
save : bool
If True, write the figure to a PNG named from the scan and flow.
"""
contour: bool = True
title: bool = True
axes: Any = None
colorbar: bool = True
cbar_v: tuple = (None, None)
show_legend: bool = True
n_contour: int = 15
marker_size: float = 80
alpha: float = 0.7
manual_clabel: bool = False
colorplot: bool = True
contour_alpha: float = 1
contour_linestyles: str = "-"
cmap: str = "viridis"
log_color: bool = False
save: bool = False