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
4 changes: 2 additions & 2 deletions helm/daq-config-server/converter_map.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -66,5 +66,5 @@
converter: DetectorXYLookupTable
- path: "/dls_sw/i19-1/software/i19-acquisition/i19-shared/lookup/energy_to_id_gap_look_up_table.txt"
converter: UndulatorEnergyGapLookupTable
- path: "/dls_sw/i15-1/software/daq_configuration/tth_angle_to_collection_time.json"
converter: AnglesToTimes
- path: "/dls_sw/i15-1/software/daq_configuration/collection_specification.json"
converter: CollectionSpecification
6 changes: 4 additions & 2 deletions src/daq_config_server/app/_file_converter_map.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@
from daq_config_server.models.feature_settings.i04_feature_settings import (
I04FeatureSettings,
)
from daq_config_server.models.i15_1.positions_to_times import AnglesToTimes
from daq_config_server.models.i15_1.collection_specification import (
CollectionSpecification,
)
from daq_config_server.models.i15_1.xpdf_crystal_lut import XpdfCrystalLookupTable
from daq_config_server.models.i15_1.xpdf_parameters import TemperatureControllersConfig
from daq_config_server.models.lookup_tables import (
Expand Down Expand Up @@ -61,7 +63,7 @@ def init_converter_map(config: ConverterConfig):
"HyperionFeatureSettings": HyperionFeatureSettings.from_domain_properties,
"TemperatureControllersConfig": TemperatureControllersConfig.from_xpdf_parameters,
"XpdfCrystalLookupTable": XpdfCrystalLookupTable.from_contents,
"AnglesToTimes": AnglesToTimes.from_lut,
"CollectionSpecification": CollectionSpecification.from_lut,
}


Expand Down
42 changes: 42 additions & 0 deletions src/daq_config_server/models/i15_1/collection_specification.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
from pydantic import BaseModel, field_validator

from daq_config_server.models.base_model import ConfigModel
from daq_config_server.models.utils import parse_lut_rows


class SpecificationPerPosition(BaseModel):
exposure_time: float
transmission: float


class CollectionSpecification(ConfigModel):
tth_angle_to_specification: dict[float, SpecificationPerPosition]

@field_validator("tth_angle_to_specification", mode="after")
@classmethod
def _normalise_to_fractions(
cls,
angles_spec: dict[float, SpecificationPerPosition],
) -> dict[float, SpecificationPerPosition]:
"""This allows the time values inside the config file to have arbitrary units.
Once parsed, they will all be as a fraction out of 1, so you can do
positions_and_rel_times[position] * total_time to get the time for that
position.
"""
weighting = 1 / sum([spec.exposure_time for spec in angles_spec.values()])
for spec in angles_spec.values():
spec.exposure_time *= weighting

return angles_spec

@classmethod
def from_lut(cls, contents: str):
rows = parse_lut_rows(contents, types=[float, float, float])
return cls(
tth_angle_to_specification={
row[0]: SpecificationPerPosition(
exposure_time=row[1], transmission=row[2]
)
for row in rows
}
)
29 changes: 0 additions & 29 deletions src/daq_config_server/models/i15_1/positions_to_times.py

This file was deleted.

28 changes: 14 additions & 14 deletions tests/test_data/i15-1/test_tth_angle_to_collection_time.txt
Original file line number Diff line number Diff line change
@@ -1,21 +1,21 @@
# This file specifies which angles the tth will go do during a regular data collection.
# It also specifies the proportion of the total collection time spent at each angle.
# It also specifies the proportion of the total collection time spent at each angle and the transmission at each angle.
# The time values can be in any arbitary units - their relative values are all that matter.
# E.g, the following two tables are equivalent
#
# 90 1
# 180 2
# 270 3
# 90 1 100
# 180 2 100
# 270 3 100
#
#
# 90 0.05
# 180 0.01
# 270 0.15
# 90 0.05 100
# 180 0.01 100
# 270 0.15 100

# Angle (deg) Time
10 0.05
20 0.05
30 0.1
40 0.2
50 0.3
60 0.3
# Angle (deg) Time Transmission (percentage)
10 0.05 0.01
20 0.05 0.1
30 0.1 1
40 0.2 10
50 0.3 50
60 0.3 100
44 changes: 44 additions & 0 deletions tests/unit_tests/models/i15_1/test_collection_specification.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import pytest
from tests.constants import TestDataPaths

from daq_config_server.models.i15_1.collection_specification import (
CollectionSpecification,
SpecificationPerPosition,
)


def test_collection_spec_parses_json_contents():
with open(TestDataPaths.TEST_I15_1_POSITIONS_TIMES_LUT) as f:
contents = f.read()

result = CollectionSpecification.from_lut(contents)
assert result.tth_angle_to_specification == {
10: SpecificationPerPosition(exposure_time=0.05, transmission=0.01),
20: SpecificationPerPosition(exposure_time=0.05, transmission=0.1),
30: SpecificationPerPosition(exposure_time=0.1, transmission=1),
40: SpecificationPerPosition(exposure_time=0.2, transmission=10),
50: SpecificationPerPosition(exposure_time=0.3, transmission=50),
60: SpecificationPerPosition(exposure_time=0.3, transmission=100),
}


def test_collection_spec_normalises_times():
result = CollectionSpecification.model_validate(
{
"tth_angle_to_specification": {
10: {"exposure_time": 1, "transmission": 0.01},
20: {"exposure_time": 1, "transmission": 0.01},
30: {"exposure_time": 2, "transmission": 0.01},
40: {"exposure_time": 4, "transmission": 0.01},
50: {"exposure_time": 6, "transmission": 0.01},
60: {"exposure_time": 6, "transmission": 0.01},
}
}
)

exposures = [
spec.exposure_time for spec in result.tth_angle_to_specification.values()
]

assert exposures == pytest.approx([0.05, 0.05, 0.1, 0.2, 0.3, 0.3]) # pyright: ignore[reportUnknownMemberType]
assert sum(exposures) == 1
44 changes: 0 additions & 44 deletions tests/unit_tests/models/i15_1/test_positions_to_times.py

This file was deleted.

Loading