Skip to content

Commit b68dfe8

Browse files
Update ID lookup with type checking (#1707)
* add i09 look up table praiser * move get_poly to lookuptable * extracted EnergyMotorLookup base class from i10EnergyMotorLookup * added new make_phase_tables function * add test for correct table output * remove_i09 * add docstring * add test for helper functions * add test for skipping * spacing fix * Refactor Lookuptable class documentation Removed outdated docstring from Lookuptable class and updated initialization docstring for I10EnergyMotorLookup class. * change lookup table schema to snake case * replace dictionary with basemodel * add tying * add gap and phase * fat finger correction * Update ID lookup logic to use type checking * Fix some tests * Improve models to not use shared defaults * undo syntax error * Fixed test to check for success on loading i10 lut * Simplified lut logic * Added back generate_lookup_table function * Fixed all tests but polarisation * Updated doc strings * Moved generic test from i10 to test_lookup_table_apple2 * Renamed lut_column_config to lut_config * Updated more doc strings * Fix default phase_file name and thus tests * Use Pol in LookupTable rather than string * Updated test_convert_csv_to_lookup_overwrite_name_convert_default to use Pol * Update tests to use Pol rather str value * Improve EnergyCoverageEntry to have a poly serializer and EnergyCoverage to use float as key * Add type checking to i10Apple2 phase * Removed commente out code * Fixed poly test * Fixed test_make_phase_tables_multiple_entries * Added test_lookup_table_is_serialisable * Update src/dodal/devices/util/lookup_tables_apple2.py Co-authored-by: Raymond Fan <[email protected]> --------- Co-authored-by: Relm-Arrowny <[email protected]>
1 parent bdebc72 commit b68dfe8

File tree

6 files changed

+397
-397
lines changed

6 files changed

+397
-397
lines changed

src/dodal/beamlines/i10_optics.py

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,10 @@
3434
from dodal.devices.i10.i10_setting_data import I10Grating
3535
from dodal.devices.pgm import PlaneGratingMonochromator
3636
from dodal.devices.synchrotron import Synchrotron
37+
from dodal.devices.util.lookup_tables_apple2 import (
38+
LookupPath,
39+
LookupTableConfig,
40+
)
3741
from dodal.log import set_beamline as set_log_beamline
3842
from dodal.utils import BeamlinePrefix, get_beamline_name
3943

@@ -117,9 +121,10 @@ def idd_controller() -> I10Apple2Controller:
117121
"""I10 downstream insertion device controller."""
118122
return I10Apple2Controller(
119123
apple2=idd(),
120-
lookuptable_dir=LOOK_UPTABLE_DIR,
121-
source=("Source", "idd"),
122124
config_client=I10_CONF_CLIENT,
125+
lut_config=LookupTableConfig(
126+
source=("Source", "idd"), path=LookupPath.create(LOOK_UPTABLE_DIR)
127+
),
123128
)
124129

125130

@@ -181,9 +186,10 @@ def idu_controller() -> I10Apple2Controller:
181186
"""I10 upstream insertion device controller."""
182187
return I10Apple2Controller(
183188
apple2=idu(),
184-
lookuptable_dir=LOOK_UPTABLE_DIR,
185-
source=("Source", "idu"),
186189
config_client=I10_CONF_CLIENT,
190+
lut_config=LookupTableConfig(
191+
source=("Source", "idu"), path=LookupPath.create(LOOK_UPTABLE_DIR)
192+
),
187193
)
188194

189195

src/dodal/devices/apple2_undulator.py

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -217,10 +217,7 @@ def __init__(self, prefix: str, infix: str, name: str = ""):
217217

218218

219219
class UndulatorLockedPhaseAxes(SafeUndulatorMover[Apple2PhaseValType]):
220-
"""
221-
Two phase Motor to make up the locked id phase motion.
222-
223-
"""
220+
"""Two phase Motor to make up the locked id phase motion."""
224221

225222
def __init__(
226223
self,

src/dodal/devices/i10/i10_apple2.py

Lines changed: 31 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,8 @@
2424
UndulatorPhaseAxes,
2525
)
2626
from dodal.devices.util.lookup_tables_apple2 import (
27-
EnergyMotorLookup,
28-
Lookuptable,
27+
BaseEnergyMotorLookup,
28+
LookupTableConfig,
2929
convert_csv_to_lookup,
3030
)
3131
from dodal.log import LOGGER
@@ -37,80 +37,38 @@
3737
ALPHA_OFFSET = 180
3838

3939

40-
class I10EnergyMotorLookup(EnergyMotorLookup):
40+
class I10EnergyMotorLookup(BaseEnergyMotorLookup):
4141
"""
4242
Handles lookup tables for I10 Apple2 ID, converting energy and polarisation to gap
43-
and phase. Fetches and parses lookup tables from a config server, supports dynamic
44-
updates, and validates input.
43+
and phase. Fetches and parses lookup tables from a config server, supports dynamic
44+
updates, and validates input.
4545
"""
4646

47-
def __init__(
48-
self,
49-
lookuptable_dir: str,
50-
source: tuple[str, str],
51-
config_client: ConfigServer,
52-
mode: str = "Mode",
53-
min_energy: str = "MinEnergy",
54-
max_energy: str = "MaxEnergy",
55-
gap_file_name: str = "IDEnergy2GapCalibrations.csv",
56-
phase_file_name: str = "IDEnergy2PhaseCalibrations.csv",
57-
poly_deg: list | None = None,
58-
):
59-
"""Initialise the I10EnergyMotorLookup class with lookup table headers provided.
60-
61-
Parameters
62-
----------
63-
look_up_table_dir:
64-
The path to look up table.
65-
source:
66-
The column name and the name of the source in look up table. e.g. ( "source", "idu")
67-
config_client:
68-
The config server client to fetch the look up table.
69-
mode:
70-
The column name of the mode in look up table.
71-
min_energy:
72-
The column name that contain the maximum energy in look up table.
73-
max_energy:
74-
The column name that contain the maximum energy in look up table.
75-
poly_deg:
76-
The column names for the parameters for the energy conversion polynomial, starting with the least significant.
77-
78-
"""
79-
super().__init__(
80-
lookuptable_dir=lookuptable_dir,
81-
config_client=config_client,
82-
mode=mode,
83-
source=source,
84-
min_energy=min_energy,
85-
max_energy=max_energy,
86-
gap_file_name=gap_file_name,
87-
phase_file_name=phase_file_name,
88-
poly_deg=poly_deg,
89-
)
90-
9147
def update_lookuptable(self):
9248
"""
9349
Update lookup tables from files and validate their format.
9450
"""
95-
LOGGER.info("Updating lookup dictionary from file.")
96-
for key, path in self.lookup_table_config.path.__dict__.items():
97-
csv_file = self.config_client.get_file_contents(
98-
path, reset_cached_result=True
99-
)
100-
self.lookup_tables[key] = convert_csv_to_lookup(
101-
file=csv_file,
102-
source=self.lookup_table_config.source,
103-
mode=self.lookup_table_config.mode,
104-
min_energy=self.lookup_table_config.min_energy,
105-
max_energy=self.lookup_table_config.max_energy,
106-
poly_deg=self.lookup_table_config.poly_deg,
107-
)
108-
Lookuptable.model_validate(self.lookup_tables[key])
51+
LOGGER.info("Updating lookup dictionary from file for gap.")
52+
gap_csv_file = self.config_client.get_file_contents(
53+
self.lut_config.path.gap, reset_cached_result=True
54+
)
55+
self.lookup_tables.gap = convert_csv_to_lookup(
56+
file_contents=gap_csv_file, lut_config=self.lut_config
57+
)
58+
self.available_pol = list(self.lookup_tables.gap.root.keys())
59+
60+
LOGGER.info("Updating lookup dictionary from file for phase.")
61+
phase_csv_file = self.config_client.get_file_contents(
62+
self.lut_config.path.phase, reset_cached_result=True
63+
)
64+
self.lookup_tables.phase = convert_csv_to_lookup(
65+
file_contents=phase_csv_file, lut_config=self.lut_config
66+
)
10967

110-
self.available_pol = list(self.lookup_tables["gap"].keys())
11168

69+
class I10Apple2(Apple2[UndulatorPhaseAxes]):
70+
"""I10Apple2 device is an apple2 with extra jaw phase motor."""
11271

113-
class I10Apple2(Apple2):
11472
def __init__(
11573
self,
11674
id_gap: UndulatorGap,
@@ -119,11 +77,8 @@ def __init__(
11977
name: str = "",
12078
) -> None:
12179
"""
122-
I10Apple2 device is an apple2 with extra jaw phase motor.
123-
124-
Parameters
125-
----------
126-
80+
Parameters:
81+
------------
12782
id_gap : UndulatorJawPhase
12883
The gap motor of the undulator.
12984
id_phase : UndulatorJawPhase
@@ -147,26 +102,22 @@ class I10Apple2Controller(Apple2Controller[I10Apple2]):
147102
def __init__(
148103
self,
149104
apple2: I10Apple2,
150-
lookuptable_dir: str,
151-
source: tuple[str, str],
152105
config_client: ConfigServer,
106+
lut_config: LookupTableConfig,
153107
jaw_phase_limit: float = 12.0,
154108
jaw_phase_poly_param: list[float] = DEFAULT_JAW_PHASE_POLY_PARAMS,
155109
angle_threshold_deg=30.0,
156110
name: str = "",
157111
) -> None:
158112
"""
159-
160-
parameters
161-
----------
113+
Parameters:
114+
-----------
162115
apple2 : I10Apple2
163116
An I10Apple2 device.
164-
lookuptable_dir : str
165-
The path to look up table.
166-
source : tuple[str, str]
167-
The column name and the name of the source in look up table. e.g. ( "source", "idu")
168117
config_client : ConfigServer
169118
The config server client to fetch the look up table.
119+
lut_config:
120+
Configuration that defines where the lookup table is and how to read it.
170121
jaw_phase_limit : float, optional
171122
The maximum allowed jaw_phase movement., by default 12.0
172123
jaw_phase_poly_param : list[float], optional
@@ -178,8 +129,7 @@ def __init__(
178129
"""
179130

180131
self.lookup_table_client = I10EnergyMotorLookup(
181-
lookuptable_dir=lookuptable_dir,
182-
source=source,
132+
lut_config=lut_config,
183133
config_client=config_client,
184134
)
185135
super().__init__(

0 commit comments

Comments
 (0)