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
18 changes: 9 additions & 9 deletions examples/BESSY2_example/BESSY2Chroma.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ simulators:
name: design
controls:
- type: pyaml_cs_oa.controlsystem
prefix: 'a3744:'
prefix: 'pons:'
name: live
data_folder: /data/store
devices:
Expand All @@ -24,15 +24,15 @@ devices:
unit: ''
- type: pyaml.diagnostics.chromaticity_monitor
name: KSI
betatron_tune: BETATRON_TUNE
RFfreq: RF
betatron_tune_name: BETATRON_TUNE
rf_plant_name: RF
fit_order: 2
N_tune_meas: 1
N_step: 5
Sleep_between_meas: 2
Sleep_between_RFvar: 2
E_delta: 1e-3
Max_E_delta: 1e-3
n_avg_meas: 1
n_step: 5
sleep_between_meas: 2
sleep_between_step: 2
e_delta: 1e-3
max_e_delta: 1e-3
- type: pyaml.rf.rf_plant
name: RF
masterclock:
Expand Down
2 changes: 1 addition & 1 deletion examples/BESSY2_example/BESSY2Orbit.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ simulators:
name: design
controls:
- type: pyaml_cs_oa.controlsystem
prefix: "a3744:"
prefix: "pons:"
name: live
data_folder: /data/store
arrays:
Expand Down
13 changes: 9 additions & 4 deletions examples/BESSY2_example/BESSY2Tune.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ simulators:
name: design
controls:
- type: pyaml_cs_oa.controlsystem
prefix: 'a3744:'
prefix: 'pons:'
name: live
data_folder: /data/store
arrays:
Expand Down Expand Up @@ -892,6 +892,11 @@ devices:
unit: ''
- type: pyaml.tuning_tools.tune
name: DEFAULT_TUNE_CORRECTION
quad_array: QForTune
betatron_tune: BETATRON_TUNE
delta: 1e-4
quad_array_name: QForTune
betatron_tune_name: BETATRON_TUNE
response_matrix: file:trm.json
- type: pyaml.tuning_tools.tune_response_matrix
name: DEFAULT_TUNE_RESPONSE_MATRIX
quad_array_name: QForTune
betatron_tune_name: BETATRON_TUNE
quad_delta: 1e-4
8 changes: 4 additions & 4 deletions examples/BESSY2_example/bessy2-chroma.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
import numpy as np

from pyaml.accelerator import Accelerator
from pyaml.common.constants import ACTION_MEASURE
from pyaml.common.constants import Action

# ----- Load the configuration -----
# Remember to change the prefix for the live mode to the one matching
Expand All @@ -22,9 +22,9 @@
# This callback is used to print output during the chromaticity measurement.


def chroma_callback(step: int, action: int, rf: float, tune: np.array):
if action == ACTION_MEASURE:
print(f"Chromaticy measurement: #{step} RF={rf} Tune={tune}")
def chroma_callback(action: int, cb_data: dict):
if action == Action.MEASURE:
print(f"Chromaticy measurement: #{cb_data['step']} RF={cb_data['rf']} Tune={cb_data['tune']}")
return True


Expand Down
27 changes: 5 additions & 22 deletions examples/BESSY2_example/bessy2-orbit.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,7 @@
import numpy as np

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
from pyaml.tuning_tools.orbit_response_matrix_data import OrbitResponseMatrixData

# ----- Load the configuration -----
# Remember to change the prefix for the live mode to the one matching your virtual
Expand All @@ -34,26 +33,10 @@

# if the ORM is not present measure it
if sr.design.orbit.response_matrix is None:
SR.orm.measure(set_wait_time=0.0 if SR == sr.design else 2.0)
orm_data = SR.orm.get()

# Save the data to json
ORM_data = {
"type": "pyaml.tuning_tools.response_matrix",
"matrix": orm_data["matrix"],
"input_names": orm_data["input_names"],
"output_names": orm_data["output_names"],
"input_planes": orm_data["input_planes"],
"output_planes": orm_data["output_planes"],
}
json.dump(ORM_data, open("orm.json", "w"))

# ----- Load the response matrix -----
# The example does the correction for the live mode but it can also be done on the
# design mode.

# Load the ORM for the live mode
sr.live.orbit.load_response_matrix("orm.json")
SR.orm.measure(sleep_between_step=0.0 if SR == sr.design else 2.0)
SR.orm.save("orm.json")
# Load it on live
sr.live.orbit.load("orm.json")

# ----- Correct the orbit -----

Expand Down
25 changes: 10 additions & 15 deletions examples/BESSY2_example/bessy2-tune.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
import numpy as np

from pyaml.accelerator import Accelerator
from pyaml.common.constants import ACTION_MEASURE
from pyaml.common.constants import Action
from pyaml.magnet.magnet import Magnet

# ----- Load the configuration -----
Expand All @@ -25,10 +25,10 @@
# This callback is used to print output during the tune response measurement.


def tune_callback(step: int, action: int, m: Magnet, dtune: np.array):
if action == ACTION_MEASURE:
def tune_callback(action: int, cb_data: dict):
if action == Action.MEASURE:
# On action measure, the measured dq / dk is passed as argument
print(f"Tune response: #{step} {m.get_name()} {dtune}")
print(f"Tune response: #{cb_data['step']} {cb_data['magnet']} {cb_data['tune']}")
return True


Expand All @@ -40,17 +40,12 @@ def tune_callback(step: int, action: int, m: Magnet, dtune: np.array):
# Choose which backend to use.
SR = sr.design

tune_adjust = sr.design.tune
tune_adjust.response.measure(
callback=tune_callback, set_wait_time=0.0 if SR == sr.design else 2.0
)
tune_adjust.response.save_json("tune-response.json")

