Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
9d19a41
first draft of pySC interface
kparasch Nov 20, 2025
33e5a46
draft for example to measure ORM. For now it is just testing the inte…
kparasch Nov 20, 2025
51237f1
add pySC as submodule
kparasch Nov 20, 2025
47b5661
example for measurement of ideal response matrix
kparasch Nov 20, 2025
a5e0e44
update to new commit of pySC (fix of a logging bug)
kparasch Nov 20, 2025
55cd9ef
add example for orbit correction
kparasch Nov 20, 2025
c539c2f
object for ORM
kparasch Nov 20, 2025
dc983fa
pySC updates, no need for rich now
kparasch Nov 20, 2025
d15b0b0
save function in orm and a bugfix in input/output names
kparasch Nov 20, 2025
da78bf8
update example by using OrbitResponseMatrix object
kparasch Nov 20, 2025
ea5cc95
update ideal orm data
kparasch Nov 20, 2025
396490a
remove very large file
kparasch Nov 20, 2025
b5a2049
Remove element_holder from OrbitResponseMatrix's ConfigModel
kparasch Nov 21, 2025
eb85763
OrbitResponseMatrix.latest_measurement is now a dictionary (instead o…
kparasch Nov 24, 2025
42d93a5
fix of printing a 'Measured response of None' at initialization
kparasch Nov 25, 2025
c0881e2
save with different types, to discuss later again on saving data
kparasch Nov 25, 2025
65a9817
do relative import pyaml.external.pySC
kparasch Nov 25, 2025
4b473d1
Allow to specify correctors for which to measure response, but fall b…
kparasch Nov 25, 2025
a8bc34d
use parenthesis to split line isntead
kparasch Nov 25, 2025
f000ad8
linting after rebasing
kparasch Nov 25, 2025
4010cd1
fixed formatting
gubaidulinvadim Nov 26, 2025
2f0fede
Correction per plane
kparasch Nov 26, 2025
a60fcb3
comment out some prints
kparasch Nov 26, 2025
e4e009f
dispersion measurement
kparasch Nov 27, 2025
19cd03b
orm and disp ideal measurement + new commit of pySC
kparasch Dec 8, 2025
36cd0bd
orbit object tuning tool for orbit correction
kparasch Dec 8, 2025
59557cc
remove some comments in example
kparasch Dec 8, 2025
fe05bd4
fix pySC commit
kparasch Dec 9, 2025
b937e47
get/set of rf main frequency somehow got removed from interface
kparasch Dec 9, 2025
6968b27
remove unused imports
kparasch Dec 9, 2025
60e130e
logging fix in pySC
kparasch Dec 9, 2025
088ce56
new pySC commit
kparasch Dec 9, 2025
6b00ed2
tests and test_data
kparasch Dec 9, 2025
136b206
submodule update in pyproject.toml
kparasch Dec 9, 2025
f1cf9ca
Revert "submodule update in pyproject.toml"
kparasch Dec 9, 2025
5e25afc
redo the same changes. ruff is doing something weird?
kparasch Dec 9, 2025
4981086
Revert "redo the same changes. ruff is doing something weird?"
kparasch Dec 9, 2025
809260c
add some dependencies and a step in the workflow to hopefully make th…
kparasch Dec 9, 2025
8ee5a57
from ssh to https in the pySC submodule
kparasch Dec 9, 2025
b579ddd
remove pySC from being submodule
kparasch Dec 9, 2025
13f6964
fix conflict in rebase
kparasch Dec 9, 2025
d8a37a7
add matplotlib and h5py installation in the test workflow
kparasch Dec 10, 2025
2902220
relax tolerance in orbit correction test
kparasch Dec 10, 2025
59eade4
make json file not be 370 thousand lines
kparasch Dec 10, 2025
01cf9f0
wrong file was added in previous commit
kparasch Dec 10, 2025
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
3 changes: 3 additions & 0 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,13 @@ jobs:
- name: Install dependencies
run: |
python -m pip install --upgrade pip
git submodule update --init --recursive
pip install numpy
pip install scipy
pip install pydantic
pip install accelerator-toolbox
pip install matplotlib
pip install h5py
pip install pyaml
pip install flake8 pytest
if [ -f requirements.txt ]; then pip install -r requirements.txt; fi
Expand Down
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[submodule "pyaml/external/pySC"]
path = pyaml/external/pySC
url = https://github.com/kparasch/pySC.git
92 changes: 92 additions & 0 deletions examples/ESRF_ORM_example/correct_orbit.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
import json
import logging
from pathlib import Path

import matplotlib.pyplot as plt
import numpy as np

from pyaml.accelerator import Accelerator
from pyaml.tuning_tools.orbit import ConfigModel as Orbit_ConfigModel
from pyaml.tuning_tools.orbit import Orbit

parent_folder = Path(__file__).parent
pyaml_folder = parent_folder.parent.parent
config_path = pyaml_folder.joinpath("tests/config/EBSOrbit.yaml").resolve()
sr = Accelerator.load(config_path)
ebs = sr.design

orbit = Orbit(
element_holder=ebs,
cfg=Orbit_ConfigModel(
bpm_array_name="BPM",
hcorr_array_name="HCorr",
vcorr_array_name="VCorr",
singular_values=162,
response_matrix_file=str(
pyaml_folder.joinpath("examples/ESRF_ORM_example/ideal_orm.json").resolve()
),
),
)

## get reference
ref_h, ref_v = orbit.element_holder.get_bpms("BPM").positions.get().T
reference = np.concat((ref_h, ref_v))
########################################################


## generate some orbit
std_kick = 1e-6
hcorr = ebs.get_magnets("HCorr")
vcorr = ebs.get_magnets("VCorr")
bpms = ebs.get_bpms("BPM")

# mangle orbit
hcorr.strengths.set(
hcorr.strengths.get() + std_kick * np.random.normal(size=len(hcorr))
)
vcorr.strengths.set(
vcorr.strengths.get() + std_kick * np.random.normal(size=len(vcorr))
)

positions_bc = bpms.positions.get()
std_bc = np.std(positions_bc, axis=0)
print(
"R.m.s. orbit before correction "
f"H: {1e6 * std_bc[0]: .1f} µm, V: {1e6 * std_bc[1]: .1f} µm."
)
########################################################

## Correct the orbit
orbit.correct(reference=reference)
# orbit.correct(plane="H")
# orbit.correct(plane="V")
########################################################

## inspect orbit correction
positions_ac = bpms.positions.get()
std_ac = np.std(positions_ac, axis=0)
print(
"R.m.s. orbit after correction H: "
f"{1e6 * std_ac[0]: .1f} µm, V: {1e6 * std_ac[1]: .1f} µm,"
)

fig = plt.figure()
ax1 = fig.add_subplot(311)
ax2 = fig.add_subplot(312)
ax3 = fig.add_subplot(313)
ax1.plot(positions_bc[:, 0] * 1e6, label="Orbit before correction")
ax2.plot(positions_bc[:, 1] * 1e6, label="Orbit before correction")
ax1.plot(positions_ac[:, 0] * 1e6, label="Orbit after correction")
ax2.plot(positions_ac[:, 1] * 1e6, label="Orbit after correction")

ax3.plot(hcorr.strengths.get())
ax3.plot(vcorr.strengths.get())

ax1.set_ylabel("Horizontal pos. [μm]")
ax2.set_ylabel("Vertical pos. [μm]")
ax2.set_xlabel("BPM number")
ax3.set_ylabel("Strength (rad)")
ax3.set_xlabel("Steerer number")
fig.tight_layout()

plt.show()
32 changes: 32 additions & 0 deletions examples/ESRF_ORM_example/esrf_orm_example.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
from pathlib import Path

import numpy as np

from pyaml.accelerator import Accelerator
from pyaml.external.pySC_interface import pySCInterface

config_path = (
Path(__file__)
.parent.parent.parent.joinpath("tests", "config", "EBSOrbit.yaml")
.resolve()
)
sr = Accelerator.load(config_path)

live_h = sr.live.get_bpms("BPM").h.get() # ok
design_h = sr.design.get_bpms("BPM").h.get() # ok

interface = pySCInterface(element_holder=sr.design)

orbit_x, orbit_y = interface.get_orbit()

one_hcorr = interface.hcorr_names[10]

sp0 = interface.get(one_hcorr)
interface.set(one_hcorr, sp0 + 10e-6)

hcorr_setpoints = interface.get_many(interface.hcorr_names)
interface.set_many(hcorr_setpoints)

orbit_x2, orbit_y2 = interface.get_orbit()

print(np.std(orbit_x2 - orbit_x))
31 changes: 31 additions & 0 deletions examples/ESRF_ORM_example/measure_dispersion.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
from pathlib import Path

import matplotlib.pyplot as plt

from pyaml.accelerator import Accelerator
from pyaml.tuning_tools.dispersion import ConfigModel as Disp_ConfigModel
from pyaml.tuning_tools.dispersion import Dispersion

parent_folder = Path(__file__).parent
config_path = parent_folder.parent.parent.joinpath(
"tests", "config", "EBSOrbit.yaml"
).resolve()
sr = Accelerator.load(config_path)
element_holder = sr.design

dispersion = Dispersion(
cfg=Disp_ConfigModel(
bpm_array_name="BPM",
rf_plant_name="RF",
frequency_delta=10,
),
element_holder=element_holder,
)

dispersion.measure()
dispersion_data = dispersion.get()

fig = plt.figure()
ax = fig.add_subplot(111)
ax.plot(dispersion_data["frequency_response_x"])
plt.show()
29 changes: 29 additions & 0 deletions examples/ESRF_ORM_example/measure_ideal_ORM.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
from pathlib import Path

from pyaml.accelerator import Accelerator
from pyaml.tuning_tools.orbit_response_matrix import ConfigModel as ORM_ConfigModel
from pyaml.tuning_tools.orbit_response_matrix import OrbitResponseMatrix

parent_folder = Path(__file__).parent
config_path = parent_folder.parent.parent.joinpath(
"tests", "config", "EBSOrbit.yaml"
).resolve()
sr = Accelerator.load(config_path)
element_holder = sr.design

orm = OrbitResponseMatrix(
cfg=ORM_ConfigModel(
bpm_array_name="BPM",
hcorr_array_name="HCorr",
vcorr_array_name="VCorr",
corrector_delta=1e-6,
),
element_holder=element_holder,
)

orm.measure()
orm.save(parent_folder / Path("ideal_orm.json"))
orm.save(parent_folder / Path("ideal_orm.yaml"), with_type="yaml")
orm.save(parent_folder / Path("ideal_orm.npz"), with_type="npz")

ormdata = orm.get()
55 changes: 55 additions & 0 deletions examples/ESRF_ORM_example/measure_ideal_ORM_and_disp.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import json
from pathlib import Path

import numpy as np

from pyaml.accelerator import Accelerator
from pyaml.tuning_tools.dispersion import ConfigModel as Disp_ConfigModel
from pyaml.tuning_tools.dispersion import Dispersion
from pyaml.tuning_tools.orbit_response_matrix import ConfigModel as ORM_ConfigModel
from pyaml.tuning_tools.orbit_response_matrix import OrbitResponseMatrix

parent_folder = Path(__file__).parent
config_path = parent_folder.parent.parent.joinpath(
"tests", "config", "EBSOrbit.yaml"
).resolve()
sr = Accelerator.load(config_path)
element_holder = sr.design

orm = OrbitResponseMatrix(
cfg=ORM_ConfigModel(
bpm_array_name="BPM",
hcorr_array_name="HCorr",
vcorr_array_name="VCorr",
corrector_delta=1e-6,
),
element_holder=element_holder,
)

orm.measure()

orm_data = orm.get()

dispersion = Dispersion(
cfg=Disp_ConfigModel(
bpm_array_name="BPM",
rf_plant_name="RF",
frequency_delta=10,
),
element_holder=element_holder,
)

dispersion.measure()
dispersion_data = dispersion.get()
rf_response = (
dispersion_data["frequency_response_x"] + dispersion_data["frequency_response_y"]
)

ideal_ORM_data = {
"matrix": orm_data["matrix"],
"input_names": orm_data["input_names"],
"output_names": orm_data["output_names"],
"rf_response": rf_response,
}

json.dump(ideal_ORM_data, open("ideal_orm_disp.json", "w"), indent=4)
38 changes: 38 additions & 0 deletions examples/ESRF_ORM_example/measure_reduced_ORM.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
from pathlib import Path

from pyaml.accelerator import Accelerator
from pyaml.tuning_tools.orbit_response_matrix import ConfigModel as ORM_ConfigModel
from pyaml.tuning_tools.orbit_response_matrix import OrbitResponseMatrix

parent_folder = Path(__file__).parent
config_path = parent_folder.parent.parent.joinpath(
"tests", "config", "EBSOrbit.yaml"
).resolve()
sr = Accelerator.load(config_path)
element_holder = sr.design

orm = OrbitResponseMatrix(
cfg=ORM_ConfigModel(
bpm_array_name="BPM",
hcorr_array_name="HCorr",
vcorr_array_name="VCorr",
corrector_delta=1e-6,
),
element_holder=element_holder,
)

hcorr = element_holder.get_magnets("HCorr")
vcorr = element_holder.get_magnets("VCorr")
corrector_names = (
hcorr["SJ2A*"].names()
+ hcorr["SF2A*"].names()
+ hcorr["SI2A*"].names()
+ vcorr["SJ2A*"].names()
+ vcorr["SF2A*"].names()
+ vcorr["SI2A*"].names()
)

orm.measure(corrector_names=corrector_names)
orm.save(parent_folder / Path("reduced_orm.json"))

ormdata = orm.get()
1 change: 1 addition & 0 deletions pyaml/external/pySC
Submodule pySC added at f509fe
Loading
Loading