Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 0 additions & 14 deletions pyaml/arrays/hcorrector.py

This file was deleted.

73 changes: 70 additions & 3 deletions pyaml/control/abstract_impl.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
from numpy import double

from pyaml.control import abstract
from pyaml.magnet.model import MagnetModel
import numpy as np

from ..control import abstract
from ..magnet.model import MagnetModel
from ..rf.rf_plant import RFPlant
from ..rf.rf_transmitter import RFTransmitter

#------------------------------------------------------------------------------

class RWHardwareScalar(abstract.ReadWriteFloatScalar):
Expand Down Expand Up @@ -115,5 +117,70 @@ def unit(self) -> list[str]:
return self.__model.get_strength_units()


#------------------------------------------------------------------------------

class RWRFVoltageScalar(abstract.ReadWriteFloatScalar):
"""
Class providing read write access to cavity voltage for a transmitter of a control system.
"""

def __init__(self, transmitter:RFTransmitter):
self.__transmitter = transmitter

def get(self) -> float:
return self.__transmitter._cfg.voltage.get()

def set(self,value:float):
return self.__transmitter._cfg.voltage.set(value)

def set_and_wait(self, value:float):
raise NotImplementedError("Not implemented yet.")

def unit(self) -> str:
return self.__transmitter._cfg.voltage.unit()

#------------------------------------------------------------------------------

class RWRFPhaseScalar(abstract.ReadWriteFloatScalar):
"""
Class providing read write access to cavity phase for a transmitter of a control system.
"""

def __init__(self, transmitter:RFTransmitter):
self.__transmitter = transmitter

def get(self) -> float:
return self.__transmitter._cfg.phase.get()

def set(self,value:float):
return self.__transmitter._cfg.phase.set(value)

def set_and_wait(self, value:float):
raise NotImplementedError("Not implemented yet.")

def unit(self) -> str:
return self.__transmitter._cfg.phase.unit()

#------------------------------------------------------------------------------

class RWRFFrequencyScalar(abstract.ReadWriteFloatScalar):
"""
Class providing read write access to RF frequency of a control system.
"""

def __init__(self, rf:RFPlant ):
self.__rf = rf

def get(self) -> float:
# Serialized cavity has the same frequency
return self.__rf._cfg.masterclock.get()

def set(self,value:float):
return self.__rf._cfg.masterclock.set(value)

def set_and_wait(self, value:float):
raise NotImplementedError("Not implemented yet.")

def unit(self) -> str:
return self.__rf._cfg.masterclock.unit()

19 changes: 19 additions & 0 deletions pyaml/control/controlsystem.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,11 @@
from ..lattice.element_holder import ElementHolder
from ..lattice.element import Element
from ..control.abstract_impl import RWHardwareScalar,RWHardwareArray,RWStrengthScalar,RWStrengthArray
from ..control.abstract_impl import RWRFFrequencyScalar,RWRFVoltageScalar,RWRFPhaseScalar
from ..magnet.magnet import Magnet
from ..magnet.cfm_magnet import CombinedFunctionMagnet
from ..rf.rf_plant import RFPlant,RWTotalVoltage
from ..rf.rf_transmitter import RFTransmitter