# ----- Load the response matrix -----
# The example does the correction for the live mode but it can also be done
# on the design mode.

sr.live.tune.response.load_json("tune-response.json")
# if the TRM is not present measure it
if sr.design.tune.response_matrix is None:
SR.trm.measure(sleep_between_step=0.0 if SR == sr.design else 2.0, callback=tune_callback)
SR.trm.save("trm.json")
# Load it on live
sr.live.tune.load("trm.json")

# ----- Correct the tune -----

Expand Down
7 changes: 7 additions & 0 deletions pyaml/tuning_tools/chromaticity.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,13 @@ def __init__(self, cfg: ConfigModel):
# TODO: Initialise first setpoint
self._setpoint = np.array([np.nan, np.nan])

@property
def response_matrix(self) -> ResponseMatrixData | None:
"""
Return the response matrix if it has been loaded None otherwise
"""
return self._cfg.response_matrix

def load(self, load_path: Path):
"""
Dyanmically loads a response matrix.
Expand Down
1 change: 1 addition & 0 deletions pyaml/tuning_tools/chromaticity_response_matrix.py
Original file line number Diff line number Diff line change
Expand Up @@ -212,5 +212,6 @@ def callback(action: Action, data:dict):
observable_names=[cm.get_name() + ".x", cm.get_name() + ".y"],
)
self.latest_measurement.update(mat.model_dump())
self.latest_measurement["type"] = "pyaml.tuning_tools.response_matrix_data"

return True
35 changes: 27 additions & 8 deletions pyaml/tuning_tools/orbit.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,25 +75,44 @@ def __init__(self, cfg: ConfigModel):
try:
cfg.response_matrix = OrbitResponseMatrixData.load(cfg.response_matrix)
except Exception as e:
logger.warning(f"{str(e)}")
logger.warning(f"Loading {cfg.response_matrix} failed {str(e)}")
cfg.response_matrix = None

# Converts to self._pySC_response_matrix
if cfg.response_matrix:
m = cfg.response_matrix._cfg.model_dump()
m["input_names"] = m.pop("variable_names")
m["output_names"] = m.pop("observable_names")
m["input_planes"] = m.pop("variable_planes")
m["output_planes"] = m.pop("observable_planes")
self._pySC_response_matrix = pySC_ResponseMatrix.model_validate(m)
self._set_response_matrix(cfg.response_matrix)

self._hcorr: MagnetArray = None
self._vcorr: MagnetArray = None
self._hvcorr: MagnetArray = None
self._rf_plant: RFPlant = None

def load(self, load_path: Path):
"""
Dynamically loads a response matrix.

Parameters
----------
load_path : Path
Filename of the :class:`~.OrbitResponseMatrixData` to load
"""
self._cfg.response_matrix = OrbitResponseMatrixData.load(load_path)
self._set_response_matrix(self._cfg.response_matrix)

def _set_response_matrix(self, mat):
m = mat._cfg.model_dump()
m["input_names"] = m.pop("variable_names")
m["output_names"] = m.pop("observable_names")
m["input_planes"] = m.pop("variable_planes")
m["output_planes"] = m.pop("observable_planes")
self._cfg.response_matrix = mat
self._pySC_response_matrix = pySC_ResponseMatrix.model_validate(m)

@property
def reponse_matrix(self) -> OrbitResponseMatrixData | None:
def response_matrix(self) -> OrbitResponseMatrixData | None:
"""
Return the response matrix if it has been loaded None otherwise
"""
return self._cfg.response_matrix

def correct(
Expand Down
1 change: 1 addition & 0 deletions pyaml/tuning_tools/orbit_response_matrix.py
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,7 @@ def measure(

orm_data = self._pySC_response_data_to_ORMData(measurement.response_data.model_dump())
self.latest_measurement.update(orm_data.model_dump())
self.latest_measurement["type"] = "pyaml.tuning_tools.orbit_response_matrix_data"

def _pySC_response_data_to_ORMData(self, data: dict) -> OrbitResponseMatrixDataConfigModel:
# all metadata is discarded here. Should we keep something?
Expand Down
2 changes: 1 addition & 1 deletion pyaml/tuning_tools/response_matrix_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ def __init__(self, cfg: ConfigModel):
self._cfg = cfg

@staticmethod
def load(filename: str) -> None:
def load(filename: str) -> "ResponseMatrixData":
"""
Load a reponse matrix from a configuration file
"""
Expand Down
9 changes: 8 additions & 1 deletion pyaml/tuning_tools/tune.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ def __init__(self, cfg: ConfigModel):

def load(self, load_path: Path):
"""
Dyanmically loads a response matrix.
Dynamically loads a response matrix.

Parameters
----------
Expand All @@ -94,6 +94,13 @@ def load(self, load_path: Path):
self._response_matrix = np.array(self._cfg.response_matrix._cfg.matrix)
self._correctionmat = np.linalg.pinv(self._response_matrix)

@property
def response_matrix(self) -> ResponseMatrixData | None:
"""
Return the response matrix if it has been loaded None otherwise
"""
return self._cfg.response_matrix

@property
def _tm(self) -> "BetatronTuneMonitor":
self.check_peer()
Expand Down
1 change: 1 addition & 0 deletions pyaml/tuning_tools/tune_response_matrix.py
Original file line number Diff line number Diff line change
Expand Up @@ -199,5 +199,6 @@ def callback(action: Action, data:dict):
observable_names=[tm.get_name() + ".x", tm.get_name() + ".y"],
)
self.latest_measurement.update(mat.model_dump())
self.latest_measurement["type"] = "pyaml.tuning_tools.response_matrix_data"

return True
Loading