Skip to content

Commit 36cd0bd

Browse files
committed
orbit object tuning tool for orbit correction
1 parent 19cd03b commit 36cd0bd

File tree

2 files changed

+119
-37
lines changed

2 files changed

+119
-37
lines changed

examples/ESRF_ORM_example/correct_orbit.py

Lines changed: 29 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -4,29 +4,42 @@
44

55
import matplotlib.pyplot as plt
66
import numpy as np
7-
from pyaml.external.pySC.pySC.apps import orbit_correction
8-
from pyaml.external.pySC.pySC.tuning.response_matrix import ResponseMatrix
97

108
from pyaml.accelerator import Accelerator
11-
from pyaml.external.pySC import pySC
12-
from pyaml.external.pySC_interface import pySCInterface
13-
14-
logging.getLogger("pyaml.external.pySC").setLevel(logging.WARNING)
9+
from pyaml.tuning_tools.orbit import ConfigModel as Orbit_ConfigModel
10+
from pyaml.tuning_tools.orbit import Orbit
1511

1612
parent_folder = Path(__file__).parent
1713
pyaml_folder = parent_folder.parent.parent
1814
config_path = pyaml_folder.joinpath("tests/config/EBSOrbit.yaml").resolve()
1915
sr = Accelerator.load(config_path)
2016
ebs = sr.design
2117

18+
orbit = Orbit(
19+
element_holder=ebs,
20+
cfg=Orbit_ConfigModel(
21+
bpm_array_name="BPM",
22+
hcorr_array_name="HCorr",
23+
vcorr_array_name="VCorr",
24+
singular_values=162,
25+
response_matrix_file=str(
26+
pyaml_folder.joinpath("examples/ESRF_ORM_example/ideal_orm.json").resolve()
27+
),
28+
),
29+
)
30+
31+
## get reference
32+
ref_h, ref_v = orbit.element_holder.get_bpms("BPM").positions.get().T
33+
reference = np.concat((ref_h, ref_v))
34+
########################################################
35+
36+
37+
## generate some orbit
2238
std_kick = 1e-6
2339
hcorr = ebs.get_magnets("HCorr")
2440
vcorr = ebs.get_magnets("VCorr")
2541
bpms = ebs.get_bpms("BPM")
2642

27-
x0, y0 = bpms.positions.get().T
28-
reference = np.concat([x0, y0])
29-
3043
# mangle orbit
3144
hcorr.strengths.set(
3245
hcorr.strengths.get() + std_kick * np.random.normal(size=len(hcorr))
@@ -41,36 +54,15 @@
4154
"R.m.s. orbit before correction "
4255
f"H: {1e6 * std_bc[0]: .1f} µm, V: {1e6 * std_bc[1]: .1f} µm."
4356
)
57+
########################################################
4458

45-
response_matrix = ResponseMatrix.from_json(parent_folder / Path("ideal_orm.json"))
46-
interface = pySCInterface(element_holder=ebs)
47-
48-
# response_matrix.disable_inputs(["SH3E-C03-V"])
49-
50-
for _ in range(5):
51-
trims = orbit_correction(
52-
interface=interface,
53-
response_matrix=response_matrix,
54-
method="svd_values",
55-
parameter=100,
56-
zerosum=True,
57-
apply=True,
58-
plane="H",
59-
reference=reference,
60-
)
61-
trims = orbit_correction(
62-
interface=interface,
63-
response_matrix=response_matrix,
64-
method="svd_values",
65-
parameter=100,
66-
zerosum=False,
67-
apply=True,
68-
plane="V",
69-
reference=reference,
70-
)
71-
72-
# print("SH3E-C03-V" in trims.keys())
59+
## Correct the orbit
60+
orbit.correct(reference=reference)
61+
# orbit.correct(plane="H")
62+
# orbit.correct(plane="V")
63+
########################################################
7364

65+
## inspect orbit correction
7466
positions_ac = bpms.positions.get()
7567
std_ac = np.std(positions_ac, axis=0)
7668
print(

pyaml/tuning_tools/orbit.py

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
import logging
2+
from pathlib import Path
3+
from typing import List, Literal, Optional
4+
5+
from pydantic import BaseModel, ConfigDict
6+
7+
from ..common.element_holder import ElementHolder
8+
from ..external.pySC import pySC
9+
from ..external.pySC.pySC import ResponseMatrix
10+
from ..external.pySC.pySC.apps import orbit_correction
11+
from ..external.pySC_interface import pySCInterface
12+
13+
logger = logging.getLogger(__name__)
14+
logging.getLogger("pyaml.external.pySC").setLevel(logging.WARNING)
15+
16+
PYAMLCLASS = "Orbit"
17+
18+
19+
class ConfigModel(BaseModel):
20+
model_config = ConfigDict(arbitrary_types_allowed=True, extra="forbid")
21+
22+
bpm_array_name: str
23+
hcorr_array_name: str
24+
vcorr_array_name: str
25+
singular_values: int
26+
response_matrix_file: str
27+
28+
29+
class Orbit(object):
30+
def __init__(self, element_holder: ElementHolder, cfg: ConfigModel):
31+
self._cfg = cfg
32+
33+
self.element_holder = element_holder
34+
self.bpm_array_name = cfg.bpm_array_name
35+
self.hcorr_array_name = cfg.hcorr_array_name
36+
self.vcorr_array_name = cfg.vcorr_array_name
37+
self.singular_values = cfg.singular_values
38+
self.response_matrix = ResponseMatrix.from_json(Path(cfg.response_matrix_file))
39+
40+
def correct(
41+
self,
42+
reference=None,
43+
gain: float = 1.0,
44+
plane: Optional[Literal["H", "V"]] = None,
45+
):
46+
interface = pySCInterface(
47+
element_holder=self.element_holder,
48+
bpm_array_name=self.bpm_array_name,
49+
hcorr_array_name=self.hcorr_array_name,
50+
vcorr_array_name=self.vcorr_array_name,
51+
)
52+
53+
if plane is None or plane == "H":
54+
trims_h = orbit_correction(
55+
interface=interface,
56+
response_matrix=self.response_matrix,
57+
method="svd_values",
58+
parameter=self.singular_values,
59+
zerosum=True,
60+
apply=False,
61+
plane="H",
62+
reference=reference,
63+
)
64+
65+
if plane is None or plane == "V":
66+
trims_v = orbit_correction(
67+
interface=interface,
68+
response_matrix=self.response_matrix,
69+
method="svd_values",
70+
parameter=self.singular_values,
71+
zerosum=False,
72+
apply=False,
73+
plane="V",
74+
reference=reference,
75+
)
76+
77+
# this is now the only place where interface.set_many and get_many are used.
78+
# if we can remove it from here then the pySCInterface will be even simpler.
79+
correctors = self.response_matrix.input_names
80+
data_to_send = interface.get_many(correctors)
81+
if plane is None or plane == "H":
82+
for name in trims_h.keys():
83+
data_to_send[name] += trims_h[name] * gain
84+
if plane is None or plane == "V":
85+
for name in trims_v.keys():
86+
data_to_send[name] += trims_v[name] * gain
87+
88+
interface.set_many(data_to_send)
89+
90+
return

0 commit comments

Comments
 (0)