"""Define the SET_SYNC_PHASE command.
.. todo::
Should also modify RFQ_CEL, CAVSIN, NCELLS according to doc.
"""
import logging
from collections.abc import Sequence
from typing import Literal
from lightwin.core.commands.command import Command
from lightwin.core.elements.field_maps.field_map import FieldMap
from lightwin.core.instruction import Instruction
from lightwin.tracewin_utils.line import DatLine
[docs]
class SetSyncPhase(Command):
"""A class that modifies reference phase of next cavity."""
is_implemented = True
n_attributes = 0
[docs]
def __init__(
self, line: DatLine, dat_idx: int | None = None, **kwargs: str
) -> None:
"""Instantiate command."""
return super().__init__(line, dat_idx)
[docs]
def set_influenced_elements(
self, instructions: Sequence[Instruction], **kwargs: float
) -> None:
"""Capture first cavity after this command."""
for instruction in instructions[self.idx["dat_idx"] + 1 :]:
if isinstance(instruction, SetSyncPhase):
logging.error("Two consecutive SET_SYNC_PHASE.")
if isinstance(instruction, FieldMap):
start = instruction.idx["dat_idx"]
stop = start + 1
self.influenced = slice(start, stop)
return
raise OSError(
"Reached end of file without finding associated FIELD_MAP."
)
[docs]
def apply(
self, instructions: Sequence[Instruction], **kwargs: float
) -> list[Instruction]:
"""Set ``phi_s``, remove previous reference phase.
When we apply this method, LightWin believes that the phase given in
the ``DAT`` file is an absolute or relative phase. We update the
``reference`` of the :class:`.CavitySettings`, as well as the actual
value of ``phi_ref == phi_s``.
"""
for cavity in instructions[self.influenced]:
assert isinstance(cavity, FieldMap)
settings = cavity.cavity_settings
# note that, at this point, LightWin believes that the phase given
# in the .dat is an absolute or relative phase
settings.set_reference("phi_s", phi_ref=settings.phi_ref)
return list(instructions)
[docs]
def to_line(
self,
*args,
which_phase: Literal["phi_0_abs", "phi_0_rel", "phi_s"],
**kwargs,
) -> list[str]:
"""Return the command, commented if output phase should not be phi_s.
.. note::
We keep old implementation for now. But this method returns nothing
because the ``to_line`` method of :class:`.FieldMap` already
handles adding a ``SET_SYNC_PHASE`` when necessary.
"""
return []
line = super().to_line(*args, **kwargs)
if which_phase == "phi_s":
return line
line.insert(0, ";")
return line