diff --git a/pyaml/arrays/hcorrector.py b/pyaml/arrays/hcorrector.py deleted file mode 100644 index a3d00291..00000000 --- a/pyaml/arrays/hcorrector.py +++ /dev/null @@ -1,14 +0,0 @@ -from .array import ArrayConfigModel -from .array import MagnetArrayConfig -from ..lattice.element_holder import ElementHolder,MagnetType - -# Define the main class name for this module -PYAMLCLASS = "HCorrector" - -class ConfigModel(ArrayConfigModel):... - -class HCorrector(MagnetArrayConfig): - - def fill_array(self,holder:ElementHolder): - holder.fill_magnet_array(MagnetType.HCORRECTOR,self._cfg.name,self._cfg.elements) - diff --git a/pyaml/control/abstract_impl.py b/pyaml/control/abstract_impl.py index aba22c08..f86e7569 100644 --- a/pyaml/control/abstract_impl.py +++ b/pyaml/control/abstract_impl.py @@ -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): @@ -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() diff --git a/pyaml/control/controlsystem.py b/pyaml/control/controlsystem.py index 74be3df8..ca272318 100644 --- a/pyaml/control/controlsystem.py +++ b/pyaml/control/controlsystem.py @@ -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): """ @@ -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 @@ -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) diff --git a/pyaml/lattice/abstract_impl.py b/pyaml/lattice/abstract_impl.py index 6ed52cac..fb5eac0c 100644 --- a/pyaml/lattice/abstract_impl.py +++ b/pyaml/lattice/abstract_impl.py @@ -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 @@ -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() + diff --git a/pyaml/lattice/element_holder.py b/pyaml/lattice/element_holder.py index 943f62d6..1b7113ff 100644 --- a/pyaml/lattice/element_holder.py +++ b/pyaml/lattice/element_holder.py @@ -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 @@ -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 @@ -39,7 +42,28 @@ 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 @@ -47,5 +71,4 @@ def get_all_magnets(self) -> dict: 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] - \ No newline at end of file + return self.__MAGNET_ARRAYS[name] \ No newline at end of file diff --git a/pyaml/lattice/simulator.py b/pyaml/lattice/simulator.py index 875ebd6e..15dd1e9e 100644 --- a/pyaml/lattice/simulator.py +++ b/pyaml/lattice/simulator.py @@ -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 @@ -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 @@ -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) diff --git a/pyaml/rf/__init__.py b/pyaml/rf/__init__.py new file mode 100644 index 00000000..bf881e4a --- /dev/null +++ b/pyaml/rf/__init__.py @@ -0,0 +1,4 @@ +""" +PyAML RF module +""" + diff --git a/pyaml/rf/rf_plant.py b/pyaml/rf/rf_plant.py new file mode 100644 index 00000000..62f6536e --- /dev/null +++ b/pyaml/rf/rf_plant.py @@ -0,0 +1,90 @@ +import numpy as np +from pydantic import BaseModel,ConfigDict +try: + from typing import Self # Python 3.11+ +except ImportError: + from typing_extensions import Self # Python 3.10 and earlier + +from .rf_transmitter import RFTransmitter +from .. import PyAMLException +from ..control.deviceaccess import DeviceAccess +from ..lattice.element import Element,ElementConfigModel +from ..control import abstract + +# Define the main class name for this module +PYAMLCLASS = "RFPlant" + +class ConfigModel(ElementConfigModel): + + masterclock: DeviceAccess|None = None + """Device to apply main RF frequency""" + transmitters: list[RFTransmitter]|None = None + """List of RF trasnmitters""" + +class RFPlant(Element): + """ + Main RF object + """ + + def __init__(self, cfg: ConfigModel): + super().__init__(cfg.name) + self._cfg = cfg + self.__frequency = None + self.__voltage = None + + @property + def frequency(self) -> abstract.ReadWriteFloatScalar: + if self.__frequency is None: + raise PyAMLException(f"{str(self)} has no masterclock device defined") + return self.__frequency + + @property + def voltage(self) -> abstract.ReadWriteFloatScalar: + if self.__voltage is None: + raise PyAMLException(f"{str(self)} has no trasmitter device defined") + return self.__voltage + + def attach(self, frequency: abstract.ReadWriteFloatScalar, voltage: abstract.ReadWriteFloatScalar) -> Self: + # Attach frequency attribute and returns a new reference + obj = self.__class__(self._cfg) + obj.__frequency = frequency + obj.__voltage = voltage + return obj + +class RWTotalVoltage(abstract.ReadWriteFloatScalar): + + def __init__(self, transmitters: list[RFTransmitter]): + """ + Construct a RWTotalVoltage setter + + Parameters + ---------- + transmitters : list[RFTransmitter] + List of attached transmitters + """ + self.__trans = transmitters + + def get(self) -> float: + sum = 0 + # Count only fundamental harmonic + for t in self.__trans: + if(t._cfg.harmonic==1.): + sum += t.voltage.get() + return sum + + def set(self,value:float): + # Assume that sum of transmitter (fundamental harmonic) distribution is 1 + for t in self.__trans: + if(t._cfg.harmonic==1.): + v = value * t._cfg.distribution + t.voltage.set(v) + + def set_and_wait(self, value:float): + raise NotImplementedError("Not implemented yet.") + + def unit(self) -> str: + return self.__trans[0]._cfg.phase.unit() + + + + diff --git a/pyaml/rf/rf_transmitter.py b/pyaml/rf/rf_transmitter.py new file mode 100644 index 00000000..a41d87d4 --- /dev/null +++ b/pyaml/rf/rf_transmitter.py @@ -0,0 +1,66 @@ +import numpy as np +from pydantic import BaseModel,ConfigDict +try: + from typing import Self # Python 3.11+ +except ImportError: + from typing_extensions import Self # Python 3.10 and earlier + +from .. import PyAMLException +from ..control.deviceaccess import DeviceAccess +from ..lattice.element import Element,ElementConfigModel +from ..control import abstract + +# Define the main class name for this module +PYAMLCLASS = "RFTransmitter" + +class ConfigModel(ElementConfigModel): + + model_config = ConfigDict(arbitrary_types_allowed=True,extra="forbid") + + voltage: DeviceAccess|None = None + """Device to apply cavity voltage""" + phase: DeviceAccess|None = None + """Device to apply cavity phase""" + cavities: list[str] + """List of cavity names connected to this transmitter""" + harmonic: float = 1.0 + """Harmonic frequency ratio, 1.0 for main frequency""" + distribution: float = 1.0 + """RF distribution (Part of the total RF voltage powered by this transmitter)""" + +class RFTransmitter(Element): + + """ + Class that handle a RF transmitter + """ + + def __init__(self, cfg: ConfigModel): + super().__init__(cfg.name) + self._cfg = cfg + self.__voltage = None + self.__phase = None + + @property + def voltage(self) -> abstract.ReadWriteFloatScalar: + if self.__voltage is None: + raise PyAMLException(f"{str(self)} has no voltage device defined") + return self.__voltage + + @property + def phase(self) -> abstract.ReadWriteFloatScalar: + if self.__phase is None: + raise PyAMLException(f"{str(self)} has no phase device defined") + return self.__phase + + def attach(self, voltage: abstract.ReadWriteFloatScalar, phase: abstract.ReadWriteFloatScalar) -> Self: + # Attach voltage and phase attribute and returns a new reference + obj = self.__class__(self._cfg) + obj.__voltage = voltage + obj.__phase = phase + return obj + + def __repr__(self): + return "%s(%s)" % ( + self.__class__.__name__, + self._cfg.name + ) diff --git a/tests/config/EBS_rf.yaml b/tests/config/EBS_rf.yaml new file mode 100644 index 00000000..3c4c4277 --- /dev/null +++ b/tests/config/EBS_rf.yaml @@ -0,0 +1,31 @@ +type: pyaml.pyaml +instruments: + - type: pyaml.instrument + name: sr + energy: 6e9 + simulators: + - type: pyaml.lattice.simulator + lattice: sr/lattices/ebs.mat + name: design + controls: + - type: tango.pyaml.controlsystem + tango_host: ebs-simu-3:10000 + name: live + data_folder: /data/store + devices: + - type: pyaml.rf.rf_plant + name: RF + masterclock: + type: tango.pyaml.attribute + attribute: sy/ms/1/Frequency + unit: Hz + transmitters: + - type: pyaml.rf.rf_transmitter + name: RFTRA + cavities: [CAV_C05_01,CAV_C05_02,CAV_C05_03,CAV_C05_04,CAV_C05_05,CAV_C07_01,CAV_C07_02,CAV_C07_03,CAV_C07_04,CAV_C07_05,CAV_C25_01,CAV_C25_02,CAV_C25_03] + harmonic: 1 + distribution: 1 + voltage: + type: tango.pyaml.attribute + attribute: sys/ringsimulator/ebs/RfVoltage + unit: V diff --git a/tests/config/EBS_rf_multi.yaml b/tests/config/EBS_rf_multi.yaml new file mode 100644 index 00000000..a774e4e7 --- /dev/null +++ b/tests/config/EBS_rf_multi.yaml @@ -0,0 +1,51 @@ +type: pyaml.pyaml +instruments: + - type: pyaml.instrument + name: sr + energy: 6e9 + simulators: + - type: pyaml.lattice.simulator + lattice: sr/lattices/ebs.mat + name: design + controls: + - type: tango.pyaml.controlsystem + tango_host: ebs-simu-3:10000 + name: live + data_folder: /data/store + devices: + - type: pyaml.rf.rf_plant + name: RF + masterclock: + type: tango.pyaml.attribute + attribute: sy/ms/1/Frequency + unit: Hz + transmitters: + - type: pyaml.rf.rf_transmitter + name: RFTRA1 + cavities: [CAV_C05_01,CAV_C05_02,CAV_C05_03,CAV_C05_04,CAV_C05_05,CAV_C07_01,CAV_C07_02,CAV_C07_03,CAV_C07_04,CAV_C07_05] + harmonic: 1 + distribution: 0.83333333333 + voltage: + type: pyaml.control.device + setpoint: sr/tra/1/RfVoltage + readback: sr/tra/1/RfVoltage + unit: V + - type: pyaml.rf.rf_transmitter + name: RFTRA2 + cavities: [CAV_C25_01,CAV_C25_02] + harmonic: 1 + distribution: 0.16666666666 + voltage: + type: pyaml.control.device + setpoint: sr/tra/2/RfVoltage + readback: sr/tra/2/RfVoltage + unit: V + - type: pyaml.rf.rf_transmitter + name: RFTRA_HARMONIC + cavities: [CAV_C25_03] + harmonic: 4 + voltage: + type: pyaml.control.device + setpoint: sr/tra/harm/RfVoltage + readback: sr/tra/harm/RfVoltage + unit: V diff --git a/tests/lattice_info.py b/tests/lattice_info.py index 7cfece36..89f6e3db 100644 --- a/tests/lattice_info.py +++ b/tests/lattice_info.py @@ -1,5 +1,5 @@ import at -ring = at.load_lattice("tests/config/sr/lattices/ebs.mat") +ring = at.load_lattice("config/sr/lattices/ebs.mat") @@ -20,11 +20,12 @@ def prepare_and_save(): if hasattr(e,"Device"): delattr(e,"Device") - at.save_lattice(ring,"tests/config/sr/lattices/ebs_jlp.mat") + at.save_lattice(ring,"config/sr/lattices/ebs_jlp.mat") def dump(): # Dump lattice for e in ring: - print(f"\"{e.FamName}\",") + if e.FamName.startswith("QD"): + print(e) dump() \ No newline at end of file diff --git a/tests/test_rf.py b/tests/test_rf.py new file mode 100644 index 00000000..34da3164 --- /dev/null +++ b/tests/test_rf.py @@ -0,0 +1,84 @@ +from pyaml.pyaml import pyaml,PyAML +from pyaml.instrument import Instrument +from pyaml.configuration.factory import Factory +import numpy as np + +def test_rf(): + + ml:PyAML = pyaml("tests/config/EBS_rf.yaml") + sr:Instrument = ml.get('sr') + RF = sr.design.get_rf_plant("RF") + + RF.frequency.set(3.523e8) + + # Check that frequency has been applied on all cavities + ring = sr.design.get_lattice() + for e in ring: + if(e.FamName.startswith("CAV")): + assert(e.Frequency==3.523e8) + + RF.voltage.set(10.e6) + + # Check that voltage has been applied on all cavities + ring = sr.design.get_lattice() + for e in ring: + if(e.FamName.startswith("CAV")): + assert(np.isclose(e.Voltage,10.e6/13.)) + + if False: + RF = sr.live.get_rf_plant("RF") + RF.frequency.set(3.523721693993786E8) + RF.voltage.set(6.5e6) + assert np.isclose(RF.frequency.get(), 3.523721693993786E8) + assert np.isclose(RF.voltage.get(), 6.5e6) + + Factory.clear() + + +def test_rf_multi(): + + ml:PyAML = pyaml("tests/config/EBS_rf_multi.yaml") + sr:Instrument = ml.get('sr') + + # Simulator + RF = sr.design.get_rf_plant("RF") + + RF.frequency.set(3.523e8) + + # Check that frequency has been applied on all cavities + ring = sr.design.get_lattice() + for e in ring: + if(e.FamName.startswith("CAV")): + if( e.FamName == "CAV_C25_03"): + # Harmonic cavity + assert(np.isclose(e.Frequency,1.4092e9)) + else: + assert(e.Frequency==3.523e8) + + RFTRA_HARMONIC = sr.design.get_rf_trasnmitter("RFTRA_HARMONIC") + RFTRA_HARMONIC.voltage.set(300e3) + RF.voltage.set(12e6) + + for e in ring: + if(e.FamName.startswith("CAV")): + if( e.FamName == "CAV_C25_03"): + # Harmonic cavity + assert(np.isclose(e.Voltage,300e3)) + else: + assert(np.isclose(e.Voltage,1e6)) + + # Control system + RF = sr.live.get_rf_plant("RF") + RF1 = sr.live.get_rf_trasnmitter("RFTRA1") + RF2 = sr.live.get_rf_trasnmitter("RFTRA2") + RFTRA_HARMONIC = sr.live.get_rf_trasnmitter("RFTRA_HARMONIC") + + RF.frequency.set(3.523e8) + RFTRA_HARMONIC.voltage.set(300e3) + RF.voltage.set(12e6) + + assert(np.isclose(RF1._cfg.voltage.get(),10e6)) + assert(np.isclose(RF2._cfg.voltage.get(),2e6)) + assert(np.isclose(RFTRA_HARMONIC._cfg.voltage.get(),3e5)) + + Factory.clear()