Source code for pyaml.magnet.magnet
from scipy.constants import speed_of_light
from .. import PyAMLException
from ..common import abstract
from ..common.element import Element, ElementConfigModel
from .model import MagnetModel
try:
from typing import Self # Python 3.11+
except ImportError:
from typing_extensions import Self # Python 3.10 and earlier
import numpy as np
[docs]
class MagnetConfigModel(ElementConfigModel):
"""
Configuration model for magnet elements.
Attributes
----------
model : MagnetModel or None, optional
Object in charge of converting magnet strengths to power supply values
"""
model: MagnetModel | None = None
[docs]
class Magnet(Element):
"""
Class providing access to one magnet of a physical or simulated lattice
"""
def __init__(self, name: str, model: MagnetModel = None):
"""
Construct a magnet
Parameters
----------
name : str
Element name
model : MagnetModel
Magnet model in charge of computing coil(s) current
"""
super().__init__(name)
self.__model = model
self.__strength: abstract.ReadWriteFloatScalar = None
self.__hardware: abstract.ReadWriteFloatScalar = None
self.__modelName = self.get_name()
@property
def strength(self) -> abstract.ReadWriteFloatScalar:
"""
Gives access to the strength of this magnet in physics unit
"""
self.check_peer()
if self.__strength is None:
raise PyAMLException(f"{str(self)} has no model that supports physics units")
return self.__strength
@property
def hardware(self) -> abstract.ReadWriteFloatScalar:
"""
Gives access to the strength of this magnet in
hardware unit when possible
"""
self.check_peer()
if self.__hardware is None:
raise PyAMLException(f"{str(self)} has no model that supports hardware units")
return self.__hardware
@property
def model(self) -> MagnetModel:
"""
Returns a handle to the underlying magnet model
"""
return self.__model
[docs]
def attach(
self,
peer,
strength: abstract.ReadWriteFloatScalar,
hardware: abstract.ReadWriteFloatScalar,
) -> Self:
"""
Create a new reference to attach this magnet to a simulator
or a control systemand.
"""
obj = self.__class__(self._cfg)
obj.__modelName = self.__modelName
obj.__strength = strength
obj.__hardware = hardware
obj._peer = peer
return obj
[docs]
def set_energy(self, energy: float):
"""
Set the energy in eV to compute and set the magnet rigidity
on the underlying magnet model.
"""
if self.__model is not None:
self.__model.set_magnet_rigidity(np.double(energy / speed_of_light))
[docs]
def set_model_name(self, name: str):
"""
Sets the name of this magnet in the model
(Used for combined function manget)
"""
self.__modelName = name
[docs]
def get_model_name(self) -> str:
"""
Returns the model name of this magnet
"""
return self.__modelName
def __repr__(self):
return "%s(peer='%s', name='%s', model_name='%s', magnet_model=%s)" % (
self.__class__.__name__,
self.get_peer_name(),
self.get_name(),
self.__modelName,
repr(self.__model),
)