Skip to content
Draft
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
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ dependencies = [
"scanspec>=0.7.3",
"pyzmq==26.3.0", # Until we can move to RHEL 8 https://github.com/DiamondLightSource/mx-bluesky/issues/1139
"deepdiff",
"daq-config-server>=v1.0.0-rc.2", # For getting Configuration settings.
"daq-config-server>=v1.1.2", # For getting Configuration settings.
]

dynamic = ["version"]
Expand Down
10 changes: 8 additions & 2 deletions src/dodal/devices/detector/det_dist_to_beam_converter.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
from enum import Enum

from daq_config_server.client import ConfigServer
from daq_config_server.models import DetectorXYLookupTable

from dodal.devices.util.lookup_tables import (
linear_extrapolation_lut,
parse_lookup_table,
)


Expand All @@ -14,7 +16,11 @@ class Axis(Enum):
class DetectorDistanceToBeamXYConverter:
def __init__(self, lookup_file: str):
self.lookup_file: str = lookup_file
lookup_table_columns: list = parse_lookup_table(self.lookup_file)
config_server = ConfigServer(url="https://daq-config.diamond.ac.uk")

lookup_table_columns: list = config_server.get_file_contents(
lookup_file, DetectorXYLookupTable
).columns
self._d_to_x = linear_extrapolation_lut(
lookup_table_columns[0], lookup_table_columns[1]
)
Expand Down
30 changes: 30 additions & 0 deletions tests/conftest.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
import importlib
import json
import os
from collections.abc import AsyncGenerator
from pathlib import Path
from types import ModuleType
from unittest.mock import patch

import pytest
from daq_config_server.models import ConfigModel
from ophyd_async.core import init_devices, set_mock_value

from conftest import mock_attributes_table
Expand Down Expand Up @@ -88,3 +90,31 @@ async def baton_in_commissioning_mode() -> AsyncGenerator[Baton]:
set_mock_value(baton.commissioning, True)
yield baton
set_commissioning_signal(None)


def _fake_config_server_get_file_contents(
filepath: str | Path,
desired_return_type: type[str] | type[dict] | ConfigModel = str,
reset_cached_result: bool = True,
):
filepath = Path(filepath)
# Minimal logic required for unit tests
with filepath.open("r") as f:
contents = f.read()
if desired_return_type is str:
return contents
elif desired_return_type is dict:
return json.loads(contents)
elif issubclass(desired_return_type, ConfigModel): # type: ignore
return desired_return_type.model_validate(json.loads(contents))


@pytest.fixture(autouse=True)
def mock_config_server():
# Don't actually talk to central service during unit tests, and reset caches between test

with patch(
"daq_config_server.client.ConfigServer.get_file_contents",
side_effect=_fake_config_server_get_file_contents,
):
yield
14 changes: 7 additions & 7 deletions tests/devices/detector/test_data/test_det_dist_converter.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#Table giving position of beam X and Y as a function of detector distance
#Units mm mm mm
# Eiger values
# distance beamY beamX (values from mosflm)
Units mm mm mm
200 153.61 162.45
500 153.57 159.96
{
"column_names": ["detector_distances_mm", "beam_centre_x_mm", "beam_centre_y_mm"],
"rows": [
[200.0, 153.61, 162.45],
[500.0, 153.57, 159.96]
]
}
14 changes: 4 additions & 10 deletions tests/devices/detector/test_detector.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,14 +46,14 @@ def test_if_path_provided_check_is_dir(tmp_path: Path):


@patch(
"dodal.devices.detector.det_dist_to_beam_converter.parse_lookup_table",
"dodal.devices.detector.det_dist_to_beam_converter.ConfigServer",
)
@patch(
"dodal.devices.detector.det_dist_to_beam_converter.linear_extrapolation_lut",
MagicMock(),
)
def test_correct_det_dist_to_beam_converter_path_passed_in(
mocked_parse_table, tmp_path: Path
mocked_config_server, tmp_path: Path
):
params = DetectorParams(
expected_energy_ev=100,
Expand All @@ -73,10 +73,7 @@ def test_correct_det_dist_to_beam_converter_path_passed_in(
assert params.beam_xy_converter.lookup_file == "a fake directory"


@patch(
"dodal.devices.detector.det_dist_to_beam_converter.parse_lookup_table",
)
def test_run_number_correct_when_not_specified(mocked_parse_table, tmp_path):
def test_run_number_correct_when_not_specified(tmp_path):
params = DetectorParams(
expected_energy_ev=100,
exposure_time_s=1.0,
Expand All @@ -94,10 +91,7 @@ def test_run_number_correct_when_not_specified(mocked_parse_table, tmp_path):
assert params.run_number == 1


@patch(
"dodal.devices.detector.det_dist_to_beam_converter.parse_lookup_table",
)
def test_run_number_correct_when_specified(mocked_parse_table, tmp_path):
def test_run_number_correct_when_specified(tmp_path):
params = DetectorParams(
expected_energy_ev=100,
exposure_time_s=1.0,
Expand Down
10 changes: 4 additions & 6 deletions tests/devices/test_beam_converter.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,25 +2,23 @@
from unittest.mock import Mock, patch

import pytest
from daq_config_server.models import DetectorXYLookupTable

from dodal.devices.detector.det_dist_to_beam_converter import (
Axis,
DetectorDistanceToBeamXYConverter,
)

# fmt: off
LOOKUP_TABLE_TEST_VALUES = [
(100.0, 200.0), # distance
(150.0, 151.0), # x
(160.0, 165.0), # y
]
LOOKUP_TABLE_TEST_VALUES = DetectorXYLookupTable(rows=[[100.0, 150.0, 160.0], [200.0, 151.0, 165.0]])

# fmt: on


@pytest.fixture
def fake_converter():
with patch(
"dodal.devices.detector.det_dist_to_beam_converter.parse_lookup_table",
"dodal.devices.detector.det_dist_to_beam_converter.ConfigServer.get_file_contents",
return_value=LOOKUP_TABLE_TEST_VALUES,
):
yield DetectorDistanceToBeamXYConverter("test.txt")
Expand Down
11 changes: 6 additions & 5 deletions tests/devices/test_data/test_lookup_table.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# Beam converter lookup table for testing

Units det_dist beam_x beam_y
100.0 150.0 160.0
200.0 151.0 165.0
{
"rows": [
[100.0, 150.0, 160.0],
[200.0, 151.0, 165.0]
]
}
15 changes: 0 additions & 15 deletions tests/devices/util/test_lookup_tables.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,6 @@
linear_interpolation_lut,
parse_lookup_table,
)
from tests.devices.detector.test_data import (
TEST_DET_DIST_CONVERTER_LUT,
)
from tests.devices.test_data import (
TEST_BEAMLINE_UNDULATOR_TO_GAP_LUT,
)
Expand All @@ -27,18 +24,6 @@ async def test_energy_to_distance_table_correct_format():
assert table.shape == (50, 2)


@mark.parametrize(
"lut_path, num_columns",
[(TEST_BEAMLINE_DCM_ROLL_CONVERTER_TXT, 2), (TEST_DET_DIST_CONVERTER_LUT, 3)],
)
def test_parse_lookup_table_returns_list_of_the_same_length_as_num_of_columns(
lut_path, num_columns
):
lut_values = parse_lookup_table(lut_path)

assert isinstance(lut_values, list) and len(lut_values) == num_columns


@mark.parametrize("s, expected_t", [(2.0, 1.0), (3.0, 1.5), (5.0, 4.0), (5.25, 6.0)])
def test_linear_interpolation(s, expected_t):
lut_converter = linear_interpolation_lut(
Expand Down