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
1 change: 1 addition & 0 deletions pyaml/apidoc/gen_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
"pyaml.common.exception",
"pyaml.common.holders.element_holder",
"pyaml.common.holders.sub_holders",
"pyaml.common.holders.rf_holder",
"pyaml.configuration.factory",
"pyaml.configuration.fileloader",
"pyaml.configuration.manager",
Expand Down
20 changes: 6 additions & 14 deletions pyaml/common/holders/element_holder.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
from ..abstract_aggregator import ScalarAggregator
from ..element import Element
from ..exception import PyAMLException
from .rf_holder import RFHolder
from .sub_holders import (
BPMHolder,
BPMsHolder,
Expand Down Expand Up @@ -89,6 +90,7 @@ def __init__(self):
self._combined_function_magnets_holder = CombinedFunctionMagnetsHolder(self)
self._bpm_holder = BPMHolder(self)
self._bpms_holder = BPMsHolder(self)
self._rf_holder = RFHolder(self)

@property
def peer(self) -> "Accelerator":
Expand Down Expand Up @@ -131,6 +133,10 @@ def bpm(self) -> BPMHolder:
def bpms(self) -> BPMsHolder:
return self._bpms_holder

@property
def rf(self) -> RFHolder:
return self._rf_holder

def post_init(self):
"""
Method triggered after all initialisations are done
Expand Down Expand Up @@ -233,20 +239,6 @@ def get_elements(self, name: str) -> ElementArray:
def get_all_elements(self) -> list[Element]:
return [value for key, value in self._ALL.items()]

# RF

def get_rf_plant(self, name: str) -> RFPlant:
return self._get("RFPlant", name, self._RFPLANT)

def add_rf_plant(self, rf: RFPlant):
self._add(self._RFPLANT, rf)

def add_rf_transmitter(self, rf: RFTransmitter):
self._add(self._RFTRANSMITTER, rf)

def get_rf_trasnmitter(self, name: str) -> RFTransmitter:
return self._get("RFTransmitter", name, self._RFTRANSMITTER)

# Tune monitor

def get_betatron_tune_monitor(self, name: str) -> BetatronTuneMonitor:
Expand Down
77 changes: 77 additions & 0 deletions pyaml/common/holders/rf_holder.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
from typing import TYPE_CHECKING

from ...rf.rf_plant import RFPlant
from ...rf.rf_transmitter import RFTransmitter
from ..abstract import ReadWriteFloatScalar

if TYPE_CHECKING:
from .element_holder import ElementHolder


class RFTransmitterHolder:
def __init__(self, peer: "ElementHolder"):
self._peer = peer

def get(self, name: str) -> RFTransmitter:
return self._peer._get("RFTransmitter", name, self._peer._RFTRANSMITTER)

def add(self, rf: RFTransmitter):
self._peer._add(self._peer._RFTRANSMITTER, rf)


class RFHolder:
"""
RF holder
"""

def __init__(self, peer: "ElementHolder"):
self._peer = peer
self._rftransmitter_holder = RFTransmitterHolder(peer)

@property
def transmitter(self) -> RFTransmitterHolder:
"""
Returns RF transmitter holder

Parameters
----------
name : str
Name of the element
"""
return self._rftransmitter_holder

@property
def frequency(self) -> ReadWriteFloatScalar:
"""
Return a handle to RF frequency of the DEFAULT_RF_PLANT
"""
return self.get("DEFAULT_RF_PLANT").frequency

@property
def voltage(self) -> ReadWriteFloatScalar:
"""
Return a handle to RF voltage of the DEFAULT_RF_PLANT
"""
return self.get("DEFAULT_RF_PLANT").voltage

def get(self, name: str) -> RFPlant:
"""
Returns the specified RF plant

Parameters
----------
name : str
Name of the RF plant
"""
return self._peer._get("RFPlant", name, self._peer._RFPLANT)

def add(self, rf: RFPlant):
"""
Adds the specified RF plant to the holder

Parameters
----------
rf : RFPlant
RF Plant to be added
"""
self._peer._add(self._peer._RFPLANT, rf)
4 changes: 2 additions & 2 deletions pyaml/control/controlsystem.py
Original file line number Diff line number Diff line change
Expand Up @@ -186,14 +186,14 @@ def fill_device(self, elements: list[Element]):
voltage = RWRFVoltageScalar(t, vDev)
phase = RWRFPhaseScalar(t, pDev)
nt = t.attach(self, voltage, phase)
self.add_rf_transmitter(nt)
self.rf.transmitter.add(nt)
attachedTrans.append(nt)

fDev = self.get_device_access(e.masterclock)
frequency = RWRFFrequencyScalar(e, fDev)
voltage = RWTotalVoltage(attachedTrans) if e.transmitters else None
ne = e.attach(self, frequency, voltage)
self.add_rf_plant(ne)
self.rf.add(ne)

elif isinstance(e, BetatronTuneMonitor):
# Built in tune monitor
Expand Down
2 changes: 1 addition & 1 deletion pyaml/diagnostics/tune_monitor.py
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ def get(self) -> NDArray:
rf_name = self.parent._rf_plant_name
if h is not None and rf_name is not None:
tune = self.parent.tune.get()
rf = self.parent.peer.get_rf_plant(rf_name)
rf = self.parent.peer.rf.get(rf_name)
freq = rf.frequency.get()
return tune * freq / h

Expand Down
2 changes: 1 addition & 1 deletion pyaml/external/pySC_interface.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ def __init__(

self.rf_plant_name = rf_plant_name
if rf_plant_name is not None:
self.rf_plant = element_holder.get_rf_plant(self.rf_plant_name)
self.rf_plant = element_holder.rf.get(self.rf_plant_name)
else:
self.rf_plant = None

Expand Down
6 changes: 3 additions & 3 deletions pyaml/lattice/simulator.py
Original file line number Diff line number Diff line change
Expand Up @@ -230,20 +230,20 @@ def fill_device(self, elements: list[Element]):
voltage = RWRFVoltageScalar(cavsPerTrans)
phase = RWRFPhaseScalar(cavsPerTrans)
nt = t.attach(self, voltage, phase)
self.add_rf_transmitter(nt)
self.rf.transmitter.add(nt)
cavs.extend(cavsPerTrans)
attachedTrans.append(nt)

frequency = RWRFFrequencyScalar(cavs, harmonics)
voltage = RWTotalVoltage(attachedTrans)
ne = e.attach(self, frequency, voltage)
self.add_rf_plant(ne)
self.rf.add(ne)
else:
# No transmitter defined switch to AT methods
frequency = RWRFATFrequencyScalar(self.ring)
voltage = RWRFATotalVoltageScalar(self.ring)
ne = e.attach(self, frequency, voltage)
self.add_rf_plant(ne)
self.rf.add(ne)

elif isinstance(e, BetatronTuneMonitor):
betatron_tune = RBetatronTuneArray(self.ring)
Expand Down
2 changes: 1 addition & 1 deletion pyaml/tuning_tools/chromaticity_monitor.py
Original file line number Diff line number Diff line change
Expand Up @@ -245,7 +245,7 @@ def measure(
# Get devices
self.check_peer()
tm = self.peer.get_betatron_tune_monitor(self.betatron_tune_name)
rf = self.peer.get_rf_plant(self.rf_plant_name)
rf = self.peer.rf.get(self.rf_plant_name)
bpms = None
n_bpm = 0
orbit = None
Expand Down
2 changes: 1 addition & 1 deletion pyaml/tuning_tools/orbit.py
Original file line number Diff line number Diff line change
Expand Up @@ -319,4 +319,4 @@ def post_init(self):
hvElts.extend(self._vcorr)
self._hvcorr = MagnetArray("", hvElts)
if self._cfg.rf_plant_name is not None:
self._rf_plant = self.peer.get_rf_plant(self._cfg.rf_plant_name)
self._rf_plant = self.peer.rf.get(self._cfg.rf_plant_name)
8 changes: 4 additions & 4 deletions tests/config/EBSOrbit.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ devices:
- type: pyaml.tuning_tools.chromaticity_monitor
name: CHROMATICITY_MONITOR
betatron_tune_name: BETATRON_TUNE
rf_plant_name: RF
rf_plant_name: DEFAULT_RF_PLANT
bpm_array_name: BPM
n_step: 5
- type: pyaml.tuning_tools.tune
Expand All @@ -98,7 +98,7 @@ devices:
bpm_array_name: BPM
hcorr_array_name: HCorr
vcorr_array_name: VCorr
rf_plant_name: RF
rf_plant_name: DEFAULT_RF_PLANT
name: DEFAULT_ORBIT_CORRECTION
singular_values: 162
response_matrix: ${path:ideal_orm_disp.json}
Expand All @@ -110,11 +110,11 @@ devices:
name: DEFAULT_ORBIT_RESPONSE_MATRIX
- type: pyaml.tuning_tools.dispersion
bpm_array_name: BPM
rf_plant_name: RF
rf_plant_name: DEFAULT_RF_PLANT
frequency_delta: 10
name: DEFAULT_DISPERSION
- type: pyaml.rf.rf_plant
name: RF
name: DEFAULT_RF_PLANT
masterclock: sy/ms/1/Frequency
transmitters:
- type: pyaml.rf.rf_transmitter
Expand Down
2 changes: 1 addition & 1 deletion tests/config/EBS_rf.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ controls:
data_folder: /data/store
devices:
- type: pyaml.rf.rf_plant
name: RF
name: DEFAULT_RF_PLANT
masterclock: sy/ms/1/Frequency
transmitters:
- type: pyaml.rf.rf_transmitter
Expand Down
2 changes: 1 addition & 1 deletion tests/config/EBS_rf_multi.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ controls:
data_folder: /data/store
devices:
- type: pyaml.rf.rf_plant
name: RF
name: DEFAULT_RF_PLANT
masterclock: sy/ms/1/Frequency
transmitters:
- type: pyaml.rf.rf_transmitter
Expand Down
2 changes: 1 addition & 1 deletion tests/config/EBS_rf_notrans.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,5 @@ controls:
data_folder: /data/store
devices:
- type: pyaml.rf.rf_plant
name: RF
name: DEFAULT_RF_PLANT
masterclock: sy/ms/1/Frequency
2 changes: 1 addition & 1 deletion tests/integration/test_dt4acc_twin_smoke.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ def test_dt4acc_twin_accelerator_instantiates_and_reads_live_values(root_folder:
assert accelerator.live is not None
assert "live" in accelerator.controls()

accelerator.live.get_rf_plant("RF")
accelerator.live.rf.get("RF")

reference_frequency = _readback_value(accelerator.live.get_device_access(RF_REFERENCE_FREQUENCY))

Expand Down
44 changes: 19 additions & 25 deletions tests/rf/test_rf.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,16 @@

def test_rf():
sr: Accelerator = Accelerator.load("tests/config/EBS_rf.yaml", ignore_external=True)
RF = sr.design.get_rf_plant("RF")

RF.frequency.set(3.523e8)
sr.design.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.0e6)
sr.design.rf.voltage.set(10.0e6)

# Check that voltage has been applied on all cavities
ring = sr.design.get_lattice()
Expand All @@ -26,11 +25,10 @@ def test_rf():
assert np.isclose(e.Voltage, 10.0e6 / 13.0)

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)
sr.live.rf.frequency.set(3.523721693993786e8)
sr.live.rf.voltage.set(6.5e6)
assert np.isclose(sr.live.rf.frequency.get(), 3.523721693993786e8)
assert np.isclose(sr.live.rf.voltage.get(), 6.5e6)


@pytest.mark.parametrize(
Expand All @@ -42,9 +40,8 @@ def test_rf_multi(install_test_package):
sr: Accelerator = Accelerator.load("tests/config/EBS_rf_multi.yaml")

# Simulator
RF = sr.design.get_rf_plant("RF")

RF.frequency.set(3.523e8)
sr.design.rf.frequency.set(3.523e8)

# Check that frequency has been applied on all cavities
ring = sr.design.get_lattice()
Expand All @@ -56,9 +53,9 @@ def test_rf_multi(install_test_package):
else:
assert e.Frequency == 3.523e8

RFTRA_HARMONIC = sr.design.get_rf_trasnmitter("RFTRA_HARMONIC")
RFTRA_HARMONIC = sr.design.rf.transmitter.get("RFTRA_HARMONIC")
RFTRA_HARMONIC.voltage.set(300e3)
RF.voltage.set(12e6)
sr.design.rf.voltage.set(12e6)

for e in ring:
if e.FamName.startswith("CAV"):
Expand All @@ -69,14 +66,13 @@ def test_rf_multi(install_test_package):
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")
RF1 = sr.live.rf.transmitter.get("RFTRA1")
RF2 = sr.live.rf.transmitter.get("RFTRA2")
RFTRA_HARMONIC = sr.live.rf.transmitter.get("RFTRA_HARMONIC")

RF.frequency.set(3.523e8)
sr.live.rf.frequency.set(3.523e8)
RFTRA_HARMONIC.voltage.set(300e3)
RF.voltage.set(12e6)
sr.live.rf.voltage.set(12e6)

assert np.isclose(RF1.voltage.get(), 10e6)
assert np.isclose(RF2.voltage.get(), 2e6)
Expand All @@ -92,9 +88,8 @@ def test_rf_multi_notrans(install_test_package):
sr: Accelerator = Accelerator.load("tests/config/EBS_rf_notrans.yaml")

# Simulator
RF = sr.design.get_rf_plant("RF")
RF.frequency.set(3.523e8)
RF.voltage.set(10e6)
sr.design.rf.frequency.set(3.523e8)
sr.design.rf.voltage.set(10e6)
# Check that frequency and voltage has been applied on all cavities
ring = sr.design.get_lattice()
for e in ring:
Expand All @@ -103,11 +98,10 @@ def test_rf_multi_notrans(install_test_package):
assert np.isclose(e.Voltage, 10e6 / 13.0)

# Control system
RF = sr.live.get_rf_plant("RF")
RF.frequency.set(3.523e8)
sr.live.rf.frequency.set(3.523e8)
with pytest.raises(PyAMLException) as exc:
RF.voltage.set(10e6)
sr.live.rf.voltage.set(10e6)
assert "has no transmitter device defined" in str(exc)

# Check that frequency and voltage has been applied on the masterclock device
assert np.isclose(RF.frequency.get(), 3.523e8)
assert np.isclose(sr.live.rf.frequency.get(), 3.523e8)
Loading
Loading