diff --git a/src/daq_queuing_service/plugins/i15_1/auxiliary.py b/src/daq_queuing_service/plugins/i15_1/auxiliary.py index 061336f..a8ef3df 100644 --- a/src/daq_queuing_service/plugins/i15_1/auxiliary.py +++ b/src/daq_queuing_service/plugins/i15_1/auxiliary.py @@ -1,5 +1,6 @@ from enum import StrEnum from pathlib import Path +from typing import Literal from daq_config_server.models.i15_1.standards_puck import StandardsPin from pydantic import BaseModel, ConfigDict, computed_field @@ -32,6 +33,9 @@ def get_background_temperatures( ) +Q_MAX_OPTIONS = Literal[25, 30, 35, 40] + + class AuxiliaryScan(BaseModel): """Auxiliary scans are scans added automatically by the queue, such as background scans and standard sample calibration scans. They are needed for analysis of user @@ -42,6 +46,7 @@ class AuxiliaryScan(BaseModel): instrument_session: str pin: StandardsPin | None time_per_pdf: float + q_max: Q_MAX_OPTIONS list_of_temperatures: list[int] | None = None @computed_field @@ -79,6 +84,7 @@ def is_suitable( self.instrument_session == required_background.instrument_session and self.pin == required_background.pin and self.time_per_pdf >= required_background.time_per_pdf + and self.q_max >= required_background.q_max ) def _temperatures_match( @@ -142,6 +148,7 @@ def attempt_to_combine_with( pin=self.pin, time_per_pdf=max(self.time_per_pdf, required_background.time_per_pdf), list_of_temperatures=list_of_temperatures, + q_max=max(self.q_max, required_background.q_max), ) assert result.is_suitable(required_background) return result @@ -164,6 +171,7 @@ def from_experiment(cls, experiment: Experiment) -> "AuxiliaryScan": instrument_session=experiment.instrument_session, pin=pin, time_per_pdf=experiment.experiment_definition.data["time_per_pdf"], + q_max=experiment.experiment_definition.data["q_max"], list_of_temperatures=experiment.experiment_definition.data.get( "list_of_temperatures" ), diff --git a/src/daq_queuing_service/plugins/i15_1/i15_1_converter.py b/src/daq_queuing_service/plugins/i15_1/i15_1_converter.py index 5819c89..f5585df 100644 --- a/src/daq_queuing_service/plugins/i15_1/i15_1_converter.py +++ b/src/daq_queuing_service/plugins/i15_1/i15_1_converter.py @@ -295,6 +295,7 @@ def _get_required_auxiliary_scans( self, experiment: Experiment ) -> list[AuxiliaryScan]: time_per_pdf = experiment.experiment_definition.data["time_per_pdf"] + q_max = experiment.experiment_definition.data["q_max"] list_of_temperatures = experiment.experiment_definition.data.get( "list_of_temperatures" ) @@ -307,6 +308,7 @@ def _get_required_auxiliary_scans( instrument_session=experiment.instrument_session, pin=None, time_per_pdf=time_per_pdf, + q_max=q_max, ), AuxiliaryScan( instrument_session=experiment.instrument_session, @@ -314,6 +316,7 @@ def _get_required_auxiliary_scans( capillary=experiment.sample.data["capillary"], contents=None ), time_per_pdf=time_per_pdf, + q_max=q_max, list_of_temperatures=list_of_temperatures, ), AuxiliaryScan( @@ -322,6 +325,7 @@ def _get_required_auxiliary_scans( capillary=experiment.sample.data["capillary"], contents="Silicon" ), time_per_pdf=time_per_pdf, + q_max=q_max, ), ] @@ -329,7 +333,10 @@ def _construct_auxiliary_experiment( self, auxiliary_scan: AuxiliaryScan, instrument_session: str ) -> Experiment: LOGGER.debug(f"Constructing experiment for auxiliary scan: {auxiliary_scan}") - data: dict[str, Any] = {"time_per_pdf": auxiliary_scan.time_per_pdf} + data: dict[str, Any] = { + "time_per_pdf": auxiliary_scan.time_per_pdf, + "q_max": auxiliary_scan.q_max, + } if auxiliary_scan.list_of_temperatures: settle_time = ( self._queue_params.blower_auxiliary_collection_params.settle_time_s diff --git a/src/daq_queuing_service/plugins/i15_1/plans.py b/src/daq_queuing_service/plugins/i15_1/plans.py index 3942268..c2ce244 100644 --- a/src/daq_queuing_service/plugins/i15_1/plans.py +++ b/src/daq_queuing_service/plugins/i15_1/plans.py @@ -105,6 +105,7 @@ def get_data_collection( "exposure_time_per_frame": data_collection_params.exposure_time_per_frame_s, "scan_type": scan_type, "metadata": collection_metadata, + "q_max": experiment_definition.data["q_max"], } if experiment_is_blower(experiment): diff --git a/src/daq_queuing_service/plugins/i15_1/tiled_interaction.py b/src/daq_queuing_service/plugins/i15_1/tiled_interaction.py index 9e00504..9966b11 100644 --- a/src/daq_queuing_service/plugins/i15_1/tiled_interaction.py +++ b/src/daq_queuing_service/plugins/i15_1/tiled_interaction.py @@ -37,6 +37,7 @@ def _query_tiled(instrument_session: str) -> list[TiledAuxiliary]: .search(Comparison("ge", "stop.time", oldest_valid_time)) .search(In("start.scan_type", list(AuxiliaryScanType))) .search(KeyPresent("start.experiment_definition.data.time_per_pdf")) + .search(KeyPresent("start.experiment_definition.data.q_max")) ) items = sorted( @@ -70,6 +71,7 @@ def _query_tiled(instrument_session: str) -> list[TiledAuxiliary]: contents=sample["data"].get("composition"), ) time_per_pdf = start_doc["experiment_definition"]["data"]["time_per_pdf"] + q_max = start_doc["experiment_definition"]["data"]["q_max"] list_of_temperatures = start_doc["experiment_definition"]["data"].get( "list_of_temperatures" ) @@ -82,6 +84,7 @@ def _query_tiled(instrument_session: str) -> list[TiledAuxiliary]: filepath=filepath, pin=pin, time_per_pdf=time_per_pdf, + q_max=q_max, list_of_temperatures=list_of_temperatures, ) if auxiliary_scan.kind != start_doc["scan_type"]: diff --git a/tests/unit_tests/plugins/i15_1/test_auxiliary.py b/tests/unit_tests/plugins/i15_1/test_auxiliary.py index e478400..1e235ce 100644 --- a/tests/unit_tests/plugins/i15_1/test_auxiliary.py +++ b/tests/unit_tests/plugins/i15_1/test_auxiliary.py @@ -12,11 +12,13 @@ instrument_session="abc", pin=StandardsPin(capillary="bs1.0", contents="Silicon"), time_per_pdf=50, + q_max=30, ), AuxiliaryScan( instrument_session="abc", pin=StandardsPin(capillary="bs1.0", contents="Silicon"), time_per_pdf=50, + q_max=30, list_of_temperatures=[], ), True, @@ -26,11 +28,29 @@ instrument_session="abc", pin=StandardsPin(capillary="bs1.0", contents="Silicon"), time_per_pdf=50, + q_max=30, + ), + AuxiliaryScan( + instrument_session="abc", + pin=StandardsPin(capillary="bs1.0", contents="Silicon"), + time_per_pdf=50, + q_max=35, + list_of_temperatures=[], + ), + False, + ), + ( + AuxiliaryScan( + instrument_session="abc", + pin=StandardsPin(capillary="bs1.0", contents="Silicon"), + time_per_pdf=50, + q_max=30, ), AuxiliaryScan( instrument_session="def", pin=StandardsPin(capillary="bs1.0", contents="Silicon"), time_per_pdf=50, + q_max=30, ), False, ), @@ -39,11 +59,13 @@ instrument_session="abc", pin=StandardsPin(capillary="bs1.0", contents="Silicon"), time_per_pdf=50, + q_max=30, ), AuxiliaryScan( instrument_session="abc", pin=StandardsPin(capillary="bs1.5", contents="Silicon"), time_per_pdf=50, + q_max=30, ), False, ), @@ -52,12 +74,14 @@ instrument_session="abc", pin=StandardsPin(capillary="bs1.0", contents="Silicon"), time_per_pdf=50, + q_max=30, list_of_temperatures=[100, 200, 300], ), AuxiliaryScan( instrument_session="abc", pin=StandardsPin(capillary="bs1.0", contents="Silicon"), time_per_pdf=50, + q_max=30, ), False, ), @@ -66,12 +90,14 @@ instrument_session="abc", pin=StandardsPin(capillary="bs1.0", contents="Silicon"), time_per_pdf=50, + q_max=30, list_of_temperatures=[100, 200, 300], ), AuxiliaryScan( instrument_session="abc", pin=StandardsPin(capillary="bs1.0", contents="Silicon"), time_per_pdf=50, + q_max=30, list_of_temperatures=[100, 200, 300, 400], ), False, @@ -81,12 +107,14 @@ instrument_session="abc", pin=StandardsPin(capillary="bs1.0", contents="Silicon"), time_per_pdf=50, + q_max=40, list_of_temperatures=[90, 290, 490], ), AuxiliaryScan( instrument_session="abc", pin=StandardsPin(capillary="bs1.0", contents="Silicon"), time_per_pdf=50, + q_max=25, list_of_temperatures=[95, 250, 300, 450], ), True, @@ -107,18 +135,21 @@ def test_is_suitable_works_as_expected( instrument_session="abc", pin=StandardsPin(capillary="bs1.0", contents="Silicon"), time_per_pdf=10, + q_max=30, list_of_temperatures=[150, 250, 350], ), AuxiliaryScan( instrument_session="abc", pin=StandardsPin(capillary="bs1.0", contents="Silicon"), time_per_pdf=50, + q_max=25, list_of_temperatures=[100, 200, 300], ), AuxiliaryScan( instrument_session="abc", pin=StandardsPin(capillary="bs1.0", contents="Silicon"), time_per_pdf=50, # Max time_per_pdf + q_max=30, # Max q_max list_of_temperatures=[100, 200, 300, 400], # Covers whole temp range ), ), @@ -127,16 +158,19 @@ def test_is_suitable_works_as_expected( instrument_session="abc", pin=StandardsPin(capillary="bs1.0", contents="Silicon"), time_per_pdf=100, + q_max=40, ), AuxiliaryScan( instrument_session="abc", pin=StandardsPin(capillary="bs1.0", contents="Silicon"), time_per_pdf=50, + q_max=30, ), AuxiliaryScan( instrument_session="abc", pin=StandardsPin(capillary="bs1.0", contents="Silicon"), time_per_pdf=100, + q_max=40, ), ), ( @@ -144,18 +178,21 @@ def test_is_suitable_works_as_expected( instrument_session="abc", pin=StandardsPin(capillary="bs1.0", contents="Silicon"), time_per_pdf=40, + q_max=30, list_of_temperatures=[50, 610], ), AuxiliaryScan( instrument_session="abc", pin=StandardsPin(capillary="bs1.0", contents="Silicon"), time_per_pdf=100, + q_max=30, list_of_temperatures=[100, 200, 300], ), AuxiliaryScan( instrument_session="abc", pin=StandardsPin(capillary="bs1.0", contents="Silicon"), time_per_pdf=100, + q_max=30, list_of_temperatures=[50, 150, 250, 350, 450, 550, 650], ), ), @@ -177,12 +214,14 @@ def test_attempt_to_combine_with_works_as_expected( instrument_session="abc", pin=StandardsPin(capillary="bs1.0", contents="Silicon"), time_per_pdf=10, + q_max=30, list_of_temperatures=[150, 250, 350], ), AuxiliaryScan( instrument_session="abc", pin=StandardsPin(capillary="bs1.0", contents="Ga/In"), time_per_pdf=50, + q_max=30, list_of_temperatures=[100, 200, 300], ), ), @@ -191,12 +230,14 @@ def test_attempt_to_combine_with_works_as_expected( instrument_session="abc", pin=StandardsPin(capillary="bs1.0", contents="Silicon"), time_per_pdf=10, + q_max=30, list_of_temperatures=[150, 250, 350], ), AuxiliaryScan( instrument_session="abc", pin=StandardsPin(capillary="bs1.0", contents="Silicon"), time_per_pdf=50, + q_max=30, list_of_temperatures=[], ), ), @@ -205,11 +246,13 @@ def test_attempt_to_combine_with_works_as_expected( instrument_session="def", pin=StandardsPin(capillary="bs1.0", contents="Silicon"), time_per_pdf=10, + q_max=30, ), AuxiliaryScan( instrument_session="abc", pin=StandardsPin(capillary="bs1.0", contents="Silicon"), time_per_pdf=50, + q_max=30, ), ), ], diff --git a/tests/unit_tests/plugins/i15_1/test_i15_1_converter.py b/tests/unit_tests/plugins/i15_1/test_i15_1_converter.py index 934eb70..0081b83 100644 --- a/tests/unit_tests/plugins/i15_1/test_i15_1_converter.py +++ b/tests/unit_tests/plugins/i15_1/test_i15_1_converter.py @@ -17,6 +17,7 @@ from daq_queuing_service.broadcaster import Broadcaster, serialise from daq_queuing_service.plugins.i15_1.auxiliary import ( + Q_MAX_OPTIONS, AuxiliaryScan, AuxiliaryScanType, TiledAuxiliary, @@ -63,6 +64,7 @@ def i15_1_tasks(): "list_of_temperatures": [0, 20], "settle_time": 5, "ramp_rate": 10, + "q_max": 30, }, ), ), @@ -91,6 +93,7 @@ def i15_1_tasks(): "list_of_temperatures": [100, 120], "settle_time": 5, "ramp_rate": 10, + "q_max": 25, }, ), ), @@ -119,6 +122,7 @@ def i15_1_tasks(): "list_of_temperatures": [200, 220], "settle_time": 5, "ramp_rate": 10, + "q_max": 35, }, ), ), @@ -140,7 +144,12 @@ def i15_1_tasks(): positionInContainer=ContainerPosition(position=2), ), experiment_definition=ExperimentDefinition( - name="", id="", data={"time_per_pdf": 20} + name="", + id="", + data={ + "time_per_pdf": 20, + "q_max": 40, + }, ), ), id="5e2571d9-2f87-45b2-ac3b-b486e83a92d6", @@ -168,6 +177,7 @@ def i15_1_tasks(): "list_of_temperatures": [400, 420], "settle_time": 5, "ramp_rate": 10, + "q_max": 25, }, ), ), @@ -180,11 +190,14 @@ def i15_1_tasks(): return tasks -def make_background_task(capillary: STANDARD_CAPILLARY, time_per_pdf: int) -> Task: +def make_background_task( + capillary: STANDARD_CAPILLARY, time_per_pdf: int, q_max: Q_MAX_OPTIONS +) -> Task: background = AuxiliaryScan( instrument_session="cm12345-1", pin=StandardsPin(capillary=capillary, contents=None), time_per_pdf=time_per_pdf, + q_max=q_max, ) return Task( experiment=I151Converter()._construct_auxiliary_experiment( @@ -215,7 +228,10 @@ def create_task_dict(task_id: str, experiment: dict[str, Any]) -> dict[str, Any] def air_task( - task_id: str, instrument_session: str, time_per_pdf: float + task_id: str, + instrument_session: str, + time_per_pdf: float, + q_max: Q_MAX_OPTIONS, ) -> dict[str, Any]: return create_task_dict( task_id, @@ -226,7 +242,7 @@ def air_task( "experiment_definition": { "name": "Air", "id": "", - "data": {"time_per_pdf": time_per_pdf}, + "data": {"time_per_pdf": time_per_pdf, "q_max": q_max}, }, }, ) @@ -236,11 +252,12 @@ def empty_capillary_task( task_id: str, instrument_session: str, time_per_pdf: float, + q_max: Q_MAX_OPTIONS, list_of_temperatures: list[float] | None, capillary: STANDARD_CAPILLARY, standards_puck: StandardsPuck, ) -> dict[str, Any]: - data: dict[str, Any] = {"time_per_pdf": time_per_pdf} + data: dict[str, Any] = {"time_per_pdf": time_per_pdf, "q_max": q_max} if list_of_temperatures is not None: data.update( { @@ -283,6 +300,7 @@ def standard_sample_task( task_id: str, instrument_session: str, time_per_pdf: float, + q_max: Q_MAX_OPTIONS, capillary: STANDARD_CAPILLARY, contents: STANDARD_SAMPLE, standards_puck: StandardsPuck, @@ -311,7 +329,7 @@ def standard_sample_task( "experiment_definition": { "name": "Standard Sample", "id": "", - "data": {"time_per_pdf": time_per_pdf}, + "data": {"time_per_pdf": time_per_pdf, "q_max": q_max}, }, }, ) @@ -341,6 +359,7 @@ def background_found_in_tiled(): filepath=Path(""), instrument_session_directory=Path(""), filename="", + q_max=25, ) ), ) as mock_get_suitable_tiled_background: @@ -367,7 +386,7 @@ def test_given_sample_name_in_correct_format_then_correct_sample_loaded(): experiment = Experiment( name="test_experiment", experiment_definition=ExperimentDefinition( - name=" ", id="", data={"time_per_pdf": 100} + name=" ", id="", data={"time_per_pdf": 100, "q_max": 30} ), sample=make_sample("test_8_1", ""), instrument_session="cm12345-1", @@ -384,7 +403,7 @@ def test_centre_sample_at_room_temperature_uses_correct_params_from_queue_params experiment = Experiment( name="test_experiment", experiment_definition=ExperimentDefinition( - name=" ", id="", data={"time_per_pdf": 100} + name=" ", id="", data={"time_per_pdf": 100, "q_max": 30} ), sample=make_sample("test_8_1", ""), instrument_session="cm12345-1", @@ -399,7 +418,7 @@ def test_centre_sample_at_room_temperature_uses_correct_params_from_queue_params "exposure_time": centring_params.exposure_time_per_frame_s, "metadata": { "experiment_definition": ExperimentDefinition( - name=" ", id="", data={"time_per_pdf": 100} + name=" ", id="", data={"time_per_pdf": 100, "q_max": 30} ), "sample": make_sample("test_8_1", ""), }, @@ -419,6 +438,7 @@ def test_centre_sample_with_blower_uses_correct_params_from_queue_params( "time_per_pdf": 100, "settle_time": 5, "ramp_rate": 10, + "q_max": 30, }, ), sample=make_sample("test_8_1", ""), @@ -440,6 +460,7 @@ def test_centre_sample_with_blower_uses_correct_params_from_queue_params( "time_per_pdf": 100, "settle_time": 5, "ramp_rate": 10, + "q_max": 30, }, ), "sample": make_sample("test_8_1", ""), @@ -451,7 +472,7 @@ def test_session_and_number_of_tasks_per_experiment_is_expected(): experiment = Experiment( name="test_experiment", experiment_definition=ExperimentDefinition( - name=" ", id="", data={"time_per_pdf": 100} + name=" ", id="", data={"time_per_pdf": 100, "q_max": 30} ), sample=make_sample("test_8_1", ""), instrument_session="cm12345-1", @@ -466,7 +487,7 @@ def test_experiment_with_correct_experiment_type_are_converted(): experiment = Experiment( name="test_experiment", experiment_definition=ExperimentDefinition( - name="run_full_collection", id="", data={"time_per_pdf": 100} + name="run_full_collection", id="", data={"time_per_pdf": 100, "q_max": 30} ), sample=make_sample("test_8_1", ""), instrument_session="cm12345-1", @@ -490,7 +511,7 @@ def test_experiment_with_no_temperatures_runs_a_room_temperature_collection(): experiment = Experiment( name="test_experiment", experiment_definition=ExperimentDefinition( - name="", id="", data={"time_per_pdf": 100} + name="", id="", data={"time_per_pdf": 100, "q_max": 30} ), sample=make_sample("test_8_1", ""), instrument_session="cm12345-1", @@ -502,7 +523,7 @@ def test_experiment_with_no_temperatures_runs_a_room_temperature_collection(): assert tasks[4].params["scan_type"] == ScanType.DATA_COLLECTION assert tasks[4].params["metadata"] == { "experiment_definition": ExperimentDefinition( - name="", id="", data={"time_per_pdf": 100} + name="", id="", data={"time_per_pdf": 100, "q_max": 30} ), "sample": make_sample("test_8_1", ""), } @@ -517,6 +538,7 @@ def test_experiment_with_temperatures_runs_a_blower_collection(): "time_per_pdf": 100, "settle_time": 5, "ramp_rate": 10, + "q_max": 30, }, ) @@ -544,7 +566,7 @@ def test_experiment_with_no_sample_converts_to_air_scan(): experiment_definition = ExperimentDefinition( name="", id="", - data={"time_per_pdf": 100}, + data={"time_per_pdf": 100, "q_max": 30}, ) experiment = Experiment( @@ -560,11 +582,12 @@ def test_experiment_with_no_sample_converts_to_air_scan(): assert tasks[1].params == { "full_collection_time": 100, "exposure_time_per_frame": 1.0, + "q_max": 30, "scan_type": ScanType.DATA_COLLECTION, "metadata": { "sample": None, "experiment_definition": ExperimentDefinition( - name="", id="", data={"time_per_pdf": 100} + name="", id="", data={"time_per_pdf": 100, "q_max": 30} ), }, } @@ -579,6 +602,7 @@ def test_wait_for_beam_plans_added_by_converter(): "time_per_pdf": 100, "settle_time": 5, "ramp_rate": 10, + "q_max": 30, }, ) @@ -604,12 +628,13 @@ def test_tiled_backgrounds_added_to_metadata_if_present(): filepath=Path(""), instrument_session_directory=Path(""), filename="", + q_max=30, ) } experiment_definition = ExperimentDefinition( name="", id="", - data={"time_per_pdf": 100}, + data={"time_per_pdf": 100, "q_max": 30}, ) experiment = Experiment( @@ -631,6 +656,7 @@ def test_tiled_backgrounds_added_to_metadata_if_present(): filepath=Path(""), instrument_session_directory=Path(""), filename="", + q_max=30, ), }, } @@ -640,7 +666,7 @@ def test_mix_of_experiments_with_correct_experiment_type_are_converted(): good_experiment = Experiment( name="test_experiment", experiment_definition=ExperimentDefinition( - name="run_full_collection", id="", data={"time_per_pdf": 100} + name="run_full_collection", id="", data={"time_per_pdf": 100, "q_max": 30} ), sample=make_sample("test_8_1", ""), instrument_session="cm12345-1", @@ -677,7 +703,7 @@ def test_if_no_background_found_in_tiled_then_background_scan_added_to_tasks( experiment = Experiment( name="test_experiment", experiment_definition=ExperimentDefinition( - name="run_full_collection", id="", data={"time_per_pdf": 100} + name="run_full_collection", id="", data={"time_per_pdf": 100, "q_max": 40} ), sample=make_sample("test_8_1", ""), instrument_session="cm12345-1", @@ -688,12 +714,12 @@ def test_if_no_background_found_in_tiled_then_background_scan_added_to_tasks( ) tasks = converter.pre_process(None, [task], [], []) assert len(tasks) == 4 - assert tasks[0].model_dump() == air_task(tasks[0].id, "cm12345-1", 100.0) + assert tasks[0].model_dump() == air_task(tasks[0].id, "cm12345-1", 100.0, 40) assert tasks[1].model_dump() == empty_capillary_task( - tasks[1].id, "cm12345-1", 100.0, None, "fq1.0", standards_puck + tasks[1].id, "cm12345-1", 100.0, 40, None, "fq1.0", standards_puck ) assert tasks[2].model_dump() == standard_sample_task( - tasks[2].id, "cm12345-1", 100.0, "fq1.0", "Silicon", standards_puck + tasks[2].id, "cm12345-1", 100.0, 40, "fq1.0", "Silicon", standards_puck ) assert converter._tiled_auxiliary_scans == {"1": {}} @@ -703,16 +729,23 @@ def test_add_required_background_scans_does_not_add_the_same_background_twice( i15_1_tasks: list[Task], background_not_found_in_tiled: MagicMock, ): - bg_1 = AuxiliaryScan(instrument_session="cm12345-1", pin=None, time_per_pdf=5) + bg_1 = AuxiliaryScan( + instrument_session="cm12345-1", + pin=None, + time_per_pdf=5, + q_max=30, + ) bg_2 = AuxiliaryScan( instrument_session="cm12345-1", pin=StandardsPin(capillary="bs1.0", contents=None), time_per_pdf=10, + q_max=25, ) bg_3 = AuxiliaryScan( instrument_session="cm12345-1", pin=StandardsPin(capillary="fq1.0", contents=None), time_per_pdf=15, + q_max=35, ) def fake_get_required_auxiliary_scans(self: I151Converter, experiment: Experiment): @@ -811,38 +844,39 @@ def test_same_experiment_in_different_instrument_sessions_will_add_backgrounds_i assert len(new_tasks) == 15 - assert new_tasks[0].model_dump() == air_task(new_tasks[0].id, "cm12345-1", 25.0) + assert new_tasks[0].model_dump() == air_task(new_tasks[0].id, "cm12345-1", 25.0, 40) assert new_tasks[1].model_dump() == empty_capillary_task( new_tasks[1].id, "cm12345-1", 25.0, + 30, [0, 100, 200, 300, 400, 500], "fq1.0", standards_puck, ) assert new_tasks[2].model_dump() == standard_sample_task( - new_tasks[2].id, "cm12345-1", 25.0, "fq1.0", "Silicon", standards_puck + new_tasks[2].id, "cm12345-1", 25.0, 40, "fq1.0", "Silicon", standards_puck ) - assert new_tasks[4].model_dump() == air_task(new_tasks[4].id, "different", 10.0) + assert new_tasks[4].model_dump() == air_task(new_tasks[4].id, "different", 10.0, 25) assert new_tasks[5].model_dump() == empty_capillary_task( - new_tasks[5].id, "different", 10.0, [100, 200], "fq1.0", standards_puck + new_tasks[5].id, "different", 10.0, 25, [100, 200], "fq1.0", standards_puck ) assert new_tasks[6].model_dump() == standard_sample_task( - new_tasks[6].id, "different", 10.0, "fq1.0", "Silicon", standards_puck + new_tasks[6].id, "different", 10.0, 25, "fq1.0", "Silicon", standards_puck ) assert new_tasks[8].model_dump() == air_task( - new_tasks[8].id, "also_different", 10.0 + new_tasks[8].id, "also_different", 10.0, 35 ) assert new_tasks[9].model_dump() == empty_capillary_task( - new_tasks[9].id, "also_different", 10.0, [200, 300], "fq1.0", standards_puck + new_tasks[9].id, "also_different", 10.0, 35, [200, 300], "fq1.0", standards_puck ) assert new_tasks[10].model_dump() == standard_sample_task( - new_tasks[10].id, "also_different", 10.0, "fq1.0", "Silicon", standards_puck + new_tasks[10].id, "also_different", 10.0, 35, "fq1.0", "Silicon", standards_puck ) assert new_tasks[12].model_dump() == empty_capillary_task( - new_tasks[12].id, "cm12345-1", 20.0, None, "fq1.0", standards_puck + new_tasks[12].id, "cm12345-1", 20.0, 40, None, "fq1.0", standards_puck ) @@ -868,6 +902,7 @@ def test_add_required_background_scans_if_found_in_tiled_then_no_background_adde filepath=Path(""), instrument_session_directory=Path(""), filename="", + q_max=25, ) } for task in i15_1_tasks @@ -891,8 +926,9 @@ def test__ensure_background_in_queue_or_tiled_returns_if_suitable_already_queued instrument_session="cm12345-1", pin=StandardsPin(capillary="fq1.0", contents=None), time_per_pdf=25, + q_max=30, ) - new_tasks = [make_background_task("fq1.0", 25)] + new_tasks = [make_background_task("fq1.0", 25, 30)] result = i15_1_converter._ensure_auxiliary_in_queue_or_tiled( background, None, new_tasks, "task_id", "cm12345-1" ) @@ -906,11 +942,12 @@ def test__ensure_background_in_queue_or_tiled_returns_if_current_task_is_suitabl instrument_session="cm12345-1", pin=StandardsPin(capillary="fq1.0", contents=None), time_per_pdf=25, + q_max=40, ) new_tasks: list[Task] = [] result = i15_1_converter._ensure_auxiliary_in_queue_or_tiled( background, - TaskWithPosition.from_task(make_background_task("fq1.0", 25)), + TaskWithPosition.from_task(make_background_task("fq1.0", 25, q_max=40)), new_tasks, "task_id", "cm12345-1", @@ -925,17 +962,18 @@ def test__ensure_background_in_queue_or_tiled_modifies_queued_background_if_poss instrument_session="cm12345-1", pin=StandardsPin(capillary="fq1.0", contents=None), time_per_pdf=25, + q_max=40, ) - current_task = TaskWithPosition.from_task(make_background_task("fq1.0", 25)) + current_task = TaskWithPosition.from_task(make_background_task("fq1.0", 25, 40)) # Current task is suitable but not a background assert isinstance(current_task.experiment, Experiment) current_task.experiment.experiment_definition.name = "Not a background" - new_tasks = [make_background_task("fq1.0", 10)] + new_tasks = [make_background_task("fq1.0", 10, 30)] result = i15_1_converter._ensure_auxiliary_in_queue_or_tiled( background, current_task, new_tasks, "task_id", "cm12345-1" ) assert len(result) == 1 - assert_tasks_equal(result[0], make_background_task("fq1.0", 25)) + assert_tasks_equal(result[0], make_background_task("fq1.0", 25, 40)) def test__ensure_background_in_queue_or_tiled_adds_background_if_none_suitable_in_queue( @@ -946,12 +984,13 @@ def test__ensure_background_in_queue_or_tiled_adds_background_if_none_suitable_i instrument_session="cm12345-1", pin=StandardsPin(capillary="fq1.0", contents=None), time_per_pdf=25, + q_max=35, ) result = i15_1_converter._ensure_auxiliary_in_queue_or_tiled( background, None, [], "task_id", "cm12345-1" ) assert len(result) == 1 - assert_tasks_equal(result[0], make_background_task("fq1.0", 25)) + assert_tasks_equal(result[0], make_background_task("fq1.0", 25, 35)) def test__ensure_background_in_queue_or_tiled_saves_tiled_info_if_exists( @@ -963,6 +1002,7 @@ def test__ensure_background_in_queue_or_tiled_saves_tiled_info_if_exists( instrument_session="cm12345-1", pin=StandardsPin(capillary="fq1.0", contents=None), time_per_pdf=25, + q_max=35, ) result = i15_1_converter._ensure_auxiliary_in_queue_or_tiled( background, None, [], "task_id", "cm12345-1" @@ -978,6 +1018,7 @@ def test__ensure_background_in_queue_or_tiled_saves_tiled_info_if_exists( filepath=Path(""), instrument_session_directory=Path(""), filename="", + q_max=25, ) } } @@ -1019,12 +1060,13 @@ def test_i15_1_tasks_can_be_serialised(): filepath=Path(""), instrument_session_directory=Path(""), filename="", + q_max=35, ) } experiment_definition = ExperimentDefinition( name="", id="", - data={"time_per_pdf": 100}, + data={"time_per_pdf": 100, "q_max": 25}, ) experiment = Experiment( diff --git a/tests/unit_tests/plugins/i15_1/test_tiled_interaction.py b/tests/unit_tests/plugins/i15_1/test_tiled_interaction.py index 1cd01b6..2ce2496 100644 --- a/tests/unit_tests/plugins/i15_1/test_tiled_interaction.py +++ b/tests/unit_tests/plugins/i15_1/test_tiled_interaction.py @@ -28,13 +28,13 @@ def mock_current_time(): @pytest.fixture() def mock_tiled_searches( tiled_client: MagicMock, -) -> tuple[MagicMock, MagicMock, MagicMock, MagicMock, MagicMock, MagicMock]: +) -> tuple[MagicMock, MagicMock, MagicMock, MagicMock, MagicMock, MagicMock, MagicMock]: result_1 = MagicMock() result_1.metadata = { "start": { "time": 1, - "experiment_definition": {"data": {"time_per_pdf": 10}}, + "experiment_definition": {"data": {"time_per_pdf": 10, "q_max": 35}}, "sample_info": None, "data_session_directory": "/path/to/data/2026/cm12345-1", "scan_file": "i15-1-10000", @@ -45,7 +45,7 @@ def mock_tiled_searches( result_2.metadata = { "start": { "time": 10, - "experiment_definition": {"data": {"time_per_pdf": 11}}, + "experiment_definition": {"data": {"time_per_pdf": 11, "q_max": 35}}, "sample_info": {"data": {"capillary": "fq1.0"}}, "data_session_directory": "/path/to/data/2026/cm12345-1", "scan_file": "i15-1-10001", @@ -56,7 +56,7 @@ def mock_tiled_searches( result_3.metadata = { "start": { "time": 2, - "experiment_definition": {"data": {"time_per_pdf": 9}}, + "experiment_definition": {"data": {"time_per_pdf": 9, "q_max": 30}}, "sample_info": {"data": {"capillary": "fq1.0"}}, "data_session_directory": "/path/to/data/2026/cm12345-1", "scan_file": "i15-1-10002", @@ -67,7 +67,7 @@ def mock_tiled_searches( result_4.metadata = { "start": { "time": 5, - "experiment_definition": {"data": {"time_per_pdf": 12}}, + "experiment_definition": {"data": {"time_per_pdf": 12, "q_max": 25}}, "sample_info": {"data": {"capillary": "fq1.0"}}, "data_session_directory": "/path/to/data/2026/cm12345-1", "scan_file": "i15-1-10003", @@ -84,6 +84,7 @@ def mock_tiled_searches( "list_of_temperatures": [100, 200, 300], "ramp_rate": 0, "settle_time": 10, + "q_max": 35, } }, "sample_info": {"data": {"capillary": "fq1.0"}}, @@ -93,8 +94,8 @@ def mock_tiled_searches( } } - search_result_6 = MagicMock() - search_result_6.search = MagicMock( + search_result_7 = MagicMock() + search_result_7.search = MagicMock( return_value={ "tiled_id_1": result_1, "tiled_id_2": result_2, @@ -104,6 +105,8 @@ def mock_tiled_searches( } ) + search_result_6 = MagicMock() + search_result_6.search = MagicMock(return_value=search_result_7) search_result_5 = MagicMock() search_result_5.search = MagicMock(return_value=search_result_6) search_result_4 = MagicMock() @@ -122,19 +125,24 @@ def mock_tiled_searches( search_result_4, search_result_5, search_result_6, + search_result_7, ) def test_get_suitable_tiled_background_makes_expected_searches( mock_tiled_searches: tuple[ - MagicMock, MagicMock, MagicMock, MagicMock, MagicMock, MagicMock + MagicMock, MagicMock, MagicMock, MagicMock, MagicMock, MagicMock, MagicMock ], queue_params: QueueParameters, ): - client, search_2, search_3, search_4, search_5, search_6 = mock_tiled_searches + client, search_2, search_3, search_4, search_5, search_6, search_7 = ( + mock_tiled_searches + ) get_suitable_tiled_scan( client, - AuxiliaryScan(instrument_session="cm12345-1", pin=None, time_per_pdf=10), + AuxiliaryScan( + instrument_session="cm12345-1", pin=None, time_per_pdf=10, q_max=35 + ), queue_params.tiled_stale_time_s, ) client.search.assert_called_once_with(Eq(key="start.instrument", value="i15-1")) @@ -151,6 +159,9 @@ def test_get_suitable_tiled_background_makes_expected_searches( search_6.search.assert_called_once_with( KeyPresent("start.experiment_definition.data.time_per_pdf") ) + search_7.search.assert_called_once_with( + KeyPresent("start.experiment_definition.data.q_max") + ) @pytest.mark.parametrize( @@ -161,6 +172,7 @@ def test_get_suitable_tiled_background_makes_expected_searches( instrument_session="cm12345-1", pin=StandardsPin(capillary="fq1.0", contents=None), time_per_pdf=10, + q_max=30, ), TiledAuxiliary( instrument_session="cm12345-1", @@ -170,6 +182,7 @@ def test_get_suitable_tiled_background_makes_expected_searches( filename="i15-1-10001.nxs", instrument_session_directory=Path("/path/to/data/2026/cm12345-1"), filepath=Path("/path/to/data/2026/cm12345-1/i15-1-10001.nxs"), + q_max=35, ), ), ( @@ -178,6 +191,7 @@ def test_get_suitable_tiled_background_makes_expected_searches( pin=StandardsPin(capillary="fq1.0", contents=None), time_per_pdf=10, list_of_temperatures=[150, 250], + q_max=30, ), TiledAuxiliary( instrument_session="cm12345-1", @@ -188,6 +202,7 @@ def test_get_suitable_tiled_background_makes_expected_searches( instrument_session_directory=Path("/path/to/data/2026/cm12345-1"), filepath=Path("/path/to/data/2026/cm12345-1/i15-1-10004.nxs"), list_of_temperatures=[100, 200, 300], + q_max=35, ), ), ], @@ -210,7 +225,9 @@ def test_get_suitable_tiled_background_returns_none_if_no_matching_backgrounds_f assert ( get_suitable_tiled_scan( client, - AuxiliaryScan(instrument_session="cm12345-1", pin=None, time_per_pdf=10), + AuxiliaryScan( + instrument_session="cm12345-1", pin=None, time_per_pdf=10, q_max=30 + ), 1000000, ) is None @@ -236,7 +253,9 @@ def test_get_suitable_tiled_background_skips_tiled_scan_if_no_capillary_found_an with caplog.at_level(logging.WARNING): tiled_scan = get_suitable_tiled_scan( client, - AuxiliaryScan(instrument_session="cm12345-1", pin=None, time_per_pdf=10), + AuxiliaryScan( + instrument_session="cm12345-1", pin=None, time_per_pdf=10, q_max=30 + ), 1000000, ) assert tiled_scan is None @@ -251,7 +270,7 @@ def test_get_suitable_tiled_background_skips_tiled_scan_if_scan_type_doesnt_matc result.metadata = { "start": { "time": 10, - "experiment_definition": {"data": {"time_per_pdf": 11}}, + "experiment_definition": {"data": {"time_per_pdf": 11, "q_max": 25}}, "sample_info": {"data": {"capillary": "fq1.0"}}, "data_session_directory": "/path/to/data/2026/cm12345-1", "scan_file": "i15-1-10001", @@ -262,7 +281,9 @@ def test_get_suitable_tiled_background_skips_tiled_scan_if_scan_type_doesnt_matc with caplog.at_level(logging.WARNING): tiled_scan = get_suitable_tiled_scan( client, - AuxiliaryScan(instrument_session="cm12345-1", pin=None, time_per_pdf=10), + AuxiliaryScan( + instrument_session="cm12345-1", pin=None, time_per_pdf=10, q_max=30 + ), 1000000, ) assert tiled_scan is None