Skip to content

Commit e4e009f

Browse files
committed
dispersion measurement
1 parent a60fcb3 commit e4e009f

File tree

3 files changed

+111
-0
lines changed

3 files changed

+111
-0
lines changed
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
from pathlib import Path
2+
3+
import matplotlib.pyplot as plt
4+
5+
from pyaml.accelerator import Accelerator
6+
from pyaml.tuning_tools.dispersion import ConfigModel as Disp_ConfigModel
7+
from pyaml.tuning_tools.dispersion import Dispersion
8+
9+
parent_folder = Path(__file__).parent
10+
config_path = parent_folder.parent.parent.joinpath(
11+
"tests", "config", "EBSOrbit.yaml"
12+
).resolve()
13+
sr = Accelerator.load(config_path)
14+
element_holder = sr.design
15+
16+
dispersion = Dispersion(
17+
cfg=Disp_ConfigModel(
18+
bpm_array_name="BPM",
19+
rf_plant_name="RF",
20+
frequency_delta=10,
21+
),
22+
element_holder=element_holder,
23+
)
24+
25+
dispersion.measure()
26+
# orm.save(parent_folder / Path("ideal_orm.json"))
27+
# orm.save(parent_folder / Path("ideal_orm.yaml"), with_type="yaml")
28+
# orm.save(parent_folder / Path("ideal_orm.npz"), with_type="npz")
29+
30+
# ormdata = orm.get()
31+
dispersion_data = dispersion.get()
32+
33+
fig = plt.figure()
34+
ax = fig.add_subplot(111)
35+
ax.plot(dispersion_data["frequency_response_x"])
36+
plt.show()

pyaml/external/pySC_interface.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ def __init__(
1313
bpm_array_name: str = "BPM",
1414
hcorr_array_name: str = "HCorr",
1515
vcorr_array_name: str = "VCorr",
16+
rf_plant_name: str = "RF",
1617
):
1718
self.element_holder = element_holder
1819

@@ -38,6 +39,9 @@ def __init__(
3839
name: ii for ii, name in enumerate(self.vcorr_names)
3940
}
4041

42+
self.rf_plant_name = rf_plant_name
43+
self.rf_plant = element_holder.get_rf_plant(self.rf_plant_name)
44+
4145
def get_orbit(self) -> Tuple[np.array, np.array]:
4246
# we should wait here somehow according to polling rate
4347
positions = self.bpm_array.positions.get()
@@ -154,3 +158,10 @@ def set_many(self, names_values: Dict[str, float]) -> None:
154158
) # ideally set_and_wait but not implemented
155159

156160
return
161+
162+
def get_rf_main_frequency(self) -> float:
163+
return self.rf_plant.frequency.get()
164+
165+
def set_rf_main_frequency(self, value: float) -> None:
166+
self.rf_plant.frequency.set(value)
167+
return

pyaml/tuning_tools/dispersion.py

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
import logging
2+
from pathlib import Path
3+
from typing import List, Optional
4+
5+
from pydantic import BaseModel, ConfigDict
6+
7+
from ..common.element_holder import ElementHolder
8+
from ..common.exception import PyAMLException
9+
from ..external.pySC import pySC
10+
from ..external.pySC.pySC.apps import measure_dispersion
11+
from ..external.pySC.pySC.apps.codes import DispersionCode
12+
from ..external.pySC_interface import pySCInterface
13+
14+
logger = logging.getLogger(__name__)
15+
16+
PYAMLCLASS = "OrbitResponseMatrix"
17+
18+
19+
class ConfigModel(BaseModel):
20+
model_config = ConfigDict(arbitrary_types_allowed=True, extra="forbid")
21+
22+
bpm_array_name: str
23+
rf_plant_name: str
24+
frequency_delta: float
25+
26+
27+
class Dispersion(object):
28+
def __init__(self, element_holder: ElementHolder, cfg: ConfigModel):
29+
self._cfg = cfg
30+
31+
self.element_holder = element_holder
32+
self.bpm_array_name = cfg.bpm_array_name
33+
self.rf_plant_name = cfg.rf_plant_name
34+
self.frequency_delta = cfg.frequency_delta
35+
self.latest_measurement = None
36+
37+
def measure(self):
38+
interface = pySCInterface(
39+
element_holder=self.element_holder,
40+
bpm_array_name=self.bpm_array_name,
41+
rf_plant_name=self.rf_plant_name,
42+
)
43+
44+
generator = measure_dispersion(
45+
interface=interface,
46+
delta=self.frequency_delta,
47+
skip_save=True,
48+
)
49+
50+
pySC.disable_pySC_rich()
51+
_, measurement = next(generator)
52+
for _, _ in generator:
53+
pass
54+
55+
dispersion_data = measurement.dispersion_data
56+
# contains also pre-processed data
57+
58+
# dispersion_data.output_names = self.element_holder.get_bpms(
59+
# self.bpm_array_name
60+
# ).names()
61+
self.latest_measurement = dispersion_data.model_dump()
62+
63+
def get(self):
64+
return self.latest_measurement

0 commit comments

Comments
 (0)