class ControlSystem(ElementHolder,metaclass=ABCMeta):
"""
Expand Down Expand Up @@ -51,6 +54,7 @@ def fill_device(self,elements:list[Element]):
# Create a unique ref for this control system
m = e.attach(strength, current)
self.add_magnet(m.get_name(),m)

elif isinstance(e,CombinedFunctionMagnet):
self.add_magnet(e.get_name(),e)
currents = RWHardwareArray(e.model) if e.model.has_hardware() else None
Expand All @@ -59,3 +63,18 @@ def fill_device(self,elements:list[Element]):
ms = e.attach(strengths,currents)
for m in ms:
self.add_magnet(m.get_name(),m)

elif isinstance(e,RFPlant):
self.add_rf_plant(e.get_name(),e)
attachedTrans: list[RFTransmitter] = []
for t in e._cfg.transmitters:
voltage = RWRFVoltageScalar(t)
phase = RWRFPhaseScalar(t)
nt = t.attach(voltage,phase)
self.add_rf_transnmitter(nt.get_name(),nt)
attachedTrans.append(nt)

frequency = RWRFFrequencyScalar(e)
voltage = RWTotalVoltage(attachedTrans)
ne = e.attach(frequency,voltage)
self.add_rf_plant(ne.get_name(),ne)
91 changes: 88 additions & 3 deletions pyaml/lattice/abstract_impl.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
from pyaml.control import abstract
from pyaml.magnet.model import MagnetModel
from .polynom_info import PolynomInfo
import numpy as np
import at
from scipy.constants import speed_of_light

from ..control import abstract
from ..magnet.model import MagnetModel
from .polynom_info import PolynomInfo
from ..rf.rf_plant import RFPlant
from ..rf.rf_transmitter import RFTransmitter

# TODO handle serialized magnets

Expand Down Expand Up @@ -142,3 +146,84 @@ def set_and_wait(self, value:np.array):
def unit(self) -> list[str]:
return self.unitconv.get_strength_units()

#------------------------------------------------------------------------------

class RWRFVoltageScalar(abstract.ReadWriteFloatScalar):
"""
Class providing read write access to a cavity voltage of a simulator for a given RF trasnmitter.
"""

def __init__(self, elements:list[at.Element], transmitter:RFTransmitter):
self.elements = elements
self.__transmitter = transmitter

def get(self) -> float:
sum = 0
for idx,e in enumerate(self.elements):
sum += e.Voltage
return sum

def set(self,value:float):
v = value / len(self.elements)
for e in self.elements:
e.Voltage = v

def set_and_wait(self, value:float):
raise NotImplementedError("Not implemented yet.")

def unit(self) -> str:
return self.__transmitter._cfg.voltage.unit()

#------------------------------------------------------------------------------

class RWRFPhaseScalar(abstract.ReadWriteFloatScalar):
"""
Class providing read write access to a cavity phase of a simulator for a given RF trasnmitter.
"""

def __init__(self, elements:list[at.Element], transmitter:RFTransmitter):
self.__elements = elements
self.__transmitter = transmitter

def get(self) -> float:
# Assume that all cavities of this transmitter have the same Time Lag and Frequency
wavelength = speed_of_light / self.__elements[0].Frequency
return (wavelength / self.__elements[0].TimeLag) * 2.0 * np.pi

def set(self,value:float):
wavelength = speed_of_light / self.__elements[0].Frequency
for e in self.__elements:
e.TimeLag = wavelength * value / (2.0 * np.pi)

def set_and_wait(self, value:float):
raise NotImplementedError("Not implemented yet.")

def unit(self) -> str:
return self.__transmitter._cfg.phase.unit()

#------------------------------------------------------------------------------

class RWRFFrequencyScalar(abstract.ReadWriteFloatScalar):
"""
Class providing read write access to RF frequency of a simulator.
"""

def __init__(self, elements:list[at.Element], harmonics:list[float], rf:RFPlant ):
self.__elements = elements
self.__harm = harmonics
self.__rf = rf

def get(self) -> float:
# Serialized cavity has the same frequency
return self.__elements[0].Frequency

def set(self,value:float):
for idx,e in enumerate(self.__elements):
e.Frequency = value * self.__harm[idx]

def set_and_wait(self, value:float):
raise NotImplementedError("Not implemented yet.")

def unit(self) -> str:
return self.__rf._cfg.masterclock.unit()

31 changes: 27 additions & 4 deletions pyaml/lattice/element_holder.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
"""
from .element import Element
from ..magnet.magnet import Magnet
from ..rf.rf_plant import RFPlant
from ..rf.rf_transmitter import RFTransmitter
from ..arrays.magnet_array import MagnetArray


Expand All @@ -15,7 +17,8 @@ def __init__(self):
# Device handle
self.__MAGNETS: dict = {}
self.__BPMS: dict = {}
self.__RF: dict = {}
self.__RFPLANT: dict = {}
self.__RFTRANSMITTER: dict = {}
self.__OTHERS: dict = {}

# Array handle
Expand All @@ -39,13 +42,33 @@ def get_magnet(self,name:str) -> Magnet:
return self.__MAGNETS[name]

def add_magnet(self,name:str,m:Magnet):
self.__MAGNETS[name] = m
self.__MAGNETS[name] = m

def get_rf_plant(self,name:str) -> RFPlant:
if name not in self.__RFPLANT:
raise Exception(f"RFPlant {name} not defined")
return self.__RFPLANT[name]

def add_rf_plant(self,name:str,rf:RFPlant):
self.__RFPLANT[name] = rf

def get_rf_plant(self,name:str) -> RFPlant:
if name not in self.__RFPLANT:
raise Exception(f"RFPlant {name} not defined")
return self.__RFPLANT[name]

def add_rf_transnmitter(self,name:str,rf:RFTransmitter):
self.__RFTRANSMITTER[name] = rf

def get_rf_trasnmitter(self,name:str) -> RFTransmitter:
if name not in self.__RFTRANSMITTER:
raise Exception(f"RFTransmitter {name} not defined")
return self.__RFTRANSMITTER[name]

def get_all_magnets(self) -> dict:
return self.__MAGNETS

def get_magnets(self,name:str) -> MagnetArray:
if name not in self.__MAGNET_ARRAYS:
raise Exception(f"Magnet array {name} not defined")
return self.__MAGNET_ARRAYS[name]

return self.__MAGNET_ARRAYS[name]
34 changes: 34 additions & 0 deletions pyaml/lattice/simulator.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,11 @@
from pathlib import Path
from ..magnet.magnet import Magnet
from ..magnet.cfm_magnet import CombinedFunctionMagnet
from ..rf.rf_plant import RFPlant,RWTotalVoltage
from ..rf.rf_transmitter import RFTransmitter
from ..lattice.abstract_impl import RWHardwareScalar,RWHardwareArray
from ..lattice.abstract_impl import RWStrengthScalar,RWStrengthArray
from ..lattice.abstract_impl import RWRFFrequencyScalar,RWRFVoltageScalar,RWRFPhaseScalar
from .element_holder import ElementHolder

# Define the main class name for this module
Expand Down Expand Up @@ -67,6 +70,7 @@ def fill_device(self,elements:list[Element]):
# Create a unique ref for this simulator
m = e.attach(strength,current)
self.add_magnet(m.get_name(),m)

elif isinstance(e,CombinedFunctionMagnet):
self.add_magnet(e.get_name(),e)
currents = RWHardwareArray(self.get_at_elems(e),e.polynoms,e.model) if e.model.has_physics() else None
Expand All @@ -76,6 +80,36 @@ def fill_device(self,elements:list[Element]):
for m in ms:
self.add_magnet(m.get_name(),m)
self.add_magnet(m.get_name(),m)

elif isinstance(e,RFPlant):
self.add_rf_plant(e.get_name(),e)
cavs: list[at.Element] = []
harmonics: list[float] = []
attachedTrans: list[RFTransmitter] = []
for t in e._cfg.transmitters:
cavsPerTrans: list[at.Element] = []
for c in t._cfg.cavities:
# Expect unique name for cavities
cav = self.get_at_elems(Element(c))
if len(cav)>1:
raise Exception(f"RF transmitter {t.get_name()}, multiple cavity definition:{cav[0]}")
if len(cav)==0:
raise Exception(f"RF transmitter {t.get_name()}, No cavity found")
cavsPerTrans.append(cav[0])
harmonics.append(t._cfg.harmonic)

voltage = RWRFVoltageScalar(cavsPerTrans,t)
phase = RWRFPhaseScalar(cavsPerTrans,t)
nt = t.attach(voltage,phase)
attachedTrans.append(nt)
self.add_rf_transnmitter(nt.get_name(),nt)
cavs.extend(cavsPerTrans)

frequency = RWRFFrequencyScalar(cavs,harmonics,e)
voltage = RWTotalVoltage(attachedTrans)
ne = e.attach(frequency,voltage)
self.add_rf_plant(ne.get_name(),ne)


def get_at_elems(self,element:Element) -> list[at.Element]:
identifier = self._linker.get_element_identifier(element)
Expand Down
4 changes: 4 additions & 0 deletions pyaml/rf/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
"""
PyAML RF module
"""

Loading
Loading